
Column shutter
Transitions
NewFree
A page change in the minimal style: from the point of the click a printer's halftone screen, dots on a grid turned 45 degrees, prints the next page's colour in a wave that fades from small dots to dots that touch. Then the new page comes out of the solid colour through holes in the same screen, its text appearing first as dots and then whole; last, the ink of the headline dries.
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 halftone transition</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/anybody@5.3.0/wdth.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage" data-stage>
<!-- the first page, on paper -->
<section class="page page--a is-on" data-page="a" aria-label="Press">
<header class="bar">
<span class="brand">Raster</span>
<nav class="nav" aria-label="Pages">
<a href="#press" aria-current="page">Press</a>
<a href="#papers" data-go="b">Papers</a>
</nav>
</header>
<div class="main">
<h1 class="big" data-big>Printed matter.</h1>
<div class="below">
<p class="lede">A small offset and riso press. Posters, zines and books, printed one dot at a time.</p>
<a class="go" href="#papers" data-go="b" data-autoclic>
<span class="go__t">See the papers</span>
<svg class="go__arrow" viewBox="0 0 26 12" aria-hidden="true"><path d="M1 6h22M18.5 1.5 23.5 6l-5 4.5"/></svg>
</a>
</div>
</div>
<footer class="foot">
<span>Print studio</span>
<span>Screen 45 degrees, 85 lines</span>
</footer>
</section>
<!-- the second page, in ink -->
<section class="page page--b" data-page="b" aria-label="Papers" aria-hidden="true">
<header class="bar">
<span class="brand">Raster</span>
<nav class="nav" aria-label="Pages">
<a href="#press" data-go="a">Press</a>
<a href="#papers" aria-current="page">Papers</a>
</nav>
</header>
<div class="main">
<h2 class="big" data-big>On paper.</h2>
<ul class="list" aria-label="Papers">
<li class="row"><span>Uncoated</span><span class="row__soft">Warm white</span><span class="row__end">120 g</span></li>
<li class="row"><span>Cotton</span><span class="row__soft">Soft, thick</span><span class="row__end">300 g</span></li>
<li class="row"><span>Newsprint</span><span class="row__soft">Grey, light</span><span class="row__end">52 g</span></li>
</ul>
<a class="go go--back" href="#press" data-go="a" data-autoclic>
<svg class="go__arrow" viewBox="0 0 26 12" aria-hidden="true"><path d="M25 6H3M7.5 1.5 2.5 6l5 4.5"/></svg>
<span class="go__t">Back to the press</span>
</a>
</div>
<footer class="foot">
<span>Print studio</span>
<span>Screen 45 degrees, 85 lines</span>
</footer>
</section>
<!-- the halftone screen: dots that print the next page's colour, then holes that print its text -->
<canvas class="screen" data-screen aria-hidden="true"></canvas>
</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.
35 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 halftone transition” from Animorio and fit it into my siteThe centres of the dots are a square lattice turned 45 degrees, like the screen of a black and white print: x = (i − j) · s and y = (i + j) · s, with s = CELL / √2, keeping only the points that fall on the screen. They are worked out once per measure and kept in a Float32Array. The full radius is 0.74 · CELL, just over half the cell's diagonal, so full dots touch and cover everything.
Each dot starts when the wave reaches it: its timing is its distance from the click over that of the farthest corner. The radius grows with power2.inOut over a window FRONT wide of the whole time, so at any moment the front of the wave shows every radius at once, from the dot just born to the full one: the gradient of a halftone print.
In the second half the canvas is filled with the solid colour and the dots are drawn with globalCompositeOperation destination-out: they are holes. Under it the new page is already there, in the same colour, so through the holes only its text shows, as dots, until the holes touch and the canvas is empty. Each frame is a single path with thousands of arcs and a single fill.
The headline is split into letters, inline-blocks whose font-weight and font-stretch are tied to two variables (Anybody runs from 50 to 150 in width and from 100 to 900 in weight). As the page comes out of the holes the letters start at weight 900 and width 58 and spring back to 780 and 62 with elastic.out, staggered: ink spreading under the press and then drawing back.
The starting point is kept as a share of the screen and the lattice is worked out again on every resize, even halfway: the canvas takes the new size and the wave carries on from the same point. The canvas follows the screen's density up to 2. On a phone the screen is finer (four fifths of CELL). With reduced motion the pages swap with a fade.
| Name | File | Default | What it changes |
|---|---|---|---|
CELL | script.js | 14 | The pixels between two dots of the screen; a phone uses four fifths. |
COVER | script.js | 0.8 | The seconds the dots take to print the colour over the whole page. |
PRINT | script.js | 0.9 | The seconds the holes take to print the new page out of the colour. |
FRONT | script.js | 0.4 | How wide the printed gradient at the front of the wave is, as a share of the time. |
SPEED | script.js | 1 | The speed of everything: 2 is twice as fast, 0.5 half as fast. |
To go from one page to another on a site that has to do with print: a print shop, a risograph studio, a publisher, a magazine, a poster archive, a black and white photographer. It works best between a light page and a dark one, because the screen prints the very colour of the page that is arriving.
The same wave with a finer screen: from the point of the tap the dots cover the tall screen and the new page comes out of the holes, with the same curves and timing.
No screen: the new page fades in over the first one, with its headline already dry.
GSAP 3.15.0, Anybody (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 6.2 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.