Skip to content
animorio
IT
All components

The slinky sidebar

Navigation, Physics, Transitions, HoverCanvas, GSAPAdvancedCompressed weight: Demo 10 KBGSAP 28 KBFreeDownload the zip

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.

The code

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>

Playground

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

Or ask Claude Code for it

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 site

What it does

On a white background, alone in the middle, the light sidebar of a small studio, Marlow Studio, 252 pixels wide: Inbox with a red badge reading 4, Today, Upcoming, then under the title Projects three projects (Riverside Cafe, Harbour Museum, Spring Catalogue) and at the bottom Archive, each with its line icon. On the left runs a column with a thin groove, and beside the page chosen, Today, lies a steel toy spring, drawn turn by turn: the front turns shining like chrome, with the pale reflection on top and the dark line of the horizon, the back ones in the shade, and under it its soft shadow on the bar. On arrival the spring drops into its row and bounces. Choosing another page, the spring walks there like a slinky on the stairs: its free end lifts, arches over and lands in the groove of the next row, the turns pour over one at a time, spreading in the arch and closing tight at both ends, then the other end peels off and lands on top; a step for every row on the way, quicker on a long walk, and at the last one the top end bounces a couple of times before it stops. Pointing at a page, or reaching it with Tab, the spring stretches a little towards it, opening its top turns, as if curious, and closes again when the pointer leaves. The spring always stays in its column: it never covers a name.

How it works

The line between the two ends

The 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 as a chain of masses

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.

The slinky's step

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 drawn as a chrome ring

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.

Curiosity, keys and rest

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.

Values to change

NameFileDefaultWhat it changes
TURNSscript.js24How many turns of steel the spring has.
RADIUSscript.js9The radius of a turn, in pixels.
PITCHscript.js0.7The width of a turn when the spring is closed, in pixels.
STIFFNESSscript.js900How hard a turn pulls on the next one.
WEIGHTscript.js300How hard the turns fall back towards the groove.
DAMPINGscript.js0.12How fast the wobble of the turns dies away (0: never, 1: at once).
STEPscript.js0.42The seconds one step from a row to the next takes.
LIFTscript.js11How far the end of the spring lifts as it steps over, in pixels.
ARCHscript.js23How far the arch of the spring may bulge out of the groove, in pixels.
BOUNCEscript.js0.5How high the spring bounces when it lands (0: it just stops).
CURIOUSscript.js0.26How far the spring leans towards a row pointed at (0: not at all).

Try them in the Playground

When to use it

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.

On phones

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.

With reduced motion

The spring does not walk or stretch: it fades out of its row and appears again, already closed, beside the new page.

Pitfalls

  • With the first light the spring looked like a dark battery rather than steel: chrome is not grey, it mirrors what is around it. Now the brightness of each bit of wire comes from a bright sky above, a dark line at the horizon and a grey ground below, plus a narrow highlight: so the turns get the glint and the dark edge of real metal.
  • The arch of the long step, over the Projects title, reached the edge of the column and would have landed on the icons: the curve's handle has a maximum (ARCH) and the canvas is as wide as the column, so the spring never covers a name.
  • With many thick turns the closed spring grew longer than the column: the Playground knobs have limits that keep the spring inside, even stretched towards a page, and the stretch of its curiosity stops short of the edge.
  • When the ends move the curve changes length and the turns, measured from the first end, lagged behind towards the other one: on every frame their distances are rescaled to the new length before the physics.
  • The grey ground of a row pointed at ran under the spring and made it look as if it stood on a rectangle: the ground and the focus ring start after the column.

Libraries

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.

Testing

Tested on 8 October 2026

  • Desktop: Done
  • Phone: Done
  • Reduced motion: Done
  • Safari on iPhone: To do

License

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.

All components