
The swatch fan menu
Menus, Physics, Transitions, Hover
NewFree
The sidebar of a project app with a steel toy spring beside the page chosen. Choosing another page the spring walks there like a slinky down the stairs: one end lifts, the spring arches, the turns pour over one at a time and the end lands on the next row, a step for every row, down to a last bounce.
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 slinky sidebar</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/onest@5.3.0/index.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage">
<!-- the sidebar of a small studio's project app. In the narrow column on the left, beside the page chosen, sits a
steel toy spring; choosing another page it walks there like a slinky down the stairs, one row at a time, and a
row pointed at makes it lean that way. The script draws the spring on the canvas, turn by turn -->
<div class="sl-wrap" data-wrap>
<nav class="sl" aria-label="Studio" data-nav data-autoclic>
<div class="sl__head">
<span class="sl__mark" aria-hidden="true">
<svg viewBox="0 0 24 24"><path d="M6.5 17.5V7.2L12 13.4L17.5 7.2V17.5"/></svg>
</span>
<span class="sl__studio">Marlow Studio</span>
</div>
<div class="sl__body" data-body>
<span class="sl__rail" aria-hidden="true" data-rail></span>
<canvas class="sl__spring" aria-hidden="true" data-spring></canvas>
<ul class="sl__list">
<li><a class="sl__item" href="#" data-item>
<svg class="sl__icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M3.5 13.5H8.2L9.6 16H14.4L15.8 13.5H20.5"/><path d="M5.6 5.5H18.4L20.5 13.5V18A1.5 1.5 0 0 1 19 19.5H5A1.5 1.5 0 0 1 3.5 18V13.5Z"/></svg>
<span class="sl__label">Inbox</span>
<span class="sl__count">4<span class="sl__sr"> new</span></span></a></li>
<li><a class="sl__item" href="#" aria-current="page" data-item>
<svg class="sl__icon" viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="12" r="3.6"/><path d="M12 3.4V5.4M12 18.6V20.6M3.4 12H5.4M18.6 12H20.6M5.9 5.9L7.3 7.3M16.7 16.7L18.1 18.1M5.9 18.1L7.3 16.7M16.7 7.3L18.1 5.9"/></svg>
<span class="sl__label">Today</span></a></li>
<li><a class="sl__item" href="#" data-item>
<svg class="sl__icon" viewBox="0 0 24 24" aria-hidden="true"><rect x="3.5" y="5" width="17" height="15" rx="2.5"/><path d="M3.5 9.5H20.5M8 3V6.5M16 3V6.5"/><path d="M8 13.5H11M8 16.5H14"/></svg>
<span class="sl__label">Upcoming</span></a></li>
</ul>
<p class="sl__title" id="sl-projects">Projects</p>
<ul class="sl__list" aria-labelledby="sl-projects">
<li><a class="sl__item" href="#" data-item>
<svg class="sl__icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M5 9.5H16.5V14A5 5 0 0 1 11.5 19H10A5 5 0 0 1 5 14Z"/><path d="M16.5 11H18A2 2 0 0 1 18 15H16.2"/><path d="M8.5 3.8C8 4.8 9.4 5.6 8.9 6.8M12.3 3.8C11.8 4.8 13.2 5.6 12.7 6.8"/></svg>
<span class="sl__label">Riverside Cafe</span></a></li>
<li><a class="sl__item" href="#" data-item>
<svg class="sl__icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M3.5 9L12 4L20.5 9Z"/><path d="M6 11.5V17M10 11.5V17M14 11.5V17M18 11.5V17"/><path d="M3.5 20H20.5"/></svg>
<span class="sl__label">Harbour Museum</span></a></li>
<li><a class="sl__item" href="#" data-item>
<svg class="sl__icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M12 6.5C10 5 7.5 4.6 4 4.8V18.2C7.5 18 10 18.4 12 19.8C14 18.4 16.5 18 20 18.2V4.8C16.5 4.6 14 5 12 6.5Z"/><path d="M12 6.5V19.8"/></svg>
<span class="sl__label">Spring Catalogue</span></a></li>
</ul>
<ul class="sl__list sl__list--foot">
<li><a class="sl__item" href="#" data-item>
<svg class="sl__icon" viewBox="0 0 24 24" aria-hidden="true"><rect x="3.5" y="4.5" width="17" height="4.5" rx="1.2"/><path d="M5 9V18A1.5 1.5 0 0 0 6.5 19.5H17.5A1.5 1.5 0 0 0 19 18V9"/><path d="M10 13H14"/></svg>
<span class="sl__label">Archive</span></a></li>
</ul>
</div>
</nav>
</div>
</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.
38 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 slinky sidebar” from Animorio and fit it into my siteThe spring has two ends, each with a place and the direction its axis enters the spring. Between them runs a cubic curve that leaves each end along its axis, with handles that grow longer the further apart the ends are (up to ARCH pixels), so closed it is a straight cylinder and open a round arch. The curve is measured on K points with its running length, to find a point and its direction at any distance from the end.
The TURNS + 1 turns are masses along the curve, at a distance s from the first end; the first and the last are the ends. Each is tied to the next by a spring of stiffness STIFFNESS with damping DAMPING, and the weight WEIGHT pulls it back towards the groove as much as the curve there runs away from it: where the curve leaves the groove the turns pile up closed, where it arches they spread, just like a real slinky on the stairs. Two turns cannot pass through each other: closed they touch and go on together. The time step is at most 1/30 of a second, split into substeps of 1/300.
A step is two flights. The top end leaves its place, lifts by LIFT pixels and lands in the groove of the next row while its axis turns half a turn; landing it gives a push to the turns that were falling with it. Two thirds into its flight, the end left behind peels off and lands on top of the spring, closed again in the new row. Then it is the top end's turn again: the two ends swap roles at every step, as in a real slinky. A long walk goes quicker, and at the last landing the top end bounces on the spring as high as BOUNCE says.
Each turn is a ring round the curve, seen a little from the left and from above: the point at an angle φ is the centre plus the normal times R cos φ plus a small fixed offset times R sin φ, which makes the ring an ellipse. The light is worked out from the normal of the steel: a bright sky above, a dark line at the horizon and a grey ground below, like chrome, plus the direct light and its highlight. The back halves are drawn first, in the shade, then the front halves from the furthest to the nearest, each with a dark edge under the shining steel; under everything the shadow on the bar, further off where the spring lifts.
A page pointed at, touched and held or reached with Tab moves the top end towards it by CURIOUS times the distance, on a spring that bounces a little, and turns it a little. The up and down arrows, Home and End go from page to page, Enter chooses, the page chosen has aria-current. When nothing has moved for a few frames the loop stops drawing until something wakes it.
| Name | File | Default | What it changes |
|---|---|---|---|
TURNS | script.js | 24 | How many turns of steel the spring has. |
RADIUS | script.js | 9 | The radius of a turn, in pixels. |
PITCH | script.js | 0.7 | The width of a turn when the spring is closed, in pixels. |
STIFFNESS | script.js | 900 | How hard a turn pulls on the next one. |
WEIGHT | script.js | 300 | How hard the turns fall back towards the groove. |
DAMPING | script.js | 0.12 | How fast the wobble of the turns dies away (0: never, 1: at once). |
STEP | script.js | 0.42 | The seconds one step from a row to the next takes. |
LIFT | script.js | 11 | How far the end of the spring lifts as it steps over, in pixels. |
ARCH | script.js | 23 | How far the arch of the spring may bulge out of the groove, in pixels. |
BOUNCE | script.js | 0.5 | How high the spring bounces when it lands (0: it just stops). |
CURIOUS | script.js | 0.26 | How far the spring leans towards a row pointed at (0: not at all). |
For the sidebar of an app with a sense of play: a project or task manager, a tool for a creative studio, an app for children or for school, a dashboard that wants a signature people remember.
The bar is 252 pixels wide and about 410 tall: at 390 pixels it fits whole on screen. Without a pointer, holding a finger on a page makes the spring stretch towards it, and tapping it makes it walk there.
The spring does not walk or stretch: it fades out of its row and appears again, already closed, beside the new page.
GSAP 3.15.0, Onest (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 10 KB; the libraries: GSAP 28 KB.
Tested on 8 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.