logo svelte /motion v0.5.1

useMotionValueEvent

useMotionValueEvent manages subscriptions to motion value store changes. It skips the initial synchronous emission that Svelte stores produce on subscribe, so the callback only fires on actual changes.

<script>
  import { useMotionValueEvent, useSpring } from '@humanspeak/svelte-motion'
  import { onDestroy } from 'svelte'

  const x = useSpring(0)

  const unsub = useMotionValueEvent(x, 'change', (latest) => {
    console.log('x changed to', latest)
  })

  onDestroy(unsub)
</script>
<script>
  import { useMotionValueEvent, useSpring } from '@humanspeak/svelte-motion'
  import { onDestroy } from 'svelte'

  const x = useSpring(0)

  const unsub = useMotionValueEvent(x, 'change', (latest) => {
    console.log('x changed to', latest)
  })

  onDestroy(unsub)
</script>

Usage

Import

<script>
  import { useMotionValueEvent } from '@humanspeak/svelte-motion'
</script>
<script>
  import { useMotionValueEvent } from '@humanspeak/svelte-motion'
</script>

Subscribe to changes

Pass a readable store, the event type 'change', and a callback:

<script>
  import { useMotionValueEvent, useSpring } from '@humanspeak/svelte-motion'
  import { onDestroy } from 'svelte'

  const scale = useSpring(1)

  const unsub = useMotionValueEvent(scale, 'change', (latest) => {
    if (latest > 1.5) {
      console.log('Scale is large!')
    }
  })

  onDestroy(unsub)
</script>

<div
  style="transform: scale({scale.current})"
  onpointerenter={() => scale.set(2)}
  onpointerleave={() => scale.set(1)}
>
  Hover me
</div>
<script>
  import { useMotionValueEvent, useSpring } from '@humanspeak/svelte-motion'
  import { onDestroy } from 'svelte'

  const scale = useSpring(1)

  const unsub = useMotionValueEvent(scale, 'change', (latest) => {
    if (latest > 1.5) {
      console.log('Scale is large!')
    }
  })

  onDestroy(unsub)
</script>

<div
  style="transform: scale({scale.current})"
  onpointerenter={() => scale.set(2)}
  onpointerleave={() => scale.set(1)}
>
  Hover me
</div>

Available events

EventDescription
'change'Fires whenever the store value updates (after the initial emission).

Cleanup

useMotionValueEvent returns an unsubscribe function. Call it inside onDestroy or at the end of an $effect:

<script>
  import { useMotionValueEvent, useSpring } from '@humanspeak/svelte-motion'
  import { onDestroy } from 'svelte'

  const y = useSpring(0)

  // Option 1: onDestroy
  const unsub = useMotionValueEvent(y, 'change', (v) => console.log(v))
  onDestroy(unsub)
</script>
<script>
  import { useMotionValueEvent, useSpring } from '@humanspeak/svelte-motion'
  import { onDestroy } from 'svelte'

  const y = useSpring(0)

  // Option 1: onDestroy
  const unsub = useMotionValueEvent(y, 'change', (v) => console.log(v))
  onDestroy(unsub)
</script>
<script>
  import { useMotionValueEvent, useSpring } from '@humanspeak/svelte-motion'

  const y = useSpring(0)

  // Option 2: $effect cleanup
  $effect(() => {
    const unsub = useMotionValueEvent(y, 'change', (v) => console.log(v))
    return unsub
  })
</script>
<script>
  import { useMotionValueEvent, useSpring } from '@humanspeak/svelte-motion'

  const y = useSpring(0)

  // Option 2: $effect cleanup
  $effect(() => {
    const unsub = useMotionValueEvent(y, 'change', (v) => console.log(v))
    return unsub
  })
</script>

Advanced — raw subscribe

For full control you can use store.subscribe() directly. Note that Svelte stores fire the callback immediately with the current value on subscribe:

<script>
  import { useSpring } from '@humanspeak/svelte-motion'
  import { onDestroy } from 'svelte'

  const x = useSpring(0)

  // Fires immediately with current value, then on every change
  const unsub = x.subscribe((value) => {
    console.log('value:', value)
  })

  onDestroy(unsub)
</script>
<script>
  import { useSpring } from '@humanspeak/svelte-motion'
  import { onDestroy } from 'svelte'

  const x = useSpring(0)

  // Fires immediately with current value, then on every change
  const unsub = x.subscribe((value) => {
    console.log('value:', value)
  })

  onDestroy(unsub)
</script>

useMotionValueEvent is preferred when you only want to react to changes and not the initial value.

API Reference

Signature

useMotionValueEvent<T>(
  store: Readable<T>,
  event: 'change',
  callback: (latest: T) => void
): () => void
useMotionValueEvent<T>(
  store: Readable<T>,
  event: 'change',
  callback: (latest: T) => void
): () => void

Parameters

  • store Readable<T> — any Svelte readable store (e.g. useSpring, useTransform, useTime)
  • event 'change' — the event type to listen for
  • callback (latest: T) => void — invoked with the latest value on each change

Returns

() => void — an unsubscribe function that stops the subscription.

See also


Based on Motion’s useMotionValueEvent API.