KQ-1524 · FLUTED/TUMBLER

Fluted Tumbler

A heavy fluted tumbler of two to four coloured layers, drawn per pixel in one WebGL2 pass: every flute is a small lens that resamples the liquid about its own centre, so the layers' boundaries break into repeating slivers with a faint colour fringe at the ribs. Drag in circles and the hand's angular velocity spins the liquid; overturning currents fold the layers into streaks and buoyancy separates them again by weight, while a sideways move tips the glass on springs.glide (heavy, no bounce) and sets the surface sloshing on a pendulum damped by the viscosity. The glass is a button: Left and Right stir, Shift with them tips it, Enter or Space gives a brisk stir.

KQ-1524 · FLUTED/TUMBLER
Coldbrook · No. 3Orchard tonicCherry, amber, cream

Drag in circles round the glass to stir it, or sideways to tip it. Left and Right stir, Shift with them tips the glass, Enter or Space gives a brisk stir.

settled · 3 layers, 20 flutes

Install

One command — the source lands in your repo. Or copy it from the Code tab.

$ pnpm dlx shadcn@latest add @kinetiq/fluted-tumbler

Props

layers
number
default 3
How many layers of liquid are stacked, 2 to 4; they take the first colours of `colors`.
colors
readonly string[]
default cherry, amber, cream, sage pigments
The layers' colours, bottom to top, as CSS colours; pigment, so they read the same in either theme.
amounts
readonly number[]
default [1, 1.1, 0.8, 0.6]
Each layer's share of the liquid, bottom to top; only the ratios matter.
fill
number
default 0.78
How full the glass is, 0.3 to 0.95 of the space above its heavy base.
fluteCount
number
default 20
Flutes round the whole glass, 8 to 40; about half face you.
fluteDepth
number
default 0.6
How hard each flute bends what is behind it, 0 (flat glass) to 1 (each flute shows a small inverted sliver).
fringe
number
default 0.5
The colour fringe where the image jumps at a rib, 0 to 1.
viscosity
number
default 0.4
How thick the liquid is, 0 to 1: runny liquid swirls long and sloshes, syrup turns slowly and comes to rest quickly.
settle
number
default 5
Roughly how long the layers take to separate again by weight, in seconds.
tilt
number
default 5
The furthest a sideways move tips the glass, in degrees.
glassColor
string
default "var(--ink-3)"
The glass's own tint, any CSS colour, resolved on the element so it follows the theme.
interactive
boolean
default true
Drag, tap and keys stir the glass.
paused
boolean
default false
Hold the liquid exactly where it is.
label
string
default "A fluted tumbler of layered colour"
Names the glass for assistive technology.
sound
boolean
default false
Play a pour while the liquid spins. Off unless asked for.
seed
number
default 3
Seeds where the overturning currents run, so two glasses never stir alike.
dpr
number
default 2
Cap on the canvas's device pixel ratio, at most 2.
onStir
() => void
default —
Fires when the visitor starts stirring a settled glass: a drag, a tap or a key.
onSettle
() => void
default —
Fires once the stirred layers have separated again and the glass is still.
disabled
boolean
default false
Shows the glass but takes no stirring.
className
string
default "h-56 w-full"
Sizes the box; give it a height.