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
This commit is contained in:
Genki Kondo
2023-06-16 10:40:39 -07:00
committed by Facebook GitHub Bot
parent 71936fcf43
commit 5f8bbf2bd2
@@ -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));
}