animare
Version:
Advanced animation library for modern JavaScript.
67 lines (61 loc) • 2.42 kB
text/typescript
import { autoPause } from 'animare/plugins';
import { useEffect } from 'preact/hooks';
import type { AutoPauseOptions, GroupTimelineObject, SingleObject, TimelineObject } from '../types';
/**
* Automatically pauses the animation when the element is not visible.
*
* Uses the IntersectionObserver API.
*
* Plays the timeline when the element becomes visible, even if the timeline was not playing before.
*
* Pauses the timeline when the element is not visible.
*
* @param timeline - The animation object returned by animare.
* @param element - The HTML element to track when entering and exiting the viewport.
* @param deps - The dependencies for the effect.
* @returns A function to remove the intersection observer and stop tracking visibility.
*
* @example
* import animare from 'animare';
* import { useAnimare, useAutoPause } from 'animare/react';
*
* function MyComponent() {
* // The element to track when entering and exiting the viewport
* const elementRef = useRef(null);
*
* const myTimeline = useAnimare(() => {
* return animare.timeline(...params);
* });
*
* useAutoPause(myTimeline, elementRef.current, []);
*
* // or you can pass in the observer options
* useAutoPause(myTimeline, elementRef.current, { threshold: 0.2 }, []);
* }
* }
*/
export function useAutoPause<Name extends string>(
timeline: TimelineObject<Name> | GroupTimelineObject | SingleObject,
element: Element | null,
deps?: React.DependencyList,
): void;
export function useAutoPause<Name extends string>(
timeline: TimelineObject<Name> | GroupTimelineObject | SingleObject,
element: Element | null,
observerOptions?: AutoPauseOptions,
deps?: React.DependencyList,
): void;
export function useAutoPause<Name extends string>(
timeline: TimelineObject<Name> | GroupTimelineObject | SingleObject,
element: Element | null,
observerOptionsOrDeps?: AutoPauseOptions | React.DependencyList,
deps: React.DependencyList = [],
): void {
const dependencies = Array.isArray(observerOptionsOrDeps) ? observerOptionsOrDeps : deps;
useEffect(() => {
if (!timeline || !element) return;
const observerOptions = (Array.isArray(observerOptionsOrDeps) ? {} : observerOptionsOrDeps) as IntersectionObserverInit;
return autoPause(timeline, element, observerOptions);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [timeline, element, ...dependencies]);
}