Composables

useAnimeLayout

Animate layout changes in position and size with AnimeJS createLayout().
Buffered

useAnimeLayout wraps the createLayout function from AnimeJS. It records the position and size of every element inside a container. After a change, it animates each element from the recorded state to the new one.

nanime creates the layout once the container mounts and reverts it on unmount. It rebuilds the layout only when the container element changes or the parameters change in value. Callbacks such as onComplete are left out of that comparison.

Usage

Size animates together with position. Here one box grows at a time and the others move aside:

const row = useTemplateRef('row')
const expanded = ref(1)

const layout = useAnimeLayout(row, { duration: 500 })

function expandNext() {
  layout.patch(() => (expanded.value = (expanded.value % 5) + 1))
}
View on GitHub

Signature

function useAnimeLayout(
  target: MaybeRef<AnimeLayoutTargets>,
  parameters?: MaybeRefOrGetter<AutoLayoutParams>
): BufferedProxyReturns<NanimeLayout>

Parameters

target
MaybeRef<AnimeLayoutTargets> required
The container whose children are animated. Accepts a CSS selector, a DOM element, a template ref or a component ref.
parameters
MaybeRefOrGetter<AutoLayoutParams>
Accepts a plain object, a ref or a getter. The layout rebuilds when a value changes. See the AnimeJS layout documentation for the options.

Returns

Returns a buffered proxy around the AnimeJS AutoLayout. Its methods and properties are in the AnimeJS layout documentation. The members nanime adds or changes:

MemberTypeNotes
patch(callback, params?)(callback: () => unknown, params?: LayoutAnimationParams) => Promise<void>Added by nanime, and the one to use for Vue state. It calls record(), awaits callback, waits for Vue's nextTick(), then calls animate(params). The promise resolves when the animation finishes.
record()() => thisCan be called straight from setup(), and runs once the layout is created.

The layout is created when the container mounts. Call patch() and read other members after mount.

Caveats

Use patch(), not update(), for Vue state

// wrong: animate() runs before Vue has patched the DOM
layout.update(() => items.value.reverse())

// right: patch() waits for nextTick() before animating
await layout.patch(() => items.value.reverse())

AnimeJS update() records, runs the callback and animates in one synchronous call. Vue applies state changes to the DOM on the next tick, so animate() compares the old DOM with itself and nothing moves. patch() awaits nextTick() between the two steps. update() still works for direct DOM changes, such as appendChild.

Read properties after mount

// wrong: timeline is undefined before mount
const layout = useAnimeLayout(grid)
console.log(layout.timeline) // undefined

// right: read it after mount
onMounted(() => {
  console.log(layout.timeline)
})

The layout is created after the container mounts. record() is queued until then, but other members, patch() included, return undefined. Call patch() from an event handler or after mount.

Type reference

See also

Copyright © 2026