
The slide-to-confirm button
Buttons, Physics, Transitions
NewFree
A filter for the price of a night over a histogram of the stays: the two handles follow the hand on springs, stretching a little, the bars change colour with a little jump as a handle goes over them, the two prices join when they meet and the number of stays counts up and down.
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 price range</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/sofia-sans@5.3.0/index.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage">
<!-- the price range: two handles on springs over a histogram of prices; the bars light up with a little jump as a
handle goes over them, the two prices join when they meet, and the number of stays counts up and down -->
<section class="price" aria-labelledby="price-title" data-price data-autoclic>
<header class="price__head">
<div>
<h2 class="price__title" id="price-title">Price per night</h2>
<p class="price__note">Before taxes and fees</p>
</div>
<p class="price__count"><span data-count>0</span> stays</p>
</header>
<div class="price__chart" data-chart>
<div class="price__bars" aria-hidden="true" data-bars></div>
<div class="price__track" aria-hidden="true"><span class="price__fill" data-fill></span></div>
<span class="price__thumb" aria-hidden="true" data-thumb></span>
<span class="price__thumb" aria-hidden="true" data-thumb></span>
<span class="price__tag" aria-hidden="true" data-tag></span>
<span class="price__tag" aria-hidden="true" data-tag></span>
<span class="price__tag price__tag--both" aria-hidden="true" data-both></span>
<input class="price__range" type="range" aria-label="Minimum price" data-range>
<input class="price__range" type="range" aria-label="Maximum price" data-range>
</div>
<div class="price__fields">
<label class="field">
<span class="field__label">Minimum</span>
<span class="field__box"><span aria-hidden="true">€</span><input class="field__input" type="text" inputmode="numeric" autocomplete="off" data-field></span>
</label>
<label class="field">
<span class="field__label">Maximum</span>
<span class="field__box"><span aria-hidden="true">€</span><input class="field__input" type="text" inputmode="numeric" autocomplete="off" data-field></span>
</label>
</div>
<p class="sr" aria-live="polite" data-live></p>
</section>
</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.
24 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 price range” from Animorio and fit it into my siteEach handle heads for the price chosen (rounded to STEP) on a spring (SPRING), worked out on GSAP’s ticker in steps of 4 milliseconds; the spring’s speed stretches it (scaleX up to 1.28, and a little thinner). The handles stop a step short of each other, so they never cross.
Each bar has its own spring (POP) between 0 (out) and 1 (in): it is in when its middle lies between the two handles where they are now, so it changes just as a handle goes over it. The colour goes from grey to teal with the spring; when the spring overshoots (held back little, it jumps) the bar stretches coming in and shrinks going out.
The labels sit under the handles, kept inside the chart; when less than 8 pixels are left between them they make way, fading, for a single label with the lowest and highest price, in the middle between the handles.
The stays’ prices are a fixed set (the same every time, from a seeded generator): the histogram counts them in BARS groups, and the number at the top is how many lie between the two prices chosen, brought to the new value in 0.5 seconds.
Under the drawn handles there are two real sliders (range inputs) with aria-valuetext in euros: Tab reaches them, the arrows move by STEP, Page Up and Down by more, Home and End to the ends, and the drawn handle shows the focus. The boxes take a price and confirm it with Enter; an aria-live region says how many stays there are between the two prices. A click from a script (the library’s preview) is a pretend hand that takes the handles to a new range, one after the other.
| Name | File | Default | What it changes |
|---|---|---|---|
RANGE | script.js | [20, 380] | The lowest and the highest price on the scale, in euros. |
STEP | script.js | 5 | How many euros a handle moves by. |
SPRING | script.js | [520, 0.72] | The handles’ spring: how stiff it is and how much it is held back. |
POP | script.js | [420, 0.4] | The bars’ spring as a handle goes over them: stiff and held back little, so it jumps. |
BARS | script.js | 36 | How many bars the histogram has. |
START | script.js | [80, 220] | The prices chosen when the page opens. |
For the filters of a booking site, a shop, an estate agent or a listings site: anywhere a range is chosen, of price, of size, of years.
The chart is dragged with a finger without scrolling the page (touch-action none) and a press anywhere takes the nearer handle; the boxes are 16 pixels, so Safari on iPhone does not zoom the page, and they open the number keyboard (inputmode numeric).
The handles go straight to the price chosen, without spring or stretch, the bars change colour without jumping, the number changes at once, the labels join without fading and nothing grows when the page opens.
GSAP 3.15.0, Sofia Sans (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 6.5 KB; the libraries: GSAP 28 KB.
Tested on 3 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.