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

114 lines (113 loc) 4.66 kB
import { type AnimationOptions } from 'motion'; /** * Measure an element's bounding client rect without current transform. * * Temporarily clears `transform` to avoid skewing measurements, restoring it * immediately after reading the rect. * * When `scrollContainers` are provided, the returned rect is shifted by the * **sum** of each container's `scrollLeft` / `scrollTop`. When * `includeViewportScroll` is true, the viewport's `window.scrollX` / * `window.scrollY` is included too. FLIP deltas computed from two such * measures stay correct even when the user scrolls between measurements — * including a nested `layoutScroll` inside another `layoutScroll`. Mirrors * framer-motion's `removeElementScroll`, which walks every ancestor in the * path, plus root scroll compensation from the projection tree. * * Pass an empty array (or omit) for viewport-relative behaviour. * * `baseTransform` is the value the element's `transform` is set to while * measuring (default `'none'`, i.e. all transforms removed). The * projection system passes the element's mount-time transform here so * that a user-authored static `transform` is preserved in the * measurement while only the motion-applied portion (written after * mount) is removed — mirroring framer-motion's `removeBoxTransforms`, * which only subtracts motion-tracked `latestValues` and leaves * user-authored transforms intact. Existing FLIP callers omit it and * get the original strip-everything behaviour. * * @param el Element to measure. * @param scrollContainers Optional ancestor chain with `layoutScroll` enabled. * @param baseTransform Transform string applied during measurement. Defaults to `'none'`. * @param includeViewportScroll Whether to include `window.scrollX/Y` in the returned rect. * @returns DOMRect snapshot of the element. * * @example * ```ts * // No scroll containers — viewport-relative rect. * const rect = measureRect(node) * * // Single ancestor scroll container (one `layoutScroll`). * const rect = measureRect(node, [scrollPanel]) * * // Nested `layoutScroll` ancestors — sums offsets from every container. * const rect = measureRect(node, [innerScroll, outerScroll]) * ``` */ export declare const measureRect: (el: HTMLElement, scrollContainers?: HTMLElement[], baseTransform?: string, includeViewportScroll?: boolean) => DOMRect; /** * Minimal rectangle shape `computeFlipTransforms` reads. A `DOMRect` * satisfies it structurally, and so does a projection `Box` converted to * `{ left, top, width, height }`. Declared here (rather than importing * the projection `Box`) so `layout.ts` stays free of a circular * dependency on `projection.ts`, which imports `measureRect` from here. */ export interface RectLike { left: number; top: number; width: number; height: number; } /** * Compute FLIP transform deltas between two rects. * * @param prev Previous rect. * @param next Next rect. * @param mode `true` for translate+scale, `'position'` for translate only. * @return Deltas and flags indicating which transforms to apply. */ export declare const computeFlipTransforms: (prev: RectLike, next: RectLike, mode: boolean | "position") => { dx: number; dy: number; sx: number; sy: number; shouldTranslate: boolean; shouldScale: boolean; }; /** * Run a FLIP animation for the provided deltas. * * Pre-applies the inverse transform to avoid layout flashes, then animates back * to identity using the provided transition. * * @param el Target element. * @param transforms Deltas computed by `computeFlipTransforms`. * @param transition Timing/options for the animation. */ export declare const runFlipAnimation: (el: HTMLElement, transforms: { dx: number; dy: number; sx: number; sy: number; shouldTranslate: boolean; shouldScale: boolean; }, transition: AnimationOptions) => void; /** * Toggle compositor hints for smoother transform animations. * * @param el Target element. * @param enabled Whether to enable compositor hints. */ export declare const setCompositorHints: (el: HTMLElement, enabled: boolean) => void; /** * Observe size/attribute changes that commonly trigger layout changes. * * Returns a cleanup function that disconnects observers. The callback is called * for resize events and attribute/class/style changes on the element and * immediate parent child-list changes. * * @param el Element to observe. * @param onChange Callback invoked when a relevant change is detected. * @return Cleanup function. */ export declare const observeLayoutChanges: (el: HTMLElement, onChange: () => void) => (() => void);