@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
TypeScript
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);