
The loader that becomes a logo
Transitions, SVG, Text
NewFree
A minimal page change made like correcting a proof: on a click a red line, wavering like a pen, strikes the title out line by line and the «del» mark appears in the margin; the letters leave one at a time from the end, narrowing. Then a caret «^» pops up on the baseline, «ins» goes in the margin, and the new title comes out of the caret letter by letter, narrow then wide, a pixel past its place and back.
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 proofreader's marks transition</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>
<header class="bar">
<span class="brand">Galley</span>
<nav class="nav" aria-label="Pages">
<a href="#draft" data-go="a" data-nav="a" aria-current="page">Draft</a>
<a href="#proof" data-go="b" data-nav="b">Proof</a>
</nav>
</header>
<!-- the margin where the proofreader writes the marks -->
<aside class="margin" data-margin aria-hidden="true">
<div class="mark mark--del" data-mark="del">
<svg viewBox="0 0 40 56"><path data-draw d="M6 8 C 14 8 26 6 30 14 C 34 22 22 28 18 22 C 14 16 24 10 30 18 C 34 26 30 42 22 50 C 18 54 12 52 14 48"/></svg>
<span class="mark__word">del</span>
</div>
<div class="mark mark--ins" data-mark="ins">
<svg viewBox="0 0 40 56"><path data-draw d="M8 40 L20 16 L32 40"/><path data-draw d="M20 16 L20 6"/></svg>
<span class="mark__word">ins</span>
</div>
</aside>
<section class="page page--a is-on" data-page="a" aria-label="Draft">
<div class="col">
<p class="kicker" data-soft>The draft</p>
<h1 class="title"><span class="line" data-line>Rough words,</span><span class="line" data-line>first thoughts.</span></h1>
<p class="text" data-soft>Everything we write starts here, loose and too long. Then the red pen comes.</p>
<a class="go" href="#proof" data-go="b" data-autoclic data-soft>
<span class="go__text">Send it to proof</span>
<span class="go__arrow" aria-hidden="true"><span class="go__shaft"></span><svg class="go__head" viewBox="0 0 8 12"><path d="M1.5 1.5 6.5 6l-5 4.5"/></svg></span>
</a>
</div>
</section>
<section class="page page--b" data-page="b" aria-label="Proof" aria-hidden="true" inert>
<div class="col">
<p class="kicker" data-soft>The proof</p>
<h1 class="title"><span class="line" data-line>Clean lines,</span><span class="line" data-line>set to print.</span></h1>
<p class="text" data-soft>Cut, corrected and read twice. What is left is ready for the press.</p>
<a class="go go--back" href="#draft" data-go="a" data-autoclic data-soft>
<span class="go__arrow" aria-hidden="true"><svg class="go__head" viewBox="0 0 8 12"><path d="M6.5 1.5 1.5 6l5 4.5"/></svg><span class="go__shaft"></span></span>
<span class="go__text">Back to the draft</span>
</a>
</div>
</section>
<!-- the strikes and the caret are drawn here, over the page -->
<svg class="ink" data-ink aria-hidden="true"></svg>
<footer class="foot">
<span>An editing studio</span>
<span>Read twice, print once</span>
</footer>
</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.
30 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 proofreader's marks transition” from Animorio and fit it into my siteThe script splits each title line into one .ch span per letter (spaces become .sp, 0.24em wide) and keeps the whole text in aria-label for screen readers. Each .ch is an inline-block with font-stretch: calc(var(--w) * 1%): GSAP moves the span and animates the --w variable, so the letter narrows and widens on Roboto Flex's wdth axis as it moves.
The strikes are drawn in an SVG as big as the stage, over the page. The line measures come from document.createRange().getClientRects(), which gives one box per line of text even when a paragraph wraps. Each stroke is a Bézier curve starting five pixels before the word and ending five after, with two control points moved WOBBLE pixels up and down: it looks hand drawn. It is drawn with stroke-dasharray and stroke-dashoffset, from the full length to zero.
Once the line is drawn, the letters leave from the last: opacity to zero, --w down to NARROW and three hundredths of the size downwards, ERASE seconds apart with power2.in. Meanwhile the stroke's stroke-dashoffset goes from zero to its length with ease none, in the same time: with the dash as long as the path, a growing offset shortens the line from its end, so the strike follows the letters as they go.
The caret is an SVG group with an upside-down V path, placed at the start of the first letter, on the baseline. It appears with scale from 0 and back.out(3). Each new letter starts at an x equal to the distance between the caret and its place, transparent, with --w at NARROW and scaleY 0.4, and reaches OVERSHOOT pixels past its place with power3.out; then it comes back to zero with elastic.out(1, 0.5). One letter every INSERT seconds; every third letter the caret dips a pixel and back. For the second line the caret slides down with power3.inOut.
The margin marks are two SVGs whose paths are drawn with stroke-dashoffset, with the word rising on back.out; they sit level with the middle of the title. Each change is one timeline: the new page's part is added only once that page is on screen, because only there can its letters be measured. A click during the change waits in a queue. The title shrinks if its longest line does not fit the column, on every resize. With reduced motion the pages swap with a fade, with no marks and nothing moving.
| Name | File | Default | What it changes |
|---|---|---|---|
STRIKE | script.js | 0.42 | The seconds the red line takes to cross one line of the title. |
ERASE | script.js | 0.022 | The seconds between one deleted letter and the next: 0 = they all go at once. |
INSERT | script.js | 0.034 | The seconds between one inserted letter and the next. |
SETTLE | script.js | 0.62 | The seconds each new letter takes to slide out of the caret into its place. |
WOBBLE | script.js | 1.4 | How many pixels the pen line wavers up and down: 0 = straight as a ruler. |
NARROW | script.js | 25 | How narrow a letter gets as it leaves or is born (font-stretch in %, 25 to 100). |
OVERSHOOT | script.js | 1 | How many pixels a new letter runs past its place before settling: 0 = it just stops. |
SPEED | script.js | 1 | The speed of everything: 2 is twice as fast, 0.5 half as fast. |
To move from one page to another on a site where words matter: an editing or copywriting studio, a publisher, a magazine, a writing blog, a translation or proofreading service. It also works well to go from a draft to the final version of something, or from «before» to «after».
The same transition with the sizes adapted: the title shrinks until its longest line fits the column, and the margin narrows with its red marks. A tap on the link sends the page back and forth.
Nothing moves and nothing is struck out: the old page fades out and the new one fades in; the red lines, the caret and the margin marks do not appear.
GSAP 3.15.0, Roboto Flex (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 7.1 KB; the libraries: GSAP 28 KB.
Tested on 23 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.