{"version":3,"file":"inertia.mjs","sources":["../../../../src/animation/generators/inertia.ts"],"sourcesContent":["import {\n    AnimationState,\n    KeyframeGenerator,\n    ValueAnimationOptions,\n} from \"../types\"\nimport { spring as createSpring } from \"./spring\"\nimport { getGeneratorVelocity } from \"./utils/velocity\"\n\nexport function inertia({\n    keyframes,\n    velocity = 0.0,\n    power = 0.8,\n    timeConstant = 325,\n    bounceDamping = 10,\n    bounceStiffness = 500,\n    modifyTarget,\n    min,\n    max,\n    restDelta = 0.5,\n    restSpeed,\n}: ValueAnimationOptions<number>): KeyframeGenerator<number> {\n    const origin = keyframes[0]\n\n    const state: AnimationState<number> = {\n        done: false,\n        value: origin,\n    }\n\n    const isOutOfBounds = (v: number) =>\n        (min !== undefined && v < min) || (max !== undefined && v > max)\n\n    const nearestBoundary = (v: number) => {\n        if (min === undefined) return max\n        if (max === undefined) return min\n\n        return Math.abs(min - v) < Math.abs(max - v) ? min : max\n    }\n\n    let amplitude = power * velocity\n    const ideal = origin + amplitude\n    const target = modifyTarget === undefined ? ideal : modifyTarget(ideal)\n\n    /**\n     * If the target has changed we need to re-calculate the amplitude, otherwise\n     * the animation will start from the wrong position.\n     */\n    if (target !== ideal) amplitude = target - origin\n\n    const calcDelta = (t: number) => -amplitude * Math.exp(-t / timeConstant)\n\n    const calcLatest = (t: number) => target + calcDelta(t)\n\n    const applyFriction = (t: number) => {\n        const delta = calcDelta(t)\n        const latest = calcLatest(t)\n        state.done = Math.abs(delta) <= restDelta\n        state.value = state.done ? target : latest\n    }\n\n    /**\n     * Ideally this would resolve for t in a stateless way, we could\n     * do that by always precalculating the animation but as we know\n     * this will be done anyway we can assume that spring will\n     * be discovered during that.\n     */\n    let timeReachedBoundary: number | undefined\n    let spring: KeyframeGenerator<number> | undefined\n\n    const checkCatchBoundary = (t: number) => {\n        if (!isOutOfBounds(state.value)) return\n\n        timeReachedBoundary = t\n\n        spring = createSpring({\n            keyframes: [state.value, nearestBoundary(state.value)!],\n            velocity: getGeneratorVelocity(calcLatest, t, state.value), // TODO: This should be passing * 1000\n            damping: bounceDamping,\n            stiffness: bounceStiffness,\n            restDelta,\n            restSpeed,\n        })\n    }\n\n    checkCatchBoundary(0)\n\n    return {\n        calculatedDuration: null,\n        next: (t: number) => {\n            /**\n             * We need to resolve the friction to figure out if we need a\n             * spring but we don't want to do this twice per frame. So here\n             * we flag if we updated for this frame and later if we did\n             * we can skip doing it again.\n             */\n            let hasUpdatedFrame = false\n            if (!spring && timeReachedBoundary === undefined) {\n                hasUpdatedFrame = true\n                applyFriction(t)\n                checkCatchBoundary(t)\n            }\n\n            /**\n             * If we have a spring and the provided t is beyond the moment the friction\n             * animation crossed the min/max boundary, use the spring.\n             */\n            if (timeReachedBoundary !== undefined && t >= timeReachedBoundary) {\n                return spring!.next(t - timeReachedBoundary)\n            } else {\n                !hasUpdatedFrame && applyFriction(t)\n                return state\n            }\n        },\n    }\n}\n"],"names":["spring","createSpring"],"mappings":"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"}