Motion Hooksregistry/hooks/use-on-twos.ts/r/use-on-twos.json
useOnTwos
Core motion hooks (useOnTwos, useCountUp, useChanged, useSize, useReducedMotion) that sample transitions at 12 poses per second (83.33ms per pose).
Light · Paper.f12-theme-light
Interactive previewuseOnTwos progress: 1.00 · changed: false
$32,805
Dark · Flashback.f12-theme-dark
Interactive previewuseOnTwos progress: 1.00 · changed: false
$32,805
Install & copy-in source
shadcn CLI (use-on-twos.json)
npx shadcn@latest add https://frame12.dev/r/use-on-twos.jsonUsage example (useOnTwos)
import { useOnTwos, useCountUp, useChanged } from '@/hooks/use-on-twos';
export function AnimatedStat({ value }: { value: number }) {
const shown = useCountUp(value, 'stepped', 600);
const changed = useChanged(value);
const progress = useOnTwos(value, 600, 'stepped');
return <output data-changed={changed} data-p={progress.toFixed(2)}>{Math.round(shown)}</output>;
}WCAG AAAccessibility guarantees
Accessibility notes
- useReducedMotion() listens to (prefers-reduced-motion: reduce) and forces instant hard cuts.
- Returns 1 on initial mount so pages render complete at rest with zero layout shift.
GrammarFRAME/12 rules
Design grammar
- Quantizes elapsed time into FRAME_MS = 1000 / 12 (83.33ms) steps and applies cubic easeOut.
Props & TypeScript API
| Prop | Type | Default | Description |
|---|---|---|---|
key | unknown | required | Dependency value; changing key replays the 0..1 progress transition. |
duration | number | 600 | Total transition duration in milliseconds. |
motion | 'stepped' | 'smooth' | 'cut' | 'stepped' | Sampling mode: 12fps stepped poses, 60fps continuous, or instant hard cut. |