useScrambleText
useScrambleText wraps the scrambleText
utility from AnimeJS. It animates an element's text content through random
characters before settling on the final string.
Both animation and scramble parameter objects accept reactive inputs. Changing
either configuration rebuilds the underlying animation. By default it
restarts. Set keepTime: true to carry the playhead over so the scramble
continues instead.
Usage
Hello from nanime!
const texts = [
'Hello from nanime!',
'Scramble text with animejs!',
'Reactive composables rock',
'Care to star us on github? :)',
]
const label = useTemplateRef('label')
const index = ref(0)
function next() {
index.value = (index.value + 1) % texts.length
}
useScrambleText(label, { onComplete: next }, () => ({
text: texts[index.value],
chars: 'symbols',
duration: 5000,
delay: 2500,
}))
<template>
<p ref="label" class="font-mono text-lg">Hello from nanime!</p>
</template>
Signature
function useScrambleText(
target: AnimeTargets,
animationOptions?: MaybeRefOrGetter<ScrambleAnimationParams>,
scrambleOptions?: MaybeRefOrGetter<ScrambleTextParams>,
options?: NanimeInstanceOptions
): JSAnimation
Parameters
loop or onComplete. Accepts a plain
object, a ref or a getter, and the animation rebuilds when it changes.
Timing goes in scrambleOptions. See the
AnimeJS animation documentation
for the options.text, chars, duration, delay
and ease. Accepts a plain object, a ref or a getter, and a new text
scrambles to the new string. See the
AnimeJS scrambleText documentation
for the options.| Option | Type | Default |
|---|---|---|
keepTime | boolean | false |
Returns
Returns a reactive proxy around the AnimeJS JSAnimation.
Its methods and properties are in the
AnimeJS animation documentation.
Call methods on the returned object, as in animation.restart(), because
a destructured method throws.
progress doesn't update a template
either.
Caveats
Timing belongs in scrambleOptions
// wrong: a type error, and AnimeJS would ignore them
useScrambleText(el, { duration: 2000, delay: 500 }, { text: 'Hello' })
// right
useScrambleText(el, {}, { text: 'Hello', duration: 2000, delay: 500 })
The tween from AnimeJS scrambleText() sets its own duration, delay and
ease, which replace the ones in animationOptions, so
ScrambleAnimationParams rejects them. Without them, the
duration comes from the text length and revealRate.
Do not destructure the returned instance
// wrong: restart() throws when called
const { restart } = useScrambleText(el, {}, { text: 'Hello' })
// right
const animation = useScrambleText(el, {}, { text: 'Hello' })
animation.restart()
The proxy hands back methods without their instance, so a destructured
restart() runs with no this and throws. A destructured property such as
progress is a copy of the value at that moment. Keep the returned object
and call methods on it.
Properties do not update templates
// wrong: progress never updates inside a template interpolation
// <p>{{ animation.progress }}</p>
// right: update a ref inside onUpdate
const progress = ref(0)
const animation = useScrambleText(el, {
onUpdate: self => progress.value = self.progress,
}, { text: 'Hello' })
Interpolating properties like progress in a template displays only their
initial value. AnimeJS updates them outside Vue's reactivity tracking, so
nothing triggers a re-render. Assign the current value to a
ref inside the onUpdate callback to drive reactive
template elements.
Type reference
type AnimeTargets = TargetsParam | MaybeElementRef | MaybeElementRef[]
type ScrambleAnimationParams = AnimationParams & {
duration?: never
delay?: never
ease?: never
}
interface NanimeInstanceOptions {
keepTime?: boolean
}
See also
useSplitText: split text elements into characters, words, and linesuseAnimate: general main-thread animation engine- AnimeJS scrambleText documentation: upstream scramble options and character sets