
Keep scrolling
Transitions, Scroll
NewFree
Scroll inside the preview
Five coloured tiles sit in the squares of a sentence; once the timeline is on screen, scrolling down drops them into it one after another, and scrolling back up sends them back into the sentence, tilting as they fly.
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 sentence and the timeline</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/mona-sans@5.3.0/standard.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/jetbrains-mono@5.3.0/index.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<header class="top">
<p class="brand">Spool</p>
<p class="top__line">Video editor</p>
</header>
<main>
<!-- the sentence: five empty squares between the words; the tiles are drawn onto them -->
<section class="statement" data-statement>
<h1 class="statement__text">
Spool<span class="slot" data-slot></span>turns every clip<span class="slot" data-slot></span>into a block<span class="slot" data-slot></span>you can pick up,<span class="slot" data-slot></span>reshape<span class="slot" data-slot></span>and drop on the timeline.
</h1>
<p class="statement__hint">Scroll down, then back up</p>
</section>
<!-- the timeline: the tiles really live here, one in each place -->
<section class="editor" data-editor>
<div class="timeline" data-timeline>
<div class="timeline__bar">
<span class="timeline__name">spring-campaign.spool</span>
<span class="timeline__code" data-code>00:00:00:00</span>
</div>
<div class="timeline__ruler" aria-hidden="true">
<span>0s</span><span>1s</span><span>2s</span><span>3s</span><span>4s</span><span>5s</span><span>6s</span>
</div>
<div class="timeline__track" data-track>
<div class="timeline__home" data-home>
<div class="tile tile--sun" data-tile><span class="tile__face">
<svg viewBox="0 0 100 100" aria-hidden="true"><path d="M18 64a32 32 0 0 1 64 0Z" fill="#fff7e6" /><path d="M14 72h72M24 81h52" stroke="#fff7e6" stroke-width="6" stroke-linecap="round" /></svg>
</span></div>
</div>
<div class="timeline__home" data-home>
<div class="tile tile--stripes" data-tile><span class="tile__face"></span></div>
</div>
<div class="timeline__home" data-home>
<div class="tile tile--wave" data-tile><span class="tile__face">
<svg viewBox="0 0 100 100" aria-hidden="true"><path d="M8 58c12-18 22-18 34 0s22 18 34 0 14-12 18-8" fill="none" stroke="#f2fff9" stroke-width="9" stroke-linecap="round" /></svg>
</span></div>
</div>
<div class="timeline__home" data-home>
<div class="tile tile--type" data-tile><span class="tile__face"><span class="tile__aa">Aa</span></span></div>
</div>
<div class="timeline__home" data-home>
<div class="tile tile--star" data-tile><span class="tile__face">
<svg viewBox="0 0 100 100" aria-hidden="true"><path d="M50 12c4 26 12 34 38 38-26 4-34 12-38 38-4-26-12-34-38-38 26-4 34-12 38-38Z" fill="#fbf7ff" /></svg>
</span></div>
</div>
<span class="timeline__head" data-head aria-hidden="true"></span>
</div>
<div class="timeline__track timeline__track--audio" aria-hidden="true" data-wave></div>
</div>
</section>
<section class="outro">
<p class="outro__text">Every block keeps its settings wherever you drop it.</p>
</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.
35 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 sentence and the timeline” from Animorio and fit it into my siteIn the code the tiles live inside the timeline’s places, as wide as the place; the sentence only holds five empty squares of 1 em (1.1 em on wide screens), with margins of 0.1 em, 0.2 em and −0.15 em. A function measures square and place and carries the tile into the sentence: the scale is the square’s width over the place’s width, the shift goes from one centre to the other. Going home is just scale 1 with x and y at zero.
An IntersectionObserver tells when the timeline is on screen; from then on every scroll event looks at the direction: down, the tiles go into the timeline; up, they go back into the sentence. If the timeline comes in after a jump (a key, a link), the tiles follow the last direction seen.
Each tile flies for 1.5 seconds of power2.inOut, 0.1 seconds after the previous one towards the timeline and 0.05 towards the sentence. In the first half of the flight it tilts up to ±15° at random with power2.in, in the second it straightens with power2.out. Before every flight the old tweens are stopped, so you can change your mind halfway.
When the sentence arrives, 300 px before the bottom of the screen and only once, the first tile’s picture falls from −300 px with 15° of rotation, over 2 seconds of power3.out: the tile is already in place, only what is inside it falls.
A ScrollTrigger with a 0.4 second scrub carries the playhead from one end of the track to the other while the editor crosses the screen, and the timecode reads the progress over 6 seconds at 24 frames. On resize the tiles are put back in place without animation.
| Name | File | Default | What it changes |
|---|---|---|---|
FLIGHT | script.js | 1.5 | How long each tile’s flight lasts, in seconds. |
STAGGER | script.js | 0.1, 0.05 | The delay between one tile and the next, towards the timeline and towards the sentence. |
TILT | script.js | 15 | The most a tile tilts in flight, in degrees. |
DROP | script.js | -300, 15, 2 | The fall of the first tile’s picture: from how many px, with how many degrees, over how many seconds. |
LENGTH, FPS | script.js | 6, 24 | The timeline’s length in seconds and the timecode’s frames per second. |
To explain a product that puts things in their place: an editor, a page builder, a configurator. It works with any pairing of a sentence and a container: icons in a sentence that end up in a basket, a grid, a calendar.
The sentence spreads over more lines and the squares stay at 1 em; the timeline takes the full width and the tiles shrink with it. The finger decides the direction just like the wheel.
No flight, no tilt and no fall: the tiles move from the sentence to the timeline, and back, at once. The playhead still follows the scroll.
GSAP 3.15.0, ScrollTrigger (GSAP) 3.15.0, Mona Sans (font variabile) 5.3.0, JetBrains Mono (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 5.0 KB; the libraries: GSAP + ScrollTrigger 45 KB.
Tested on 28 September 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.