
The loader that becomes a logo
Transitions, SVG, Text
NewFree
A minimal click page change: a thin line cuts the page in half, the two halves open up and down like a drawer and the new page widens out of the gap, its title running in along the line. Going back the halves slide shut with a little knock and the line closes like a seam.
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 split-line transition</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/instrument-sans@5.3.0/wdth.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage" data-stage>
<!-- the first page: the headline sits right across the line, so the cut runs through its letters -->
<section class="page page--a is-on" data-page="a" aria-label="Objects">
<header class="bar">
<span class="brand">Halden</span>
<nav class="nav" aria-label="Pages">
<a href="#objects" aria-current="page">Objects</a>
<a href="#studio" data-go="b">Studio</a>
</nav>
</header>
<div class="hero hero--a" data-hero-a>
<p class="kicker">Spring collection</p>
<h1 class="headline" data-headline>Made slowly.</h1>
<a class="go go--next" href="#studio" data-go="b" data-autoclic>
<span class="go__text">Visit the studio</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>
<footer class="foot">
<span>Ceramics and furniture</span>
<span>Since 2009</span>
</footer>
</section>
<!-- the second page: its title stands on the line -->
<section class="page page--b" data-page="b" aria-label="Studio" aria-hidden="true">
<header class="bar" data-b-top>
<span class="brand">Halden</span>
<nav class="nav" aria-label="Pages">
<a href="#objects" data-go="a">Objects</a>
<a href="#studio" aria-current="page">Studio</a>
</nav>
</header>
<div class="hero hero--b">
<h2 class="title" data-title>The studio</h2>
<div class="below" data-below>
<p class="lede" data-rise>Six people, one kiln and a long oak table. We make a few things each year, and mend them for life.</p>
<a class="go go--back" href="#objects" data-go="a" data-autoclic data-rise>
<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 objects</span>
</a>
</div>
</div>
<footer class="foot" data-b-foot>
<span>Open by appointment</span>
<span>Since 2009</span>
</footer>
</section>
<!-- the two halves of the page being cut, and the line itself (both built and moved by the script) -->
<div class="halves" data-halves aria-hidden="true"></div>
<div class="cut" data-cut 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.
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 split-line transition” from Animorio and fit it into my siteThe real pages are never cut. The script makes two copies of the page that is leaving, lays them one on the other exactly in its place and clips them with clip-path: inset(0 0 calc(100% - var(--cut)) 0) for the top copy, inset(var(--cut) 0 0 0) for the bottom one. The clip moves with the copy, so moving the two copies in y is enough. In the copies data-go and data-autoclic are removed and the links leave the Tab order, so nobody clicks them.
The line is a div one pixel tall, as wide as the page, with transform-origin on the left. Its position is written as a left end (x) and a length (scaleX): starting from the click means x at the click point and scaleX zero, and reaching the edges means x zero and scaleX one. With the same easing both ends arrive together even when one side is longer. The same trick shrinks it under the title and closes it into the middle.
First a crack of a few pixels with power3.out, then a moment still, then the halves run to the edges with power4.inOut: the pause between the two pushes is what makes it feel like a drawer. When shutting, the halves come in with power3.in (speeding up into the knock), bounce back KNOCK pixels in 0.09 seconds and settle with elastic.out(1, 0.4). The new page waits underneath, while its header and footer open out from the middle with expo.out, a little behind the halves.
The title is split into letters, each an inline-block whose font-stretch is tied to the --w variable (Instrument Sans runs from 75 to 100 in width). Each letter starts pushed left by nearly a letter height plus TRAIL for every letter ahead of it: arriving with expo.out the gaps close and the letters bunch up like carriages braking. The lean springs back to zero with an elastic, and --w widens to 100 starting from the last letter. The title's baseline is measured with an empty element sitting on the baseline, so it stands exactly on the line.
Each change is one timeline with the labels draw, crack, open, title, settle (and leave, run, shut, knock on the way back) and timeScale for SPEED. A click that comes while the page is changing waits in a queue. The measures are taken again on every resize: both big lines fit the width, the cut sits at LINE_AT of the height. With reduced motion the line fades in, the pages swap with a fade and the title appears already in place.
| Name | File | Default | What it changes |
|---|---|---|---|
LINE_AT | script.js | 0.5 | Where the cut runs, from the top: 0.5 is right in the middle, 0.35 higher, 0.65 lower. |
DRAW | script.js | 0.6 | The seconds the line takes to cross the page. |
OPEN | script.js | 1.05 | The seconds the two halves take to open (and, a little faster, to shut). |
CRACK | script.js | 6 | How many pixels the page cracks open before it slides: 0 = the halves go at once. |
KNOCK | script.js | 5 | How many pixels the halves bounce back when they shut: 0 = they just stop. |
TRAIL | script.js | 0.32 | How strung out the title's letters arrive along the line, in letter heights: 0 = all together. |
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 quiet site where the type does all the work: a designer's or an architect's studio, a furniture or ceramics brand, a portfolio, an agency's about page, the step from the home page to a section. It works well with a light and a dark background taking turns.
The same transition with the sizes adapted: both titles shrink to fit the width of the screen, the cut stays halfway down and the text wraps under the line. A tap on the link opens it and shuts it again.
Nothing moves: the line fades in, the first page fades out as the second fades in with its title already in place, then the text; going back the first page fades back in and the line disappears.
GSAP 3.15.0, Instrument Sans (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 7.4 KB; the libraries: GSAP 28 KB.
Tested on 14 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.