Files
laconic.com/src/hooks/use-timeline-effect.ts
T
2022-03-28 15:00:11 -03:00

51 lines
1.5 KiB
TypeScript

import * as React from 'react'
import { gsap } from '~/lib/gsap'
import { useLocomotiveScroll } from '~/lib/locomotive-scroll/provider'
import { useIsomorphicLayoutEffect } from './use-isomorphic-layout-effect'
/**
* With a similar API as `React.useEffect`, this hook will create a `gsap.timeline` and run a callback with arbitrary dependencies.
*
* ```tsx
* useTimelineEffect((tl) => {
* tl.to(".my-element", { duration: 1, opacity: 0 });
* tl.to(".my-other-element", { duration: 1, opacity: 0 });
*
* return () => {
* // cleanup
* tl.kill();
* }
* }, []);
* ```
*
* @param callback A callback that is executed whenever dependencies change. Receives the timeline as a parameter. Returns a cleanup function.
* @param dependencies Dependencies for the effect.
* @param options Common options.
* @returns
*/
export const useTimelineEffect = (
callback: (timeline: GSAPTimeline) => void | (() => void),
dependencies: React.DependencyList,
options?: { autoKill?: boolean; autoPlay?: boolean }
) => {
const { isReady } = useLocomotiveScroll()
const [timeline] = React.useState(() =>
gsap.timeline({ paused: options?.autoPlay ? false : true })
)
useIsomorphicLayoutEffect(() => {
if (!isReady) return
const cleanup = callback?.(timeline)
return () => {
cleanup?.()
if (options?.autoKill !== false) {
timeline.kill()
}
}
}, [isReady, callback, timeline, options, ...(dependencies || [])])
return { timeline }
}