
The menu that opens from its button
Menus, Transitions, Text
Free
A select in the minimal style, all on one thin line: the words Ship to, the chosen country and the delivery days. Opened, the other countries roll out above and below the value like the faces of a drum, smaller and lighter as they turn away; the one in the middle gains weight and width. It turns with the wheel, a finger or the keys; choosing, the drum rolls shut on the country and the new value lands on the line one pixel too low, then settles.
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 thin drum select</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/archivo@5.3.0/wdth.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage">
<!-- a select on a thin line. Opened, the options roll out above and below the value like the faces of a drum;
the one in the middle gains weight, and choosing rolls the drum shut on it. The options are drawn by the
script from the list below -->
<div class="frame" data-frame>
<div class="sel" data-select>
<span class="sel__label" id="sel-label">Ship to</span>
<button class="sel__field" type="button" role="combobox" aria-haspopup="listbox" aria-expanded="false"
aria-controls="sel-list" aria-labelledby="sel-label sel-value" data-field>
<span class="sel__value" id="sel-value"><span class="sel__value-in" data-value>Italy</span></span>
</button>
<span class="sel__days" aria-hidden="true"><span class="sel__days-in" data-days>2–3 days</span></span>
<svg class="sel__chev" viewBox="0 0 14 14" aria-hidden="true"><path d="M3 5.5 7 9.5 11 5.5" /></svg>
<div class="sel__drum" id="sel-list" role="listbox" aria-labelledby="sel-label" data-drum hidden>
<div class="sel__roll" data-roll></div>
</div>
<span class="sel__band sel__band--top" aria-hidden="true"></span>
<span class="sel__band sel__band--bottom" aria-hidden="true"></span>
<span class="sel__line" aria-hidden="true" data-line></span>
<span class="sel__ink" aria-hidden="true" data-ink></span>
</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>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.
17 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 thin drum select” from Animorio and fit it into my siteEach country is a face turned STEP degrees for its distance from the middle (rotateX) and pushed out by the drum's radius (translateZ); the roll is pushed back by the same radius, so the middle face stays exactly where the field's value sits. The radius comes from the height of a face so that two neighbouring faces just touch; faces turned past 89 degrees are not drawn.
On every frame each face gets its font-variation-settings: wght from LIGHT to HEAVY and wdth from 84 to 100 depending on how near the middle it is, and an opacity that follows the cosine of its angle. The middle face has the same type as the field's value: opening, the value hides behind it without the change showing.
The drum's position is a number with decimals that a spring pulls towards the right face (SPRING and DAMP, with the time step kept under 1/30 of a second). A drag holds it, giving way less and less past the ends; let go, the face it would stop on with the speed it had is chosen and the spring takes it there.
Opening is a single number from 0 to 1 that multiplies the angles: at 0 every face is squeezed behind the value, at 1 the drum is open; GSAP takes it up with back.out, which goes just past. Closing takes it back to 0 while the drum comes round to the chosen face, then the new value drops on to the line LAND pixels too low and settles.
The field is a button with role combobox, aria-expanded, aria-controls and aria-activedescendant; the list is a listbox of options with aria-selected. The focus always stays on the field: arrows, Page Up and Down, Home and End turn the drum, Enter and Space choose, Tab chooses and moves on, Esc closes without a change, letters typed in a row look for the country.
| Name | File | Default | What it changes |
|---|---|---|---|
START | script.js | 6 | The country chosen when the page opens, by its place in the list. |
STEP | script.js | 22 | The degrees between two faces of the drum: fewer degrees, a bigger drum with more countries in view. |
SPRING | script.js | 190 | How hard the spring pulls the drum on to its face. |
DAMP | script.js | 21 | How much the spring holds the drum back: less, and it swings further past. |
OPEN_TIME | script.js | 0.6 | The seconds the drum takes to roll out. |
CLOSE_TIME | script.js | 0.34 | The seconds the drum takes to roll shut. |
LAND | script.js | 1 | How many pixels too low the new value lands before it settles. |
HEAVY | script.js | 760 | The weight of the middle face. |
LIGHT | script.js | 330 | The weight of the faces furthest away. |
For a select with many short options in a clean form: the shipping country at a shop's checkout, the size, the language, the time zone, the category of a request.
With a finger the drum is dragged and flung; under 420 pixels the type drops to 20 pixels and the delivery days hide, to leave room for long names.
No turning and no springs: opened, the countries sit in a flat column that fades upwards and downwards and fades in; the drum jumps straight to the right face and the new value does not drop.
GSAP 3.15.0, Archivo (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 6.8 KB; the libraries: GSAP 28 KB.
Tested on 22 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.