Skip to content

Commit

Permalink
Add optional configs to constructors for AnimatedValue/ValueXY/Color
Browse files Browse the repository at this point in the history
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
  • Loading branch information
genkikondo authored and facebook-github-bot committed May 20, 2022
1 parent 841793a commit 73191ed
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 8 deletions.
17 changes: 10 additions & 7 deletions Libraries/Animated/nodes/AnimatedColor.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ import type {ColorValue} from '../../StyleSheet/StyleSheet';
import type {NativeColorValue} from '../../StyleSheet/PlatformColorValueTypes';
import type {ProcessedColorValue} from '../../StyleSheet/processColor';

export type AnimatedColorConfig = $ReadOnly<{
useNativeDriver: boolean,
}>;
type ColorListenerCallback = (value: string) => mixed;
export type RgbaValue = {
+r: number,
Expand Down Expand Up @@ -116,7 +119,10 @@ export default class AnimatedColor extends AnimatedWithChildren {
...
} = {};

constructor(valueIn?: ?(RgbaValue | RgbaAnimatedValue | ColorValue)) {
constructor(
valueIn?: ?(RgbaValue | RgbaAnimatedValue | ColorValue),
config?: ?AnimatedColorConfig,
) {
super();
let value: RgbaValue | RgbaAnimatedValue | ColorValue =
valueIn ?? defaultColor;
Expand Down Expand Up @@ -144,12 +150,9 @@ export default class AnimatedColor extends AnimatedWithChildren {
this.g = new AnimatedValue(initColor.g);
this.b = new AnimatedValue(initColor.b);
this.a = new AnimatedValue(initColor.a);

if (this.nativeColor) {
if (!this.__isNative) {
this.__makeNative();
}
}
}
if (this.nativeColor || (config && config.useNativeDriver)) {
this.__makeNative();
}
}

Expand Down
9 changes: 8 additions & 1 deletion Libraries/Animated/nodes/AnimatedValue.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ import type Animation, {EndCallback} from '../animations/Animation';
import type {InterpolationConfigType} from './AnimatedInterpolation';
import type AnimatedTracking from './AnimatedTracking';

export type AnimatedValueConfig = $ReadOnly<{
useNativeDriver: boolean,
}>;

const NativeAnimatedAPI = NativeAnimatedHelper.API;

/**
Expand Down Expand Up @@ -87,14 +91,17 @@ class AnimatedValue extends AnimatedWithChildren {
_animation: ?Animation;
_tracking: ?AnimatedTracking;

constructor(value: number) {
constructor(value: number, config?: ?AnimatedValueConfig) {
super();
if (typeof value !== 'number') {
throw new Error('AnimatedValue: Attempting to set value to undefined');
}
this._startingValue = this._value = value;
this._offset = 0;
this._animation = null;
if (config && config.useNativeDriver) {
this.__makeNative();
}
}

__detach() {
Expand Down
27 changes: 27 additions & 0 deletions Libraries/Animated/nodes/AnimatedValueXY.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,16 @@

'use strict';

import type {PlatformConfig} from '../AnimatedPlatformConfig';

const AnimatedValue = require('./AnimatedValue');
const AnimatedWithChildren = require('./AnimatedWithChildren');

const invariant = require('invariant');

export type AnimatedValueXYConfig = $ReadOnly<{
useNativeDriver: boolean,
}>;
type ValueXYListenerCallback = (value: {
x: number,
y: number,
Expand Down Expand Up @@ -47,6 +52,7 @@ class AnimatedValueXY extends AnimatedWithChildren {
+y: number | AnimatedValue,
...
},
config?: ?AnimatedValueXYConfig,
) {
super();
const value: any = valueIn || {x: 0, y: 0}; // @flowfixme: shouldn't need `: any`
Expand All @@ -63,6 +69,9 @@ class AnimatedValueXY extends AnimatedWithChildren {
this.y = value.y;
}
this._listeners = {};
if (config && config.useNativeDriver) {
this.__makeNative();
}
}

/**
Expand Down Expand Up @@ -221,6 +230,24 @@ class AnimatedValueXY extends AnimatedWithChildren {
getTranslateTransform(): Array<{[key: string]: AnimatedValue, ...}> {
return [{translateX: this.x}, {translateY: this.y}];
}

__attach(): void {
this.x.__addChild(this);
this.y.__addChild(this);
super.__attach();
}

__detach(): void {
this.x.__removeChild(this);
this.y.__removeChild(this);
super.__detach();
}

__makeNative(platformConfig: ?PlatformConfig) {
this.x.__makeNative(platformConfig);
this.y.__makeNative(platformConfig);
super.__makeNative(platformConfig);
}
}

module.exports = AnimatedValueXY;

0 comments on commit 73191ed

Please sign in to comment.