svelte-motion
Version:
Svelte animation library based on the React library framer-motion.
271 lines (269 loc) • 7.79 kB
TypeScript
/**
based on framer-motion@4.1.17,
Copyright (c) 2018 Framer B.V.
*/
import { SubscriptionManager } from "../utils/subscription-manager";
import type { Writable, Unsubscriber } from 'svelte/store'
export declare type Transformer<T> = (v: T) => T;
/**
* @public
*/
export declare type Subscriber<T> = (v: T) => void;
/**
* @public
*/
export declare type PassiveEffect<T> = (v: T, safeSetter: (v: T) => void) => void;
export declare type StartAnimation = (complete: () => void) => () => void;
/**
* `MotionValue` is used to track the state and velocity of motion values.
*
* @public
*/
export declare class MotionValue<V = any> implements Writable<V> {
/**
* Subscribe method to make MotionValue compatible with Svelte store. Returns a unsubscribe function.
* Same as onChange.
*
* @public
*/
subscribe: (this: void, run: Subscriber<V>) => Unsubscriber;
/**
* Update method to make MotionValue compatible with Svelte writable store
*
* @public
*/
update: (cb:(value:V) => V) => void;
/**
* The current state of the `MotionValue`.
*
* @internal
*/
private current;
/**
* The previous state of the `MotionValue`.
*
* @internal
*/
private prev;
/**
* Duration, in milliseconds, since last updating frame.
*
* @internal
*/
private timeDelta;
/**
* Timestamp of the last time this `MotionValue` was updated.
*
* @internal
*/
private lastUpdated;
/**
* Functions to notify when the `MotionValue` updates.
*
* @internal
*/
private updateSubscribers;
/**
* Functions to notify when the velocity updates.
*
* @internal
*/
velocityUpdateSubscribers: SubscriptionManager<Subscriber<number>>;
/**
* Functions to notify when the `MotionValue` updates and `render` is set to `true`.
*
* @internal
*/
private renderSubscribers;
/**
* Add a passive effect to this `MotionValue`.
*
* A passive effect intercepts calls to `set`. For instance, `useSpring` adds
* a passive effect that attaches a `spring` to the latest
* set value. Hypothetically there could be a `useSmooth` that attaches an input smoothing effect.
*
* @internal
*/
private passiveEffect?;
/**
* A reference to the currently-controlling Popmotion animation
*
* @internal
*/
private stopAnimation?;
/**
* Tracks whether this value can output a velocity. Currently this is only true
* if the value is numerical, but we might be able to widen the scope here and support
* other value types.
*
* @internal
*/
private canTrackVelocity;
/**
* @param init - The initiating value
* @param startStopNotifier - a function that is called, once the first subscriber is added to this motion value.
* The return function is called, when the last subscriber unsubscribes.
*
* - `transformer`: A function to transform incoming values with.
*
* @internal
*/
constructor(init: V, startStopNotifier: ()=>()=>void);
/**
* Adds a function that will be notified when the `MotionValue` is updated.
*
* It returns a function that, when called, will cancel the subscription.
*
* When calling `onChange` inside a React component, it should be wrapped with the
* `useEffect` hook. As it returns an unsubscribe function, this should be returned
* from the `useEffect` function to ensure you don't add duplicate subscribers..
*
* @motion
*
* ```jsx
* <script>
* import { useMotionValue } from 'svelte-motion'
*
* const x = useMotionValue(0)
* const y = useMotionValue(0)
* const opacity = useMotionValue(1)
*
*
* function updateOpacity() {
* const maxXY = Math.max(x.get(), y.get())
* const newOpacity = transform(maxXY, [0, 100], [1, 0])
* opacity.set(newOpacity)
* }
*
* // framer-motion style:
* const unsubscribeX = x.onChange(updateOpacity)
* onDestroy(()=>{
* unsubscribeX()
* })
* // equivalent Svelte style. Subscription and un-subscription is automatically handled:
* $: updateOpacity($y)
* </script>
*
* <Motion let:motion style={{ x }}><div use:motion/></Motion>
* ```
*
* @param subscriber - A function that receives the latest value.
* @returns A function that, when called, will cancel this subscription.
*
* @public
*/
onChange(subscription: Subscriber<V>): () => void;
clearListeners(): void;
/**
* Adds a function that will be notified when the `MotionValue` requests a render.
*
* @param subscriber - A function that's provided the latest value.
* @returns A function that, when called, will cancel this subscription.
*
* @internal
*/
onRenderRequest(subscription: Subscriber<V>): () => void;
/**
* Attaches a passive effect to the `MotionValue`.
*
* @internal
*/
attach(passiveEffect: PassiveEffect<V>): void;
/**
* Sets the state of the `MotionValue`.
*
* @remarks
*
* ```jsx
* const x = useMotionValue(0)
* x.set(10)
* ```
*
* @param latest - Latest value to set.
* @param render - Whether to notify render subscribers. Defaults to `true`
*
* @public
*/
set(v: V, render?: boolean): void;
updateAndNotify: (v: V, render?: boolean) => void;
/**
* Returns the latest state of `MotionValue`
*
* @returns - The latest state of `MotionValue`
*
* @public
*/
get(): V;
/**
* @public
*/
getPrevious(): V;
/**
* Returns the latest velocity of `MotionValue`
*
* @returns - The latest velocity of `MotionValue`. Returns `0` if the state is non-numerical.
*
* @public
*/
getVelocity(): number;
/**
* Schedule a velocity check for the next frame.
*
* This is an instanced and bound function to prevent generating a new
* function once per frame.
*
* @internal
*/
private scheduleVelocityCheck;
/**
* Updates `prev` with `current` if the value hasn't been updated this frame.
* This ensures velocity calculations return `0`.
*
* This is an instanced and bound function to prevent generating a new
* function once per frame.
*
* @internal
*/
private velocityCheck;
hasAnimated: boolean;
/**
* Registers a new animation to control this `MotionValue`. Only one
* animation can drive a `MotionValue` at one time.
*
* ```jsx
* value.start()
* ```
*
* @param animation - A function that starts the provided animation
*
* @internal
*/
start(animation: StartAnimation): Promise<void>;
/**
* Stop the currently active animation.
*
* @public
*/
stop(): void;
/**
* Returns `true` if this value is currently animating.
*
* @public
*/
isAnimating(): boolean;
private clearAnimation;
/**
* Destroy and clean up subscribers to this `MotionValue`.
*
* The `MotionValue` hooks like `useMotionValue` and `useTransform` automatically
* handle the lifecycle of the returned `MotionValue`, so this method is only necessary if you've manually
* created a `MotionValue` via the `motionValue` function.
*
* @public
*/
destroy(): void;
}
/**
* @internal
*/
export declare function motionValue<V>(init: V): MotionValue<V>;