
Words that melt into each other
Text, Scroll, SVG
NewFree
A thin square rolls along a line, a quarter turn at a time, and every cell it leaves keeps a letter: it rises out of the line narrow and light and, when the square lands, it widens and takes weight. Then the square rolls back and presses them into the line again. Minimal style.
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 square that rolls and writes</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/anybody@5.3.0/wdth.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage" data-stage>
<!-- a thin square rolls along a thin line, a quarter turn at a time: every cell it leaves keeps a letter, which
rises out of the line narrow and widens when the square lands; then it rolls back and presses them in -->
<svg class="figure" role="img" aria-label="Quarto" data-figure>
<defs>
<clipPath id="above-the-line">
<path data-clip></path>
</clipPath>
</defs>
<g class="ticks" data-ticks></g>
<path class="line" data-line></path>
<g class="letters" clip-path="url(#above-the-line)" data-letters></g>
<path class="square" data-square></path>
<text class="turns" data-turns>0°</text>
</svg>
</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.
12 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 square that rolls and writes” from Animorio and fit it into my siteEverything is a single SVG with a viewBox in units: every cell is 100 wide, one per letter plus the one the square ends on. The line, the ticks, the square and the letters are redrawn on every frame by a render function hooked to gsap.ticker, starting from a few numbers: the square's cell, its angle, how far the line gives and, for every letter, how far it has risen, its width and its weight. The thickness of the lines is worked out from the true width of the drawing, so it stays STROKE pixels.
The square is a cell c and an angle a. With a positive it turns on its bottom right corner, with a negative on its bottom left one: every corner is rotated round that corner with sine and cosine. At 90 degrees the cell becomes c + 1 and the angle goes back to 0: the shape is the same, so the switch does not show. The turn uses power2.in, slow at first and fast at the end, like a falling body; after the landing a small timeline takes the angle to minus 3.2 degrees, to zero, to minus 0.8 and to zero again: the bounce on the corner.
The line is a polyline with a point every 6 units. Under every landing it sinks with a bell (a Gaussian almost a cell wide) whose height goes to KNOCK in 0.07 seconds and back to zero with elastic.out, which makes it swing. The square, the ticks and the letters take their height from the same curve, so the neighbours feel the knock with no extra code, and meanwhile the square squashes a hair from the middle of its base.
The letters are SVG texts in Anybody, a variable typeface with a wdth axis from 50 to 150. They sit in a group cut by a clipPath that is all the space above the line (its curve too), so a letter moved down disappears into the line. While the square turns, the letter of the cell it has left rises narrow (wdth 54) and light (240); on the landing the width goes to the right measure with back.out and the weight climbs to 700 and back to 540. The right measure is worked out at start with getBBox: the widest setting, up to WIDE, at which the widest letter takes at most 80 percent of its cell.
A paused timeline only holds the moments with tl.call: a quarter turn forward for every letter, the word taking weight with a stagger and the square's hop, the HOLD pause, the quarter turns back that press the letters into the line. At the end the timeline starts again by itself with restart, because the state is back where it began; the entrance (the line drawing itself, the ticks, the square falling) only shows on opening and after a click.
| Name | File | Default | What it changes |
|---|---|---|---|
WORD | script.js | 'QUARTO' | The word the square writes, 2 to 10 letters (spaces are removed). More letters, smaller drawing. |
ROLL | script.js | 0.8 | How many seconds every quarter turn forward takes; going back the square goes almost twice as fast. |
REST | script.js | 0.4 | How many seconds the square rests on every cell before it tips again. |
KNOCK | script.js | 3 | How far the line gives under every landing, in units (a cell is 100): 0 keeps it straight. |
WIDE | script.js | 125 | How wide the letters get when the square lands, on the wdth axis (50 to 150); if a letter does not fit its cell, the script narrows it by itself. |
STROKE | script.js | 1.5 | How thick the square and the line are, in pixels. |
HOLD | script.js | 2.4 | How many seconds the written word stays before the square rolls back. |
For the opening or the loading screen of a short brand that wants to look precise and a little playful: a print shop or a bindery, a graphic design studio, a stationery shop, a writing app, a typeface. Also as the intro of a name on an about page or as a placeholder while a document is being prepared.
The same animation with the sizes adapted: the drawing shrinks to the width of the screen, the lines stay just as thin and the letters stay in their cells. A tap starts it over.
Nothing rolls or moves: the line and the ticks are already in place, the square fades from one cell to the next, every letter fades in already wide, the word takes weight without moving and on the way back the letters fade out.
GSAP 3.15.0, Anybody (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 5.7 KB; the libraries: GSAP 28 KB.
Tested on 16 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.