
Blinds over images
Images, Scroll
NewFree
Scroll inside the preview
A magazine article in two columns: on the left a still photograph, on the right the text split into chapters. When a chapter reaches the middle of the screen the photograph moves to the next one with a clean curtain, the caption rolls its letters and a small index of chapter names marks the one you are reading.
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 article with the still photograph</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/newsreader@5.3.0/index.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/instrument-sans@5.3.0/index.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<header class="testata">
<a class="testata__nome" href="#">Plinth</a>
<p class="testata__motto">Rooms, houses and the light in them</p>
<nav class="testata__voci" aria-label="Sections">
<a href="#">Houses</a><a href="#">Interiors</a><a href="#">Cities</a><a href="#">Archive</a>
</nav>
</header>
<section class="apertura" aria-labelledby="titolo">
<p class="apertura__occhiello" data-entra>Houses</p>
<h1 class="apertura__titolo" id="titolo" data-titolo>A house that waits for the tide</h1>
<p class="apertura__catenaccio" data-entra>On a bare stretch of the Atlantic coast, the architect Marta Ilves built a single long wall and let the weather finish the rest. We spent four days inside it.</p>
<p class="apertura__firma" data-entra><span>Words by <b>Ines Carvalho</b></span><span>Photographs by <b>Tomas Weir</b></span><span>October 2026, nine minutes</span></p>
</section>
<main class="articolo" data-articolo>
<aside class="foto" data-foto>
<div class="foto__palco">
<figure class="foto__cornice" data-cornice aria-hidden="true"></figure>
<div class="foto__piede">
<p class="foto__didascalia"><span class="foto__righe" data-didascalia></span><span class="foto__credito">Photograph: Tomas Weir for Plinth</span></p>
<nav class="indice" data-indice aria-label="Chapters">
<span class="indice__segno" data-segno aria-hidden="true"></span>
</nav>
</div>
</div>
</aside>
<div class="testo">
<section class="capitolo" data-capitolo="Arrival" data-foto-di="arrivo" data-didascalia-di="The north approach, across the dunes, just after six">
<h2 class="capitolo__titolo">Arrival</h2>
<p class="capitolo__primo">You see the wall before you see the house. It runs along the crest of the last dune like a line someone forgot to rub out, sixty-four metres of pale lime that catches the first light long before the sand does. From the road it could be a sea defence, or a ruin, or nothing at all.</p>
<p>Only when the track bends does the house reveal that it is there, folded behind the wall, low enough that the marram grass hides its lower edge. There is no front door to look for. There is a gap in the wall, a little wider than a person, and the path simply goes through it.</p>
<p>“I wanted the arrival to feel like finding shelter,” Ilves says, standing in that gap with the wind pulling at her coat. “Not like visiting a building. You walk along, and then the noise stops.”</p>
</section>
<section class="capitolo" data-capitolo="The wall" data-foto-di="muro" data-didascalia-di="Lime render over stone quarried two fields away">
<h2 class="capitolo__titolo">The wall</h2>
<p class="capitolo__primo">The wall is the whole idea, and almost the whole budget. It is built from a soft yellow stone taken from a field two farms inland, laid rough and then rendered by hand in three coats of lime, the last one barely thicker than paint.</p>
<p>Lime stays alive for years. It breathes out the damp of winter and drinks the salt of the spray, and slowly it hardens again from the air. Ilves left it unpainted on purpose: in a decade the seaward face will be a different colour from the landward one, and she is curious to see which.</p>
<p>In the low sun of the morning the surface shows every pass of the trowel. By noon it goes flat and white, almost blinding. The builders called it the long patience, because nothing on it could be hurried.</p>
</section>
<section class="capitolo" data-capitolo="The stair" data-foto-di="scala" data-didascalia-di="The stair, lit from a single slot in the roof">
<h2 class="capitolo__titolo">The stair</h2>
<p class="capitolo__primo">Inside, the house is a single room that turns a corner. A concrete stair climbs along the back of the wall to a sleeping loft, and above it a slot cut into the roof lets in one long blade of light.</p>
<p>At ten in the morning the blade lies across the fourth and fifth steps. By lunch it has climbed to the landing; in the afternoon it slides up the wall and fades. People who stay here, Ilves says, stop wearing watches by the second day.</p>
<p>The treads were cast in place with the boards still showing, so that bare feet find the grain of the timber in the stone. It is the warmest thing in a cold material, and the first thing every guest touches.</p>
</section>
<section class="capitolo" data-capitolo="The courtyard" data-foto-di="corte" data-didascalia-di="An old olive, kept where it stood">
<h2 class="capitolo__titolo">The courtyard</h2>
<p class="capitolo__primo">Halfway along, the wall opens around a small courtyard paved in the same stone. An olive tree that was here long before the house still stands in the middle of it; the plan was bent twice to keep it.</p>
<p>A shallow pool, no deeper than a hand, runs along one side. It holds the sky on still days and on windy ones it shivers into grey. Its real job is quieter: in August it cools the air that drifts into the kitchen through the open doors.</p>
<p>The shadow of the wall moves across the paving like the hand of a slow clock. In the morning the courtyard is in shade; by four it is full of light, and the olive throws its shadow back onto the lime.</p>
</section>
<section class="capitolo" data-capitolo="Evening" data-foto-di="sera" data-didascalia-di="The house at dusk, from the edge of the water">
<h2 class="capitolo__titolo">Evening</h2>
<p class="capitolo__primo">At dusk the house turns itself inside out. The wall goes dark against the sky and the long window behind it lights up, a single warm line along the dune, the only light for a long way in either direction.</p>
<p>The tide comes in quietly here, over a flat beach, and on the highest springs it reaches the foot of the dune. Ilves set the floor exactly one step above the worst water anyone in the village could remember. So far, she says, the sea has agreed.</p>
<p>We left on the fourth morning, through the gap in the wall. Looking back from the road, it was already a line again, pale, patient, waiting for the light.</p>
</section>
</div>
</main>
<footer class="fine">
<p class="fine__nota">Marta Ilves Studio. Structural engineering by Halden & Roe. The house can be rented for a week in spring and autumn.</p>
<p class="fine__testata">Plinth</p>
</footer>
<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="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/CustomEase.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/lenis@1.3.26/dist/lenis.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.
58 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 article with the still photograph” from Animorio and fit it into my siteThe article is a two-column grid. The photograph's column has position: sticky, top 0, height 100lvh and align-self: start: it stays still while the text scrolls beside it, with no spacer and no recalculation. Inside, the frame takes all the room left above the caption and the index.
Each chapter has its own ScrollTrigger with start «top 50%» and end «bottom 50%»: it is active while it crosses the line in the middle of the screen, and the chapters touch, so there is always exactly one. When one becomes active the curtain, the caption, the index and the chapter opacities all start.
Each photograph is an absolute layer in the frame. The new one goes above the others with clip-path: inset(100% 0% 0% 0%), that is closed, and GSAP opens it to inset(0% 0% 0% 0%) on a curve that is slow at the start and at the end. Meanwhile the SVG inside the layer goes from scale 1.08 to 1, a little longer than the curtain, and the old photograph rises by 5%. Scrolling back, the curtain runs the other way.
The caption is split into words with overflow: hidden and letters in inline-block. The old line and the new one share the same grid cell: the old letters rise out of their word (yPercent −115) and the new ones come from below, each slightly after the last. The index instead is a hairline with an ink mark that moves to the active entry with back.out.
Below 760 pixels the grid becomes one column: the photograph sits on top, sticky, 34% of the screen tall, with the caption and the index in a row that scrolls itself to the active name. Since less room is left under the photograph, the reading line moves down to 70% of the screen, the middle of the visible text.
| Name | File | Default | What it changes |
|---|---|---|---|
CURTAIN_TIME | script.js | 1.1 | How many seconds the curtain takes to cover the old photograph. |
CURTAIN_EASE | script.js | 0.76, 0, 0.18, 1 | The curve of the curtain: slow to start and slow to arrive. |
START_SCALE | script.js | 1.08 | How large the new photograph is when it comes in, before it settles to 1. |
DIM_OPACITY | script.js | 0.28 | The opacity of the chapters you are not reading (1 = all full). |
DIRECTION | script.js | up | Where the curtain travels: up (rises from the bottom), down, left or right. Scrolling back it runs the other way. |
LETTER_STAGGER | script.js | 0.012 | Seconds between one caption letter and the next. |
data-foto-di e data-didascalia-di | index.html | 5 capitoli | On each chapter: which photograph it shows and its caption. The name in the index is data-capitolo. The drawings can be replaced by real photographs (an img with object-fit: cover in the layer). |
For a long read, a feature, the story of a project or a restaurant, an «about» page in chapters: whenever each part of the text has its own picture and the page should stay calm.
A single column: the photograph sits on top, still and shorter (a third of the screen), with the caption and the index in a row below it; the text scrolls underneath. Curtain, scale, letters and index are the same; the line that picks the chapter moves down to 70% of the screen.
No curtain, no scale, no rolling letters and no smooth scrolling: the new photograph fades in over the old one, the caption changes with a fade and the index mark jumps into place. The chapters still brighten and fade, as a fade.
GSAP 3.15.0, Lenis 1.3.26, Newsreader (font variabile) 5.3.0, Instrument Sans (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 15 KB; the libraries: GSAP + ScrollTrigger + CustomEase 49 KB, Lenis 5.3 KB.
Tested on 12 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.