{"version":3,"file":"keyframes.mjs","sources":["../../../../src/animation/generators/keyframes.ts"],"sourcesContent":["import {\n    easeInOut,\n    easingDefinitionToFunction,\n    EasingFunction,\n    isEasingArray,\n    MotionGlobalConfig,\n} from \"motion-utils\"\nimport { interpolate } from \"../../utils/interpolate\"\nimport { mix } from \"../../utils/mix\"\nimport { defaultOffset } from \"../keyframes/offsets/default\"\nimport { convertOffsetToTimes } from \"../keyframes/offsets/time\"\nimport {\n    AnimationState,\n    AnyResolvedKeyframe,\n    KeyframeGenerator,\n    ValueAnimationOptions,\n} from \"../types\"\n\nexport function defaultEasing(\n    values: any[],\n    easing?: EasingFunction\n): EasingFunction[] {\n    return values.map(() => easing || easeInOut).splice(0, values.length - 1)\n}\n\nexport function keyframes<T extends AnyResolvedKeyframe>({\n    duration = 300,\n    keyframes: keyframeValues,\n    times,\n    ease = \"easeInOut\",\n    mixer: transitionMixer,\n}: ValueAnimationOptions<T>): KeyframeGenerator<T> {\n    /**\n     * A mixer only blends values that aren't numbers. Numbers blend as\n     * usual, as they do in springs, and so do the progress animations\n     * behind layout and path animations, which take the same transition.\n     */\n    const customMixer =\n        typeof keyframeValues[0] === \"number\" ? undefined : transitionMixer\n\n    /**\n     * Easing functions can be externally defined as strings. Here we convert them\n     * into actual functions.\n     */\n    const easingFunctions = isEasingArray(ease)\n        ? ease.map(easingDefinitionToFunction)\n        : easingDefinitionToFunction(ease) || easeInOut\n\n    /**\n     * This is the Iterator-spec return value. We ensure it's mutable rather than using a generator\n     * to reduce GC during animation.\n     */\n    const state: AnimationState<T> = {\n        done: false,\n        value: keyframeValues[0],\n    }\n\n    /**\n     * Two keyframes, or keyframes that hold, move once, then hold, as each\n     * value of a sequence does, ease and mix only the pair that moves.\n     */\n    let span = -1\n    if (!customMixer) {\n        for (let i = 1; i < keyframeValues.length; i++) {\n            if (keyframeValues[i] !== keyframeValues[i - 1]) {\n                if (span >= 0) {\n                    span = -2\n                    break\n                }\n                span = i - 1\n            }\n        }\n    }\n\n    if (span >= 0) {\n        const offsets =\n            times && times.length === keyframeValues.length\n                ? times\n                : defaultOffset(keyframeValues)\n        const from = offsets[span] * duration\n        const to = offsets[span + 1] * duration\n        const origin = keyframeValues[span]\n        const target = keyframeValues[span + 1]\n        const ease = Array.isArray(easingFunctions)\n            ? easingFunctions[span]\n            : easingFunctions\n        const mixer = (MotionGlobalConfig.mix || mix)(origin, target)\n        const last = keyframeValues.length - 2\n\n        return {\n            calculatedDuration: duration,\n            next: (t: number) => {\n                /**\n                 * Held keyframes either side of the move are mixed as\n                 * interpolate() mixes them, so colours keep its format.\n                 */\n                state.value =\n                    span && t < from\n                        ? mixer(0)\n                        : span < last && (t >= to || !duration)\n                        ? typeof target === \"number\"\n                            ? target\n                            : mixer(1)\n                        : mixer(\n                              ease(\n                                  t >= to || !duration\n                                      ? 1\n                                      : t <= from\n                                      ? 0\n                                      : (t - from) / (to - from)\n                              )\n                          )\n                state.done = t >= duration\n                return state\n            },\n        }\n    }\n\n    /**\n     * Create a times array based on the provided 0-1 offsets\n     */\n    const absoluteTimes = convertOffsetToTimes(\n        // Only use the provided offsets if they're the correct length\n        // TODO Maybe we should warn here if there's a length mismatch\n        times && times.length === keyframeValues.length\n            ? times\n            : defaultOffset(keyframeValues),\n        duration\n    )\n\n    const mapTimeToKeyframe = interpolate<T>(absoluteTimes, keyframeValues, {\n        ease: Array.isArray(easingFunctions)\n            ? easingFunctions\n            : defaultEasing(keyframeValues, easingFunctions),\n        mixer: customMixer,\n    })\n\n    return {\n        calculatedDuration: duration,\n        next: (t: number) => {\n            state.value = mapTimeToKeyframe(t)\n            state.done = t >= duration\n            return state\n        },\n    }\n}\n"],"names":[],"mappings":"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"}