mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Correctly batch AnimatedColor updates
Summary: Call `setWaitingForIdentifier` before we do any `setValue` calls to make sure we execute them together (and only call start/finish batch once). Only calll `updateAnimatedNodeConfig` conditionally when we changed nativeColor. Changelog: [Internal] Reviewed By: JoshuaGross Differential Revision: D36517302 fbshipit-source-id: ecbae2d1df69e4456620c58a922275406e22a2f8
This commit is contained in:
committed by
Facebook GitHub Bot
parent
7e646361ee
commit
406a474e52
@@ -24,7 +24,9 @@ import type {ProcessedColorValue} from '../../StyleSheet/processColor';
|
||||
export type AnimatedColorConfig = $ReadOnly<{
|
||||
useNativeDriver: boolean,
|
||||
}>;
|
||||
type ColorListenerCallback = (value: string) => mixed;
|
||||
|
||||
type ColorListenerCallback = (value: ColorValue) => mixed;
|
||||
|
||||
export type RgbaValue = {
|
||||
+r: number,
|
||||
+g: number,
|
||||
@@ -32,6 +34,7 @@ export type RgbaValue = {
|
||||
+a: number,
|
||||
...
|
||||
};
|
||||
|
||||
type RgbaAnimatedValue = {
|
||||
+r: AnimatedValue,
|
||||
+g: AnimatedValue,
|
||||
@@ -40,6 +43,8 @@ type RgbaAnimatedValue = {
|
||||
...
|
||||
};
|
||||
|
||||
const NativeAnimatedAPI = NativeAnimatedHelper.API;
|
||||
|
||||
const defaultColor: RgbaValue = {r: 0, g: 0, b: 0, a: 1.0};
|
||||
let _uniqueId = 1;
|
||||
|
||||
@@ -161,34 +166,43 @@ export default class AnimatedColor extends AnimatedWithChildren {
|
||||
* and update all the bound properties.
|
||||
*/
|
||||
setValue(value: RgbaValue | ColorValue): void {
|
||||
this.nativeColor = null;
|
||||
let shouldUpdateNodeConfig = false;
|
||||
if (this.__isNative) {
|
||||
const nativeTag = this.__getNativeTag();
|
||||
NativeAnimatedAPI.setWaitingForIdentifier(nativeTag.toString());
|
||||
}
|
||||
|
||||
const processedColor: RgbaValue | NativeColorValue =
|
||||
processColor(value) ?? defaultColor;
|
||||
if (isRgbaValue(processedColor)) {
|
||||
// $FlowIgnore[incompatible-cast] - Type is verified above
|
||||
const rgbaValue: RgbaValue = (processedColor: RgbaValue);
|
||||
// $FlowIgnore[incompatible-type] - Type is verified above
|
||||
const rgbaValue: RgbaValue = processedColor;
|
||||
this.r.setValue(rgbaValue.r);
|
||||
this.g.setValue(rgbaValue.g);
|
||||
this.b.setValue(rgbaValue.b);
|
||||
this.a.setValue(rgbaValue.a);
|
||||
if (this.nativeColor != null) {
|
||||
this.nativeColor = null;
|
||||
shouldUpdateNodeConfig = true;
|
||||
}
|
||||
} else {
|
||||
// $FlowIgnore[incompatible-cast] - Type is verified above
|
||||
this.nativeColor = (processedColor: NativeColorValue);
|
||||
// $FlowIgnore[incompatible-type] - Type is verified above
|
||||
const nativeColor: NativeColorValue = processedColor;
|
||||
if (this.nativeColor !== nativeColor) {
|
||||
this.nativeColor = nativeColor;
|
||||
shouldUpdateNodeConfig = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.nativeColor) {
|
||||
if (!this.__isNative) {
|
||||
this.__makeNative();
|
||||
}
|
||||
|
||||
if (this.__isNative) {
|
||||
const nativeTag = this.__getNativeTag();
|
||||
NativeAnimatedHelper.API.setWaitingForIdentifier(nativeTag.toString());
|
||||
NativeAnimatedHelper.API.updateAnimatedNodeConfig(
|
||||
nativeTag,
|
||||
this.__getNativeConfig(),
|
||||
);
|
||||
NativeAnimatedHelper.API.unsetWaitingForIdentifier(nativeTag.toString());
|
||||
if (shouldUpdateNodeConfig) {
|
||||
NativeAnimatedAPI.updateAnimatedNodeConfig(
|
||||
nativeTag,
|
||||
this.__getNativeConfig(),
|
||||
);
|
||||
}
|
||||
NativeAnimatedAPI.unsetWaitingForIdentifier(nativeTag.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,7 +289,7 @@ export default class AnimatedColor extends AnimatedWithChildren {
|
||||
* final value after stopping the animation, which is useful for updating
|
||||
* state to match the animation position with layout.
|
||||
*/
|
||||
stopAnimation(callback?: (value: string) => void): void {
|
||||
stopAnimation(callback?: ColorListenerCallback): void {
|
||||
this.r.stopAnimation();
|
||||
this.g.stopAnimation();
|
||||
this.b.stopAnimation();
|
||||
@@ -286,7 +300,7 @@ export default class AnimatedColor extends AnimatedWithChildren {
|
||||
/**
|
||||
* Stops any animation and resets the value to its original.
|
||||
*/
|
||||
resetAnimation(callback?: (value: string) => void): void {
|
||||
resetAnimation(callback?: ColorListenerCallback): void {
|
||||
this.r.resetAnimation();
|
||||
this.g.resetAnimation();
|
||||
this.b.resetAnimation();
|
||||
@@ -294,8 +308,12 @@ export default class AnimatedColor extends AnimatedWithChildren {
|
||||
callback && callback(this.__getValue());
|
||||
}
|
||||
|
||||
__getValue(): string {
|
||||
return `rgba(${this.r.__getValue()}, ${this.g.__getValue()}, ${this.b.__getValue()}, ${this.a.__getValue()})`;
|
||||
__getValue(): ColorValue {
|
||||
if (this.nativeColor != null) {
|
||||
return this.nativeColor;
|
||||
} else {
|
||||
return `rgba(${this.r.__getValue()}, ${this.g.__getValue()}, ${this.b.__getValue()}, ${this.a.__getValue()})`;
|
||||
}
|
||||
}
|
||||
|
||||
__attach(): void {
|
||||
|
||||
@@ -134,9 +134,9 @@ class AnimatedValue extends AnimatedWithChildren {
|
||||
!this.__isNative /* don't perform a flush for natively driven values */,
|
||||
);
|
||||
if (this.__isNative) {
|
||||
_executeAsAnimatedBatch(this.__getNativeTag().toString(), () => {
|
||||
NativeAnimatedAPI.setAnimatedNodeValue(this.__getNativeTag(), value);
|
||||
});
|
||||
_executeAsAnimatedBatch(this.__getNativeTag().toString(), () =>
|
||||
NativeAnimatedAPI.setAnimatedNodeValue(this.__getNativeTag(), value),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user