Skip to content
animorio
IT
Back to the library

The square that rolls and writes

SVG, TextGSAPMediumCompressed weight: Demo 5.7 KBGSAP 28 KBFreeDownload the zip

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.

The code

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>

Playground

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

Or ask Claude Code for it

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 site

What it does

On a warm white page a thin black line draws itself from the middle out and grey ticks drop under it, splitting it into cells like a ruler. A thin vermilion square falls onto the first cell: the line gives a little under the knock and swings back up with a small elastic, the square squashes a hair and rises again. Then it tips over its front corner and rolls a quarter turn: it starts slowly, speeds up as if it were falling and lands on the next cell; as soon as it touches the line it rocks back three degrees on its corner, drops again, bounces even less and stops. While the square is in the air, a letter rises out of the cell it has left, narrow and light, as if it came out of a slot in the line; when the square lands the letter widens on the wdth axis until it fills its cell, goes a little past and comes back, and takes weight. Every landing makes the line give, and the nearby letters, which stand on it, go down and up with it. At the bottom right a grey counter says how many degrees the square has turned: 90, 180, up to 540. When the word QUARTO is written, it takes full weight from the first letter to the last; the wave reaches the square, which makes a small hop and lands again. After a pause the square rolls back, faster, and every time it lands on a letter it presses it back into the line, narrow and light, while the counter goes down to zero. Then it starts again. A click or a tap starts it over from the beginning.

How it works

A drawing in cells

Everything 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 quarter turn

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 that gives

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.

Letters out of the line

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.

The direction

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.

Values to change

NameFileDefaultWhat it changes
WORDscript.js'QUARTO'The word the square writes, 2 to 10 letters (spaces are removed). More letters, smaller drawing.
ROLLscript.js0.8How many seconds every quarter turn forward takes; going back the square goes almost twice as fast.
RESTscript.js0.4How many seconds the square rests on every cell before it tips again.
KNOCKscript.js3How far the line gives under every landing, in units (a cell is 100): 0 keeps it straight.
WIDEscript.js125How 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.
STROKEscript.js1.5How thick the square and the line are, in pixels.
HOLDscript.js2.4How many seconds the written word stays before the square rolls back.

Try them in the Playground

When to use it

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.

On phones

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.

With reduced motion

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.

Pitfalls

  • Turning the square with a transform and an svgOrigin on its corner means changing the rotation point at every cell, and on the change the square jumps for a frame. Here the four corners are worked out by hand: at 90 degrees it moves to the next cell and the angle goes back to 0, which is exactly the same shape.
  • The bounce after the landing must use the angle with the opposite sign, so it turns on the opposite corner of the new cell: that is right, because the corner the square has just turned on has become the bottom left corner of the new cell (the bottom right one when it rolls back).
  • The tail of Anybody's Q goes below the baseline: the clip above the line cuts it exactly on the line, so it looks as if it rests there instead of going under.
  • If the letters were cut by a fixed rectangle, when the line gives the nearby letters would go down and their foot would be cut straight, apart from the curve. The clipPath follows the same curve as the line and is rewritten on every frame.
  • With REST at zero in the Playground a new quarter turn starts while the bounce of the previous one is still going, and two tweens would fight over the angle: every turn first stops the angle's tweens with killTweensOf and starts from wherever the angle is, which is continuous between the two corners.

Libraries

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.

Testing

Tested on 16 October 2026

  • Desktop: Done
  • Phone: Done
  • Reduced motion: Done
  • Safari on iPhone: To do

License

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.

All animations