
The loader that becomes a logo
Transitions, SVG, Text
NewFree
A minimal click page change for a theatre: the new page's title falls over the page as a curtain of dark slats, one per letter, each with its letter standing tall and narrow on it. The slats hit the floor and bounce, then the letters let go, shrink and widen until they are the title.
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 letter curtain transition</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/roboto-flex@5.3.0/full.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage" data-stage>
<!-- the first page, light -->
<section class="page page--a is-on" data-page="a" aria-label="Tonight">
<header class="bar">
<span class="brand">Velde Theatre</span>
<nav class="nav" aria-label="Pages">
<a href="#tonight" aria-current="page">Tonight</a>
<a href="#season" data-go="b">Season</a>
</nav>
</header>
<div class="hero hero--a" data-hero>
<p class="kicker">Tonight at eight</p>
<h1 class="big">The Glass Hour</h1>
<a class="go go--next" href="#season" data-go="b" data-autoclic>
<span>See the season</span>
<svg class="go__arrow" viewBox="0 0 22 12" aria-hidden="true"><path d="M1 6h19M15 1.5 20 6l-5 4.5"/></svg>
</a>
</div>
<footer class="foot">
<span>Doors open at seven</span>
<span>Box office</span>
</footer>
</section>
<!-- the second page, dark: its title is the curtain -->
<section class="page page--b" data-page="b" aria-label="Season" aria-hidden="true">
<header class="bar">
<span class="brand">Velde Theatre</span>
<nav class="nav" aria-label="Pages">
<a href="#tonight" data-go="a">Tonight</a>
<a href="#season" aria-current="page">Season</a>
</nav>
</header>
<div class="hero hero--b" data-hero>
<h2 class="title" data-title>SEASON</h2>
<ul class="shows">
<li><span class="shows__name">The Glass Hour</span><span class="shows__when">November</span></li>
<li><span class="shows__name">Salt and Iron</span><span class="shows__when">January</span></li>
<li><span class="shows__name">A Quiet Year</span><span class="shows__when">March</span></li>
</ul>
<a class="go go--back" href="#tonight" data-go="a" data-autoclic>
<svg class="go__arrow" viewBox="0 0 22 12" aria-hidden="true"><path d="M21 6H2M7 1.5 2 6l5 4.5"/></svg>
<span>Back to tonight</span>
</a>
</div>
<footer class="foot">
<span>Doors open at seven</span>
<span>Box office</span>
</footer>
</section>
<!-- the curtain, built by the script: one slat for each letter of the title, and the letters -->
<div class="curtain" data-curtain aria-hidden="true"></div>
</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.
34 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 letter curtain transition” from Animorio and fit it into my siteThe title is split into letters and for each the script makes a slat (a div a sixth of the screen wide, black like the new page) and a separate letter in a layer above. Slat and letter fall with the same y tween, so they look like one thing; but the letter is not inside the slat, so it can fly off when the slats go.
Each letter is one element for GSAP (where its centre is and how far it is scaled) with a span inside centred by the CSS with translate(−50%, −50%), whose font-stretch and font-weight come from the --w and --g variables. On the slat it is Roboto Flex at width 25 and weight 760, stretched upwards with scaleY; in the title width 100 and weight 560. The title's centres are measured on the boxes of the real letters (line-height 1, no letter spacing), so at the end the swap with the real title does not show.
The letter's wrapper has its own width, and GSAP scales from its centre by default: the letter, drawn round the top left corner, slid away as it scaled. With transformOrigin at 0 0 it scales right from the letter's centre. And since the box of a line of type is not centred on the capitals, the position on the slat shifts the letter just enough for the capital's middle to be halfway down the screen even when stretched.
Each slat falls in DROP seconds with power3.in, delayed STAGGER for every column away from the click; once down it comes back up BOUNCE pixels and falls again, and the letter squashes a little. Then the pages swap under the curtain, the slats are hidden and the letters fly with expo.inOut for the position, power3.inOut for the scale and power2.inOut for width and weight, each a little after the other.
Each change is one timeline with timeScale for SPEED, and a click that comes halfway waits in a queue. The measures are taken again on every resize: slats, letter size, stretch (at most STRETCH) and the title's positions. With reduced motion the pages swap with fades, one after the other.
| Name | File | Default | What it changes |
|---|---|---|---|
DROP | script.js | 0.55 | The seconds a slat takes to fall. |
STAGGER | script.js | 0.06 | The seconds between one slat and the next. |
BOUNCE | script.js | 10 | How many pixels a slat bounces when it hits the floor: 0 = it just lands. |
STRETCH | script.js | 2.2 | How far a curtain letter may be stretched upwards, at most (1 = not at all). |
FLY | script.js | 0.95 | The seconds the letters take to fly into the title. |
SPEED | script.js | 1 | The speed of everything: 2 is twice as fast, 0.5 half as fast. |
To enter a page with a short, strong title: the programme of a theatre, a cinema, a festival or a concert, the tickets page, a portfolio section, a venue's menu. It works best with titles of four to eight letters and a dark new page.
The same transition with the sizes adapted: the six slats are narrow, the letters smaller and stretched more, the title shrinks to the width of the screen and the shows go underneath.
Nothing falls and nothing flies: the old page fades out and then the new one fades in.
GSAP 3.15.0, Roboto Flex (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 6.8 KB; the libraries: GSAP 28 KB.
Tested on 19 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.