useAnimatable
useAnimatable wraps the createAnimatable
function from AnimeJS. It gives each listed property a setter that tweens
to the value you pass, for values that change many times a second.
nanime rebuilds the animatable only when target points to a new element,
and reverts it when the component unmounts.
Usage
Counter: {"x":0}
import { round } from '#nanime/utils'
const progress = shallowRef(false)
const counter = reactive({ x: 0 })
const animator = useAnimatable(counter, {
x: 0,
duration: 1000,
modifier: round(0),
ease: 'outElastic',
onComplete() {
if (!progress.value) return
animator.x?.(counter.x + 1, 1000)
},
})
<template>
<p>Counter: {{ JSON.stringify(counter) }}</p>
</template>
{ x: 500 },
animator.x(100) tweens x to 100 over 500ms.Signature
function useAnimatable(
target: AnimeTargets,
options?: MaybeRefOrGetter<AnimatableParams>
): AnimatableObject
Parameters
Returns
Returns a reactive proxy around the AnimeJS AnimatableObject.
Its setters and methods are in the
AnimeJS animatable documentation.
Call setters and methods on the returned object, as in animator.x(100).
Destructured, they break:
revert() throws, and a setter keeps moving the old element once target
changes.
Caveats
Changing options alone does not rebuild the animatable
// wrong: changing durationRef does not alter the animatable instance
const durationRef = ref(300)
const anim = useAnimatable(target, () => ({ duration: durationRef.value }))
// right: supply explicit durations per setter or recreate when the target changes
anim.x(200, 500)
The underlying watcher bails out early when the normalized target element has
not changed. Mutating a ref passed inside options will not rebuild or update
the animatable controller. Pass override parameters directly to property setter
functions when dynamic durations or easings are needed.
Do not destructure the returned instance
// wrong: revert() throws, and x() drives the old animatable after a rebuild
const { revert, x } = useAnimatable(target, { x: 300 })
// right
const animator = useAnimatable(target, { x: 300 })
animator.x(200)
animator.revert()
The proxy hands back methods without their instance, so a destructured
revert() runs with no this and throws. Setters like x carry their own
instance, so a destructured one works until target changes. After that it
still drives the old animatable, not the rebuilt one. Keep the returned
object and call setters and methods on it.
Type reference
type AnimeTargets = TargetsParam | MaybeElementRef | MaybeElementRef[]
See also
useAnimatefor standard keyframe animation.useDraggablefor interactive pointer dragging.- AnimeJS animatable documentation for the upstream property accessor guides.