
The title that rises from a line
Transitions, Text, Images
NewFree
In the minimal style: a gallery with a single thin frame in the middle. The pictures behind it stay still, and at every change the frame takes a breath and springs to another proportion (square, portrait, panorama, landscape, story), cropping them in a new way; the caption underneath rolls letter by letter.
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>Ratio</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>
<!-- one thin frame in the middle of the room: the pictures behind it never move, the frame crops them -->
<main class="room" data-room tabindex="0" role="region" aria-roledescription="gallery" aria-label="Ratio, a gallery of five pictures. Press the arrow keys or click to change picture.">
<header class="top">
<p class="mark" data-mark aria-hidden="true">Ratio</p>
<p class="sub" data-sub>Studies in crop</p>
</header>
<div class="pictures" data-pictures aria-hidden="true"></div>
<svg class="frame" data-frame aria-hidden="true">
<path class="frame__line" data-line pathLength="1" d="" />
</svg>
<div class="caption" data-caption aria-hidden="true">
<p class="caption__title"><span class="slot" data-title></span></p>
<p class="caption__meta"><span class="slot slot--format" data-format></span><span class="slot slot--ratio" data-ratio></span></p>
</div>
<p class="hint" data-hint aria-hidden="true">Click for the next picture</p>
<p class="sr" data-live aria-live="polite"></p>
</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.
33 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 frame that changes shape” from Animorio and fit it into my siteEvery picture is an SVG as big as the room, drawn by the script around the middle of the frame: the sun, the hills, the island and the arch always sit in the centre, so every crop is a good one. They all live in one container cut with clip-path: inset(), and the window is the frame: changing the four inset values changes the shape, while the pictures stay where they are. On top sits a tile of noise drawn once on a canvas, in multiply, for the grain.
Every entry in PICTURES has its proportion written as width:height. For each one the size is found by fitting it into the free space (less the name at the top and the caption at the bottom) and then capping its area at a little more than the square's: so the panorama does not get huge and the story does not vanish, and it really looks like the same picture cut another way.
The ease is a function written by hand: the position of a spring let go from rest, 1 minus e to the minus dt times (cos wt plus d/w sin wt). The first overshoot is e to the minus d pi over w, so SPRING picks exactly how far the frame goes past; the tiny remainder left at the end is spread over the tail, so the tween lands precisely. Before the spring the frame shrinks by 1.6% in a sixth of a second: the breath that sets up the jump.
The thin line is a path in an SVG as big as the room, redrawn on every frame by the GSAP ticker around the window, on half a pixel to stay sharp. The space between picture and line is a number of its own: during a change it opens with power2.out and closes again with elastic.out, and with the mouse over it it tightens; so the line never touches the picture, even when the spring overshoots. At the opening the line draws itself with stroke-dashoffset on pathLength 1.
The new picture comes on top of the others and is uncovered by a clip-path: inset() of its own, running from one side of the box that holds both the old and the new frame; it starts when the spring is already a third of the way, so first you see the old picture cropped another way. The caption follows the bottom edge of the line and is as wide as it. Every text sits in a slot with hidden overflow: old and new lines stack in the same grid cell, letters leave upwards and come in from below, and the --w variable takes the typeface's wdth axis from 76 to 100 with an elastic.
| Name | File | Default | What it changes |
|---|---|---|---|
PICTURES | script.js | [{ title: 'Low sun', shape: 'Square', ratio: '1:1' }, …] | The pictures, in order: the title, the name of the shape and the proportion of the frame (width:height, for example 16:9). There are five drawings, repeated if there are more entries. |
HOLD | script.js | 2.6 | How many seconds each picture stays before the next one. |
MORPH | script.js | 1.15 | How many seconds the frame takes to change shape. |
SPRING | script.js | 0.4 | How far the frame goes past before it settles: 0 arrives smoothly, 1 bounces a lot. |
MAT | script.js | 10 | The white space between the picture and the line, in pixels (0 = the line on the picture's edge). |
SIZE | script.js | 0.8 | How much of the room the frame takes up. |
AUTOPLAY | script.js | true | Whether the pictures change by themselves. With false they change only with a click, a swipe or the arrow keys. |
For a gallery that should feel like an object, not a grid: a photographer's or illustrator's portfolio, an exhibition page, a design studio's showcase, an art print shop, a project presentation. It shows pictures of different formats well, without stretching them or cropping them at random.
The same animation with the sizes adapted: the frame takes up almost the whole width and the title is smaller. A tap goes to the next picture, a swipe right or left goes forwards or back.
Nothing moves: everything fades in, and at every change frame, picture and caption fade out and back in with the new shape, with no spring, blind or rolling letters.
GSAP 3.15.0, Instrument Sans (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 9.7 KB; the libraries: GSAP 28 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.