All files / src/animation animate.ts

80% Statements 8/10
75% Branches 3/4
33.33% Functions 1/3
80% Lines 8/10

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74  38x 38x 38x                                                                                                                 38x     4x   4x 4x   4x          
import { Spring, Tween } from "../types"
import { motionValue, MotionValue } from "../value"
import { isMotionValue } from "../value/utils/is-motion-value"
import { startAnimation } from "./utils/transitions"
 
/**
 * @public
 */
export interface AnimationPlaybackControls {
    stop: () => void
    isAnimating: () => boolean
}
 
/**
 * @public
 */
export interface AnimationPlaybackLifecycles<V> {
    onUpdate?: (latest: V) => void
    onPlay?: () => void
    onComplete?: () => void
    onRepeat?: () => void
    onStop?: () => void
}
 
/**
 * @public
 */
export type AnimationOptions<V> = (Tween | Spring) &
    AnimationPlaybackLifecycles<V> & {
        delay?: number
        type?: "tween" | "spring"
    }
 
/**
 * Animate a single value or a `MotionValue`.
 *
 * The first argument is either a `MotionValue` to animate, or an initial animation value.
 *
 * The second is either a value to animate to, or an array of keyframes to animate through.
 *
 * The third argument can be either tween or spring options, and optional lifecycle methods: `onUpdate`, `onPlay`, `onComplete`, `onRepeat` and `onStop`.
 *
 * Returns `AnimationPlaybackControls`, currently just a `stop` method.
 *
 * ```javascript
 * const x = useMotionValue(0)
 *
 * useEffect(() => {
 *   const controls = animate(x, 100, {
 *     type: "spring",
 *     stiffness: 2000,
 *     onComplete: v => {}
 *   })
 *
 *   return controls.stop
 * })
 * ```
 *
 * @public
 */
export function animate<V>(
    from: MotionValue<V> | V,
    to: V | V[],
    Itransition: AnimationOptions<V> = {}
): AnimationPlaybackControls {
    const value = isMotionValue(from) ? from : motionValue(from)
    startAnimation("", value, to as any, transition)
 
    return {
        stop: () => value.stop(),
        isAnimating: () => value.isAnimating(),
    }
}