Skip to content
animorio
IT
Back to the library

The sentence and the timeline

Scroll, TransitionsGSAP, CSS onlyMediumCompressed weight: Demo 5.0 KBGSAP + ScrollTrigger 45 KBFreeDownload the zip

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.

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

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.

35 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 sentence and the timeline” from Animorio and fit it into my site

What it does

At the top a large sentence, «Spool turns every clip into a block you can pick up, reshape and drop on the timeline.», with five squares between the words; in each one a glossy tile like an app icon: a rising sun, blue stripes, a wave, «Aa», a star. When the page opens, the picture on the first tile falls into place from above. Below is the dark timeline of a video editor, with the project’s name, the timecode, the seconds ruler, five empty places and an audio track. Once the timeline is on screen, scrolling down makes the tiles leave the sentence and drop into it one after another, each tilting a little in flight; scrolling back up sends them back to their squares. Meanwhile the orange playhead runs along the timeline with the scroll and the timecode counts the frames.

How it works

Where they really live

In 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.

The direction decides

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.

The flight

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.

The first tile

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.

Playhead and timecode

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.

Values to change

NameFileDefaultWhat it changes
FLIGHTscript.js1.5How long each tile’s flight lasts, in seconds.
STAGGERscript.js0.1, 0.05The delay between one tile and the next, towards the timeline and towards the sentence.
TILTscript.js15The most a tile tilts in flight, in degrees.
DROPscript.js-300, 15, 2The fall of the first tile’s picture: from how many px, with how many degrees, over how many seconds.
LENGTH, FPSscript.js6, 24The timeline’s length in seconds and the timecode’s frames per second.

Try them in the Playground

When to use it

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.

On phones

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.

With reduced motion

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.

Pitfalls

  • The transform is worked out from the place in the timeline, which does not move, not from the tile, which is already transformed: measuring the tile adds the old shift to the new one.
  • Sentence and timeline must scroll together with the page: if either were fixed or sticky, the measured shift would change at every scroll.
  • An IntersectionObserver answers after the scroll event: after a jump the timeline turns out to be on screen when the last event has already gone, and the tiles would not move. That is why, when it comes in, the last direction seen is used.
  • On iPhone the retracting toolbar fires resize at every scroll: the tiles are measured again only when the width changes.

Libraries

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.

Testing

Tested on 28 September 2026

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

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