All files / src/animation use-animated-state.ts

100% Statements 35/35
75% Branches 3/4
66.67% Functions 10/15
100% Lines 30/30

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 75 76 77 78 7931x 31x 31x   31x   31x 31x 31x           31x   31x                           1x     1x 1x 1x 1x       31x                   31x 11x   10x   10x 2x     10x 1x 1x     10x 5x 3x       10x 2x 1x       10x    
import { useEffect, useState } from "react"
import { useConstant } from "../utils/use-constant"
import { checkTargetForNewValues, getOrigin } from "../render/utils/setters"
import { TargetAndTransition } from "../types"
import { visualElement } from "../render"
import { ResolvedValues } from "../render/types"
import { animateVisualElement } from "../render/utils/animation"
import { makeUseVisualState } from "../motion/utils/use-visual-state"
import { createBox } from "../projection/geometry/models"
 
interface AnimatedStateOptions {
    initialState: ResolvedValues
}
 
const createObject = () => ({})
 
const stateVisualElement = visualElement<
    ResolvedValues,
    {},
    AnimatedStateOptions
>({
    build() {},
    measureViewportBox: createBox,
    resetTransform() {},
    restoreTransform() {},
    removeValueFromRenderState() {},
    render() {},
    scrapeMotionValuesFromProps: createObject,
 
    readValueFromInstance(_state, key, options) {
        return options.initialState[key] || 0
    },
 
    makeTargetAnimatable(element, { transition, transitionEnd, ...target }) {
        const origin = getOrigin(target as any, transition || {}, element)
        checkTargetForNewValues(element, target, origin as any)
        return { transition, transitionEnd, ...target }
    },
})
 
const useVisualState = makeUseVisualState({
    scrapeMotionValuesFromProps: createObject,
    createRenderState: createObject,
})
 
/**
 * This is not an officially supported API and may be removed
 * on any version.
 * @internal
 */
export function useAnimatedState(initialState: any) {
    const [animationState, setAnimationState] = useState(initialState)
 
    const visualState = useVisualState({}, false)
 
    const element = useConstant(() =>
        stateVisualElement({ props: {}, visualState }, { initialState })
    )
 
    useEffect(() => {
        element.mount({})
        return element.unmount()
    }, [])
 
    useEffect(() => {
        element.setProps({
            onUpdate: (v) => setAnimationState({ ...v }),
        })
    })
 
    const startAnimation = useConstant(
        () => (animationDefinition: TargetAndTransition) => {
            return animateVisualElement(element, animationDefinition)
        }
    )
 
    return [animationState, startAnimation]
}