useSequencePlayer
ericts-ui/use-sequence-playerFreeHook
A client-safe React hook that spotlights one scripted animation sequence at a time, pausing off-screen, on hidden tabs, while focused, and under reduced motion.
Install it
npx shadcn@latest add https://ui.ericts.com/r/use-sequence-player.jsonSource
1"use client";23import { useCallback, useEffect, useRef, useState } from "react";45import { useReducedMotion } from "@/hooks/use-reduced-motion";67/**8 * One scripted sequence: how many beats it plays and how long each beat rests.9 *10 * `stepMs` accepts an array when the beats are unequal — a code-entry demo that11 * types four digits and then holds on a success check needs a long final beat,12 * and averaging that into one number makes the payoff read as a glitch. The last13 * entry repeats if the array is shorter than `steps`.14 */15export type SequenceScript = {16 steps: number;17 stepMs: number | readonly number[];18};1920export type UseSequencePlayerOptions = {21 /** One entry per sequence, in spotlight order. */22 sequences: readonly SequenceScript[];23 /**24 * Quiet beat before the first sequence starts, so a page that just scrolled25 * into view settles before anything moves. Defaults to 500ms.26 */27 leadInMs?: number;28 /** Set false to hold everything at its poster frame. Defaults to true. */29 enabled?: boolean;30 /**31 * Whether `takeOver` keeps replaying its sequence instead of handing off.32 * Defaults to true — the point of taking over is to watch one thing repeat.33 */34 loopTakeOver?: boolean;35};3637type ContainerProps = {38 ref: (node: HTMLElement | null) => void;39 onFocusCapture: () => void;40 onBlurCapture: (event: { currentTarget: HTMLElement; relatedTarget: EventTarget | null }) => void;41 onPointerLeave: () => void;42};4344export type UseSequencePlayerResult = {45 /**46 * Spread onto the element that wraps every sequence. Supplies the visibility47 * observer plus the focus and pointer pauses; without it the player would keep48 * animating off-screen and would yank the spotlight away from a keyboard user49 * reading one sequence.50 */51 containerProps: ContainerProps;52 /** Index of the sequence currently holding the spotlight. */53 activeIndex: number;54 /** Beats already fired in the active sequence; the last one is still resting. */55 stepsFired: number;56 /**57 * Per-sequence play counter. Feed `runs[i]` to a sequence as a prop (or a58 * React `key`) and derive its visual state from that number — the player never59 * needs to know what any sequence actually renders.60 */61 runs: readonly number[];62 /** False while paused: reduced motion, off-screen, background tab, or focused. */63 isPlaying: boolean;64 /** Dwell for one beat, for driving a progress indicator. */65// … truncated
What it pulls in
Other registry items
Files it writes
More from ericts-ui
All 43 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| useElementHeightuse-element-height | ericts-ui | Hooks | Free | no deps | |
| useElementSizeMapuse-element-size-map | ericts-ui | Hooks | Free | no deps | |
| useReducedMotionuse-reduced-motion | ericts-ui | Hooks | Free | no deps | |
| useScrollAnchoruse-scroll-anchor | ericts-ui | Hooks | Free | no deps | |
| useScrollProgressuse-scroll-progress | ericts-ui | Hooks | Free | no deps | |
| useSwipeNavigationuse-swipe-navigation | ericts-ui | Hooks | Free | no deps |
