Presets
resolveMotionPreset(name, { reducedMotion: true }) forces 1ms linear transitions.
Motion system
Duration and easing tokens set the baseline. Spring presets, scroll effects, view transitions, and stagger build on top. Always ship a reduced motion path.
Every Glin UI animation reads from the same curve and duration tokens. Click a name to copy the variable, press play to feel the curve.
cubic-bezier(0.23, 1, 0.32, 1)
Entrances and hovers. Fast start, soft landing.
cubic-bezier(0.77, 0, 0.175, 1)
On-screen movement and morphs.
cubic-bezier(0.32, 0.72, 0, 1)
Sheets, drawers, and docked panels.
150ms
Hover and press feedback.
250ms
Menus, tooltips, small reveals.
400ms
Large surfaces and page level shifts.
Reduced motion: when the visitor sets prefers-reduced-motion, every demo above and in the grid pauses or drops its transition. Animate only transform and opacity, and keep a still frame that carries the same meaning.
Respect prefers-reduced-motion. Remove travel and parallax, keep short opacity changes, and never gate meaning behind an animation. In Tailwind, use motion-safe: to opt in and motion-reduce: to opt out.
resolveMotionPreset(name, { reducedMotion: true }) forces 1ms linear transitions.
resolveViewTransition, createScrollLinkedEffect.style, and createStaggerSequence each accept reduced-motion behavior.
Configurable spring dynamics. Use preset names or pass customtension,friction, andmass values.
gentle
tension 160 / friction 22 / mass 1.15
damping 0.81 / settle 481ms
cubic-bezier(0.167, 1.072, 0.313, 1)
smooth
tension 220 / friction 24 / mass 1
damping 0.81 / settle 384ms
cubic-bezier(0.189, 1.073, 0.351, 1)
snappy
tension 320 / friction 28 / mass 0.9
damping 0.82 / settle 296ms
cubic-bezier(0.225, 1.067, 0.415, 1)
bouncy
tension 280 / friction 18 / mass 0.95
damping 0.55 / settle 486ms
cubic-bezier(0.211, 1.17, 0.389, 1)
Use pointer-based primitives for drag, swipe, and pinch without adding runtime dependencies.
Drag
createDragGesture / useDragGesture
Swipe
createSwipeGesture / useSwipeGesture
Pinch
createPinchGesture / usePinchGesture
import { createSwipeGesture } from "@glinui/motion"
const swipe = createSwipeGesture({ axis: "x", onSwipe: ({ swipe }) => { if (!swipe) return handleSwipe(swipe.direction, swipe.velocity) }})
element.onpointerdown = swipe.onPointerDownelement.onpointermove = swipe.onPointerMoveelement.onpointerup = swipe.onPointerUpelement.onpointercancel = swipe.onPointerCancelTie blur, opacity, and transform values to scroll progress with one resolver.
scrollY 0px
progress 0.00 / opacity 0.60
filter blur(12px)
transform translate3d(0, 32px, 0) scale(0.96)
scrollY 150px
progress 0.25 / opacity 0.70
filter blur(9px)
transform translate3d(0, 24px, 0) scale(0.97)
scrollY 300px
progress 0.50 / opacity 0.80
filter blur(6px)
transform translate3d(0, 16px, 0) scale(0.98)
scrollY 450px
progress 0.75 / opacity 0.90
filter blur(3px)
transform translate3d(0, 8px, 0) scale(0.99)
scrollY 600px
progress 1.00 / opacity 1.00
filter blur(0px)
transform translate3d(0, 0px, 0) scale(1)
import { createScrollLinkedEffect } from "@glinui/motion"
const heroEffect = createScrollLinkedEffect({ start: 0, end: 600, opacity: [0.6, 1], blur: [12, 0], translateY: [32, 0]})
const style = heroEffect.style(window.scrollY)Presets provide page and component enter/exit choreography with consistent opacity and transform transitions.
pageFade
enter 240ms / exit 180ms
opacity 240ms var(--easing-standard), transform 240ms var(--easing-standard), filter 240ms var(--easing-standard)
pageSlide
enter 320ms / exit 220ms
opacity 320ms var(--easing-glass), transform 320ms var(--easing-glass), filter 320ms var(--easing-glass)
glassLift
enter 280ms / exit 200ms
opacity 280ms var(--easing-glass), transform 280ms var(--easing-glass), filter 280ms var(--easing-glass)
import { resolveViewTransition } from "@glinui/motion"
const transition = resolveViewTransition("pageSlide")
// Initial render styleconst initialStyle = transition.initial// Apply on mountconst enterStyle = transition.enter// Apply before unmountconst exitStyle = transition.exitOrchestrate list and grid choreography with deterministic stagger delays.
#1
328ms
#2
232ms
#3
136ms
#4
40ms
#5
88ms
#6
184ms
#7
280ms
#8
376ms
import { createStaggerSequence } from "@glinui/motion"
const stagger = createStaggerSequence({ count: items.length, direction: "center-out", stepMs: 48, initialDelayMs: 40})
const style = stagger.getStyle(index) // { transitionDelay: "..." }Tune spring parameters and inspect derived damping, frequency, settle duration, and easing output.
Damping Ratio
0.809
Angular Frequency
14.832
Settle Duration
384ms
CSS Easing
cubic-bezier(0.189, 1.073, 0.351, 1)
Optional adapters let you reuse Glin motion tokens with Framer Motion variants and spring transitions.
// Optional peerpnpm add framer-motion
import { motion } from "framer-motion"import { toFramerSpring, toFramerVariants } from "@glinui/motion"
const variants = toFramerVariants("glassLift")const spring = toFramerSpring("snappy")
export function Card() { return ( <motion.div initial="initial" animate="animate" exit="exit" variants={variants} transition={spring} /> )}