
The loader that becomes a logo
Transitions, SVG, Text
NewFree
A minimal-style page change for a mountain hotel’s site: on a click a curtain of 240 sand-coloured cells, twenty columns of twelve, closes over the page in a wave that starts from the bottom right corner while a veil darkens underneath; then it opens again with the same wave and the words of the new headline arrive in jumps, in scattered order, wide and light, and narrow down as they gain weight. Remade from scratch on the idea of the page change of sondaven.com.
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 cell transition</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/archivo@5.3.0/wdth.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage" data-stage>
<!-- the first page: the rooms of a small mountain hotel, on warm paper -->
<section class="page page--a is-on" data-page="a" aria-label="Rooms">
<header class="bar">
<span class="brand">Hollin</span>
<nav class="nav" aria-label="Pages">
<a class="nav__link" href="#rooms" aria-current="page">Rooms</a>
<a class="nav__link" href="#seasons" data-go="b">Seasons</a>
</nav>
</header>
<span class="rule" aria-hidden="true"></span>
<h1 class="title" data-title><span class="title__line">Rooms above</span><span class="title__line">the treeline.</span></h1>
<div class="under">
<p class="lede" data-late>Twelve rooms of larch and stone, a stove in each, and windows that open on the valley.</p>
<a class="go" href="#seasons" data-go="b" data-autoclic data-late>
<span class="go__text">See the seasons</span>
<svg class="go__arrow" viewBox="0 0 26 12" aria-hidden="true"><path d="M1 6h22"/><path d="M18.5 1.5 23.5 6l-5 4.5"/></svg>
</a>
</div>
<footer class="foot" data-late>
<span>A hotel in the high woods</span>
<span>Open all year</span>
</footer>
</section>
<!-- the second page: the seasons, on the dark brown of the woods at night -->
<section class="page page--b" data-page="b" aria-label="Seasons" aria-hidden="true">
<header class="bar">
<span class="brand">Hollin</span>
<nav class="nav" aria-label="Pages">
<a class="nav__link" href="#rooms" data-go="a">Rooms</a>
<a class="nav__link" href="#seasons" aria-current="page">Seasons</a>
</nav>
</header>
<span class="rule" aria-hidden="true"></span>
<h2 class="title" data-title><span class="title__line">Snow comes</span><span class="title__line">early here.</span></h2>
<div class="under">
<p class="lede" data-late>Trails and rivers in summer, quiet slopes from November. The stove is lit either way.</p>
<a class="go" href="#rooms" data-go="a" data-autoclic data-late>
<svg class="go__arrow go__arrow--back" viewBox="0 0 26 12" aria-hidden="true"><path d="M25 6H3"/><path d="M7.5 1.5 2.5 6l5 4.5"/></svg>
<span class="go__text">Back to the rooms</span>
</a>
</div>
<footer class="foot" data-late>
<span>Summer and winter</span>
<span>Open all year</span>
</footer>
</section>
<!-- the curtain: a veil and a grid of cells, built by the script -->
<div class="curtain" data-curtain aria-hidden="true">
<div class="curtain__veil" data-veil></div>
<div class="curtain__cells" data-cells></div>
</div>
</main>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/CustomEase.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.
41 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 cell transition” from Animorio and fit it into my siteThe curtain is a div over the pages holding a black veil and twenty flex columns, each with twelve cells stacked (flex: 1). Every cell has margin -1px, as on the site: the cells overlap by a pixel and with the curtain closed no gap is left. They start at scaleX(0), squeezed to nothing towards their middle line, because the transform origin is the centre.
The cells sit in column order: the first column top to bottom, then the second. For GSAP’s stagger the grid is [COLS, ROWS], so each of its ‘rows’ is one of our columns and the distance between two cells is the real one. With from: 'end' the wave starts from the last cell, bottom right, and with each 0.03 every cell waits three hundredths of a second for each step of distance: the farthest cell starts after about two thirds of a second. Each cell stretches in 0.4 seconds with the curve 0.76, 0, 0.24, 1, slow at the start and at the end.
Under the cells a black veil goes from clear to full in 1.2 seconds with the same curve: it darkens the strips of page still showing. 1.2 seconds after the click the curtain is closed: the old page hides, the new one shows with its words already at their starting point, and the opening begins, with the cells going back to scaleX(0) in the same order and the veil fading away.
The headline’s words are split by hand into spans (one for GSAP, with one inside for the font axes). They start from yPercent -150, 75, -75 and 150 in turn, scale 0 and opacity 0 and arrive at zero, one and one in 1.2 seconds with the curve 0.25, 1, 0.5, 1, 0.2 seconds after the curtain starts to open, one every 0.025 seconds in random order. The text inside starts at font-stretch 125% and weight 280 and ends at 88% and 640: the word lands wide and light and tightens.
With prefers-reduced-motion there is no curtain: the new page fades in over the other in 0.6 seconds, already set.
| Name | File | Default | What it changes |
|---|---|---|---|
COLS | script.js | 20 | The columns of the curtain (twenty on the site). |
ROWS | script.js | 12 | The cells in each column (twelve on the site). |
CELL_TIME | script.js | 0.4 | How many seconds a cell takes to stretch or pull in. |
EACH | script.js | 0.03 | The gap between a cell and the next, in seconds: higher makes the wave slower. |
FROM | script.js | 'end' | Where the wave starts: end (bottom right), start (top left), center, edges, random. |
HOLD | script.js | 1.2 | How many seconds after the click, with the curtain closed, the page changes. |
VEIL | script.js | 1 | How dark the veil under the cells gets: 0 none, 1 black. |
VEIL_TIME | script.js | 1.2 | How many seconds the veil takes to come, and to go. |
JUMPS | script.js | [-150, 75, -75, 150] | Where the words come from, as a percentage of their height, in turn: negative from above, positive from below. |
WORD_TIME | script.js | 1.2 | How many seconds a word takes to arrive. |
WORD_EACH | script.js | 0.025 | The gap between one word and the next, in scattered order. |
WORD_DELAY | script.js | 0.2 | How long the words wait after the curtain starts opening. |
WIDE | script.js | 125 | The width of the typeface (wdth axis, in %) a word lands with, before it narrows. |
LIGHT | script.js | 280 | The weight a word lands with, before taking the headline’s. |
CELL_EASE | script.js | '0.76, 0, 0.24, 1' | The curve of the cells and the veil (the site’s). |
WORD_EASE | script.js | '0.25, 1, 0.5, 1' | The curve of the words (the site’s). |
For the page change of a hotel, a holiday home, an architecture studio or a brand with warm tones, where the new page arrives with a big headline.
The same curtain of twenty columns by twelve cells, narrower and taller; the headline smaller and the link under the text. A tap changes page.
No curtain and no jumps: the new page fades in, already set.
GSAP 3.15.0, CustomEase (GSAP) 3.15.0, Archivo (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 5.7 KB; the libraries: GSAP + CustomEase 31 KB.
Tested on 21 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.