Skip to main content
This is an internal low-level API. Most users should use animate() or useAnimate() instead.
animateVisualElement() is a low-level function that animates a Motion visual element directly. It’s used internally by Motion’s component system and the higher-level animation APIs.

Signature

function animateVisualElement(
  visualElement: VisualElement,
  definition: AnimationDefinition,
  options?: VisualElementAnimationOptions
): Promise<any>

Parameters

visualElement
VisualElement
required
The visual element to animate. This is Motion’s internal representation of a DOM element or component.
definition
AnimationDefinition
required
What to animate to. Can be:
  • Target object: { x: 100, opacity: 0 }
  • Variant name: "visible" (string)
  • Variant array: ["visible", "active"]
  • Variant function: (custom) => ({ x: 100 })
options
VisualElementAnimationOptions
Animation configuration options

Return Value

Returns a Promise that resolves when the animation completes.

Type Definitions

interface VisualElementAnimationOptions {
  delay?: number
  transitionOverride?: Transition
  custom?: any
  type?: AnimationType
}

type AnimationDefinition =
  | VariantLabels
  | TargetAndTransition
  | TargetResolver

type VariantLabels = string | string[]

type TargetAndTransition = Target & {
  transition?: Transition
  transitionEnd?: ResolvedValues
}

type TargetResolver = (
  custom: any,
  current: ResolvedValues,
  velocity: ResolvedValues
) => TargetAndTransition | string

interface VisualElement {
  values: Map<string, MotionValue>
  notify(eventName: string, data: any): void
  getVariant(name: string): Variant | undefined
  variantChildren?: Set<VisualElement>
  // ... other internal properties
}

How It Works

When called, animateVisualElement():
  1. Notifies start: Fires "AnimationStart" event
  2. Resolves definition:
    • If array of variants: animates each variant in sequence
    • If string variant: looks up and animates that variant
    • If object/function: resolves and animates target values
  3. Animates values: Uses animateTarget() or animateVariant() internally
  4. Notifies complete: Fires "AnimationComplete" event

Usage Example

You typically won’t use this directly. This example is for understanding Motion’s internals.
import { animateVisualElement } from "motion-dom"

// Get or create a visual element (internal API)
const visualElement = getVisualElement(element)

// Animate to target values
await animateVisualElement(
  visualElement,
  { x: 100, opacity: 0 },
  { 
    transitionOverride: {
      duration: 1,
      ease: "easeOut"
    }
  }
)

console.log("Animation complete")

Animating Variants

// Animate to a variant
await animateVisualElement(
  visualElement,
  "visible",
  { delay: 0.5 }
)

// Animate multiple variants in sequence
await animateVisualElement(
  visualElement,
  ["visible", "active"]
)

With Custom Data

// Variant function receives custom data
const variants = {
  visible: (custom) => ({
    opacity: 1,
    transition: { delay: custom.index * 0.1 }
  })
}

visualElement.variants = variants

await animateVisualElement(
  visualElement,
  "visible",
  { custom: { index: 5 } }
)

Events

The visual element fires events during animation:
visualElement.notify = (eventName, data) => {
  if (eventName === "AnimationStart") {
    console.log("Animation started:", data)
  } else if (eventName === "AnimationComplete") {
    console.log("Animation completed:", data)
  }
}

await animateVisualElement(visualElement, { x: 100 })

Internal Architecture

This function is part of Motion’s animation pipeline:
React Component

motion.div (with animate prop)

VisualElement created

animateVisualElement() ←── You are here

animateTarget() / animateVariant()

animateMotionValue()

NativeAnimation / JSAnimation

WAAAPI / JavaScript animation

animateTarget()

Animates a visual element to target values:
function animateTarget(
  visualElement: VisualElement,
  definition: TargetAndTransition,
  options: VisualElementAnimationOptions
): AnimationPlaybackControls[]

animateVariant()

Animates a visual element to a variant:
function animateVariant(
  visualElement: VisualElement,
  variantLabel: string,
  options: VisualElementAnimationOptions
): Promise<any>

setTarget()

Instantly sets values without animating:
function setTarget(
  visualElement: VisualElement,
  definition: TargetAndTransition
): void

When to Use This

You might need this if you’re:
  1. Building a custom animation library on top of Motion
  2. Creating custom Motion components with specialized behavior
  3. Integrating deeply with Motion’s internal systems
  4. Contributing to Motion itself
For normal use cases, prefer:

Source Code

Location: packages/motion-dom/src/animation/interfaces/visual-element.ts
export function animateVisualElement(
    visualElement: VisualElement,
    definition: AnimationDefinition,
    options: VisualElementAnimationOptions = {}
) {
    visualElement.notify("AnimationStart", definition)
    let animation: Promise<any>

    if (Array.isArray(definition)) {
        const animations = definition.map((variant) =>
            animateVariant(visualElement, variant, options)
        )
        animation = Promise.all(animations)
    } else if (typeof definition === "string") {
        animation = animateVariant(visualElement, definition, options)
    } else {
        const resolvedDefinition =
            typeof definition === "function"
                ? resolveVariant(visualElement, definition, options.custom)
                : definition

        animation = Promise.all(
            animateTarget(visualElement, resolvedDefinition, options)
        )
    }

    return animation.then(() => {
        visualElement.notify("AnimationComplete", definition)
    })
}

See Also

Build docs developers (and LLMs) love