Vai al contenuto
animorio
EN
Tutti i componenti

Il pulsante della carta regalo

Pulsanti, 3D, SVGCanvas, GSAPImpegnativaPeso compresso: Demo 15 KBGSAP 28 KBGratisScarica lo zip

La riga Add gift wrap · €4 di un carrello, con una scatolina di cartone avana nella punta tonda della pillola, disegnata in 3D su un canvas. Al clic la impacchetta davvero: un foglio di carta a righe arriva aperto intorno alla scatola, i due fianchi si alzano e schioccano sulle facce, poi il davanti e il dietro, e le due metà del coperchio si piegano una sull'altra; la stampa continua da un lembo all'altro e il retro bianco della carta si vede finché il lembo non si gira. Poi un nastro di raso corre intorno nei due sensi e sopra si annoda un fiocco in SVG ridisegnato a ogni fotogramma: i cappi si gonfiano dal nodo, le code scendono e oscillano su una molla, un riflesso passa sul raso. La pillola dice Gift wrapped con una piccola pillola Remove; un altro clic tira una coda, scioglie il fiocco, sfila il nastro e riapre la carta.

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 gift wrap button</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/mona-sans@5.3.0/wdth.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <!-- the gift wrap button: the Add gift wrap line of a shopping cart, with a small kraft box in the round left end
         of the pill. A click wraps it for real, in 3D: a sheet of printed paper folds up onto its faces and over its
         top, a satin ribbon runs round it both ways and a bow is tied on top, its loops puffing out and its tails
         swinging. Another click unties the bow, slides the ribbon off and opens the paper -->
    <div class="wrap" data-gift>
      <button class="wrap__btn" type="button" data-btn data-autoclic>
        <span class="wrap__fill" aria-hidden="true"></span>
        <span class="wrap__art" aria-hidden="true">
          <canvas class="wrap__box" data-box></canvas>
          <svg class="wrap__bow" viewBox="0 0 76 60" data-bow>
            <defs>
              <linearGradient id="gift-loop" x1="0" y1="0" x2="1" y2="0.35">
                <stop offset="0" class="st-dark"/>
                <stop offset="0.22" class="st-mid"/>
                <stop offset="0.5" class="st-light"/>
                <stop offset="0.68" class="st-mid"/>
                <stop offset="1" class="st-dark"/>
              </linearGradient>
              <linearGradient id="gift-tail" x1="0" y1="0" x2="0.4" y2="1">
                <stop offset="0" class="st-dark"/>
                <stop offset="0.3" class="st-mid"/>
                <stop offset="0.62" class="st-light"/>
                <stop offset="1" class="st-mid"/>
              </linearGradient>
              <linearGradient id="gift-knot" x1="0" y1="0" x2="0" y2="1">
                <stop offset="0" class="st-light"/>
                <stop offset="0.55" class="st-mid"/>
                <stop offset="1" class="st-dark"/>
              </linearGradient>
              <linearGradient id="gift-sheen" gradientUnits="userSpaceOnUse" x1="0" y1="0" x2="10" y2="6" data-sheen>
                <stop offset="0" stop-color="#fff" stop-opacity="0"/>
                <stop offset="0.5" stop-color="#fff" stop-opacity="0.7"/>
                <stop offset="1" stop-color="#fff" stop-opacity="0"/>
              </linearGradient>
            </defs>
            <g data-bow-all>
              <path class="wrap__tail" fill="url(#gift-tail)" data-tail="l"/>
              <path class="wrap__tail" fill="url(#gift-tail)" data-tail="r"/>
              <path fill="url(#gift-loop)" data-loop="l"/>
              <path class="wrap__hole" data-hole="l"/>
              <path class="wrap__gleam" data-gleam="l"/>
              <path fill="url(#gift-loop)" data-loop="r"/>
              <path class="wrap__hole" data-hole="r"/>
              <path class="wrap__gleam" data-gleam="r"/>
              <path fill="url(#gift-knot)" data-knot/>
              <path class="wrap__crease" data-crease/>
              <path fill="url(#gift-sheen)" data-shine/>
            </g>
          </svg>
        </span>
        <span class="wrap__faces">
          <span class="wrap__face" data-face="rest">
            <span class="wrap__word" data-wide="Add gift wrap" data-rest-text>Add gift wrap</span>
            <span class="wrap__price" data-price-text>· €4</span>
          </span>
          <span class="wrap__face wrap__face--busy" data-face="busy" aria-hidden="true">
            <span class="wrap__shine" data-busy-text>Wrapping…</span>
          </span>
          <span class="wrap__face wrap__face--done" data-face="done" aria-hidden="true">
            <span class="wrap__done" data-done-text>Gift wrapped</span>
            <span class="wrap__chip" data-remove-text>Remove</span>
          </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.

26 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 della carta regalo» da Animorio e adattala al mio sito

Cosa fa

Su un fondo bianco una pillola verde pino scuro, alta 60 pixel, con un filo di luce in alto e un'ombra morbida sotto. Nella punta tonda di sinistra, su una piccola pozza di luce, una scatolina di cartone avana vista dall'alto e di tre quarti: il fondo e il coperchio un poco più largo, ogni faccia illuminata dalla lampada in alto a sinistra, col bordo sottile e l'ombra del coperchio sul fondo. A destra, in Mona Sans color avorio, Add gift wrap e, più spento, · €4. All'arrivo il pulsante sale piano e il coperchio fa un saltello. Passando sopra la pillola la scritta si allarga, il fondo si gonfia con un rimbalzo e il coperchio salta su e ricade rimbalzando, mostrando il buio dentro la scatola. Al clic la scritta sale sfocandosi e arriva Wrapping…, con un riflesso che la attraversa. Intorno alla scatola compare un foglio di carta avorio a righe rosse oblique con un filo d'oro e una fila di puntini, ancora aperto: i due fianchi si alzano e schioccano sulle facce con un piccolo rimbalzo, poi il davanti e il dietro; la scatola si schiaccia appena a ogni colpo. Le due metà del coperchio si piegano sopra, prima quella davanti e poi quella dietro, che le si posa sopra con la sua ombra. Le righe continuano da un lembo all'altro come su un foglio vero, e finché un lembo guarda dall'altra parte se ne vede il retro bianco. Poi un nastro di raso rosso sale sul davanti e corre sopra, un altro attraversa il coperchio e scende sul fianco, con la luce che corre lungo il raso. Sul nodo si gonfia un fiocco: due cappi che escono dal nodo, si aprono con la loro piega scura dentro e sbattono un poco, due code dal taglio a coda di rondine che scendono e oscillano, e un riflesso passa su tutto il fiocco. La pillola si allarga con un rimbalzo su Gift wrapped e una piccola pillola Remove. Un altro clic tira una coda: i cappi rientrano nel nodo, il nastro si sfila, le metà del coperchio si rialzano, i lembi si riaprono e la carta sparisce; il coperchio fa un saltello e la pillola torna a Add gift wrap · €4. Con la tastiera il fuoco mostra un anello e il coperchio saluta; Invio o Spazio impacchettano.

Come funziona

Una scatola in 3D su un canvas

Una camera ortografica guarda la scatola dall'alto (27 gradi) e di lato (36 gradi): tre vettori, VIEW verso l'occhio, RIGHT e UP sullo schermo, e un punto 3D diventa un punto dello schermo con due prodotti scalari. La camera vede sempre il davanti, il fianco destro e il sopra, quindi la scatola (il fondo e il coperchio, due parallelepipedi) si disegna senza ordinare niente: solo le tre facce visibili, ognuna col colore schiarito o scurito dal prodotto scalare fra la sua normale e la lampada, un gradiente verso l'alto e un bordo sottile. Il coperchio ha un'altezza in più che una molla con la gravità fa saltare sotto il puntatore.

La carta: un foglio piegato dalle sue cerniere

Il foglio è una rete piatta: il fondo, quattro lembi intorno e due metà del coperchio attaccate al davanti e al dietro. Ogni lembo conserva il suo rettangolo nella rete (u lungo la larghezza, v lungo la profondità) e un punto di riferimento con due vettori 3D, che dipendono dagli angoli delle cerniere: aperto di a gradi, il davanti va lungo (0, cos a, sin a), e la sua metà del coperchio gira ancora di g gradi sul bordo di sopra. In una proiezione ortografica un rettangolo resta un parallelogramma, quindi una sola trasformazione affine (setTransform) porta le coordinate della rete sullo schermo in modo esatto, e la stampa (un pattern in unità del foglio) continua da un lembo all'altro attraverso le pieghe. Il segno del prodotto scalare fra la normale e l'occhio dice quale lato si vede: la stampa o il retro bianco.

L'ordine in cui si disegna

Niente z-buffer: i lembi del dietro e del fianco sinistro si disegnano prima della scatola, quelli del davanti e del fianco destro dopo, e la metà dietro del coperchio passa da prima a dopo quando ha superato i 45 gradi, cioè quando sta sopra la scatola. La metà dietro ha una cerniera tre decimi più alta, così chiusa si posa su quella davanti, e il suo bordo libero lascia un filo d'ombra. Il nastro si disegna alla fine, a strisce sulle facce chiuse, con un gradiente di traverso (scuro ai bordi, una riga di luce) che fa il raso: la sua corsa è una lunghezza che sale sul davanti e poi attraversa il coperchio, e un'altra che attraversa il coperchio e scende sul fianco.

Il fiocco in SVG

Il fiocco è un SVG sopra il canvas, ridisegnato a ogni fotogramma: ogni cappio è una goccia di due curve di Bézier che parte dal nodo, con dentro l'apertura più scura e un filo di luce sul bordo di sopra, il destro e il sinistro speculari e girati di 15 gradi in su; le code sono strisce un poco curve con la coda di rondine e il taglio storto delle forbici. La grandezza dei cappi viene da GSAP, il loro battere da una molla (2,4 oscillazioni al secondo) e l'oscillazione delle code da un'altra (1,6), spinte da un colpo quando il fiocco si annoda o il puntatore arriva. Un gradiente bianco che corre su cappi e nodo fa il riflesso del raso. Per sciogliere, una variabile pull rimpicciolisce i cappi verso il nodo mentre la coda destra si allunga.

I tempi e gli stati

Una timeline GSAP muove gli angoli dei lembi (power3.in, poi un piccolo schiocco di 3,5 gradi e una schiacciata elastica di tutta la scatola), le pieghe del coperchio, le due corse del nastro e il fiocco; PACE ne cambia la velocità con timeScale. Il ciclo di disegno gira solo mentre qualcosa si muove: un'impronta di tutti i valori decide se ridisegnare, e quando molle e coperchio sono fermi si addormenta. Il pulsante è un button vero: aria-disabled mentre impacchetta e scarta, una zona aria-live dice Wrapping your gift…, Gift wrap added, €4. e Gift wrap removed., e impacchettato l'aria-label dice Gift wrapped. Remove gift wrap. Impacchettare dura circa tre secondi, più dei 2,8 fra un clic e l'altro dell'anteprima: il secondo clic cade nell'attesa e il pacchetto finito resta in vista un giro intero.

Valori da cambiare

NomeFileDi partenzaCosa cambia
LABELscript.jsAdd gift wrapLa scritta a riposo. Se è troppo lunga per lo spazio, il carattere si rimpicciolisce.
PRICEscript.js€4Il prezzo della confezione, dopo la scritta (vuoto, niente prezzo); lo dice anche la zona aria-live.
BUSYscript.jsWrapping…La scritta mentre la carta si piega e il nastro corre.
DONEscript.jsGift wrappedLa scritta a pacchetto fatto.
REMOVEscript.jsRemoveLa piccola pillola a destra: dice che un altro clic toglie la confezione.
PACEscript.js1Il passo dell'impacchettare: 2 ci mette il doppio, 0,5 la metà.
OPENscript.js36Quanto è aperta la carta quando arriva, in gradi: più alto, i lembi arrivano più distesi e fanno più strada.
LOOPSscript.js1La grandezza dei cappi e delle code del fiocco.
SPRINGscript.js1Quanto è vivo il fiocco: quanto battono i cappi e oscillano le code quando si annoda o arriva il puntatore. 0 stanno fermi.
HOPscript.js1Quanto salta il coperchio sotto il puntatore. 0 resta fermo.

Provali nel Playground

Quando usarla

Per l'opzione regalo di un carrello o di una cassa: la confezione regalo, il biglietto d'auguri, l'imballo speciale. Sta bene nei negozi di cose da regalare, di cosmetica, di libri, di cioccolato e nei periodi delle feste. Il pacchetto è simulato: in un negozio vero il clic aggiunge la voce al carrello, e lo stato fatto aspetta la risposta del server.

Sul telefono

La pillola a riposo è larga circa 255 pixel e quella fatta circa 290: a 390 pixel ci stanno con margine, e se la scritta è più lunga dello spazio il carattere si rimpicciolisce. Il tocco schiaccia il fondo e impacchetta; senza il puntatore il coperchio salta all'arrivo e quando la carta va via. La scatola resta della sua misura.

Con il movimento ridotto

Niente pieghe, niente nastro che corre e niente fiocco che si gonfia: al clic il pacchetto finito appare in dissolvenza sopra la scatola nuda, poi il fiocco in dissolvenza, e Wrapping… e Gift wrapped arrivano in dissolvenza; la pillola prende la nuova larghezza mentre le parole sono sparite. Il coperchio non salta e la pillola non si gonfia (sotto il mouse il fondo si schiarisce appena). Un altro clic fa sparire carta e fiocco in dissolvenza.

Trappole

  • Gli stop dei gradienti SVG scritti come stop-color="var(--satin)" restavano neri: un attributo di presentazione non legge le variabili CSS. I colori del raso stanno in tre classi CSS (stop-color in una regola), così il Playground li cambia.
  • Il foglio arrivava aperto a 42 gradi con le metà del coperchio dritte: il lembo di dietro, alto più di venti unità, usciva sopra la punta tonda della pillola, sul bianco della pagina. Ora arriva a 36 gradi con le metà già piegate a 50, e il canvas è ritagliato con la forma della punta tonda.
  • Il prezzo · €4 stava lontano dalla scritta: la copia invisibile della scritta larga, che tiene il posto per l'hover, aggiunge una quindicina di pixel. Il prezzo ha un margine negativo, e sotto il puntatore la scritta allargata gli arriva giusta accanto.
  • Alla prima prova il saltello del coperchio sotto il puntatore non si vedeva: due pixel e mezzo, a 60 pixel di pillola. La spinta è passata da 34 a 50 unità al secondo, un salto di circa cinque pixel che ricade con due rimbalzi.

Librerie

GSAP 3.15.0, Mona Sans (font variabile) 5.3.0.

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

Collaudo

Provata il 12 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