
The title that rises from a line
Transitions, Text, Images
NewFree
In the minimal style: a photo of a lake at dusk cut into chips. A thin red line crosses it and every column it touches sorts its chips by light, bright ones up and dark ones down: the photo becomes a field of gradients, one per column, then the line passes again and every chip goes home.
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 photo sorted by light</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>
<p class="mark" data-mark>Lowlight</p>
<!-- the plate: the photo cut into small chips, column by column; a red hairline passes over it and every column
it touches sorts its chips by light, then puts them back -->
<figure class="plate" data-plate role="img">
<canvas class="chips" data-chips aria-hidden="true"></canvas>
<i class="head" data-head aria-hidden="true"></i>
<figcaption class="cap" aria-hidden="true">
<span class="cap__title" data-title></span>
<span class="cap__state">
<span class="cap__word" data-word="shot">As shot</span>
<span class="cap__word" data-word="light">By light</span>
</span>
</figcaption>
</figure>
</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.
16 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 photo sorted by light” from Animorio and fit it into my siteThe photo sits on a hidden canvas (drawn by the script or loaded from IMAGE). The script cuts it into COLUMNS columns and as many rows as it takes for the chips to be almost square, and with getImageData works out the average colour and the light of every chip (0.2126 R + 0.7152 G + 0.0722 B).
Every column sorts its chips by light, from the brightest to the darkest (LIGHT_ON_TOP), and a chip's place in that order is where it will go. Only the columns are sorted, not the whole photo: the chips only move up and down, and the sorted photo stays a field of vertical gradients that still recalls its sky.
Every column has a number, p, that a GSAP timeline takes from 0 to 1 when the red line passes over it. Inside the column every chip starts a little after the one above (SPREAD), runs to its place on a power3.out curve, then goes OVERSHOOT pixels past it and comes back on half a sine. In the first third of the run the detail fades into the average colour and the chip shrinks by GAP pixels, so a thread of paper stays between the chips.
More than nine hundred chips are not elements of the page: GSAP's ticker redraws the canvas only when something has moved. A column at home is drawn in one piece, with no seams; the edges of the chips fall on whole pixels, so no thin lines are left between them.
The red line is a one-pixel element that the timeline takes from left to right in SWEEP seconds; every column starts when the line reaches its centre. The two words under the photo keep their weight and width in two CSS variables read by font-variation-settings: the word of the new state takes its weight with elastic.out, the other turns thin and grey again.
| Name | File | Default | What it changes |
|---|---|---|---|
IMAGE | script.js | '' | The photo: an address, or a file loaded in the Playground. Empty, the script draws the photo. A photo from another site that cannot be read gives way to the drawn one. |
CAPTION | script.js | 'Lake at dusk' | The caption under the photo. |
COLUMNS | script.js | 28 | How many columns of chips the photo is cut into; the rows follow the photo's shape. |
LIGHT_ON_TOP | script.js | true | The bright chips climb to the top; with false they sink to the bottom and the sorted photo turns upside down. |
SWEEP | script.js | 2.4 | The seconds the red line takes to cross the photo. |
GAP | script.js | 1 | The pixels of paper between the chips once they are sorted (0 = none). |
OVERSHOOT | script.js | 1 | How many pixels every chip goes past its place before coming back. |
HOLD | script.js | 2.2 | How many seconds the photo stays still, whole or sorted, before the line passes again. |
LOOP | script.js | true | Whether the photo sorts and comes back on and on. With false it does it once and then waits for a click. |
To show a photo as something to look at twice: the opening of a photographer's or a colourist's portfolio, the page of a print for sale, the cover of a photo story, an app that works on photos. It works with any photo, including one loaded in the Playground.
The same animation with the sizes adapted: the photo is almost as wide as the screen and the columns are narrower. A tap on the photo sends the line across at once.
Nothing moves: the photo fades in and stays. A click goes from the photo to the field of gradients (and back) with a fade, with no running chips.
GSAP 3.15.0, Instrument Sans (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 8.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.