Vai al contenuto
animorio
EN
Tutti i componenti

Il pulsante di miele

Pulsanti, SVG, FisicaGSAPImpegnativaPeso compresso: Demo 7,0 KBGSAP 28 KBGratisScarica lo zip

Una pillola di miele con una goccia che pende sotto: un riflesso di luce scivola sulla superficie dietro al puntatore, la goccia si gonfia e si allunga quando ti avvicini, e al clic il filo si assottiglia e si spezza, la goccia cade, schizza e si apre in una piccola pozza. Poi dalla pillola ricresce una goccia nuova.

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 honey button</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/geist@5.3.0/index.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <!-- the honey button: an amber pill of real-looking honey with a drop hanging under it. A light glides over its
         surface after the pointer, the drop swells and stretches when you come near, and pressing lets it go: the
         thread thins and snaps, the drop falls, splashes and settles into a small pool, the words say "Added to
         cart", and a moment later a new drop grows back out of the pill -->
    <div class="honey" data-honey>
      <svg class="honey__svg" aria-hidden="true" data-svg>
        <defs>
          <linearGradient id="honey-fill" gradientUnits="userSpaceOnUse" x1="0" y1="0" x2="0" y2="260" data-fill></linearGradient>
          <filter id="honey-goo" filterUnits="userSpaceOnUse" x="-64" y="-24" width="360" height="340" color-interpolation-filters="sRGB" data-filter>
            <feGaussianBlur in="SourceGraphic" stdDeviation="3.4" result="blur"/>
            <feColorMatrix in="blur" type="matrix" values="1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 20 -9" result="goo"/>
            <feGaussianBlur in="goo" stdDeviation="1.7" result="bump"/>
            <feDiffuseLighting in="bump" surfaceScale="5" diffuseConstant="1.3" lighting-color="#ffffff" result="shade">
              <fePointLight x="116" y="-60" z="140" data-light-a/>
            </feDiffuseLighting>
            <feComponentTransfer in="shade" result="soft">
              <feFuncR type="linear" slope="0.5" intercept="0.55"/>
              <feFuncG type="linear" slope="0.5" intercept="0.55"/>
              <feFuncB type="linear" slope="0.5" intercept="0.55"/>
            </feComponentTransfer>
            <feComposite in="goo" in2="soft" operator="arithmetic" k1="1" k2="0" k3="0" k4="0" result="lit"/>
            <feSpecularLighting in="bump" surfaceScale="5" specularConstant="1.1" specularExponent="26" lighting-color="#fff4cf" result="glint" data-glint>
              <fePointLight x="116" y="-60" z="140" data-light-b/>
            </feSpecularLighting>
            <feComposite in="glint" in2="goo" operator="in" result="glint-in"/>
            <feComposite in="lit" in2="glint-in" operator="arithmetic" k1="0" k2="1" k3="1" k4="0" result="honey"/>
            <feDropShadow in="honey" dx="0" dy="10" stdDeviation="7" flood-color="#a35a00" flood-opacity="0.28"/>
          </filter>
        </defs>
        <g filter="url(#honey-goo)" data-goo>
          <rect data-pill x="0" y="0" width="232" height="60" rx="30" fill="url(#honey-fill)"/>
        </g>
      </svg>
      <button class="honey__btn" type="button" aria-label="Order a jar" data-btn data-autoclic>
        <span class="honey__word" aria-hidden="true" data-word>Order a jar</span>
        <span class="honey__word honey__word--done" aria-hidden="true" data-done>
          <svg class="honey__tick" viewBox="0 0 20 20"><path data-tick d="M4.5 10.5l3.6 3.6 7.4-8.2"/></svg>
          <span data-done-text>Added to cart</span>
        </span>
      </button>
      <p class="sr" aria-live="polite" data-live></p>
    </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 di miele» da Animorio e adattala al mio sito

Cosa fa

Su un fondo bianco una pillola alta 60 pixel di miele ambrato, lucida, con un bordo scuro che le dà volume e una goccia che pende sotto di lei attaccata da un filo sottile. Sotto il mouse un riflesso di luce segue il puntatore sulla superficie, la goccia si gonfia e il filo si allunga di un'altra metà, e la goccia oscilla su una molla morbida inclinandosi verso il puntatore. Premendo la pillola si schiaccia; al clic la goccia cade: il filo si assottiglia mentre la goccia accelera, si spezza, il moncone rientra nella pillola e dal mezzo del filo cade una goccina. Arrivata a terra la goccia schizza sei goccioline e si apre in una pozza larga e bassa che ondeggia un attimo. La scritta sale e diventa «Added to cart» con una spunta che si disegna. Dopo due secondi e mezzo la pozza viene ripresa e una goccia nuova esce dalla pillola con un rimbalzo, mentre la scritta torna. Con la tastiera il comportamento è lo stesso.

Come funziona

Il miele è un gruppo SVG con un filtro

Un rettangolo arrotondato, un'ellisse per la goccia, una fila di dodici cerchi per il filo, la pozza e le goccioline stanno tutti in un solo gruppo. Il filtro sfoca il gruppo di 3,4 pixel e poi ritaglia il bordo con una matrice di colore sull'alfa (moltiplica per 20 e toglie 9): le forme che si toccano si fondono come metaball e i bordi tornano netti.

La luce

Il risultato del filtro precedente, sfocato un poco di nuovo, fa da mappa di altezze per due luci dallo stesso punto: una diffusa, che dà il volume (alzata di un minimo con un feComponentTransfer, altrimenti il lato lontano diventa nero), e una speculare, il riflesso lucido. Lo script sposta il punto di luce verso il puntatore e lo riporta in alto a riposo.

La goccia è una molla, poi un corpo che cade

A riposo la goccia segue una molla sulla lunghezza voluta (più lunga se il puntatore è vicino) e un'altra sull'orizzontale, che la piega verso il puntatore. Al clic le molle si spengono e valgono gravità e velocità. L'ellisse si allunga con la velocità tenendo la stessa area.

Il filo

Dodici cerchi tra il piede della pillola e la goccia, più grossi alle due estremità e più sottili in mezzo. Il raggio di mezzo scende con la lunghezza (come una stima del volume che si conserva); quando scende sotto 1,3 il filo si spezza: un moncone rientra nella pillola e una goccina parte dal punto di mezzo.

L'arrivo

La pozza è un'ellisse con due molle sotto-smorzate, una per la larghezza e una per l'altezza, così al contatto ondeggia. Le goccioline sono corpi con una gravità più leggera; quando toccano terra danno un colpetto alla molla della pozza. Dopo HOLD secondi la pozza viene portata a zero e la goccia nuova cresce dalla pillola, con la molla che la fa rimbalzare.

Valori da cambiare

NomeFileDi partenzaCosa cambia
LABELscript.js'Order a jar'La scritta a riposo.
DONEscript.js'Added to cart'La scritta dopo che la goccia è caduta.
DRIPscript.js[32, 50]La lunghezza della goccia che pende, a riposo e con il puntatore vicino, in pixel.
GRAVITYscript.js2600Quanto forte cade la goccia.
HOLDscript.js2.6I secondi in cui resta la pozza prima di riprendere il miele.
PUDDLEscript.js30La mezza larghezza della pozza, in pixel.
SPLASHscript.js6Quante goccioline lancia l'arrivo.
GROUNDscript.js230A che distanza sotto la pillola si forma la pozza, in pixel.
SHINEscript.js[0.85, 30]Il riflesso lucido: quanto forte e quanto stretto.
COLORSscript.js['#ffcb3d', '#f39a00', '#c9700a']Il miele, dall'alto al piede.

Provali nel Playground

Quando usarla

Per un acquisto, un'ordinazione o un «aggiungi» dove il prodotto è una cosa da mangiare, da cucinare o da regalare, e il pulsante può avere una materia e un gesto.

Sul telefono

I tocchi fanno come i clic. Col dito non ci sono il riflesso che segue il puntatore né la goccia che si allunga all'avvicinarsi; la caduta e la pozza sì. La parte bassa della scena (circa 230 pixel sotto la pillola) deve poter stare nello schermo.

Con il movimento ridotto

Niente molle, niente caduta, niente schizzi e niente riflesso che si muove. Al clic la goccia sparisce, la pozza è già al suo posto e le scritte si danno il cambio con una dissolvenza; poi la goccia torna.

Trappole

  • La luce diffusa moltiplicata sul colore rende neri i bordi che guardano lontano dalla luce: va alzata con un minimo (feComponentTransfer, pendenza 0,5 e base 0,55).
  • Un filo più sottile di circa un pixel e mezzo sparisce nel filtro: il filo si spezza prima che sparisca, non dopo.
  • La regione del filtro è in coordinate dell'SVG e non della forma: se si lascia quella di default le gocce che cadono vengono tagliate sul bordo.
  • Il clic non deve aspettare che la goccia sia cresciuta: un clic arrivato nel primo secondo veniva ignorato e l'anteprima automatica non vedeva niente.
  • Pozza, goccioline e goccia si disegnano con una sola serie di elementi riusati: crearne di nuovi a ogni clic fa crescere il gruppo e il filtro rallenta.

Librerie

GSAP 3.15.0, Geist (font variabile) 5.3.0.

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

Collaudo

Provata il 6 ottobre 2026

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

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