diff --git a/dev/examples/Animation-animate.tsx b/dev/examples/Animation-animate.tsx index b17799ee2b..603fb8e336 100644 --- a/dev/examples/Animation-animate.tsx +++ b/dev/examples/Animation-animate.tsx @@ -22,7 +22,13 @@ const Child = ({ setState }: any) => { const [scope, animate] = useAnimate() useEffect(() => { - const controls = animate("div", { x: 100, opacity: 0 }, transition) + const controls = animate([ + [ + "div", + { x: 500, opacity: 0 }, + { type: "spring", duration: 1, bounce: 0 }, + ], + ]) controls.then(() => console.log("complete")) diff --git a/packages/framer-motion/src/animation/animators/waapi/create-accelerated-animation.ts b/packages/framer-motion/src/animation/animators/waapi/create-accelerated-animation.ts index fb9fad25d8..5f0a2c53fd 100644 --- a/packages/framer-motion/src/animation/animators/waapi/create-accelerated-animation.ts +++ b/packages/framer-motion/src/animation/animators/waapi/create-accelerated-animation.ts @@ -81,7 +81,7 @@ export function createAcceleratedAnimation( // Create the first finished promise updateFinishedPromise() - let { keyframes, duration = 300, ease } = options + let { keyframes, duration = 300, ease, times } = options /** * If this animation needs pre-generated keyframes then generate. @@ -106,6 +106,7 @@ export function createAcceleratedAnimation( t += sampleDelta } + times = undefined keyframes = pregeneratedKeyframes duration = t - sampleDelta ease = "linear" @@ -127,6 +128,7 @@ export function createAcceleratedAnimation( * support the upcoming `linear()` easing function. */ ease: ease as EasingDefinition, + times, } ) diff --git a/packages/framer-motion/src/animation/sequence/__tests__/index.test.ts b/packages/framer-motion/src/animation/sequence/__tests__/index.test.ts index 4dbed8bac2..35d0b17ba2 100644 --- a/packages/framer-motion/src/animation/sequence/__tests__/index.test.ts +++ b/packages/framer-motion/src/animation/sequence/__tests__/index.test.ts @@ -471,6 +471,18 @@ describe("createAnimationsFromSequence", () => { expect(times).toEqual([0, 0.5, 0.5, 1]) }) + test("Adds spring as duration-based easing when only one keyframe defined", () => { + const animations = createAnimationsFromSequence([ + [a, { x: [0, 100] }, { type: "spring" }], + ]) + + expect(animations.get(a)!.keyframes.x).toEqual([0, 100]) + const { duration, ease } = animations.get(a)!.transition.x + + expect(duration).toEqual(1.1) + expect(typeof ease![0]).toEqual("function") + }) + test("Adds springs as duration-based simulation when two keyframes defined", () => { const animations = createAnimationsFromSequence([ [a, { x: 200 }, { duration: 1, ease: "linear" }], diff --git a/packages/framer-motion/src/animation/sequence/create.ts b/packages/framer-motion/src/animation/sequence/create.ts index baef4690a0..5463388936 100644 --- a/packages/framer-motion/src/animation/sequence/create.ts +++ b/packages/framer-motion/src/animation/sequence/create.ts @@ -33,6 +33,7 @@ export function createAnimationsFromSequence( { defaultTransition = {}, ...sequenceTransition }: SequenceOptions = {}, scope?: AnimationScope ): ResolvedAnimationDefinitions { + const defaultDuration = defaultTransition.duration || 0.3 const animationDefinitions: ResolvedAnimationDefinitions = new Map() const sequences = new Map() const elementCache = {} @@ -99,10 +100,8 @@ export function createAnimationsFromSequence( type = "keyframes", ...remainingTransition } = valueTransition - let { - ease = defaultTransition.ease || "easeOut", - duration = defaultTransition.duration || 0.3, - } = valueTransition + let { ease = defaultTransition.ease || "easeOut", duration } = + valueTransition /** * Resolve stagger() if defined. @@ -133,11 +132,13 @@ export function createAnimationsFromSequence( absoluteDelta = Math.abs(delta) } + const springTransition = { ...remainingTransition } + if (duration !== undefined) { + springTransition.duration = secondsToMilliseconds(duration) + } + const springEasing = createGeneratorEasing( - { - ...remainingTransition, - duration: secondsToMilliseconds(duration), - }, + springTransition, absoluteDelta ) @@ -145,6 +146,8 @@ export function createAnimationsFromSequence( duration = springEasing.duration } + duration ??= defaultDuration + const startTime = currentTime + calculatedDelay const targetTime = startTime + duration diff --git a/packages/framer-motion/src/motion/__tests__/waapi.test.tsx b/packages/framer-motion/src/motion/__tests__/waapi.test.tsx index 26299992bd..7a5483fda8 100644 --- a/packages/framer-motion/src/motion/__tests__/waapi.test.tsx +++ b/packages/framer-motion/src/motion/__tests__/waapi.test.tsx @@ -372,6 +372,7 @@ describe("WAAPI animations", () => { duration: 0.05, delay: 2, ease: () => 0.5, + times: [0, 1], }} /> )