diff --git a/dev/react/src/tests/issue-2826-linear-motion-value.tsx b/dev/react/src/tests/issue-2826-linear-motion-value.tsx new file mode 100644 index 0000000000..456d562ec2 --- /dev/null +++ b/dev/react/src/tests/issue-2826-linear-motion-value.tsx @@ -0,0 +1,33 @@ +import { animate, motion, useMotionValue } from "framer-motion" +import { useEffect } from "react" + +/** + * Reproduces the scenario from issue #2826: + * useMotionValue + animate(motionValue, [0, 1], { ease: "linear", + * type: "keyframes", times: [0, 1] }) wired to motion.div opacity. + * The animation should progress linearly across its duration. + */ +export const App = () => { + const opacity = useMotionValue(0) + + useEffect(() => { + animate(opacity, [0, 1], { + duration: 10, + ease: "linear", + type: "keyframes", + times: [0, 1], + }) + }, []) + + return ( + + ) +} diff --git a/packages/framer-motion/cypress/integration/issue-2826-linear-motion-value.ts b/packages/framer-motion/cypress/integration/issue-2826-linear-motion-value.ts new file mode 100644 index 0000000000..e0e9ba5a93 --- /dev/null +++ b/packages/framer-motion/cypress/integration/issue-2826-linear-motion-value.ts @@ -0,0 +1,35 @@ +describe("issue 2826: animate(motionValue) with ease: 'linear' renders linearly", () => { + it("opacity progresses linearly across the duration", () => { + const tolerance = 0.1 + + cy.visit("?test=issue-2826-linear-motion-value") + .wait(2500) + .get("#box") + .then(([$element]: any) => { + const opacity = parseFloat( + getComputedStyle($element).opacity + ) + // 25% through 10s should be ~0.25 + expect(opacity).to.be.greaterThan(0.25 - tolerance) + expect(opacity).to.be.lessThan(0.25 + tolerance) + }) + .wait(2500) + .then(([$element]: any) => { + const opacity = parseFloat( + getComputedStyle($element).opacity + ) + // 50% through 10s should be ~0.5 + expect(opacity).to.be.greaterThan(0.5 - tolerance) + expect(opacity).to.be.lessThan(0.5 + tolerance) + }) + .wait(2500) + .then(([$element]: any) => { + const opacity = parseFloat( + getComputedStyle($element).opacity + ) + // 75% through 10s should be ~0.75 + expect(opacity).to.be.greaterThan(0.75 - tolerance) + expect(opacity).to.be.lessThan(0.75 + tolerance) + }) + }) +})