From 8b199ca984fa3ce5c5bc1ac5eb71f8d150f035d1 Mon Sep 17 00:00:00 2001 From: Matt Perry Date: Fri, 24 Feb 2023 11:44:07 +0100 Subject: [PATCH 1/9] Animate background-color via WAAPI --- CHANGELOG.md | 4 ++ .../waapi/create-accelerated-animation.ts | 7 ++- .../src/motion/__tests__/waapi.test.tsx | 61 +++++++++++++++++++ 3 files changed, 71 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a5dd41d92..86bd7a57f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ Undocumented APIs should be considered internal and may change without warning. ## [10.0.0] 2023-02-24 +### Added + +- `background-color` animations are now hardware accelerated. + ### Removed - Removing fallback for `IntersectionObserver`. Use a polyfill for support in older browsers. diff --git a/packages/framer-motion/src/animation/waapi/create-accelerated-animation.ts b/packages/framer-motion/src/animation/waapi/create-accelerated-animation.ts index cb98bea333..8b21c3f4e4 100644 --- a/packages/framer-motion/src/animation/waapi/create-accelerated-animation.ts +++ b/packages/framer-motion/src/animation/waapi/create-accelerated-animation.ts @@ -17,6 +17,7 @@ const acceleratedValues = new Set([ "clipPath", "filter", "transform", + "backgroundColor", ]) /** @@ -45,7 +46,11 @@ export function createAcceleratedAnimation( /** * If this animation needs pre-generated keyframes then generate. */ - if (options.type === "spring" || !isWaapiSupportedEasing(options.ease)) { + if ( + options.type === "spring" || + valueName === "backgroundColor" || + !isWaapiSupportedEasing(options.ease) + ) { /** * If we need to pre-generate keyframes and repeat is infinite then * early return as this will lock the thread. diff --git a/packages/framer-motion/src/motion/__tests__/waapi.test.tsx b/packages/framer-motion/src/motion/__tests__/waapi.test.tsx index e932468849..78a7b881ed 100644 --- a/packages/framer-motion/src/motion/__tests__/waapi.test.tsx +++ b/packages/framer-motion/src/motion/__tests__/waapi.test.tsx @@ -144,6 +144,67 @@ describe("WAAPI animations", () => { ) }) + test("backgroundColor animates with WAAPI at default settings", () => { + const ref = createRef() + const Component = () => ( + + ) + const { rerender } = render() + rerender() + + expect(ref.current!.animate).toBeCalled() + expect(ref.current!.animate).toBeCalledWith( + { + backgroundColor: [ + "rgba(255, 0, 0, 1)", + "rgba(253, 0, 35, 1)", + "rgba(249, 0, 56, 1)", + "rgba(244, 0, 75, 1)", + "rgba(237, 0, 94, 1)", + "rgba(229, 0, 112, 1)", + "rgba(220, 0, 128, 1)", + "rgba(211, 0, 144, 1)", + "rgba(200, 0, 158, 1)", + "rgba(190, 0, 171, 1)", + "rgba(179, 0, 182, 1)", + "rgba(168, 0, 192, 1)", + "rgba(157, 0, 201, 1)", + "rgba(147, 0, 209, 1)", + "rgba(136, 0, 215, 1)", + "rgba(126, 0, 222, 1)", + "rgba(116, 0, 227, 1)", + "rgba(107, 0, 232, 1)", + "rgba(97, 0, 236, 1)", + "rgba(88, 0, 239, 1)", + "rgba(79, 0, 242, 1)", + "rgba(71, 0, 245, 1)", + "rgba(62, 0, 247, 1)", + "rgba(54, 0, 249, 1)", + "rgba(46, 0, 251, 1)", + "rgba(38, 0, 252, 1)", + "rgba(30, 0, 253, 1)", + "rgba(22, 0, 254, 1)", + "rgba(15, 0, 255, 1)", + "rgba(7, 0, 255, 1)", + "rgba(0, 0, 255, 1)", + ], + offset: undefined, + }, + { + delay: -0, + duration: 300, + easing: "cubic-bezier(0.25, 0.1, 0.35, 1)", + iterations: 1, + direction: "normal", + fill: "both", + } + ) + }) + test("opacity animates with WAAPI when no value is originally provided via initial", () => { const ref = createRef() const Component = () => ( From bb4fb0fcab253c6a1304e8109b847f820c5a6d16 Mon Sep 17 00:00:00 2001 From: Matt Perry Date: Fri, 24 Feb 2023 13:19:12 +0100 Subject: [PATCH 2/9] Updating test --- packages/framer-motion/src/motion/__tests__/waapi.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/framer-motion/src/motion/__tests__/waapi.test.tsx b/packages/framer-motion/src/motion/__tests__/waapi.test.tsx index 78a7b881ed..a31473c802 100644 --- a/packages/framer-motion/src/motion/__tests__/waapi.test.tsx +++ b/packages/framer-motion/src/motion/__tests__/waapi.test.tsx @@ -197,7 +197,7 @@ describe("WAAPI animations", () => { { delay: -0, duration: 300, - easing: "cubic-bezier(0.25, 0.1, 0.35, 1)", + easing: "linear", iterations: 1, direction: "normal", fill: "both", From 747d925d9ad301d322fe93562eddd84d124eda4b Mon Sep 17 00:00:00 2001 From: Matt Perry Date: Fri, 24 Feb 2023 13:19:28 +0100 Subject: [PATCH 3/9] v10.0.0-alpha.0 --- dev/package.json | 6 +++--- lerna.json | 2 +- packages/framer-motion-3d/package.json | 4 ++-- packages/framer-motion/package.json | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/dev/package.json b/dev/package.json index 1f17552d85..9894d6a5b7 100644 --- a/dev/package.json +++ b/dev/package.json @@ -1,6 +1,6 @@ { "name": "framer-motion--dev", - "version": "10.0.0", + "version": "10.0.0-alpha.0", "private": true, "scripts": { "dev": "webpack serve --config ./webpack/config.js --hot" @@ -8,8 +8,8 @@ "dependencies": { "@react-three/drei": "^7.27.3", "@react-three/fiber": "^8.2.2", - "framer-motion": "^10.0.0", - "framer-motion-3d": "^10.0.0", + "framer-motion": "^10.0.0-alpha.0", + "framer-motion-3d": "^10.0.0-alpha.0", "path-browserify": "^1.0.1", "react": "^18.2.0", "react-dom": "^18.2.0", diff --git a/lerna.json b/lerna.json index a693ab314a..b78e200846 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "10.0.0", + "version": "10.0.0-alpha.0", "packages": [ "packages/*" ], diff --git a/packages/framer-motion-3d/package.json b/packages/framer-motion-3d/package.json index e3220ca708..4f8c8d29ea 100644 --- a/packages/framer-motion-3d/package.json +++ b/packages/framer-motion-3d/package.json @@ -1,6 +1,6 @@ { "name": "framer-motion-3d", - "version": "10.0.0", + "version": "10.0.0-alpha.0", "description": "A simple and powerful React animation library for @react-three/fiber", "main": "dist/cjs/index.js", "module": "dist/es/index.mjs", @@ -46,7 +46,7 @@ "postpublish": "git push --tags" }, "dependencies": { - "framer-motion": "^10.0.0", + "framer-motion": "^10.0.0-alpha.0", "react-merge-refs": "^2.0.1" }, "peerDependencies": { diff --git a/packages/framer-motion/package.json b/packages/framer-motion/package.json index 0676aff93c..ce3589a77e 100644 --- a/packages/framer-motion/package.json +++ b/packages/framer-motion/package.json @@ -1,6 +1,6 @@ { "name": "framer-motion", - "version": "10.0.0", + "version": "10.0.0-alpha.0", "description": "A simple and powerful React animation library", "main": "dist/cjs/index.js", "module": "dist/es/index.mjs", From a251dde6cb6c192f331924fa79f6b73e4c5b842e Mon Sep 17 00:00:00 2001 From: Matt Perry Date: Fri, 24 Feb 2023 13:19:45 +0100 Subject: [PATCH 4/9] Making alpha release --- yarn.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/yarn.lock b/yarn.lock index 4f3e1c62a8..88fda803c9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7844,8 +7844,8 @@ __metadata: cache-loader: ^1.2.5 convert-tsconfig-paths-to-webpack-aliases: ^0.9.2 fork-ts-checker-webpack-plugin: ^6.2.0 - framer-motion: ^10.0.0 - framer-motion-3d: ^10.0.0 + framer-motion: ^10.0.0-alpha.0 + framer-motion-3d: ^10.0.0-alpha.0 path-browserify: ^1.0.1 react: ^18.2.0 react-dom: ^18.2.0 @@ -7911,14 +7911,14 @@ __metadata: languageName: unknown linkType: soft -"framer-motion-3d@^10.0.0, framer-motion-3d@workspace:packages/framer-motion-3d": +"framer-motion-3d@^10.0.0-alpha.0, framer-motion-3d@workspace:packages/framer-motion-3d": version: 0.0.0-use.local resolution: "framer-motion-3d@workspace:packages/framer-motion-3d" dependencies: "@react-three/fiber": ^8.2.2 "@react-three/test-renderer": ^9.0.0 "@rollup/plugin-commonjs": ^22.0.1 - framer-motion: ^10.0.0 + framer-motion: ^10.0.0-alpha.0 react-merge-refs: ^2.0.1 peerDependencies: "@react-three/fiber": ^8.2.2 @@ -7928,7 +7928,7 @@ __metadata: languageName: unknown linkType: soft -"framer-motion@^10.0.0, framer-motion@workspace:packages/framer-motion": +"framer-motion@^10.0.0-alpha.0, framer-motion@workspace:packages/framer-motion": version: 0.0.0-use.local resolution: "framer-motion@workspace:packages/framer-motion" dependencies: From ba1d33a54ed107a3a863ecd12cfc1b84478c6269 Mon Sep 17 00:00:00 2001 From: Matt Perry Date: Fri, 24 Feb 2023 14:01:50 +0100 Subject: [PATCH 5/9] Fixing repeat Infinity deopt --- CHANGELOG.md | 4 ++ .../waapi/create-accelerated-animation.ts | 12 ++-- .../src/motion/__tests__/waapi.test.tsx | 66 +++++++++++++++++-- 3 files changed, 71 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 86bd7a57f2..0157c16f2f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,10 @@ Undocumented APIs should be considered internal and may change without warning. - Using `value.onChange` will now throw a warning with instructions to change to `value.on("change", callback)`. - Using `AnimateSharedLayout` now throws an error. +### Fixed + +- `repeat: Infinity` no longer de-opts from pre-generated WAAPI animations. + ## [9.1.7] 2023-02-24 ### Fixed diff --git a/packages/framer-motion/src/animation/waapi/create-accelerated-animation.ts b/packages/framer-motion/src/animation/waapi/create-accelerated-animation.ts index 8b21c3f4e4..a91336b547 100644 --- a/packages/framer-motion/src/animation/waapi/create-accelerated-animation.ts +++ b/packages/framer-motion/src/animation/waapi/create-accelerated-animation.ts @@ -51,13 +51,11 @@ export function createAcceleratedAnimation( valueName === "backgroundColor" || !isWaapiSupportedEasing(options.ease) ) { - /** - * If we need to pre-generate keyframes and repeat is infinite then - * early return as this will lock the thread. - */ - if (options.repeat === Infinity) return - - const sampleAnimation = animateValue({ ...options, elapsed: 0 }) + const sampleAnimation = animateValue({ + ...options, + repeat: 0, + elapsed: 0, + }) let state = { done: false, value: keyframes[0] } const pregeneratedKeyframes: number[] = [] diff --git a/packages/framer-motion/src/motion/__tests__/waapi.test.tsx b/packages/framer-motion/src/motion/__tests__/waapi.test.tsx index a31473c802..694ddbb854 100644 --- a/packages/framer-motion/src/motion/__tests__/waapi.test.tsx +++ b/packages/framer-motion/src/motion/__tests__/waapi.test.tsx @@ -811,19 +811,77 @@ describe("WAAPI animations", () => { expect(ref.current!.animate).not.toBeCalled() }) - test("Doesn't animate with WAAPI if repeat is Infinity and we need to generate keyframes", () => { + test("Animates with WAAPI if repeat is defined and we need to generate keyframes", () => { const ref = createRef() const Component = () => ( ) const { rerender } = render() rerender() - expect(ref.current!.animate).not.toBeCalled() + expect(ref.current!.animate).toBeCalled() + expect(ref.current!.animate).toBeCalledWith( + { + opacity: [ + 0, -0.038019759996313955, 0.14036703066311026, + 0.7596329693368897, 0.9380197599963139, 0.9, + ], + offset: undefined, + }, + { + delay: -0, + direction: "normal", + duration: 50, + easing: "linear", + fill: "both", + iterations: 3, + } + ) + }) + + test("Animates with WAAPI if repeat is Infinity and we need to generate keyframes", () => { + const ref = createRef() + const Component = () => ( + + ) + const { rerender } = render() + rerender() + + expect(ref.current!.animate).toBeCalled() + expect(ref.current!.animate).toBeCalledWith( + { + opacity: [ + 0, -0.038019759996313955, 0.14036703066311026, + 0.7596329693368897, 0.9380197599963139, 0.9, + ], + offset: undefined, + }, + { + delay: -0, + direction: "normal", + duration: 50, + easing: "linear", + fill: "both", + iterations: Infinity, + } + ) }) }) From 12fb2e9c6c007d7f2e5665f1b5d28e7d97dc506a Mon Sep 17 00:00:00 2001 From: Matt Perry Date: Fri, 24 Feb 2023 14:03:24 +0100 Subject: [PATCH 6/9] v10.0.0-alpha.1 --- dev/package.json | 6 +++--- lerna.json | 2 +- packages/framer-motion-3d/package.json | 4 ++-- packages/framer-motion/package.json | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/dev/package.json b/dev/package.json index 9894d6a5b7..3c051fcc84 100644 --- a/dev/package.json +++ b/dev/package.json @@ -1,6 +1,6 @@ { "name": "framer-motion--dev", - "version": "10.0.0-alpha.0", + "version": "10.0.0-alpha.1", "private": true, "scripts": { "dev": "webpack serve --config ./webpack/config.js --hot" @@ -8,8 +8,8 @@ "dependencies": { "@react-three/drei": "^7.27.3", "@react-three/fiber": "^8.2.2", - "framer-motion": "^10.0.0-alpha.0", - "framer-motion-3d": "^10.0.0-alpha.0", + "framer-motion": "^10.0.0-alpha.1", + "framer-motion-3d": "^10.0.0-alpha.1", "path-browserify": "^1.0.1", "react": "^18.2.0", "react-dom": "^18.2.0", diff --git a/lerna.json b/lerna.json index b78e200846..a9233f9d2e 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "10.0.0-alpha.0", + "version": "10.0.0-alpha.1", "packages": [ "packages/*" ], diff --git a/packages/framer-motion-3d/package.json b/packages/framer-motion-3d/package.json index 4f8c8d29ea..6ab010c14f 100644 --- a/packages/framer-motion-3d/package.json +++ b/packages/framer-motion-3d/package.json @@ -1,6 +1,6 @@ { "name": "framer-motion-3d", - "version": "10.0.0-alpha.0", + "version": "10.0.0-alpha.1", "description": "A simple and powerful React animation library for @react-three/fiber", "main": "dist/cjs/index.js", "module": "dist/es/index.mjs", @@ -46,7 +46,7 @@ "postpublish": "git push --tags" }, "dependencies": { - "framer-motion": "^10.0.0-alpha.0", + "framer-motion": "^10.0.0-alpha.1", "react-merge-refs": "^2.0.1" }, "peerDependencies": { diff --git a/packages/framer-motion/package.json b/packages/framer-motion/package.json index ce3589a77e..b52d286093 100644 --- a/packages/framer-motion/package.json +++ b/packages/framer-motion/package.json @@ -1,6 +1,6 @@ { "name": "framer-motion", - "version": "10.0.0-alpha.0", + "version": "10.0.0-alpha.1", "description": "A simple and powerful React animation library", "main": "dist/cjs/index.js", "module": "dist/es/index.mjs", From b953fdb7ff0240938a33399ade2b8344671485d2 Mon Sep 17 00:00:00 2001 From: Matt Perry Date: Fri, 24 Feb 2023 14:08:44 +0100 Subject: [PATCH 7/9] Reducing size limits --- packages/framer-motion/package.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/framer-motion/package.json b/packages/framer-motion/package.json index b52d286093..2f459b3c3c 100644 --- a/packages/framer-motion/package.json +++ b/packages/framer-motion/package.json @@ -70,7 +70,7 @@ "bundlesize": [ { "path": "./dist/size-rollup-motion.js", - "maxSize": "29.92 kB" + "maxSize": "29.88 kB" }, { "path": "./dist/size-rollup-m.js", @@ -78,11 +78,11 @@ }, { "path": "./dist/size-rollup-dom-animation.js", - "maxSize": "14.85 kB" + "maxSize": "14.75 kB" }, { "path": "./dist/size-rollup-dom-max.js", - "maxSize": "25.67 kB" + "maxSize": "25.61 kB" }, { "path": "./dist/size-webpack-m.js", @@ -90,11 +90,11 @@ }, { "path": "./dist/size-webpack-dom-animation.js", - "maxSize": "18.81 kB" + "maxSize": "18.75 kB" }, { "path": "./dist/size-webpack-dom-max.js", - "maxSize": "30.52 kB" + "maxSize": "30.47 kB" } ], "gitHead": "79675ba44230ae86bfb212be8bd903fc68524976" From 6e3dd89d1b902ce038d08db542ded1a6da848593 Mon Sep 17 00:00:00 2001 From: Matt Perry Date: Fri, 24 Feb 2023 15:28:18 +0100 Subject: [PATCH 8/9] Capping pregenerated keyframes --- .../waapi/create-accelerated-animation.ts | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/framer-motion/src/animation/waapi/create-accelerated-animation.ts b/packages/framer-motion/src/animation/waapi/create-accelerated-animation.ts index a91336b547..7af8329323 100644 --- a/packages/framer-motion/src/animation/waapi/create-accelerated-animation.ts +++ b/packages/framer-motion/src/animation/waapi/create-accelerated-animation.ts @@ -27,6 +27,14 @@ const acceleratedValues = new Set([ */ const sampleDelta = 10 //ms +const requiresPregeneratedKeyframes = ( + valueName: string, + options: AnimationOptions +) => + options.type === "spring" || + valueName === "backgroundColor" || + !isWaapiSupportedEasing(options.ease) + export function createAcceleratedAnimation( value: MotionValue, valueName: string, @@ -46,11 +54,7 @@ export function createAcceleratedAnimation( /** * If this animation needs pre-generated keyframes then generate. */ - if ( - options.type === "spring" || - valueName === "backgroundColor" || - !isWaapiSupportedEasing(options.ease) - ) { + if (requiresPregeneratedKeyframes(valueName, options)) { const sampleAnimation = animateValue({ ...options, repeat: 0, From f27c2719e61cb0299dd1b9fadc6d292c4ef47257 Mon Sep 17 00:00:00 2001 From: Matt Perry Date: Fri, 24 Feb 2023 15:30:16 +0100 Subject: [PATCH 9/9] yarn --- yarn.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/yarn.lock b/yarn.lock index 88fda803c9..93371ca769 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7844,8 +7844,8 @@ __metadata: cache-loader: ^1.2.5 convert-tsconfig-paths-to-webpack-aliases: ^0.9.2 fork-ts-checker-webpack-plugin: ^6.2.0 - framer-motion: ^10.0.0-alpha.0 - framer-motion-3d: ^10.0.0-alpha.0 + framer-motion: ^10.0.0-alpha.1 + framer-motion-3d: ^10.0.0-alpha.1 path-browserify: ^1.0.1 react: ^18.2.0 react-dom: ^18.2.0 @@ -7911,14 +7911,14 @@ __metadata: languageName: unknown linkType: soft -"framer-motion-3d@^10.0.0-alpha.0, framer-motion-3d@workspace:packages/framer-motion-3d": +"framer-motion-3d@^10.0.0-alpha.1, framer-motion-3d@workspace:packages/framer-motion-3d": version: 0.0.0-use.local resolution: "framer-motion-3d@workspace:packages/framer-motion-3d" dependencies: "@react-three/fiber": ^8.2.2 "@react-three/test-renderer": ^9.0.0 "@rollup/plugin-commonjs": ^22.0.1 - framer-motion: ^10.0.0-alpha.0 + framer-motion: ^10.0.0-alpha.1 react-merge-refs: ^2.0.1 peerDependencies: "@react-three/fiber": ^8.2.2 @@ -7928,7 +7928,7 @@ __metadata: languageName: unknown linkType: soft -"framer-motion@^10.0.0-alpha.0, framer-motion@workspace:packages/framer-motion": +"framer-motion@^10.0.0-alpha.1, framer-motion@workspace:packages/framer-motion": version: 0.0.0-use.local resolution: "framer-motion@workspace:packages/framer-motion" dependencies: