Vai al contenuto
animorio
EN
Tutti i componenti

Il pulsante magnetico

Pulsanti, HoverGSAPMediaPeso compresso: Demo 4,8 KBGSAP 28 KBGratisScarica lo zip

Un grande pulsante rotondo che viene incontro al puntatore: quando il puntatore si avvicina il pulsante si sporge verso di lui, la scritta dentro si sporge ancora un po’ e una luce calda gli si accende sotto; quando se ne va, il pulsante torna al suo posto su una molla. Intorno gira un anello di parole, più veloce finché la calamita tiene.

Il codice

Una cartella che funziona da sola: index.html, style.css, script.js e le librerie da CDN. Nelle schede React e Vue la stessa demo è già un componente, che spegne le sue animazioni quando esce dalla pagina.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>The magnetic button</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/manrope@5.3.0/index.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <div class="magnets" data-magnets>
      <!-- the big magnet: a round button with a ring of words turning around it, faster while the pointer holds it -->
      <div class="reel" data-reel>
        <svg class="reel__ring" data-ring viewBox="0 0 300 300" aria-hidden="true">
          <defs><path id="ring-path" d="M150 150m-128 0a128 128 0 1 1 256 0a128 128 0 1 1-256 0"/></defs>
          <text xml:space="preserve"><textPath href="#ring-path" textLength="800">WATCH THE FILM  /  TWO MINUTES  /  TURN THE SOUND ON  /  </textPath></text>
        </svg>
        <div class="magnet magnet--round" data-magnet data-pull="1">
          <span class="magnet__ripple" aria-hidden="true"></span>
          <a class="magnet__body round" href="#" data-body aria-label="Play the film">
            <span class="magnet__glow" aria-hidden="true"></span>
            <span class="magnet__label round__label" data-label>
              <svg class="round__play" viewBox="0 0 24 24" aria-hidden="true"><path d="M8 5.5v13l10.5-6.5z"/></svg>
              <span>Play<br>the film</span>
            </span>
          </a>
        </div>
      </div>

      <!-- two smaller magnets: they follow the pointer half as much as the big one -->
      <div class="pills">
        <div class="magnet" data-magnet data-pull="0.55">
          <span class="magnet__ripple" aria-hidden="true"></span>
          <a class="magnet__body pill pill--full" href="#" data-body>
            <span class="magnet__glow" aria-hidden="true"></span>
            <span class="magnet__label" data-label>Our work</span>
          </a>
        </div>
        <div class="magnet" data-magnet data-pull="0.55">
          <span class="magnet__ripple" aria-hidden="true"></span>
          <a class="magnet__body pill pill--line" href="#" data-body>
            <span class="magnet__glow" aria-hidden="true"></span>
            <span class="magnet__label" data-label>Say hello</span>
          </a>
        </div>
      </div>
    </div>
  </main>

  <script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.min.js"></script>
  <script src="script.js"></script>
</body>
</html>

Playground

Cambia valori, colori e testi con le manopole e guarda l’animazione rispondere dal vivo. Oppure scrivi tu nel codice. Poi scarica la cartella con le tue modifiche.

20 valori da cambiare

Oppure chiedila a Claude Code

Col connettore di Animorio, Claude Code la prende da qui con tutta la sua guida e la adatta al tuo progetto. Incolla questa richiesta:

Prendi «Il pulsante magnetico» da Animorio e adattala al mio sito

Cosa fa

Un grande pulsante rotondo color crema su un fondo nero, Play the film, con un anello di parole che gli gira intorno: WATCH THE FILM, TWO MINUTES, TURN THE SOUND ON. Sotto ci sono due pillole, Our work piena e Say hello col solo contorno. Quando il puntatore arriva a meno di 90 pixel dai bordi di un pulsante, il pulsante lo insegue: si sposta verso di lui del 40% della distanza dal suo centro, la scritta dentro di un altro 22%, e dentro il pulsante si accende una luce color ambra proprio sotto il puntatore. Le pillole fanno lo stesso a poco più di metà. Quando il puntatore se ne va, il pulsante torna al suo posto con un rimbalzo elastico. L’anello fa un giro ogni 26 secondi e, finché la calamita tiene il pulsante grande, accelera fino a un giro ogni 7. Premendo, il pulsante si stringe al 92% e ne esce un anello color ambra che si allarga e svanisce. All’arrivo il pulsante grande cresce al suo posto e le pillole salgono dopo di lui.

Come funziona

La zona che non si muove

Ogni calamita è un involucro che non si sposta mai, con dentro il corpo del pulsante che si muove. La zona che cattura il puntatore è il rettangolo dell’involucro allargato di REACH pixel per lato: se fosse il pulsante stesso, spostandosi verso il puntatore si porterebbe dietro la zona e non lo lascerebbe più andare.

L’inseguimento

A ogni movimento del mouse ogni calamita misura la distanza fra il puntatore e il centro del suo involucro e la moltiplica per PULL per il corpo, per LABEL per la scritta, e per il data-pull del pulsante (1 per quello grande, 0,55 per le pillole). Il corpo non salta lì: a ogni fotogramma del ticker di GSAP percorre una parte della strada che resta, 1 − e^(−dt / (FOLLOW / 4)), che non dipende da quanti fotogrammi al secondo fa lo schermo. Una sola scrittura dello stile per fotogramma sposta il corpo, e una la scritta.

La luce

Dentro il pulsante c’è uno strato con un gradiente radiale centrato su due variabili CSS, --gx e --gy, che lo script aggiorna con la posizione del puntatore in percentuale del pulsante. Lo strato si accende con una transizione d’opacità quando la calamita tiene.

Il ritorno

Quando il puntatore esce dalla zona, un tween porta gli stessi numeri a zero in 1,2 secondi con un elastic.out di forza e tempo SPRING: il pulsante oltrepassa il suo posto, torna indietro e si ferma.

L’anello di parole

Le parole stanno su un textPath lungo un cerchio, con textLength perché coprano il giro intero. GSAP le fa girare all’infinito, un giro ogni SPIN[0] secondi; quando la calamita tiene il pulsante grande la timeScale del tween sale a SPIN[0] / SPIN[1] in 0,8 secondi, e torna a 1 quando lo lascia.

La pressione

Premere stringe il corpo a PRESS in 0,15 secondi e fa partire dall’involucro un anello che cresce di RIPPLE[0] volte e svanisce in RIPPLE[1] secondi, partendo da dove si trova il corpo in quel momento. Lasciare riporta il corpo alla sua misura con una molla. Con il tasto Tab la luce si accende al centro del pulsante, e Invio lo preme.

Valori da cambiare

NomeFileDi partenzaCosa cambia
PULLscript.js0.4Quanto segue il puntatore un pulsante, come parte della distanza (le pillole fanno poco più di metà).
LABELscript.js0.22Quanto va oltre la scritta dentro il pulsante, come parte della distanza.
REACHscript.js90A quanti pixel dai bordi di un pulsante la calamita cattura il puntatore.
FOLLOWscript.js0.6I secondi che impiega un pulsante a raggiungere il puntatore.
SPRINGscript.js[1, 0.3]La molla quando il puntatore lascia il pulsante: la sua forza e quanto in fretta si ferma.
PRESSscript.js0.92Quanto si stringe un pulsante premuto.
RIPPLEscript.js[1.6, 0.75]L’anello di una pressione: quanto cresce e in quanti secondi.
SPINscript.js[26, 7]I secondi di un giro dell’anello di parole: a riposo e finché la calamita tiene.

Provali nel Playground

Quando usarla

Per un’azione sola e importante su una pagina calma: guarda il film, scrivici, prenota. Il pulsante grande vuole spazio intorno, almeno quanto la sua zona di cattura, e non va messo accanto ad altre calamite: si contenderebbero il puntatore.

Sul telefono

Il pulsante grande si stringe alla larghezza dello schermo e le pillole restano sotto. Senza un puntatore che si avvicina non c’è attrazione: il tocco accende la luce dove tocca il dito per mezzo secondo, stringe il pulsante e fa partire l’anello.

Con il movimento ridotto

I pulsanti non si muovono, la pressione non li stringe e l’anello di parole sta fermo. Restano la luce sotto il puntatore e l’anello della pressione, che compare e svanisce senza crescere.

Trappole

  • La zona di cattura deve stare ferma: se si misura il pulsante che si muove, il pulsante si porta dietro la zona e il puntatore non riesce più a liberarsene.
  • Corpo e scritta si spostano con un translate3d scritto a mano a ogni fotogramma: un gsap.to a ogni movimento del mouse creerebbe decine di tween al secondo che si contendono lo stesso elemento.
  • L’anello va fatto girare intorno al suo centro con transformOrigin: svgOrigin vale solo per gli elementi dentro un svg, e sull’svg principale lo fa girare intorno al punto sbagliato.
  • Il testo dell’anello ha xml:space="preserve": senza, gli spazi doppi intorno alle barre si riducono a uno e la frase non si distribuisce sul giro come previsto.

Librerie

GSAP 3.15.0, Manrope (font variabile) 5.3.0.

Compressi con gzip, i tre file della demo pesano 4,8 KB; le librerie: GSAP 28 KB.

Collaudo

Provata il 2 ottobre 2026

  • Computer: Fatto
  • Telefono: Fatto
  • Movimento ridotto: Fatto
  • Safari su iPhone: Fatto

Licenza d’uso

Puoi usarla nei tuoi progetti e in quelli dei tuoi clienti. Non puoi rivenderla né ridistribuirla così com’è. GSAP resta sotto la sua licenza Standard. Licenza completa.

Tutti i componenti