
Keep scrolling
Transitions, Scroll
NewFree
Scroll inside the preview
A paint maker’s colour card: a row of tall, narrow chips slides sideways and the one that reaches the middle stretches to the top, then widens until it fills the screen, and its name writes itself large, from narrow to wide. Then it folds back into the row and the page keeps a pale wash of its colour. Minimal style.
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>Paint chips</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>
<!-- the colour card of a made-up paint maker: a row of tall, narrow chips slides sideways as you scroll. The chip
that reaches the middle stretches to the full height, then widens until it fills the screen, and its name writes
itself in big letters, from narrow to wide. Then the name leaves, the chip folds back into the row and the page
keeps a pale tint of it while the next chip slides in -->
<main>
<section class="apertura">
<p class="piccolo">Fennick Paints</p>
<h1 class="titolo">Six colours<br>for quiet rooms.</h1>
<p class="piccolo piccolo--tenue">The autumn card. Scroll.</p>
</section>
<section class="racconto" data-racconto>
<div class="palco" data-palco>
<header class="testa" data-testa>
<p class="marchio">Fennick</p>
<p class="piccolo">Autumn colour card</p>
</header>
<div class="campioni" data-campioni>
<div class="campione" data-campione style="--tinta: var(--clay)" data-nota="A warm earth, sun on brick">
<span class="campione__nome">Clay</span>
</div>
<div class="campione" data-campione style="--tinta: var(--fog)" data-nota="A soft grey with a blue breath">
<span class="campione__nome">Fog</span>
</div>
<div class="campione" data-campione style="--tinta: var(--saffron)" data-nota="A deep yellow, late afternoon">
<span class="campione__nome">Saffron</span>
</div>
<div class="campione" data-campione style="--tinta: var(--moss)" data-nota="A green that sits back">
<span class="campione__nome">Moss</span>
</div>
<div class="campione" data-campione style="--tinta: var(--lagoon)" data-nota="Still water, just before rain">
<span class="campione__nome">Lagoon</span>
</div>
<div class="campione" data-campione style="--tinta: var(--plum)" data-nota="A dark red for the evening">
<span class="campione__nome">Plum</span>
</div>
</div>
</div>
</section>
<section class="apertura apertura--fine">
<h2 class="titolo titolo--medio">Order a sample pot.</h2>
<p class="piccolo piccolo--tenue">Every colour, in a small tin.</p>
</section>
</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/ScrollTrigger.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.
32 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 “Paint chips” from Animorio and fit it into my siteEvery chip is a layer in position absolute as big as the stage, filled with its paint and cut down by an inset() clip-path with rounded corners. The narrow chip and the one that fills the screen are the same element: only the cut changes. So the big name, the hairline and the copy of the header already sit in their place inside the chip and show only where the paint is.
The timeline, tied to the scroll with scrub SCRUB, does not move elements: it moves the position of the row and, for each chip, four numbers from 0 to 1 (rising into the row, lifting, stretching in height, widening). On every update of the timeline one function redraws all the cuts from those numbers: the widest chip decides where the others go, and they stay beside it with a gap that grows.
Opening, the height goes from 0 to 1 with power3.inOut and the width starts a little later with expo.inOut: the chip becomes a column and then a wall. Closing does the opposite, and the height comes back with SETTLE, a back.out: the number dips a little under zero and the chip is shorter than the row for a moment before it settles.
Archivo is a variable font with a width axis (from 62 to 125). Every letter sits in an overflow hidden window and rises from below with yPercent; meanwhile a CSS variable --wd, which is the font-stretch of the word, goes from NARROW to WIDE with elastic.out. The size is measured beforehand at the final width, so the word always fits the screen.
While the paint covers everything, the background of the stage changes to a mix of the page white and the paint (TINT): you do not see it change, but when the chip folds back the page is washed with its colour. The header is copied inside every chip in the colour that reads on that paint (black or white, chosen from the luminance): it shows only where the paint covers it.
| Name | File | Default | What it changes |
|---|---|---|---|
STRIP | script.js | 56 | How wide a chip is in the row, in pixels (two thirds on a phone). |
GAP | script.js | 12 | The space between two chips, in pixels. |
NARROW | script.js | 62 | The width of the big letters as they arrive, from 62 (narrow) to 125 (wide). |
WIDE | script.js | 112 | The width they settle on. |
WEIGHT | script.js | 640 | The weight of the big name. |
TINT | script.js | 0.16 | How much of the paint the page keeps once the chip folds back: 0 none, 0.5 a lot. |
SETTLE | script.js | 'back.out(1.8)' | The curve of the chip going back to its height: the number in brackets is how much it bounces. |
SCRUB | script.js | 0.7 | How many seconds the drawing takes to catch up with the scroll. |
To present a palette: the colour card of someone who sells paint, fabric or tiles, a season’s collection, the colours of a new brand on a launch page. It works with short names (one word) and five to eight colours; with more colours the section must be made longer.
The same, with narrower chips closer together, the row running off the right of the screen and the big name in proportion to the width.
No movement: the row is already in place in the middle and each chip opens and closes with a cross-fade, its name already written; the wash on the page arrives with a fade too.
GSAP 3.15.0, ScrollTrigger (GSAP) 3.15.0, Archivo (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 7.3 KB; the libraries: GSAP + ScrollTrigger 45 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.