<!-- Source: https://motion.svelte.page/docs/motion-values -->

# Motion values

> An overview of motion values — reactive primitives that drive animations outside the render cycle.

**Source:** [https://motion.svelte.page/docs/motion-values](https://motion.svelte.page/docs/motion-values)

---

# Motion values overview

Motion values are reactive primitives that track the state and velocity of animating values. They're updated and read **outside** Svelte's reactive render cycle, so animations can run at full frame rate without triggering component re-renders.

In `@humanspeak/svelte-motion`, every motion-value-producing hook returns the **same shape**: a real motion-dom `MotionValue` (passes `isMotionValue`, composes with `animate()`, follows other motion values) augmented with a Svelte-5 reactive `.current` getter and a `.subscribe` shim for legacy `$store` readers.

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

  const x = useSpring(0)
</script>

<div
  style="transform: translateX({x.current}px)"
  onpointerdown={() => x.set(100)}
>
  Spring animated
</div>
```

Motion values:

- Have a **`.current`** getter backed by `$state` for native Svelte 5 reads in templates, `$derived`, and `$effect`
- Can be updated and read **outside** Svelte's reactive render cycle
- Track **velocity** automatically so springs and transforms stay smooth
- Can be **composed** — pass one into another to build animation chains
- Are **SSR-safe** — on the server they return static values with no timers
- Implement Svelte's `Readable` store contract via a `.subscribe` shim, so `$x` template syntax, `svelte/store`'s `get()`, and `derived()` keep working

## Hooks at a glance

| Hook | Returns | Read pattern |
| --- | --- | --- |
| [`useSpring`](/docs/use-spring) | `MotionValue<number \| string>` | `spring.current` (preferred) or `$spring` |
| [`useMotionValue`](/docs/motion-values) | `MotionValue<T>` | `mv.current` (preferred) or `$mv` |
| [`useTransform`](/docs/use-transform) | `MotionValue<T>` | `transformed.current` (preferred) or `$transformed` |
| [`useScroll`](/docs/use-scroll) | `{ scrollX, scrollY, scrollXProgress, scrollYProgress }` of `MotionValue<number>` | `scrollY.current` (preferred) or `$scrollY` |
| [`useTime`](/docs/use-time) | `MotionValue<number>` | `time.current` (preferred) or `$time` |
| [`useVelocity`](/docs/use-velocity) | `MotionValue<number>` | `velocity.current` (preferred) or `$velocity` |
| [`useMotionTemplate`](/docs/use-motion-template) | `MotionValue<string>` | `template.current` (preferred) or `$template` |

For new code, prefer `.current` everywhere — it tracks under Svelte 5 runes without going through the subscribe path.

## Usage

### Creating motion values

Use `useMotionValue` for a value with no spring physics:

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

  const x = useMotionValue(0)
</script>

<div style="transform: translateX({x.current}px)">
  Current value: {x.current}
</div>
```

Use `useSpring` to animate toward each target with spring physics:

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

  const x = useSpring(0, { stiffness: 300, damping: 30 })
</script>

<button onclick={() => x.set(100)}>Animate</button>
<div style="transform: translateX({x.current}px)">{x.current}</div>
```

A plain Svelte `writable` also works for values that don't need motion-value composition or velocity tracking:

```svelte
<script>
  import { writable } from 'svelte/store'

  const x = writable(0)
</script>
```

### Reading values

In templates, `$derived`, and `$effect` — use `.current`:

```svelte
<div style="transform: translateX({x.current}px)">
  {x.current}
</div>
```

In imperative code (event handlers, callbacks) — use `.get()`:

```svelte
<script>
  function logPosition() {
    console.log(x.get())
  }
</script>
```

The Svelte 4–style `$x` syntax still works on every motion value via the `.subscribe()` shim — useful when migrating existing components incrementally.

### Setting values

```svelte
<script>
  x.set(200)   // useSpring: animates with spring physics. useMotionValue: immediate write.
  x.jump(200)  // useSpring only: instantly sets without animation.
</script>
```

### Events

Subscribe to value changes with `useMotionValueEvent`:

```svelte
<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 is now', latest)
  })
  onDestroy(unsub)
</script>
```

Springs additionally expose motion-dom event types via `.on(...)`:

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

  const x = useSpring(0)

  x.on('animationStart', () => console.log('spring started'))
  x.on('animationComplete', () => console.log('spring settled'))
</script>
```

### Composition

Motion values become powerful when you chain them. The output of one feeds into the next:

```svelte
<script>
  import { useSpring, useTransform, useVelocity, useMotionTemplate } from '@humanspeak/svelte-motion'

  const x = useSpring(0)
  const velocity = useVelocity(x)
  const skew = useTransform(velocity, [-1000, 0, 1000], [-20, 0, 20])
  const filter = useMotionTemplate`drop-shadow(0 0 ${skew}px rgba(0, 0, 0, 0.4))`
</script>

<div
  style="transform: translateX({x.current}px) skewX({skew.current}deg); filter: {filter.current}"
  onpointermove={(e) => x.set(e.clientX)}
>
  Composed chain
</div>
```

Every step in the chain is a `MotionValue`, so `.current` reads reactively without crossing the subscribe boundary.

### Chain helpers

- **[useTransform](/docs/use-transform)** — map a motion value's output range to a new range
- **[useSpring](/docs/use-spring)** — add spring physics to any motion value or readable
- **[useVelocity](/docs/use-velocity)** — derive velocity from any motion value
- **[useMotionTemplate](/docs/use-motion-template)** — build CSS strings from multiple motion values

## API

Every motion-value-producing hook in this library returns a value implementing the motion-dom `MotionValue` interface plus a Svelte 5 reactive surface:

| Member                  | Description                                                            |
| ----------------------- | ---------------------------------------------------------------------- |
| `current`               | Svelte 5 reactive getter — use in templates / `$derived` / `$effect`.   |
| `get()`                 | Imperative current-value read.                                          |
| `set(value)`            | Update the value. `useSpring` animates with spring physics; every other hook writes immediately. |
| `jump(value)`           | Set immediately without animation. `useSpring` only.                    |
| `on(event, cb)`         | Subscribe to `'change'`, `'animationStart'`, `'animationComplete'`, etc.|
| `getVelocity()`         | Current velocity of the value.                                          |
| `subscribe(run)`        | Svelte readable store contract — powers `$mv` template syntax and `derived(mv, …)`. |
| `destroy()`             | Tear down the motion value early (normally bound to the surrounding `$effect`). |

## See also

- [useMotionTemplate](/docs/use-motion-template) — compose CSS strings from motion values
- [useMotionValueEvent](/docs/use-motion-value-event) — subscribe to change events with cleanup
- [useScroll](/docs/use-scroll) — create scroll-linked motion values
- [useSpring](/docs/use-spring) — spring-animated motion value
- [useTime](/docs/use-time) — time-based motion value
- [useTransform](/docs/use-transform) — map and transform motion values
- [useVelocity](/docs/use-velocity) — derive velocity from a motion value

---

Based on [Motion's motion value](https://motion.dev/docs/react-motion-value) API.
