Skip to content
animorio
IT
Back to the library

Letters that swap places

Text, SVGGSAP, CSS onlyMediumCompressed weight: Demo 6.2 KBGSAP 28 KBFreeDownload the zip

A text animation in the minimal style: one word in a variable serif and the same six letters lining up again to make another, listen, silent, enlist, tinsel, inlets. Every letter flies to its place on its own arc, over the word if it goes right and under it if it goes left; in the air it gets lighter and its serifs round off, landing it sharpens and takes weight for a moment, and behind it runs a vermilion hairline that fades into it.

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>Letters that swap places</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/fraunces@5.3.0/full.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage" data-stage>
    <header class="top">
      <span class="top__brand">Verso</span>
      <span class="top__note">A quarterly of short poems</span>
    </header>

    <!-- the hairline trails: each letter leaves one behind it on its way to its new place -->
    <svg class="trails" data-trails aria-hidden="true"></svg>
    <!-- the letters: the script places them one by one and moves each along its own arc -->
    <h1 class="word" data-word aria-live="polite"></h1>
    <i class="rule" data-rule aria-hidden="true"></i>
    <!-- a hidden copy of the word, to measure where every letter stands -->
    <span class="meter" data-meter aria-hidden="true"></span>

    <nav class="list" data-list aria-label="Anagrams"></nav>
  </main>

  <script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.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.

20 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 “Letters that swap places” from Animorio and fit it into my site

What it does

On warm white paper, at the top, the name of an invented poetry magazine, Verso, and its line on the right; in the middle a thin rule with the word listen on it in a large, high-contrast serif, which arrives rising letter by letter. After a couple of seconds the letters set off, one after the other, to become silent: each flies on its own arc, over the word the ones going right and under it the ones going left, so they never collide; the further the new place, the higher the arc. In flight the letter gets lighter, its serifs round off and its drawing opens up a little, tilted just slightly in the direction it travels; behind it a thin vermilion hairline follows the arc and shortens until it vanishes into the letter as it lands. Landing it sharpens again, takes weight for a moment and sinks a pixel into the line, then comes back up. Then come enlist, tinsel, inlets and listen again. At the bottom the five words in small type: the one being read is full, the others grey; a click on one calls it, a click on the page moves to the next.

How it works

Three axes of Fraunces

Fraunces, in Fontsource’s «full» file, has weight (100-900), optical size (9-144) and SOFT, softness (0-100), which rounds off the serifs and terminals. On the line the letters have opsz 144, weight WEIGHT and SOFT 0, the display drawing; in flight they drop to opsz 48, weight AIR and full SOFT. Every letter is a span placed by hand with translate3d, which the script rewrites on each frame only when it changes.

Where every letter stands

For every word of the list a hidden span sets it letter by letter, with the real kerning, and from there come the x and the width of every letter. The letters are always the same six: the third «e» of a word is the third «e» of the letters, so every letter knows where to go in every word.

An arc for each letter

For every letter that moves a quadratic SVG path is written from the centre of where it stands to the centre of where it goes, with the control point above the word if it goes right and below if it goes left, 42% of the distance high (with a minimum and a maximum). A tween from 0 to 1 with power3.inOut carries the letter along the arc with getPointAtLength, and the angle between two close points tilts it by a few degrees.

The hairline behind it

The same path is the vermilion hairline: stroke-dasharray and stroke-dashoffset show only the stretch between the tail and the letter. The tail starts a third of the flight later and arrives together with the letter, so the hairline shortens until it vanishes on landing.

The landing

Once there, the letter has a «land» value that rises in 0.12 seconds and goes back to 0 with elastic.out: together it lowers the letter by a pixel (a little more at large sizes) and adds 140 to its weight. The letters take off in the order they stand in the old word, staggered by STAGGER; the next change waits for a gsap.delayedCall of HOLD seconds.

Values to change

NameFileDefaultWhat it changes
WORDSscript.js['listen', 'silent', 'enlist', 'tinsel', 'inlets']The anagrams, one after the other: every word must have exactly the same letters as the first (the ones that do not are skipped).
WEIGHTscript.js520The weight of the letters standing on the line, from 100 to 900.
AIRscript.js200Their weight in flight.
SOFTscript.js100How round the serifs get in flight: 0 they stay sharp, 100 round.
ARCscript.js0.5How high the arcs are: 0 almost flat, 1 high.
STAGGERscript.js0.07The seconds between one letter taking off and the next.
HOLDscript.js2.2How many seconds a word stays before the next.
SPEEDscript.js1The speed of the flights: 2 is twice as fast, 0.5 half as fast.
AUTOscript.jstrueWhether the words change on their own; with false only on click.

Try them in the Playground

When to use it

For the headline of a magazine, a writing or poetry blog, a word game, a foundry showing off a serif; also for a name that reads two ways. It works with short words that are anagrams of each other (listen and silent, earth and heart, night and thing).

On phones

The same animation: the word is measured for the narrow screen and the arcs stay in proportion. A tap on the page moves to the next word, a tap on a word of the list calls it.

With reduced motion

Nothing flies: the letters fade out and fade back in already in their places in the new word, with no arcs and no hairlines; the list changes without a transition.

Pitfalls

  • In a classic script a constant called «top» clashes with window.top and stops everything with «Identifier has already been declared»: the header is called header.
  • The fromTo tweens of a timeline write their starting values as soon as they are created and call onUpdate early: the hairline asked getPointAtLength of a path that was still empty. With immediateRender: false and the path written in onStart the problem goes away.
  • With the lighter weight in flight the letters still looked dark: at a low optical size Fraunces has less contrast and thicker strokes. The weight in flight came down to 200.
  • The positions are read from a word really set, not by adding up the widths of the letters: that keeps the kerning (the space between «t» and «e» is not the one between «l» and «i»).

Libraries

GSAP 3.15.0, Fraunces (font variabile, assi opsz, wght, SOFT e WONK) 5.3.0.

Compressed with gzip, the three demo files weigh 6.2 KB; the libraries: GSAP 28 KB.

Testing

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