Skip to content

Commit 406a474

Browse files
javachefacebook-github-bot
authored andcommitted
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
1 parent 7e64636 commit 406a474

File tree

2 files changed

+42
-24
lines changed

2 files changed

+42
-24
lines changed

Libraries/Animated/nodes/AnimatedColor.js

+39-21
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,17 @@ import type {ProcessedColorValue} from '../../StyleSheet/processColor';
2424
export type AnimatedColorConfig = $ReadOnly<{
2525
useNativeDriver: boolean,
2626
}>;
27-
type ColorListenerCallback = (value: string) => mixed;
27+
28+
type ColorListenerCallback = (value: ColorValue) => mixed;
29+
2830
export type RgbaValue = {
2931
+r: number,
3032
+g: number,
3133
+b: number,
3234
+a: number,
3335
...
3436
};
37+
3538
type RgbaAnimatedValue = {
3639
+r: AnimatedValue,
3740
+g: AnimatedValue,
@@ -40,6 +43,8 @@ type RgbaAnimatedValue = {
4043
...
4144
};
4245

46+
const NativeAnimatedAPI = NativeAnimatedHelper.API;
47+
4348
const defaultColor: RgbaValue = {r: 0, g: 0, b: 0, a: 1.0};
4449
let _uniqueId = 1;
4550

@@ -161,34 +166,43 @@ export default class AnimatedColor extends AnimatedWithChildren {
161166
* and update all the bound properties.
162167
*/
163168
setValue(value: RgbaValue | ColorValue): void {
164-
this.nativeColor = null;
169+
let shouldUpdateNodeConfig = false;
170+
if (this.__isNative) {
171+
const nativeTag = this.__getNativeTag();
172+
NativeAnimatedAPI.setWaitingForIdentifier(nativeTag.toString());
173+
}
165174

166175
const processedColor: RgbaValue | NativeColorValue =
167176
processColor(value) ?? defaultColor;
168177
if (isRgbaValue(processedColor)) {
169-
// $FlowIgnore[incompatible-cast] - Type is verified above
170-
const rgbaValue: RgbaValue = (processedColor: RgbaValue);
178+
// $FlowIgnore[incompatible-type] - Type is verified above
179+
const rgbaValue: RgbaValue = processedColor;
171180
this.r.setValue(rgbaValue.r);
172181
this.g.setValue(rgbaValue.g);
173182
this.b.setValue(rgbaValue.b);
174183
this.a.setValue(rgbaValue.a);
184+
if (this.nativeColor != null) {
185+
this.nativeColor = null;
186+
shouldUpdateNodeConfig = true;
187+
}
175188
} else {
176-
// $FlowIgnore[incompatible-cast] - Type is verified above
177-
this.nativeColor = (processedColor: NativeColorValue);
178-
}
179-
180-
if (this.nativeColor) {
181-
if (!this.__isNative) {
182-
this.__makeNative();
189+
// $FlowIgnore[incompatible-type] - Type is verified above
190+
const nativeColor: NativeColorValue = processedColor;
191+
if (this.nativeColor !== nativeColor) {
192+
this.nativeColor = nativeColor;
193+
shouldUpdateNodeConfig = true;
183194
}
195+
}
184196

197+
if (this.__isNative) {
185198
const nativeTag = this.__getNativeTag();
186-
NativeAnimatedHelper.API.setWaitingForIdentifier(nativeTag.toString());
187-
NativeAnimatedHelper.API.updateAnimatedNodeConfig(
188-
nativeTag,
189-
this.__getNativeConfig(),
190-
);
191-
NativeAnimatedHelper.API.unsetWaitingForIdentifier(nativeTag.toString());
199+
if (shouldUpdateNodeConfig) {
200+
NativeAnimatedAPI.updateAnimatedNodeConfig(
201+
nativeTag,
202+
this.__getNativeConfig(),
203+
);
204+
}
205+
NativeAnimatedAPI.unsetWaitingForIdentifier(nativeTag.toString());
192206
}
193207
}
194208

@@ -275,7 +289,7 @@ export default class AnimatedColor extends AnimatedWithChildren {
275289
* final value after stopping the animation, which is useful for updating
276290
* state to match the animation position with layout.
277291
*/
278-
stopAnimation(callback?: (value: string) => void): void {
292+
stopAnimation(callback?: ColorListenerCallback): void {
279293
this.r.stopAnimation();
280294
this.g.stopAnimation();
281295
this.b.stopAnimation();
@@ -286,16 +300,20 @@ export default class AnimatedColor extends AnimatedWithChildren {
286300
/**
287301
* Stops any animation and resets the value to its original.
288302
*/
289-
resetAnimation(callback?: (value: string) => void): void {
303+
resetAnimation(callback?: ColorListenerCallback): void {
290304
this.r.resetAnimation();
291305
this.g.resetAnimation();
292306
this.b.resetAnimation();
293307
this.a.resetAnimation();
294308
callback && callback(this.__getValue());
295309
}
296310

297-
__getValue(): string {
298-
return `rgba(${this.r.__getValue()}, ${this.g.__getValue()}, ${this.b.__getValue()}, ${this.a.__getValue()})`;
311+
__getValue(): ColorValue {
312+
if (this.nativeColor != null) {
313+
return this.nativeColor;
314+
} else {
315+
return `rgba(${this.r.__getValue()}, ${this.g.__getValue()}, ${this.b.__getValue()}, ${this.a.__getValue()})`;
316+
}
299317
}
300318

301319
__attach(): void {

Libraries/Animated/nodes/AnimatedValue.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,9 @@ class AnimatedValue extends AnimatedWithChildren {
134134
!this.__isNative /* don't perform a flush for natively driven values */,
135135
);
136136
if (this.__isNative) {
137-
_executeAsAnimatedBatch(this.__getNativeTag().toString(), () => {
138-
NativeAnimatedAPI.setAnimatedNodeValue(this.__getNativeTag(), value);
139-
});
137+
_executeAsAnimatedBatch(this.__getNativeTag().toString(), () =>
138+
NativeAnimatedAPI.setAnimatedNodeValue(this.__getNativeTag(), value),
139+
);
140140
}
141141
}
142142

0 commit comments

Comments
 (0)