From 5f8bbf2bd27ccff2c83be8d9dedc7005854fecaa Mon Sep 17 00:00:00 2001 From: Genki Kondo Date: Fri, 16 Jun 2023 10:40:39 -0700 Subject: [PATCH] Mitigate flickering on color animations (#37925) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/37925 Vectorized animations (XY, Color) are split into multiple animations for each component that execute in parallel. Upon each of these animations completing, a rerender is triggered to sync the state back to the JS AnimatedValue nodes. The problem with this is that calling update() on AnimatedProps when each animation completes results in potential flickering as all animations that are part of the vectorized animation may not have completed yet. For example, only the animation for the red channel of an animating color may have been completed, resulting in a temporary red color being rendered. So, for now, ignore AnimatedProps that use a vectorized animation. Follow up will properly address vectorized animations - only call the update() when all animations complete. Changelog: [General][Fixed] - Mitigate flickering on color animations Reviewed By: rshest Differential Revision: D46778405 fbshipit-source-id: 5ecb0be95a131b22e5081024d4e094b22b57aac4 --- .../Libraries/Animated/animations/Animation.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/packages/react-native/Libraries/Animated/animations/Animation.js b/packages/react-native/Libraries/Animated/animations/Animation.js index ad956cd79d9d6d..29dda1c4e8eb04 100644 --- a/packages/react-native/Libraries/Animated/animations/Animation.js +++ b/packages/react-native/Libraries/Animated/animations/Animation.js @@ -15,7 +15,9 @@ import type AnimatedNode from '../nodes/AnimatedNode'; import type AnimatedValue from '../nodes/AnimatedValue'; import NativeAnimatedHelper from '../NativeAnimatedHelper'; +import AnimatedColor from '../nodes/AnimatedColor'; import AnimatedProps from '../nodes/AnimatedProps'; +import AnimatedValueXY from '../nodes/AnimatedValueXY'; export type EndResult = {finished: boolean, value?: number, ...}; export type EndCallback = (result: EndResult) => void; @@ -75,6 +77,17 @@ export default class Animation { return result; } + // Vectorized animations (animations on AnimatedValueXY, AnimatedColor nodes) + // are split into multiple animations for each component that execute in parallel. + // Calling update() on AnimatedProps when each animation completes results in + // potential flickering as all animations that are part of the vectorized animation + // may not have completed yet. For example, only the animation for the red channel of + // an animating color may have been completed, resulting in a temporary red color + // being rendered. So, for now, ignore AnimatedProps that use a vectorized animation. + if (node instanceof AnimatedValueXY || node instanceof AnimatedColor) { + return result; + } + for (const child of node.__getChildren()) { result.push(...this.__findAnimatedPropsNodes(child)); }