
Standing letters with a long shadow
Text, Scroll, 3D
NewFree
Scroll inside the preview
A can drawn on a canvas, with no 3D and no frames: the flat label wraps around it one column of pixels at a time, and as you scroll it turns a full circle between two huge words uncovered by a curtain.
A folder that runs on its own: index.html, style.css, script.js and the libraries from a CDN. The React and Vue tabs hold the same demo as a ready component, which switches its animations off when it leaves the page.
<!doctype html>
<html lang="it">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>La lattina che gira</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/mona-sans@5.3.0/standard.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main>
<section class="intro">
<p class="nota" data-nota>Scorri: la lattina fa un giro intero mentre attraversi la sezione, e le due parole dietro si scoprono sotto una tenda che cade.</p>
<h1 class="intro__titolo">Tutta l’etichetta, un giro alla volta.</h1>
</section>
<!-- il giro: più alto dello schermo, il palco resta fermo e la lattina gira con lo scorrimento -->
<section class="giro" data-giro>
<div class="palco" data-palco>
<p class="parole" data-parole aria-hidden="true"><span>Cin</span> <span>cin</span><span class="tenda" data-tenda></span></p>
<canvas class="lattina" data-lattina role="img" aria-label="Una lattina di chinotto che gira su sé stessa"></canvas>
</div>
</section>
<section class="fine">
<p class="fine__testo">Davanti il nome, di lato gli ingredienti, dietro un sole che tramonta nel mare. L’etichetta è una sola immagine, avvolta intorno alla lattina una colonna alla volta.</p>
</section>
</main>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/ScrollTrigger.min.js"></script>
<script src="script.js"></script>
</body>
</html>Change values, colours and text with the controls and watch the animation respond live. Or write in the code yourself. Then download the folder with your changes.
21 values to change
With the Animorio connector, Claude Code takes it from here, guide included, and fits it into your project. Paste this request:
Take “The spinning can” from Animorio and fit it into my siteThe label is drawn once on an off-screen canvas, as wide as the circumference, 2π r, and 4.3 r tall, with the fonts already loaded: the brand rotated upright, the ingredients, a sun straddling the seam, drawn at both ends, and waves that match up after a full turn. Its beginning is repeated at the end, so the columns straddling the seam are taken in one go.
Column x of the can, from −1 to 1, looks at the surface at the angle asin(x): its strip of label starts at 0.5 + (asin(x) + turn) / 2π and is as wide as the angle difference with the next column, so it is wide in the middle and more and more squeezed at the edges. Every column is copied with a drawImage and moves down by 0.16 r × cos(angle), because the top and bottom edges, seen slightly from above, are ellipses.
Over the body, with source-atop, a horizontal gradient darkens the edges and puts a bright highlight a quarter of the way across: it stays still while the label moves, and that is what makes the can look round. Neck, lid with its ring, tab and base are ellipses and curves in a striped metal grey; the shadow is drawn behind everything with destination-over.
The section is three screens tall with a sticky stage: the turn goes from 0 to a full circle while the stage is still, and it carries on before and after, so the can arrives spinning. The drawn turn chases the wanted one with a time-based follow, 9 per second, and is redrawn only when it changes. The curtain is an 82% paper-coloured veil over the words: a scrubbed ScrollTrigger moves it down by 190% and rotates it by −8 degrees while the words rise.
| Name | File | Default | What it changes |
|---|---|---|---|
GIRI | script.js | 1 | How many turns the can makes while the stage holds still. |
SEGUE | script.js | 9 | How fast the can catches up with the scroll, per second. |
ALTEZZA | script.js | 0.72 | How tall the can is, as a share of the screen height. |
INCLINA | script.js | 0.16 | How much of the lid shows: 0 from the side, 1 from above. |
TENDA | script.js | 190, −8 | Where the curtain ends up: in percent of its height, and in degrees. |
COLORI | script.js | #FF6B2C… | The label colours; the whole label is drawn in the scriviEtichetta function. |
For a shop’s round product: a drink, a beer, a tomato passata, a jar of honey, a candle. It shows the whole label without a 360-degree photo shoot.
The words go one above and one below the can, which stays large; scrolling drives the turn as on a computer, and the columns are in the phone’s pixels, up to two per point.
The can stands still at three quarters, with the brand easy to read; the section is one screen tall and there is no curtain.
GSAP 3.15.0, Mona Sans (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 6.7 KB; the libraries: GSAP + ScrollTrigger 45 KB.
Tested on 28 September 2026
Use it in your own projects and in your clients’ projects. Do not resell it or redistribute it as is. GSAP stays under its own Standard license. Full license.
With your account’s email and password.
or with your email
You’re signed in as .
With your account, you can download the zip of every animation and every pack, for free.