Skip to content
animorio
IT
Back to the library

The line typed on the ruler

Scroll, TextGSAP, CSS onlyMediumCompressed weight: Demo 7.4 KBGSAP + ScrollTrigger 45 KBFreeDownload the zip

Scroll inside the preview

A short note typed as you scroll, in the minimal style: a thin ruler with a red mark that steps one column at every key, letters that fall light and gain weight as they land, and at the end of each line the carriage springing back while the paper rises by one line.

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 line typed on the ruler</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/martian-mono@5.3.0/wdth.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <!-- a short note of a made-up small press, typed as you scroll: a thin ruler with a red carriage mark that steps one
       column at a time; at every step a letter is struck onto the line and gains weight as it lands; at the end of a
       line the carriage springs back to the margin and the paper rises by one line. The lines are in LINES, at the top
       of script.js -->
  <main>
    <section class="racconto" data-racconto>
      <div class="palco" data-palco>
        <header class="testa">
          <p class="marchio">Pica</p>
          <p class="piccolo">A note on writing</p>
        </header>

        <!-- the whole note for screen readers; the script writes it here and strikes the letters on their own layer -->
        <p class="nota" data-nota></p>

        <div class="macchina" aria-hidden="true">
          <div class="carta" data-carta></div>
          <div class="righello" data-righello>
            <span class="righello__linea" data-linea></span>
            <span class="carrello" data-carrello><span class="carrello__segno" data-segno></span></span>
          </div>
        </div>

        <p class="piccolo invito" data-invito>Scroll to type</p>
      </div>
    </section>

    <section class="coda">
      <p class="coda__testo">Pica is a small press<br>for slow writing.</p>
      <p class="piccolo">Notes, 2026</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.

19 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 line typed on the ruler” from Animorio and fit it into my site

What it does

On a warm white, with black ink and a single red, there is only a thin ruler: a hairline with a tick for every column, longer every five, and the numbers 0, 5 and 10 beneath. On arrival the line draws itself from the left, the ticks drop in one after the other with a small bounce and the red carriage mark falls onto the margin with a spring. Then the screen stops and, as you scroll, the note of a made-up small press, Pica, is typed: «Write slowly. Read it twice. Keep it short.». At every key the letter falls onto the line just above the ruler, narrow, thin and see-through, faster and faster; as it lands it squashes a little and takes its width and weight with an elastic settle that goes a hair past and back. At the same moment the tick under it jumps, the red mark stretches a touch and the letter before it feels the blow and dips by a pixel. Then the carriage steps on by one column, a pixel past and back; a space moves it on without striking. At the end of the line the carriage runs back faster and faster, the ticks lift one by one as it passes over them, it hits the margin with a spring, the ruler trembles and the paper rises by one line, with the lines already typed. After the last line the final full stop turns red with a small kick. The scroll says how many keys have been struck, but every key plays in its own time, like someone typing and trying to keep up: scroll fast and the keys come quicker, stop and the letters are always settled. Scrolling back, the letters lift off one at a time and the carriage steps back.

How it works

Lines in columns

The note lives in LINES, one string per line. The face is monospaced and variable (Martian Mono, with weight and width axes), so every letter has its own column: the script makes one element per letter, one column wide, and measures with a canvas how wide a figure is, to get the column from the width of the screen (and, if needed, from its height). The ruler has one column more than the longest line: that is where the carriage stops.

The scroll counts the keys

Every key (letter, space, carriage return) has its share of the scroll: a return is worth almost two. A ScrollTrigger without scrub reads how far the section has gone and works out how many keys should be struck. There is no timeline dragged by the scroll: a dragged elastic would stop halfway when the reader stops, with a letter still narrow or the carriage between two columns.

The typist

A small queue plays one key at a time towards the one the scroll asks for, never faster than PACE seconds per key, with gsap.delayedCall (so it stays in GSAP’s time). If the scroll runs too far ahead, the extra keys go in at once and the last six are still played; scrolling back, the queue runs backwards and lifts the letters off.

The strike

A letter starts at yPercent -DROP, NARROW wide and LIGHT in weight, and falls with power3.in. As it lands it squashes with scaleX and scaleY and takes its weight and width with elastic.out: the axes go through two CSS variables inside font-variation-settings, which GSAP tweens as numbers. Meanwhile the tick below jumps (an inner element, since the outer one belongs to the entrance), the mark stretches and the letter before dips by 1.2 pixels and comes back.

The carriage return

The carriage is a number in columns: one function draws it together with the paper and the tremor of the ruler, so it holds when the window is resized. On the return it runs to -0.14 columns with power3.in, the ticks lift at the exact moment the mark passes over them (the inverse of the cubic curve), then elastic.out with SPRING brings it back to zero, the ruler trembles by two pixels and the paper rises by one line with back.out.

Values to change

NameFileDefaultWhat it changes
LINESscript.js['Write slowly.', 'Read it twice.', 'Keep it short.']The note, one string per line. Short lines work best, up to about twenty letters: the column narrows by itself to fit the screen.
LIGHTscript.js130The weight of a letter while it falls.
WEIGHTscript.js560The weight the letter settles on.
NARROWscript.js75How narrow a letter is while it falls (the width axis, 75 to 100).
DROPscript.js70How high a letter falls from, in percent of a line.
PACEscript.js0.11The top speed when the scroll runs ahead, in seconds per key.
SPRINGscript.js0.35How loose the carriage is when it hits the margin: higher, more it swings.

Try them in the Playground

When to use it

For the page of someone who writes (a small press, a newsletter, a blog), a studio’s short manifesto, the opening of an article, the welcome line of a site that wants to feel handmade. It works with two to four short lines.

On phones

The same: the column narrows to the width of the screen, and the letters, the ruler and the blows are the same.

With reduced motion

No falling, no carriage and no rising paper: the note is already in its place above the ruler at full weight with its red full stop, and the letters fade in one after another as you scroll.

Pitfalls

  • With a timeline dragged by the scroll (scrub) the elastics stop where the reader stops: letters were left narrow halfway through their settle and the carriage between two columns. The scroll should only say how many keys, and every key should play in its own time.
  • A delayed call that moves the carriage on, if the reader scrolls back at once, fires after the step back and moves it forward again: it belongs inside the letter’s timeline, killed with it when the letter is taken off.
  • A tick has two elements: the outer one grows in on arrival, the inner one jumps on the blows. With a single element, a blow during the entrance left it at half height.

Libraries

GSAP 3.15.0, ScrollTrigger (GSAP) 3.15.0, Martian Mono (font variabile) 5.3.0.

Compressed with gzip, the three demo files weigh 7.4 KB; the libraries: GSAP + ScrollTrigger 45 KB.

Testing

Tested on 15 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