Skip to content

Commit 73191ed

Browse files
genkikondofacebook-github-bot
authored andcommitted
Add optional configs to constructors for AnimatedValue/ValueXY/Color
Summary: There are use cases of needing to setValue multiple times per second (for example, using PanResponder to update a slider component). This requires the use of the native driver for perf reasons as using the JS driver will cause a rerender. Currently, the only way to make an animated node native is via setting useNativeDriver: true on an animation config. For example: ``` Animated.timing(animatedValue, { toValue: newValue, duration: 0, useNativeDriver: true }).start(); ``` To avoid needing to call the above, add a useNativeDriver param to the constructor. When set to true, the node will be made native immediately. ``` const animatedValue = new Animated.Value(0, useNativeDriver); ... animatedValue.setValue(newValue); ``` Note that, like with useNativeDriver in the animation config, once a node is made native, it cannot be reverted to JS-only. --- As an aside, PanResponder uses JS-side events, and thus we cannot use Animated.event with native driver; we instead need to setValue on a native AnimatedValue. A much more thorough explanation is in D34564598. --- Changelog: [General][Added] - [Animated] Add useNativeDriver as a param for setValue Reviewed By: JoshuaGross Differential Revision: D36459457 fbshipit-source-id: 284148a6d16537429efeab8b07184019990909cd
1 parent 841793a commit 73191ed

File tree

3 files changed

+45
-8
lines changed

3 files changed

+45
-8
lines changed

Libraries/Animated/nodes/AnimatedColor.js

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ import type {ColorValue} from '../../StyleSheet/StyleSheet';
2121
import type {NativeColorValue} from '../../StyleSheet/PlatformColorValueTypes';
2222
import type {ProcessedColorValue} from '../../StyleSheet/processColor';
2323

24+
export type AnimatedColorConfig = $ReadOnly<{
25+
useNativeDriver: boolean,
26+
}>;
2427
type ColorListenerCallback = (value: string) => mixed;
2528
export type RgbaValue = {
2629
+r: number,
@@ -116,7 +119,10 @@ export default class AnimatedColor extends AnimatedWithChildren {
116119
...
117120
} = {};
118121

119-
constructor(valueIn?: ?(RgbaValue | RgbaAnimatedValue | ColorValue)) {
122+
constructor(
123+
valueIn?: ?(RgbaValue | RgbaAnimatedValue | ColorValue),
124+
config?: ?AnimatedColorConfig,
125+
) {
120126
super();
121127
let value: RgbaValue | RgbaAnimatedValue | ColorValue =
122128
valueIn ?? defaultColor;
@@ -144,12 +150,9 @@ export default class AnimatedColor extends AnimatedWithChildren {
144150
this.g = new AnimatedValue(initColor.g);
145151
this.b = new AnimatedValue(initColor.b);
146152
this.a = new AnimatedValue(initColor.a);
147-
148-
if (this.nativeColor) {
149-
if (!this.__isNative) {
150-
this.__makeNative();
151-
}
152-
}
153+
}
154+
if (this.nativeColor || (config && config.useNativeDriver)) {
155+
this.__makeNative();
153156
}
154157
}
155158

Libraries/Animated/nodes/AnimatedValue.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ import type Animation, {EndCallback} from '../animations/Animation';
2020
import type {InterpolationConfigType} from './AnimatedInterpolation';
2121
import type AnimatedTracking from './AnimatedTracking';
2222

23+
export type AnimatedValueConfig = $ReadOnly<{
24+
useNativeDriver: boolean,
25+
}>;
26+
2327
const NativeAnimatedAPI = NativeAnimatedHelper.API;
2428

2529
/**
@@ -87,14 +91,17 @@ class AnimatedValue extends AnimatedWithChildren {
8791
_animation: ?Animation;
8892
_tracking: ?AnimatedTracking;
8993

90-
constructor(value: number) {
94+
constructor(value: number, config?: ?AnimatedValueConfig) {
9195
super();
9296
if (typeof value !== 'number') {
9397
throw new Error('AnimatedValue: Attempting to set value to undefined');
9498
}
9599
this._startingValue = this._value = value;
96100
this._offset = 0;
97101
this._animation = null;
102+
if (config && config.useNativeDriver) {
103+
this.__makeNative();
104+
}
98105
}
99106

100107
__detach() {

Libraries/Animated/nodes/AnimatedValueXY.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,16 @@
1010

1111
'use strict';
1212

13+
import type {PlatformConfig} from '../AnimatedPlatformConfig';
14+
1315
const AnimatedValue = require('./AnimatedValue');
1416
const AnimatedWithChildren = require('./AnimatedWithChildren');
1517

1618
const invariant = require('invariant');
1719

20+
export type AnimatedValueXYConfig = $ReadOnly<{
21+
useNativeDriver: boolean,
22+
}>;
1823
type ValueXYListenerCallback = (value: {
1924
x: number,
2025
y: number,
@@ -47,6 +52,7 @@ class AnimatedValueXY extends AnimatedWithChildren {
4752
+y: number | AnimatedValue,
4853
...
4954
},
55+
config?: ?AnimatedValueXYConfig,
5056
) {
5157
super();
5258
const value: any = valueIn || {x: 0, y: 0}; // @flowfixme: shouldn't need `: any`
@@ -63,6 +69,9 @@ class AnimatedValueXY extends AnimatedWithChildren {
6369
this.y = value.y;
6470
}
6571
this._listeners = {};
72+
if (config && config.useNativeDriver) {
73+
this.__makeNative();
74+
}
6675
}
6776

6877
/**
@@ -221,6 +230,24 @@ class AnimatedValueXY extends AnimatedWithChildren {
221230
getTranslateTransform(): Array<{[key: string]: AnimatedValue, ...}> {
222231
return [{translateX: this.x}, {translateY: this.y}];
223232
}
233+
234+
__attach(): void {
235+
this.x.__addChild(this);
236+
this.y.__addChild(this);
237+
super.__attach();
238+
}
239+
240+
__detach(): void {
241+
this.x.__removeChild(this);
242+
this.y.__removeChild(this);
243+
super.__detach();
244+
}
245+
246+
__makeNative(platformConfig: ?PlatformConfig) {
247+
this.x.__makeNative(platformConfig);
248+
this.y.__makeNative(platformConfig);
249+
super.__makeNative(platformConfig);
250+
}
224251
}
225252

226253
module.exports = AnimatedValueXY;

0 commit comments

Comments
 (0)