feat(rnre): background-image for css animations - #10664
tshmieldev wants to merge 9 commits into
Conversation
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThe PR adds native interpolation support for linear and radial Priority: ➖ Normal Change: Feature Merge Risk: 🔵 Low · up to Malformed non-finite gradients can still reach native interpolation, and a regression in Web object-form keyframe processing could escape current tests. Both risks are bounded, but the native validation and Web integration coverage should be addressed or accepted before merge. 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Advanced
Run ID: 24bc7660-3478-48be-8930-c14d0d61780e
📒 Files selected for processing (14)
apps/common-app/runtime-tests/reanimated/suites.tsapps/common-app/runtime-tests/reanimated/tests/css/backgroundImage.test.tsxapps/common-app/src/apps/css/examples/animations/routes/properties/base.tsapps/common-app/src/apps/css/examples/animations/screens/animatedProperties/base/appearance/others/BackgroundImage.tsxapps/common-app/src/apps/css/examples/animations/screens/animatedProperties/base/appearance/others/index.tsdocs/docs-reanimated/docs/guides/supported-properties.mdxpackages/react-native-reanimated/CHANGELOG.mdpackages/react-native-reanimated/Common/cpp/reanimated/CSS/InterpolatorRegistry.cpppackages/react-native-reanimated/Common/cpp/reanimated/CSS/common/values/CSSValueVariant.cpppackages/react-native-reanimated/Common/cpp/reanimated/CSS/common/values/complex/CSSGradient.cpppackages/react-native-reanimated/Common/cpp/reanimated/CSS/common/values/complex/CSSGradient.hpackages/react-native-reanimated/Common/cpp/reanimated/CSS/interpolation/values/SimpleValueInterpolator.cpppackages/react-native-reanimated/src/common/style/registry.tspackages/react-native-reanimated/src/css/native/__tests__/registry.test.ts
Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review.
There was a problem hiding this comment.
Actionable comments posted: 2
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Advanced
Run ID: 943dd468-f063-434a-b646-feb3811d5928
📒 Files selected for processing (8)
docs/docs-reanimated/docs/guides/supported-properties.mdxpackages/react-native-reanimated/CHANGELOG.mdpackages/react-native-reanimated/src/common/style/processors/__tests__/backgroundImage.test.tspackages/react-native-reanimated/src/common/style/processors/backgroundImage.tspackages/react-native-reanimated/src/common/web/style/config.tspackages/react-native-reanimated/src/common/web/style/processors/__tests__/backgroundImage.test.tspackages/react-native-reanimated/src/common/web/style/processors/backgroundImage.tspackages/react-native-reanimated/src/common/web/style/processors/index.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/react-native-reanimated/CHANGELOG.md
Included review availability: Your plan provides up to 10 included reviews per hour; 8 remain after this review.
There was a problem hiding this comment.
🧹 Nitpick comments (1)
packages/react-native-reanimated/src/common/web/style/config.ts (1)
196-196: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winAdd an object-form
backgroundImagekeyframe integration test.
CSSAnimationsManagersends object keyframes throughprocessKeyframeDefinitions, which useswebPropsBuilder. The parser tests cover onlyopacity, and the manager tests coveropacityand SVGd. ThebackgroundImagetests callprocessBackgroundImageWebdirectly.A regression that removes
backgroundImagefromPROPERTIES_CONFIGcan therefore pass all existing tests while generated@keyframescontain no serialized background-image declaration.Suggested fix
+ test('builds backgroundImage keyframes with the Web props builder', () => { + const backgroundImageKeyframes = { + from: { + backgroundImage: [ + { + type: 'linear-gradient', + direction: 'to right', + colorStops: [{ color: 'red' }, { color: 'blue' }], + }, + ], + }, + to: { + backgroundImage: [ + { + type: 'linear-gradient', + direction: 'to left', + colorStops: [{ color: 'red' }, { color: 'blue' }], + }, + ], + }, + }; + + manager.update({ + animationName: backgroundImageKeyframes, + animationDuration: 200, + } as unknown as ExistingCSSAnimationProperties); + + expect(insertCSSAnimation).toHaveBeenCalledWith( + element.style.animationName, + 'from { background-image: linear-gradient(to right, red, blue) } to { background-image: linear-gradient(to left, red, blue) }' + ); + }); +
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Advanced
Run ID: 06ae4cef-b8a2-45c3-90bd-fa84c56f4e73
📒 Files selected for processing (1)
packages/react-native-reanimated/changelog/bgimg-css.feature.md
Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review.
Note
This pull request was authored by AI on behalf of @tshmieldev.
Summary
Adds
backgroundImage(linear and radial gradients) to CSS animations and CSS transitions. #10486 added the JS processor and made gradients work inuseAnimatedStyle; the CSS engine had no interpolator for the property, soanimationName/transitionPropertywithbackgroundImagethrewNo interpolator factory found for property: backgroundImage.Native
CSSGradient(Common/cpp/reanimated/CSS/common/values/complex/CSSGradient.{h,cpp}) registered asarray({value<CSSGradient>(CSSGradient())}), one interpolator per layer, likeboxShadow. It reads and emits the exact shape produced byprocessBackgroundImage, so React Native parses the animated value with its existingbackgroundImageparser on both platforms.'backgroundImage'is added toDEFAULT_SEPARATELY_INTERPOLATED_NESTED_PROPERTIES, so keyframes are split per layer index.red, blue→red, blue, limeanimates instead of snapping;nullin both keyframes staysnullin the output so React Native resolves it;FALLBACK_INTERPOLATION_THRESHOLD): linear ↔ radial, keyword ↔ angle direction, different keywords, shape mismatch, size keyword ↔ explicit size,px↔%, transition hint ↔ color stop at the same index.supported-properties.mdx.Web
processBackgroundImageWebturns the object form into a CSSlinear-gradient()/radial-gradient()string (strings pass through), with the same defaults as the native processor. Browsers treatbackground-imageas a discrete animation type, so on the Web the gradient switches at the midpoint between keyframes; the docs say so.Related
Unsupported type for radius property: Nullonce per color stop without a position on everybackgroundImageupdate (also for plain React Native, and at frame rate for any animated gradient). Fix in React Native: fix(android): skip null gradient color stop positions instead of warning react/react-native#58636.Test plan
Example screen:
apps/common-app→ CSS → Animations → Animated properties → Others → Background Image (Linear / Radial / Layers tabs). Checked on the Android emulator (Pixel 9 Pro, API 37), the iPhone 17 simulator, and Expo web.Runtime tests (new suite
css/backgroundImage.test.tsx, 8 cases; it pins a paused animation at a known progress with a negativeanimationDelayand reads the parsed native prop back withgetViewProp):10/10 on Android (incl. the existing cancellation cases).
Jest:
yarn workspace react-native-reanimated jest backgroundImage registry(native processor incl. new validation cases, web processor, nested properties registry).yarn workspace react-native-reanimated type:check,type:check:legacy-rn-types,lint:js;clang-formatv19 andscripts/validate-common.shon the C++.Minimal snippet:
Expected: the gradient rotates a full turn while its colors blend, on both platforms.
Changelog
Unpublishedsection of each changed package'sCHANGELOG.md, or this PR does not changereact-native-reanimatedorreact-native-worklets.