
Words that melt into each other
Text, Scroll, SVG
NewFree
A title made of shortbread: the rolling pin rolls out the dough, a cutter cuts the letters with one blow, the tray goes into the oven and you watch through the glass, the letters rise and turn golden, then drizzled icing and bouncing sprinkles. A click takes a bite out of a letter, crumbs and all.
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="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>The shortbread title</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/fredoka@5.3.0/index.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/fraunces@5.3.0/index.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="scena">
<!-- the stage: the script fills it with the board, the dough, the rolling pin, the cutter, the tray, the oven and the biscuits -->
<svg class="palco" data-stage role="img" aria-label="Crumb, a bakery" xmlns="http://www.w3.org/2000/svg">
<defs>
<!-- the soft edge of the baked dough, where it turns golden -->
<filter id="soften" x="-20%" y="-20%" width="140%" height="140%" data-soften>
<feGaussianBlur stdDeviation="3" data-soften-blur />
</filter>
<!-- soft shadows and steam -->
<filter id="blur" x="-50%" y="-50%" width="200%" height="200%" data-blur>
<feGaussianBlur stdDeviation="8" data-blur-std />
</filter>
<filter id="haze" x="-80%" y="-80%" width="260%" height="260%" data-haze>
<feGaussianBlur stdDeviation="5" data-haze-std />
</filter>
<!-- the crumb of the biscuits: little specks of butter and sugar -->
<pattern id="crumb" patternUnits="userSpaceOnUse" width="46" height="46" data-crumb>
<circle class="briciola-a" cx="7" cy="9" r="1.6" />
<circle class="briciola-b" cx="29" cy="5" r="1.1" />
<circle class="briciola-a" cx="38" cy="27" r="1.4" />
<circle class="briciola-b" cx="15" cy="31" r="1.2" />
<circle class="briciola-a" cx="24" cy="41" r="1" />
<circle class="briciola-b" cx="4" cy="22" r="0.9" />
</pattern>
<!-- the rolling pin is a cylinder: dark at the sides, a highlight on top -->
<linearGradient id="barrel" x1="0" y1="0" x2="1" y2="0">
<stop offset="0" class="stop-legno-scuro" />
<stop offset="0.38" class="stop-legno-luce" />
<stop offset="0.55" class="stop-legno" />
<stop offset="1" class="stop-legno-scuro" />
</linearGradient>
<!-- the warm light in the oven -->
<radialGradient id="glow" cx="0.5" cy="0.15" r="0.95">
<stop offset="0" class="stop-forno-forte" />
<stop offset="0.6" class="stop-forno" />
<stop offset="1" class="stop-forno-via" />
</radialGradient>
<linearGradient id="steel" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" class="stop-acciaio-luce" />
<stop offset="1" class="stop-acciaio" />
</linearGradient>
</defs>
<g data-world></g>
</svg>
<p class="nota" data-hint>Click or tap a biscuit to take a bite</p>
</main>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.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.
49 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 shortbread title” from Animorio and fit it into my siteThe stage is an SVG whose viewBox is as big as the window; inside it a group, the world, 1600 by 1000 units (880 by 1500 on a tall screen), is centred and scaled so that everything fits. The letters are measured on a canvas in the Fredoka face (measureText, actualBoundingBoxAscent for the true height) and everything is counted in letter heights: the sheet, the board, the tray and the oven window are the word plus a margin. On the same canvas each letter is painted in a different red: that is the map that says which letter a point falls on, for the sprinkles and the bites.
The dough is one rectangle with rounded corners: a ball when width, height and radius are the same, a sheet when it widens along with the rolling pin, with the same timings and the same curve. The rolling pin, seen from above, is a cylinder with a dark to light to dark gradient; its grain, clipped inside, moves at every step by the remainder of a division, so it seems to roll. The cutter is the word drawn as an outline only, in three strokes of steel; its height above the board is a single number that enlarges it, lifts it and moves its blurred shadow away. At the blow the letters appear and so do the holes in the sheet's mask, so that, pulled away, the sheet takes the right holes with it.
The bake is made of strokes: every letter is three identical texts, one over the other. The edge has a wide stroke that turns golden and darker, the body a narrower stroke and a blur filter that softens the step between them, and on top sits a pattern of specks, the grain of the shortbread. Widening the strokes makes the letter swell without changing its shape; the colours warm up with a tween on fill and stroke, and BAKE decides how far. The door is a huge path with a rounded hole in it (fill-rule evenodd): it arrives three times bigger and opens by squashing towards its hinge at the bottom. The warm light is a rectangle with mix-blend-mode multiply plus a gradient in screen.
The icing is a single zigzag path across the whole word, drawn with stroke-dashoffset; each letter uses it with a use inside a clipPath made of its own shape, so the line only shows on the biscuits. The piping bag follows the tip of the line with getPointAtLength and leans with the direction. The sprinkles settle only where the map says there is a letter, a little further out in every direction too, so they do not stick out; they fall with bounce.out, spinning, and live inside the letter, so a bite takes them away as well.
Each letter has a mask: a white rectangle and a group where the bite adds black shapes. The bite is a circle with seven smaller circles around it, so its edge has tooth marks; the same drawing, a little bigger and paler, inside the letter's clipPath, is the inside of the shortbread. The right spot is found on the map: start from outside, in the direction of the click, and walk towards the middle until you meet the letter; the bite sits just outside there. The crumbs leave from the edge, rise and fall back on the tray with bounce.out, then fade.
| Name | File | Default | What it changes |
|---|---|---|---|
NAME | script.js | 'CRUMB' | The word cut out of the dough: one biscuit per letter (spaces leave a little room). |
BAKE | script.js | 1 | How long they bake: 0.4 pale, 1 golden, 1.6 dark at the edges. It also lengthens the time in the oven. |
RISE | script.js | 1 | How much the letters puff up in the oven (0 = they stay flat). |
SPRINKLES | script.js | 40 | How many sprinkles fall on the biscuits (0 = none). |
ZIGZAG | script.js | 1 | How close the lines of icing are: 2 twice as many, 0 no icing. |
SPEED | script.js | 1 | The speed of the whole story: 2 is twice as fast, 0.5 half as fast. |
REST | script.js | 4 | How many seconds the decorated title stays on show before the tray slides away. |
LOOP | script.js | true | Whether the tray slides away and a new batch is baked. With false the biscuits stay, ready to be bitten. |
For the opening of a pastry shop's site, a bakery, an ice cream parlour or a recipe blog, for the page of a cooking class, for a long loading screen or a social post. It works with short words, three to eight letters: a brand name, BAKE, SWEET, YUM.
The same story with the sizes adapted: on a tall screen the world is narrower and the word takes almost the whole width. A tap on a letter takes a bite out of it.
Nothing moves: the sheet on the board fades in, then the letters, then the tray in place of the board; the oven fades in and out while the colours turn golden, then the icing, the sprinkles already in place and the name. A bite fades in, with its crumbs already on the tray.
GSAP 3.15.0, Fredoka (font variabile) 5.3.0, Fraunces (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 17 KB; the libraries: GSAP 28 KB.
Tested on 11 October 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.