onUpdate

onUpdate is called once per frame while any of a motion component’s values change. It receives every latest value on the element, not just the one that changed.

<script lang="ts">
  import { motion } from '@humanspeak/svelte-motion'

  let x = $state(0)
</script>

<motion.div
  animate={{ x: 100, opacity: 1 }}
  onUpdate={(latest) => (x = Number(latest.x))}
/>
<script lang="ts">
  import { motion } from '@humanspeak/svelte-motion'

  let x = $state(0)
</script>

<motion.div
  animate={{ x: 100, opacity: 1 }}
  onUpdate={(latest) => (x = Number(latest.x))}
/>
mode · live running open
// on-update frames: 0
latest.x
—
latest.rotate
—
onUpdate(latest) every value, every frame

Callback Shape

type MotionOnUpdate = (latest: ResolvedValues) => void
type MotionOnUpdate = (latest: ResolvedValues) => void
  • latest holds every current value on the element, keyed by name, for example { x: 42, rotate: 90, opacity: 0.5 }.
  • It runs at most once per frame, after values change and before they render, however many values changed that frame.

Prop vs transition onUpdate

onUpdate can also go in a transition. The two are different:

<!-- Prop: every value on the element, once per frame -->
<motion.div animate={{ x: 100, opacity: 1 }} onUpdate={(latest) => console.log(latest)} />

<!-- Transition: per animation, only that animation's value -->
<motion.div
  animate={{ x: 100 }}
  transition={{ duration: 1, onUpdate: (x) => console.log(x) }}
/>
<!-- Prop: every value on the element, once per frame -->
<motion.div animate={{ x: 100, opacity: 1 }} onUpdate={(latest) => console.log(latest)} />

<!-- Transition: per animation, only that animation's value -->
<motion.div
  animate={{ x: 100 }}
  transition={{ duration: 1, onUpdate: (x) => console.log(x) }}
/>

The transition-level callback is called by each animation it applies to, with that one value.

Hardware acceleration

Having onUpdate keeps the element’s transforms on the main thread, so only use it when you need every frame. Since Motion 14.2, transform shortcuts like x, scale, and rotate otherwise run as one hardware-accelerated animation per element. Adding onUpdate while an accelerated animation is playing moves it to the main thread. For a single value, prefer useMotionValueEvent. transformTemplate has the same effect on acceleration.

API Reference

onUpdate

onUpdate?: (latest: ResolvedValues) => void
onUpdate?: (latest: ResolvedValues) => void

Pass a callback to any motion.* component. The MotionOnUpdate type is exported from @humanspeak/svelte-motion.

Based on Motion’s onUpdate prop.