
Standing letters with a long shadow
Text, Scroll, 3D
NewFree
A text animation in the minimal style: a big word is cut into thin strips, each one pushed sideways and drawn a little wider or narrower, so it cannot be read. A red hairline runs down the word and every strip it touches comes into register, passes its place by a pixel and goes back; then the strips slide away one after the other and bring the next word, out of register again.
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 word coming into register</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/roboto-flex@5.3.0/standard.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage" data-stage>
<!-- the word people read; everything drawn below is only its picture -->
<h1 class="sr" data-read>Offset</h1>
<!-- the rig: a column with the word in it. The script cuts the word into thin horizontal strips, each one a
window on its own copy of the line; a hairline runs down and the strips fall into register behind it -->
<div class="rig" data-rig aria-hidden="true">
<div class="guide guide--left" data-guide><i></i></div>
<div class="guide guide--right" data-guide><i></i></div>
<div class="line line--whole" data-whole></div>
<div class="strips" data-strips></div>
<div class="scan" data-scan><i></i></div>
</div>
<!-- an invisible copy of the word, to measure sizes and the baseline -->
<div class="line line--probe" data-probe aria-hidden="true"></div>
</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.
16 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 word coming into register” from Animorio and fit it into my siteThe word is measured once: the size of the type, the baseline (an empty inline-block placed at the end of the word sits right on it) and the cap height (measureText of an H on a canvas). The cuts are made between the top of the capitals and the baseline, each rounded to the pixel; the first strip reaches up to the top of the line and the last one down to its bottom, so no piece of a letter is left out. Every strip is a window with overflow hidden on a whole copy of the line.
Every word has its own out-of-register pattern, made once with a seeded random generator: neighbouring strips go opposite ways, and how far they move swells and shrinks down the word like a wave, with a little noise. On the same wave every strip is wider or narrower on the wdth axis (STRETCH) and lighter on the wght axis. Thanks to the seed every round is identical to the one before.
The red hairline runs down with sine.inOut. The moment it crosses the middle of a strip comes from inverting the curve (acos of 1 minus twice the height, divided by pi), and that is when the strip's return starts: a single number from 0 to 1 that gives the slide (power3.out), the width, the weight and the swing of OVERSHOOT pixels past the place, which dies out on its own. The strip above, already in register, takes a share of that swing: the neighbours feel the knock.
In every strip slides a track with two copies of the line: the word now in the middle and the next one just outside the column, to the right or to the left depending on the strip. Moving the track by a whole column, with expo.inOut and a small delay from one strip to the next, the old word leaves in pieces and the new one arrives already out of register. Then a function puts the new word in the middle copy and the one after it on the track, and it all starts again without a jump.
The timeline only moves numbers: for every strip the return and the change of word, and the position of the hairline. A function on the GSAP ticker turns them into transform and font-variation-settings and writes only what changes. When every strip is in register a single copy of the word shows in their place, identical to the pixel. The sizes are measured again when the window changes, and the timeline never notices.
| Name | File | Default | What it changes |
|---|---|---|---|
WORDS | script.js | ['Offset', 'Proof', 'Press'] | The words, one after the other: each arrives out of register and the hairline puts it back in place. Short words of similar length read best. |
WEIGHT | script.js | 760 | The weight of the word in register, from 100 (a hairline) to 1000 (black). Out of register the strips are lighter. |
WIDTH | script.js | 90 | The width of the word on the typeface's wdth axis: 25 very narrow, 151 very wide. |
STRIPS | script.js | 14 | How many strips the word is cut into: a few thick ones show at once what happens, many thin ones look like a misregistered print. |
SCATTER | script.js | 0.12 | How far the strips are pushed out of register, as a share of the width of the word. The column widens to match. |
STRETCH | script.js | 18 | How much wider or narrower the strips are out of register, on the wdth axis. With 0 they all have the right width and are only pushed. |
OVERSHOOT | script.js | 1 | How many pixels a strip passes its place by before it stops. 0 stops dead; above 4 it becomes a bounce. |
HOLD | script.js | 1.4 | How many seconds the word stays in register, whole, before it leaves for the next one. |
SPEED | script.js | 1 | The speed of the whole animation: 2 is twice as fast, 0.5 half as fast. |
For the opening of a site where a single word has to be noticed and the theme is precision: a printer, an art print shop, a design studio, a magazine, a design festival, a brand whose motto is care for detail. It also suits the changing words of a headline (a studio's services, the sections of a portfolio). It wants a heavy, large typeface and plenty of room around it.
The same animation: the column is measured to fit almost the whole width of the screen, and the strips, the pushes and the hairline come from the size of the word. There are as many strips on a phone too, only thinner. Turning the phone measures everything again without stopping.
No strips moving and no hairline: the column is already there, the word stays still in register for a few seconds, fades out and the next one fades in in its place.
GSAP 3.15.0, Roboto Flex (font variabile, assi wght e wdth) 5.3.0.
Compressed with gzip, the three demo files weigh 7.2 KB; the libraries: GSAP 28 KB.
Tested on 14 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.