Other hooks
useCycle, usePageInView, useAnimationControls, useDomEvent and other utilities.
useCycle
Cycles through a list of values. It works like a signal whose setter moves to the next value, and wraps around after the last one:
const [shape, cycleShape] = useCycle(
{ borderRadius: "16px", rotate: 0 },
{ borderRadius: "50%", rotate: 0 },
{ borderRadius: "4px", rotate: 45 }
)
return <motion.div animate={shape()} onTap={() => cycleShape()} />Pass an index to jump to a value: cycleShape(0).
function useCycle<T>(...items: T[]): [Accessor<T>, (index?: number) => void]usePageInView
An accessor of whether the page is visible. It turns false when the user switches to another
tab or minimizes the window (document.hidden). Use it to pause work nobody can see:
const isPageInView = usePageInView()
createEffect(isPageInView, (visible) => {
visible ? video.play() : video.pause()
})On the server, it's true.
function usePageInView(): Accessor<boolean>useAnimationControls
Creates controls that start and stop animations on one or more motion components. Pass the
controls as their animate prop:
const controls = useAnimationControls()
return <motion.div animate={controls} />Then call:
controls.start(definition, transition?): animates every component to a target, a variant label, or a function called with each component'scustomprop. Returns a promise that resolves when all the animations finish.controls.set(definition): sets the values without animating.controls.stop(): stops the running animations.
start and set can be called from an effect or from onSettled, as the component mounts:
motion components that are still waiting to mount are mounted first.
For most animations, changing animate from a signal is simpler. Controls are useful to run a
sequence with await, or to drive several components from one place. useAnimation is an alias.
function useAnimationControls(): LegacyAnimationControlsuseDomEvent
Adds an event listener to an element, window or document, and removes it when the component
is disposed:
useDomEvent(window, "resize", () => setWidth(window.innerWidth))The target can be an element, an accessor of one, or a { current } object, like the refs of
useScroll. It's read once the component's elements
exist. When a signal it reads switches to another element, the listener moves to it.
let element!: HTMLDivElement
useDomEvent(
() => element,
"wheel",
(event) => event.preventDefault(),
{
passive: false,
}
)
return <div ref={element} />function useDomEvent(
ref: ElementRef<EventTarget>,
eventName: string,
handler?: EventListener,
options?: AddEventListenerOptions
): voiduseInstantTransition
Returns a function that runs a state change with animations turned off. Every motion component
that animates because of the change jumps to its new values, layout animations included.
Animations are turned back on two frames after the callback runs:
const startInstantTransition = useInstantTransition()
const reset = () => startInstantTransition(() => setStep(0))disableInstantTransitions() turns animations back on immediately.
function useInstantTransition(): (callback: () => void) => voiduseInstantLayoutTransition
Like useInstantTransition, but only for layout animations: layout changes made in the callback
don't animate. Other animations still run.
const startInstantLayoutTransition = useInstantLayoutTransition()
startInstantLayoutTransition(() => setExpanded(false))function useInstantLayoutTransition(): (callback?: () => void) => voiduseResetProjection
Returns a function that stops every running layout animation and clears the layout measurements they're based on. Use it after the page changed in a way layout animations can't follow, for example when content is replaced while elements are mid-animation. The next layout change measures from scratch.
const resetProjection = useResetProjection()function useResetProjection(): () => voiduseWillChange
Returns a motion value for the will-change style. Pass it as style.willChange, and it becomes
"transform" once the component animates a transform or a value the browser can accelerate
(opacity, filter, clipPath, backgroundColor). It stays "auto" otherwise:
const willChange = useWillChange()
return <motion.div animate={{ x: 100 }} style={{ willChange }} />function useWillChange(): WillChangeNot listed here
useUnmountEffect(callback) is exported for parity with Motion for React. It's the same as
Solid's onCleanup, which you can use directly.