
Il banner dei cookie
Consenso, Transizioni, SVG, Fisica
NuovaGratis
Il carrello di un fioraio dove l'ordine è il mazzo: ogni stelo nel carrello è uno stelo nel disegno, su una sua molla. Col più uno stelo entra dall'alto e gli altri si aprono per fargli posto oscillando, col meno viene sfilato; una riga tolta sfila tutti i suoi steli (con Annulla, che li rimette ognuno al suo posto) e, raggiunta la consegna gratis, la carta da pacchi avvolge il mazzo e un nastro si annoda in un fiocco.
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 florist's cart</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource/young-serif@5.3.0/index.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/wix-madefor-text@5.3.0/index.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<!-- the drawings: flower heads, leaves; the bouquet and the thumbnails use them -->
<svg class="defs" aria-hidden="true" focusable="false">
<defs>
<radialGradient id="g-ranunculus" cx="0.45" cy="0.35" r="0.75">
<stop offset="0" class="st-ra-hi"/>
<stop offset="1" class="st-ra"/>
</radialGradient>
<linearGradient id="g-tulip" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" class="st-tu-hi"/>
<stop offset="1" class="st-tu"/>
</linearGradient>
<radialGradient id="g-anemone" cx="0.5" cy="0.5" r="0.6">
<stop offset="0.35" class="st-an-in"/>
<stop offset="1" class="st-an"/>
</radialGradient>
<g id="h-ranunculus">
<circle r="16" class="ra-out"/>
<path d="M-15.6 2.4A16 16 0 0 0 15.6 2.4A17 13 0 0 1-15.6 2.4Z" class="ra-shade"/>
<circle cy="-1.6" r="12.4" class="ra-mid"/>
<path d="M-12 0.6A12.4 12.4 0 0 0 12 0.6A13 9.6 0 0 1-12 0.6Z" class="ra-shade"/>
<circle cy="-3" r="8.8" class="ra-out"/>
<path d="M-8.4 -1.6A8.8 8.8 0 0 0 8.4 -1.6A9.2 6.8 0 0 1-8.4 -1.6Z" class="ra-shade"/>
<circle cy="-4.2" r="5.2" class="ra-mid"/>
<circle cy="-4.8" r="2.3" class="ra-heart"/>
</g>
<g id="h-tulip">
<path d="M-11.5 -3C-12.5 -13 -7 -19.5 0 -21.5C7 -19.5 12.5 -13 11.5 -3C10.5 6.5 5.5 11 0 11C-5.5 11 -10.5 6.5 -11.5 -3Z" class="tu-back"/>
<path d="M-12.5 -6C-13.5 -15.5 -9.5 -21 -4.5 -23C-2 -15 2.5 -6 3 2.5C3 8.5 1 11.2 0 11.2C-6.5 11.2 -11.5 5 -12.5 -6Z" class="tu-side"/>
<path d="M12.5 -6C13.5 -15.5 9.5 -21 5 -22.5C2 -15 -1.5 -6 -2 2.5C-2 8.5 0 11.2 1 11.2C6.5 11.2 11.5 5 12.5 -6Z" class="tu-side"/>
<path d="M-6.5 -1.5C-7.2 -12 -3.2 -18.5 0 -20.8C3.2 -18.5 7.2 -12 6.5 -1.5C5.8 6 3.2 10.4 0 10.8C-3.2 10.4 -5.8 6 -6.5 -1.5Z" class="tu-front"/>
<path d="M-2.6 -14C-3.4 -8 -3 -1 -1.6 5" class="tu-gleam"/>
</g>
<g id="h-anemone">
<g transform="scale(1 0.88)">
<path d="M0 -1C-7 -4 -9.5 -12 -6 -16.5C-3 -19.5 3 -19.5 6 -16.5C9.5 -12 7 -4 0 -1Z" class="an-petal" transform="rotate(10)"/>
<path d="M0 -1C-7 -4 -9.5 -12 -6 -16.5C-3 -19.5 3 -19.5 6 -16.5C9.5 -12 7 -4 0 -1Z" class="an-petal" transform="rotate(130)"/>
<path d="M0 -1C-7 -4 -9.5 -12 -6 -16.5C-3 -19.5 3 -19.5 6 -16.5C9.5 -12 7 -4 0 -1Z" class="an-petal" transform="rotate(250)"/>
<path d="M0 -1C-7.5 -4 -10 -12.5 -6.4 -17.4C-3.2 -20.4 3.2 -20.4 6.4 -17.4C10 -12.5 7.5 -4 0 -1Z" class="an-petal" transform="rotate(70)"/>
<path d="M0 -1C-7.5 -4 -10 -12.5 -6.4 -17.4C-3.2 -20.4 3.2 -20.4 6.4 -17.4C10 -12.5 7.5 -4 0 -1Z" class="an-petal" transform="rotate(190)"/>
<path d="M0 -1C-7.5 -4 -10 -12.5 -6.4 -17.4C-3.2 -20.4 3.2 -20.4 6.4 -17.4C10 -12.5 7.5 -4 0 -1Z" class="an-petal" transform="rotate(310)"/>
<circle r="6.6" class="an-ring"/>
<circle r="3.9" class="an-heart"/>
<circle cx="-1.2" cy="-1.3" r="1.3" class="an-gleam"/>
</g>
</g>
<g id="lf-eucalyptus">
<ellipse rx="6" ry="5.2" class="eu-leaf"/>
<path d="M-3.8 -1.2C-1.6 -3 1.8 -3 3.6 -1.4" class="eu-bloom"/>
</g>
<path id="lf-tulip" d="M0 0C5.5 -9 7.5 -27 2.6 -44C-2.6 -28 -4.4 -11 0 0Z" class="tu-leaf"/>
</defs>
</svg>
<main class="stage">
<!-- a florist's cart, and the order is the bouquet: every stem in it is a stem in the drawing, on its own spring.
More stems open the bouquet, a line removed is pulled out of it (with undo), and from the free delivery
total the bouquet is wrapped in kraft paper and tied with a ribbon -->
<section class="cart" aria-labelledby="cart-title" data-cart data-autoclic>
<header class="cart__head">
<h2 class="cart__title" id="cart-title">Your bouquet</h2>
<p class="cart__count" data-count></p>
</header>
<div class="table" data-table>
<svg class="bouquet" viewBox="0 0 360 178" aria-hidden="true" data-bouquet>
<g data-paper-back>
<path class="paper-back" d="M166 170L86 52C96 40 108 36 120 42C130 26 148 24 160 34C172 18 190 18 200 32C212 22 230 26 238 42C250 36 264 40 274 52L194 170Z"/>
<path class="paper-back-fold" d="M120 42C126 60 132 80 142 104M200 32C198 56 194 82 188 106M238 42C232 62 224 84 214 106"/>
</g>
<g data-stems-back></g>
<g data-stems-front></g>
<g class="twine-wrap">
<g class="twine" data-twine>
<path d="M171 134C176 137 184 137 189 134M170.5 138C176 141 184 141 189.5 138"/>
<path d="M189 136C194 139 196 145 194 150"/>
</g>
</g>
<g data-paper-left>
<path class="paper-front" d="M186 172L92 78C112 86 140 92 168 90L192 150Z"/>
<path class="paper-lip" d="M92 78C112 86 140 92 168 90L166 97C140 98 114 92 92 78Z"/>
</g>
<g data-paper-right>
<path class="paper-front paper-front--r" d="M174 172L268 78C248 86 220 92 192 90L168 150Z"/>
<path class="paper-lip" d="M268 78C248 86 220 92 192 90L194 97C220 98 246 92 268 78Z"/>
</g>
<g data-ribbon>
<path class="ribbon" d="M152 130C170 135 190 135 208 130L207 138C190 143 170 143 153 138Z" data-band/>
<g data-tails>
<path class="ribbon ribbon--dark" d="M178 136C174 146 168 156 160 166L166 166L168 172C176 160 181 148 182 137Z" data-tail-l/>
<path class="ribbon" d="M182 136C186 146 192 156 200 166L194 166L192 172C184 160 179 148 178 137Z" data-tail-r/>
</g>
<g data-loops>
<path class="ribbon" d="M178 133C170 122 154 120 152 128C150 136 166 140 178 136Z"/>
<path class="ribbon" d="M182 133C190 122 206 120 208 128C210 136 194 140 182 136Z"/>
<path class="ribbon-fold" d="M176 132C168 126 160 125 157 128M184 132C192 126 200 125 203 128"/>
<rect class="ribbon ribbon--knot" x="175.5" y="129.5" width="9" height="8.5" rx="3"/>
</g>
</g>
</svg>
<p class="goal" data-goal></p>
<button class="restart" type="button" hidden data-restart>Start with the house mix</button>
</div>
<ul class="lines" aria-label="Stems in your bouquet" data-lines></ul>
<div class="sums">
<p class="sums__row"><span>Subtotal</span><span class="sums__n" data-sub></span></p>
<p class="sums__row"><span>Delivery</span><span class="sums__n"><s class="sums__was" data-was></s><span data-ship></span></span></p>
</div>
<button class="pay" type="button" data-pay>
<span class="pay__face" data-pay-face>
<svg class="pay__spin" viewBox="0 0 20 20" aria-hidden="true" data-pay-spin><path d="M10 2.6a7.4 7.4 0 1 1-7.4 7.4"/></svg>
<svg class="pay__tick" viewBox="0 0 20 20" aria-hidden="true" data-pay-tick><path d="M4.6 10.4l3.6 3.6 7.2-7.6"/></svg>
<span class="pay__label" data-pay-label></span>
</span>
</button>
<p class="sr" aria-live="polite" data-live></p>
</section>
</main>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.min.js"></script>
<script src="script.js"></script>
</body>
</html>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.
48 valori da cambiare
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 carrello del fioraio» da Animorio e adattala al mio sitoOgni stelo ha un angolo e una lunghezza che inseguono il loro posto con una molla (SPRING: rigidità e smorzamento), calcolata in due mezzi passi per fotogramma col passo limitato a 1/30 di secondo. Lo stelo nuovo parte 72 unità più in alto e scende al suo posto; quello sfilato prende come meta 96 unità più in su e intanto svanisce. Un solo requestAnimationFrame muove tutti gli steli e si ferma quando nessuno si muove più: a riposo non si ridisegna niente.
Ogni stelo nasce con una preferenza fra sinistra e destra presa a passi della sezione aurea, così le specie restano mescolate (l'eucalipto va verso i bordi, come il verde intorno ai fiori). Gli steli in ordine di preferenza si dividono il ventaglio, largo fino a SPREAD gradi e tanto più quanti sono; quelli in mezzo sono più lunghi, così le teste fanno una cupola, e una fila sta davanti all'altra. Incartato, il ventaglio si stringe del 13%.
A ogni fotogramma lo stelo è un tracciato SVG: dritto sotto la legatura, poi una curva quadratica fino alla testa. Il punto di controllo sta a un angolo più chiuso, così il gambo sale a fontana e si apre verso la testa, e si sposta con la velocità di rotazione: la metà del gambo va avanti e la testa resta indietro, come in un fiore vero. Spinto in su, il pezzo sotto la legatura si accorcia. La testa è un use ruotato lungo la tangente della curva, le foglie dell'eucalipto sono messe lungo la curva coi punti e le tangenti della Bézier.
Remove sfila gli steli uno dopo l'altro e ne tiene le proprietà (preferenza, fila, lunghezza, inclinazione): Undo li ricrea uguali e nello stesso ordine di disegno, quindi tornano al loro posto e alla loro profondità. La riga cambia altezza misurata prima e dopo lo scambio fra corpo e striscia; l'anello di Undo è un cerchio il cui stroke-dashoffset scorre in UNDO secondi insieme a un delayedCall di GSAP, e tutti e due si fermano col puntatore o il fuoco sulla striscia.
La consegna gratis fa partire una timeline sui gruppi SVG della carta, con svgOrigin sulla punta del cono: il foglio dietro cresce dalla punta, i due davanti girano e si allungano con back.out, il nastro si stende, una spinta in giù su tutte le molle fa affondare il mazzo nella carta, e il fiocco e le code arrivano con elastic.out. Tornando sotto, i fogli si ripiegano nella punta invece di aprirsi di lato, così non passano mai sopra la frase accanto. Un clic da script (l'anteprima della libreria) è un cliente finto: un ranuncolo in più, via i tulipani, Undo, un eucalipto in più e uno in meno, un ranuncolo in meno.
| Nome | File | Di partenza | Cosa cambia |
|---|---|---|---|
ITEMS | script.js | [['Ranunculus', 3.2, 4, 'ranunculus'], …] | Le righe del carrello: nome, prezzo di uno stelo in euro, quanti e disegno (ranunculus, tulip, anemone o eucalyptus). |
FREE | script.js | 35 | Il subtotale da cui la consegna è gratis e il mazzo viene incartato, in euro. |
DELIVERY | script.js | 4.95 | Quanto costa la consegna sotto quella cifra, in euro. |
MAX | script.js | 9 | Il massimo di steli di una specie. |
SPRING | script.js | [230, 0.42] | Le molle degli steli: quanto sono rigide e quanto sono frenate (1 = senza oscillare). |
SPREAD | script.js | 62 | Quanto si apre al massimo il mazzo, in gradi da ogni lato della verticale. |
WRAP | script.js | 0.7 | I secondi che la carta impiega ad avvolgere il mazzo. |
UNDO | script.js | 5 | I secondi in cui resta Undo dopo aver tolto una riga. |
BRUSH | script.js | 1 | Quanto ondeggiano i fiori quando il puntatore ci passa in mezzo (0 = per niente). |
Per il carrello di un fioraio, di un vivaio o di chi compone qualcosa pezzo per pezzo (un cesto regalo, una scatola di dolci, una cassetta di frutta): un elenco con un totale, una soglia da raggiungere e un'anteprima viva di quello che si sta comprando.
A 390 pixel il carrello è largo 358 e il mazzo si ridisegna nella stessa scala; tutti i bottoni si toccano col dito e non aspettano il doppio tocco (touch-action manipulation). Il passaggio del dito sul mazzo lo fa ondeggiare come il mouse, e la pagina scorre lo stesso in verticale (touch-action pan-y). Steli alzati e altri trasparenti solo col mouse o con la tastiera, mai dopo un tocco.
Niente molle e niente spostamenti: gli steli compaiono e spariscono in dissolvenza direttamente al loro posto, la carta e il fiocco arrivano e se ne vanno in dissolvenza, le cifre cambiano senza sfocarsi, le righe cambiano senza animare l'altezza e i fiori non ondeggiano sotto il puntatore.
GSAP 3.15.0, Young Serif 5.3.0, Wix Madefor Text (font variabile) 5.3.0.
Compressi con gzip, i tre file della demo pesano 16 KB; le librerie: GSAP 28 KB.
Provata il 6 ottobre 2026
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.
Con l’email e la password del tuo account.
oppure con l’email
Hai fatto l’accesso come .
Con l’account scarichi lo zip di ogni animazione e di ogni pacchetto, gratis.