useAnimate
Reactive Web Animations API wrapper. Drives element.animate() with Observable-based reactive state for playState, currentTime, playbackRate, and pending.
Reactive wrapper around element.animate() with play / pause / reverse controls.
import { const useRef$: { <T = any>(initialValue: null): Ref$<T | null>; <T = any>(initialValue: T): Ref$<T>; <T = any>(): Ref$<T | null>;}
useRef$ } from "@usels/core";import { const useAnimate: (target: MaybeEventTarget, keyframes: UseAnimateKeyframes, options?: number | DeepMaybeObservable<UseAnimateOptions>) => UseAnimateReturn
useAnimate } from "@usels/web";
function function Component(): JSX.Element
Component() { const const el$: Ref$<HTMLSpanElement | null>
el$ = useRef$<HTMLSpanElement>(): Ref$<HTMLSpanElement | null> (+2 overloads)
Core (framework-agnostic) version of useRef$.
Creates an observable element ref with opaque wrapping.
- non-null value →
Ref$<T>: current, get(), peek() return T
- null / no arg →
Ref$<T | null>: current, get(), peek() return T | null
Nullability is expressed via the type parameter, mirroring T | null at the call site.
useRef$<interface HTMLSpanElement
HTMLSpanElement>(); const { const playState$: ReadonlyObservable<AnimationPlayState>
playState$, const play: Fn
play, const pause: Fn
pause } = function useAnimate(target: MaybeEventTarget, keyframes: UseAnimateKeyframes, options?: number | DeepMaybeObservable<UseAnimateOptions>): UseAnimateReturn
Framework-agnostic reactive wrapper around the
Web Animations API.
Must be called inside a useScope factory — resource setup (update) is
registered via onMount and cleanup via onUnmount. rAF sync, element
tracking, keyframe reactivity, and animation-event listening are all driven
by scope-aware observe() so the whole pipeline tears down on scope
disposal.
useAnimate( const el$: Ref$<HTMLSpanElement | null>
el$, { transform: string
transform: "rotate(360deg)" }, 1000 );
return ( <JSX.IntrinsicElements.div: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div> <JSX.IntrinsicElements.span: DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>
span RefAttributes<HTMLSpanElement>.ref?: Ref<HTMLSpanElement> | undefined
Allows getting a ref to the component instance.
Once the component unmounts, React will set ref.current to null
(or call the ref with null if you passed a callback ref).
ref={const el$: Ref$<HTMLSpanElement | null>
el$} HTMLAttributes<HTMLSpanElement>.style?: CSSProperties | undefined
style={{ StandardLonghandProperties<string | number, string & {}>.display?: Property.Display | undefined
This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.
Syntax: [ <display-outside> || <display-inside> ] | <display-listitem> | <display-internal> | <display-box> | <display-legacy>
Initial value: inline
| Chrome | Firefox | Safari | Edge | IE |
| :----: | :-----: | :----: | :----: | :---: |
| 1 | 1 | 1 | 12 | 4 |
display: "inline-block" }}>useAnimate</JSX.IntrinsicElements.span: DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>
span> <JSX.IntrinsicElements.p: DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p>{const playState$: ReadonlyObservable<AnimationPlayState>
playState$.ImmutableObservableBase<AnimationPlayState>.get(trackingType?: TrackingType | GetOptions): any
get()}</JSX.IntrinsicElements.p: DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p> <JSX.IntrinsicElements.button: DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
button DOMAttributes<HTMLButtonElement>.onClick?: MouseEventHandler<HTMLButtonElement> | undefined
onClick={const play: Fn
play}>Play</JSX.IntrinsicElements.button: DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
button> <JSX.IntrinsicElements.button: DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
button DOMAttributes<HTMLButtonElement>.onClick?: MouseEventHandler<HTMLButtonElement> | undefined
onClick={const pause: Fn
pause}>Pause</JSX.IntrinsicElements.button: DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
button> </JSX.IntrinsicElements.div: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div> );}import { createRef$ } from "@usels/core";import { createAnimate } from "@usels/web";
function Component() { "use scope" const el$ = createRef$<HTMLSpanElement>(); const { playState$, play, pause } = createAnimate( el$, { transform: "rotate(360deg)" }, 1000 );
return ( <div> <span ref={el$} style={{ display: "inline-block" }}>useAnimate</span> <p>{playState$.get()}</p> <button onClick={play}>Play</button> <button onClick={pause}>Pause</button> </div> );}Custom Keyframes
Section titled “Custom Keyframes”Array, object, or Observable keyframes are all supported.
import { useRef$ } from "@usels/core";import { useAnimate } from "@usels/web";import { useObservable } from "@usels/core";
function Component() { const el$ = useRef$<HTMLDivElement>();
// Object form (PropertyIndexedKeyframes) useAnimate(el$, { transform: "rotate(360deg)" }, 1000);
// Array form useAnimate(el$, [{ transform: "rotate(0deg)" }, { transform: "rotate(360deg)" }], 1000);
// Observable — effect updates when value changes const keyframes$ = useObservable([ { clipPath: "circle(20% at 0% 30%)" }, { clipPath: "circle(20% at 50% 80%)" }, ]); useAnimate(el$, keyframes$, 1000);}import { observable } from "@usels/core";import { createRef$ } from "@usels/core";import { createAnimate } from "@usels/web";
function Component() { "use scope" const el$ = createRef$<HTMLDivElement>();
// Object form (PropertyIndexedKeyframes) createAnimate(el$, { transform: "rotate(360deg)" }, 1000);
// Array form createAnimate(el$, [{ transform: "rotate(0deg)" }, { transform: "rotate(360deg)" }], 1000);
// Observable — effect updates when value changes const keyframes$ = observable([ { clipPath: "circle(20% at 0% 30%)" }, { clipPath: "circle(20% at 50% 80%)" }, ]); createAnimate(el$, keyframes$, 1000);}Options
Section titled “Options”Pass a number as duration shorthand, or an options object with full configuration.
useAnimate(el$, keyframes, { duration: 1000, immediate: true, // auto-play on mount (default: true) commitStyles: false, // commit styles on finish (default: false) persist: false, // persist animation (default: false) onReady(animate) { console.log("ready", animate); }, onError(e) { console.error(e); },});Delaying Start
Section titled “Delaying Start”import { useRef$ } from "@usels/core";import { useAnimate } from "@usels/web";
function Component() { const el$ = useRef$<HTMLDivElement>(); const { play } = useAnimate( el$, { opacity: [0, 1] }, { duration: 1000, immediate: false, } );
return ( <> <div ref={el$} /> <button onClick={play}>Start Animation</button> </> );}import { createRef$ } from "@usels/core";import { createAnimate } from "@usels/web";
function Component() { "use scope" const el$ = createRef$<HTMLDivElement>(); const { play } = createAnimate( el$, { opacity: [0, 1] }, { duration: 1000, immediate: false, } );
return ( <> <div ref={el$} /> <button onClick={play}>Start Animation</button> </> );}Parameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
target | MaybeEventTarget | - |
keyframes | UseAnimateKeyframes | - |
options | number | DeepMaybeObservable<UseAnimateOptions> | undefined (optional) | - |
UseAnimateOptions
Section titled “UseAnimateOptions”Returns
Section titled “Returns”UseAnimateReturn
| Name | Type | Description |
|---|---|---|
animate$ | ReadonlyObservable<Animation | null> | Current Animation instance. |
play | Fn | - |
pause | Fn | - |
reverse | Fn | - |
finish | Fn | - |
cancel | Fn | - |
pending$ | ReadonlyObservable<boolean> | - |
playState$ | ReadonlyObservable<AnimationPlayState> | - |
replaceState$ | ReadonlyObservable<AnimationReplaceState> | - |
startTime$ | ObservablePrimitive<number | null> | - |
currentTime$ | ObservablePrimitive<number | null> | - |
timeline$ | Observable<AnimationTimeline | null> | - |
playbackRate$ | ObservablePrimitive<number> | - |
isSupported$ | ReadonlyObservable<boolean> | - |