UNPKG

@humanspeak/svelte-motion

Version:

Framer Motion for Svelte 5. Declarative motion.<tag> components with AnimatePresence exit animations, gestures (hover, tap, drag, focus, in-view), variants, FLIP layout animations, shared-layout transitions, spring physics, and scroll-linked motion values

62 lines (61 loc) 2.56 kB
import { type Readable } from 'svelte/store'; import { type AugmentedMotionValue } from './augmentMotionValue.svelte.js'; /** * Source for {@link useVelocity}: a motion-dom `MotionValue` or a Svelte * readable. Svelte readables are bridged into a `MotionValue` so motion-dom's * native velocity tracking can drive the result. */ export type VelocitySource = AugmentedMotionValue<number | string> | Readable<number | string>; /** * Creates an augmented `MotionValue<number>` whose value tracks the velocity * of `source` in units/second. * * Mirrors React framer-motion 1:1: on every `source` change, schedules an * `updateVelocity` callback in motion-dom's frame loop via * `frame.update(updateVelocity, false, true)`. `updateVelocity` reads * `source.getVelocity()` (motion-dom tracks per-frame deltas + timestamps * for free) and writes it to the result. If velocity is still non-zero, * `updateVelocity` re-schedules itself for the next frame — so the loop * only runs while there's actual motion and snaps to `0` the moment things * settle. Idle CPU is zero. * * Returned value is a real motion-dom `MotionValue` (composes with * `useTransform`, `useSpring`, `useMotionTemplate`, etc.) plus a * `$state`-backed `.current` getter and a `.subscribe` shim. * * Lifecycle: must be called during component initialization. The change * subscription, the frame-loop callback, and any Svelte-readable bridge are * all torn down when the surrounding `$effect` unmounts. * * SSR-safe: returns a static augmented motion value with no subscriptions * and no frame loop on the server. * * @param source A motion value or readable store of numeric or unit-string values. * @returns A `MotionValue<number>` with `.current` and `.subscribe`. * * @example * ```svelte * <script lang="ts"> * import { * useMotionValue, * useTransform, * useVelocity * } from '@humanspeak/svelte-motion' * * const x = useMotionValue(0) * const xVelocity = useVelocity(x) * // Map velocity to a momentum-driven skew. Skew goes positive when x is * // accelerating right, negative when accelerating left, and snaps to 0 * // when motion settles. * const skew = useTransform(xVelocity, [-1000, 0, 1000], [-15, 0, 15]) * </script> * * <div * style="transform: translateX({x.current}px) skewX({skew.current}deg)" * onpointermove={(e) => x.set(e.clientX)} * /> * ``` * * @see https://motion.dev/docs/react-use-velocity */ export declare const useVelocity: (source: VelocitySource) => AugmentedMotionValue<number>;