/ component

Easing Picker

CSS easing function picker — bezier canvas, spring/bounce/wiggle physics baked to linear(), polynomial preset gallery, 6-property animation preview, 3-format output (CSS/Tailwind v3/v4).

/ component · playground

Easing Picker

Basis
Direction
Presets
Curve
Cubic bezier curve editor
Preview · moveX (linear ghost shown)
Property
cubic-bezier(0.65, 0, 0.35, 1)
/ basis-narrow

Type-Locked

Setting basis narrows the value and onChange types at compile time. Each picker below emits a different literal-string flavor.

→ bezier
→ spring
→ steps
/ sub-component

BezierCanvas (standalone)

Drop just the bezier editor into your own UI. Drag the handles; the component owns nothing — you bring the state.

Cubic bezier curve editor
cubic-bezier(0.42, 0.00, 0.58, 1.00)
/ sub-component

Spring physics (standalone)

Compose SpringControls + sampleSpring + bakeLinear to roll your own spring picker. The picker baking happens client-side; no runtime physics in production.

linear(0, 0.2537 1.6949%, 0.6959 3.3898%, 1.0234 5.0847%, 1.1553 6.7797%, 1.1435 8.4746%, 1.0114 11.8644%, 0.9789 13.5593%, 0.9742 15.2542%, 1.0022 20.339%, 1)
/ api

API

Public surface — component props, runtime helpers, and the type exports.

§ EasingPicker

<EasingPicker
  value: EasingString | (string & {})
  onChange: (next: EasingString | string) => void
  basis?: EasingBasis
  output?: 'css' | 'tailwind-v3' | 'tailwind-v4'
  className?: string
  aria-label?: string
/>

Popover-wrapped composed wizard.

PropTypeDescription
valueEasingString | (string & {})Current CSS easing function or keyword. Required.
onChange(next) => voidCalled when the easing changes. Return type narrows by `basis`.
basisEasingBasis?Lock the wizard to "bezier" | "spring" | "bounce" | "wiggle" | "steps". Narrows onChange.
output'css' | 'tailwind-v3' | 'tailwind-v4'Default snippet format in the OutputPanel.
classNamestringApplied to the trigger button wrapper.
aria-labelstringRequired when no visible label is associated externally.

§ EasingPanel

<EasingPanel /* same props as EasingPicker */ />

Renders the wizard inline without a popover wrapper. Same prop surface as EasingPicker.

§ Sub-components

All controlled-only — value + onChange required.

BezierCanvas
Draggable P1/P2 SVG canvas.
PresetGallery
39-preset card grid.
EasingPreview
CSS-animated preview with 6 property options.
StepsControls
n + position editor.
SpringControls
Stiffness / damping / mass sliders.
BounceControls
Bounces / stiffness sliders.
WiggleControls
Wiggles / damping sliders.

§ Runtime helpers

easing<S extends string>(value: S & EasingLiteral<S>): S

Call-site validator. Mirrors color() and gradient().

parseEasing(s: string): EasingState | null

String → EasingState, or null when unrecognized.

formatEasing(state: EasingState): string

EasingState → CSS-valid string.

bezierFromPreset(name: PresetName): string

Preset name → cubic-bezier(...) literal.

matchPreset(x1, y1, x2, y2): PresetName | null

Reverse lookup by coords with tolerance 0.005.

sampleSpring(k, c, m, n) / sampleBounce(n, k) / sampleWiggle(n, d)

Physics samplers — emit sample arrays for baking.

bakeLinear(samples): string

Sample array → linear(...) string with collinear-prune pass.

§ Types

EasingString
Union of all valid output strings.
EasingLiteral<S>
Strict literal validator for call-site validation.
EasingBasis
"bezier" | "spring" | "bounce" | "wiggle" | "steps".
EasingStringMap
Basis → output-string map for type narrowing.
PresetName
Named preset union (39 entries).
EasingState
Internal discriminated union (exported for advanced use).

§ Limitations

  • Round-trip from linear() back to physics params is lossy — the baked output erases the source {stiffness, damping, mass}.
  • Preset selection emits the underlying cubic-bezier(...) literal, never the keyword form.
  • LinearLiteral<S> does weak validation (variadic stop ranges not checked at type level); the runtime parser is authoritative.
/ install

Drop it in

One command via the shadcn CLI.

$ pnpm dlx shadcn@latest add https://turtiesocks.github.io/ridiculous/r/easing-picker.json