
Standing letters with a long shadow
Text, Scroll, 3D
NewFree
Scroll inside the preview
A studio’s hundred clients in a single number: as you scroll, the “100” opens into a hundred thin marks cut to the shape of the digits, which line up in tens, fold into a ten by ten grid, lie down into one bar per year and in the end close back into the number. 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>A number made of marks</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/archivo@5.3.0/wdth.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<!-- the clients of a made-up design studio, told with one big number. Scrolling, the number comes apart into one
thin mark per client: the marks line up in tens, fold into a ten by ten grid, lie down into one bar per year,
and in the end stand up again into the number -->
<main>
<section class="apertura">
<p class="piccolo">Orrin, design studio</p>
<h1 class="titolo">Five years,<br>one client at a time.</h1>
<p class="piccolo piccolo--tenue">Scroll to count them.</p>
</section>
<section class="racconto" data-racconto>
<div class="palco" data-palco>
<header class="testa">
<p class="marchio">Orrin</p>
<p class="piccolo piccolo--tenue">Clients since <span data-dal>2021</span></p>
</header>
<h2 class="nascosto" data-numero>100 clients since 2021</h2>
<canvas class="tela" data-tela aria-hidden="true"></canvas>
<div class="anni" data-anni aria-hidden="true"></div>
<p class="didascalia" aria-hidden="true">
<span class="didascalia__riga" data-dida>A hundred clients.</span>
<span class="didascalia__riga" data-dida>One mark for each.</span>
<span class="didascalia__riga" data-dida>Ten to a row.</span>
<span class="didascalia__riga" data-dida>Year by year.</span>
<span class="didascalia__riga" data-dida>And counting.</span>
</p>
</div>
</section>
<section class="apertura apertura--fine">
<h2 class="titolo titolo--medio">Thank you,<br>every one of you.</h2>
</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.
31 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 “A number made of marks” from Animorio and fit it into my siteThe script writes the number once on a canvas outside the page, at twice the size, and reads its pixels. It keeps only the columns that have ink (so no mark falls between two digits) and picks as many as there are clients, evenly spaced. For each one it notes where the column enters and leaves the ink: a column through a zero has two pieces, above and below the hole.
Every mark is a line through a point, at an angle, cut into K pieces along its length. Five shapes are prepared for every mark: the solid number, the number in lines, the row of tens, the grid and the bar of its year. Outside the number the K pieces lie on top of each other, so going from one shape to another only means blending numbers: position, angle, the ends of the pieces, thickness, how blue it is.
The timeline, tied to the scroll with scrub SCRUB, only moves five numbers from 0 to 1, one per change of shape, plus the one for the final squash. Every mark starts a little after the one before it (SPREAD) and uses different curves for its parts: power3.inOut for the flight, power2.inOut for turning, LAND for the length, which goes a little too far and settles. The drawing happens once per frame, in GSAP’s ticker.
While they are inside the number, the marks are drawn on a second canvas outside the page, twice as wide as the gap between two lines and a little longer than they need to be; then the number is written over them with destination-in, which keeps only what is inside the digits. So the thickening lines become a number with smooth edges and not steps, and the real number can appear on top without the switch showing.
The years and the counts are HTML elements over the canvas. The years rise out of an overflow hidden window with yPercent, while the --wd variable takes font-stretch from 70% to 100% (Archivo is variable in width too). Every count shows how many marks of its year have already landed and rises with the top of the bar. The caption at the bottom plays the same game as the years, one sentence at a time.
| Name | File | Default | What it changes |
|---|---|---|---|
COUNTS | script.js | [8, 14, 21, 26, 31] | The new clients of every year, oldest first: one mark each, one bar per year, and their sum is the big number. |
FIRST_YEAR | script.js | 2021 | The year of the first bar. |
WEIGHT | script.js | 800 | The weight of the big number: the fuller it is, the better the lines tell the shape of the digits. |
LINE | script.js | 1.5 | How thick a mark is, in pixels. |
LAND | script.js | 'back.out(2.2)' | The curve each mark takes its length with: the number in brackets is how far it overshoots before settling. |
SPREAD | script.js | 0.55 | How far apart the marks leave: 0 all together, 0.9 one after the other. |
SCRUB | script.js | 0.6 | How many seconds the drawing takes to catch up with the scroll. |
For a number that counts people or things one by one: a studio’s clients, delivered projects, the members of a club, the seats sold for an event. It works up to a few hundred: there is one mark per unit, so with thousands of pieces the grid and the bars would no longer read.
The same, with adapted measures: the number takes almost the whole width, the row of tens goes on two lines and the bars get narrower.
No flights and no bounces: at every step the drawing fades out and comes back already in its new shape (number in lines, row, grid, bars, solid number); captions and years take turns with a cross-fade.
GSAP 3.15.0, ScrollTrigger (GSAP) 3.15.0, Archivo (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 9.2 KB; the libraries: GSAP + ScrollTrigger 45 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.