Skip to content
animorio
IT
All components

The string slider

Sliders, Physics, SVGGSAPMediumCompressed weight: Demo 6.0 KBGSAP 28 KBFreeDownload the zip

A volume slider made like a taut string: dragging the knob you can also pull the string up or down and, let go, it twangs; the value sits in a bubble on a stem that leans when the knob runs and swings upright again.

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 string slider</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/bricolage-grotesque@5.3.0/index.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <!-- the slider: a string held at its two ends with the knob riding on it. Dragging, the pointer can pull the string
         up or down; let go, it twangs. The value hangs over the knob in a bubble on a stem, which leans with the
         speed and swings back. The string is drawn by the script -->
    <div class="volume" data-volume>
      <div class="volume__head">
        <svg class="volume__icon" viewBox="0 0 24 24" aria-hidden="true">
          <path class="volume__speaker" d="M3.5 9.2h3.6l4.9-4.1v13.8l-4.9-4.1H3.5z"/>
          <path class="volume__wave" data-wave d="M15.2 9.4a3.7 3.7 0 0 1 0 5.2"/>
          <path class="volume__wave" data-wave d="M17.8 6.8a7.4 7.4 0 0 1 0 10.4"/>
          <path class="volume__wave" data-wave d="M20.4 4.2a11.1 11.1 0 0 1 0 15.6"/>
          <path class="volume__mute" data-mute d="M15.6 9.6l4.8 4.8M20.4 9.6l-4.8 4.8"/>
        </svg>
        <span class="volume__label" id="volume-label">Volume</span>
      </div>
      <div class="volume__track" role="slider" tabindex="0" aria-labelledby="volume-label" aria-valuemin="0" aria-valuemax="100" data-track data-autoclic>
        <svg class="volume__string" aria-hidden="true" data-string>
          <!-- while the string shakes, the eye sees the space it sweeps: two pale shapes between its two extremes -->
          <path class="volume__sweep volume__sweep--empty" data-sweep-empty/>
          <path class="volume__sweep volume__sweep--full" data-sweep-full/>
          <path class="volume__empty" data-empty/>
          <path class="volume__full" data-full/>
        </svg>
        <div class="volume__thumb" data-thumb>
          <span class="volume__knob" data-knob></span>
          <span class="volume__bubble" aria-hidden="true" data-bubble><span class="volume__number" data-number></span></span>
        </div>
      </div>
    </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.

15 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 string slider” from Animorio and fit it into my site

What it does

On a white background a speaker with two waves and the word Volume, and below it a line, coral up to a white knob and pale grey after it; over the knob, on a stem, a black bubble with the value 64. When the page opens the line opens out from the middle, the knob pops up and the string is plucked once. Dragging the knob the value changes and the bubble leans back, the more the faster you go, and swings upright again when you stop; taking the pointer up or down, the string stretches in two straight pieces to the knob. Let go, the string twangs with the knob on it, and for a moment the pale shadow of the space it sweeps stays around it. Pressing on the line the knob hops there; the arrow keys move it, and every press plucks the string a little. The speaker shows one, two or three waves depending on the volume, and a small coral cross at zero.

How it works

A string and a knob

The string is two straight SVG paths, from the left end to the knob and from the knob to the right end; the knob is an HTML element the script moves with transform. The slider, with role slider and tabindex, is the whole line: that way a click anywhere on it focuses it, and from there the keys work.

Pulling

While it is held the string goes where the hand takes it: the pointer’s distance from the string times PULL, MAX_PULL pixels at most. It follows quickly and without bouncing, and the script keeps track of the speed it moves at, for the moment it is let go.

The twang

Let go, the string is a spring with the stiffness and damping of TWANG, worked out on GSAP’s ticker in steps of 4 milliseconds. The shadow comes from the size of the swing, √(y² + (v/ω)²): two pale shapes running from how high it goes to how low, fading with it.

The bubble on its stem

The bubble is a pendulum: it wants to lean by the knob’s speed times SWING, the other way (22 degrees at most), and gets there on a loosely held spring, so it goes past and comes back. It turns around the foot of the stem, where it touches the knob.

Keys and the preview

The arrows move the value by KEYS[0], with Shift or the Page keys by KEYS[1], Home and End go to the ends; every press gives the string a little push. A click from a script (detail 0, the one of the library’s preview) is a pretend hand: it pulls the string up, carries the knob to another value and lets go.

Values to change

NameFileDefaultWhat it changes
START_ATscript.js64The value when the page opens, from 0 to 100.
PULLscript.js0.42How much the string follows the pointer up and down while it is held.
MAX_PULLscript.js32How far the string can be pulled, in pixels.
TWANGscript.js[1500, 0.06]The spring of the string once let go: how stiff it is and how much it is held back.
SWINGscript.js0.05How much the bubble leans with the knob’s speed.
KEYSscript.js[1, 10]How far an arrow key moves the value, and with Shift or the Page keys.

Try them in the Playground

When to use it

For a player’s volume, brightness, a price filter, an amount: wherever a value is chosen along a line and touching it should be a pleasure.

On phones

The slider takes the width of the screen minus a margin. A finger drags it sideways while the page can still scroll up and down (touch-action: pan-y); a drag that started sideways can then pull the string up or down too.

With reduced motion

The string does not stretch or twang, the bubble does not lean and there is no entrance: the knob follows the finger, jumps where you press and goes straight to the value chosen with the keys.

Pitfalls

  • If the slider role were on the knob, a click on the line would not focus it and the keys would not answer; and focusing it from a script, Chrome would show the keyboard ring even with the mouse. That is why the slider is the whole line.
  • With the string’s stiffness, a spring worked out in whole frames would blow up on the first slow frame: the script works it out in steps of 4 milliseconds at most.
  • With the keys the knob glides towards the new value: each press must start from the value being headed for, not from the one in passing, or quick presses would be lost.
  • A zero-length SVG path with round caps shows as a little dot: at 0 and at 100 one of the two pieces of the string is zero long, and it stays hidden under the knob.

Libraries

GSAP 3.15.0, Bricolage Grotesque (font variabile) 5.3.0.

Compressed with gzip, the three demo files weigh 6.0 KB; the libraries: GSAP 28 KB.

Testing

Tested on 3 October 2026

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

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