Skip to content

Commit

Permalink
Add platformConfig to native animations and nodes (#32736)
Browse files Browse the repository at this point in the history
Summary:
Pull Request resolved: #32736

The ability to pass an additional property bag to further configure NativeAnimated is useful for a few reasons, e.g., experimentation with multiple implementations of the NativeAnimated module.

The specific use case this solves is on react-native-windows, where there are two underlying animation graph options, one "optimized" animation graph that uses UI.Composition, and another similar to the approach to iOS and Android that uses a frame rendering callback.

The platform configuration can be supplied to the animation node when `useNativeDriver` is set to `true`, and we pass the platform configuration object to the connected AnimatedValue and all it's children.

Changelog:
[General][Added] - Option to supply `platformConfig` to NativeAnimated

Reviewed By: yungsters

Differential Revision: D32988285

fbshipit-source-id: ab8a7bbf197573fc9e9a4737c255f124321295ac
  • Loading branch information
rozele authored and facebook-github-bot committed Jan 20, 2022
1 parent 5fa3807 commit 4a227ce
Show file tree
Hide file tree
Showing 19 changed files with 124 additions and 53 deletions.
9 changes: 8 additions & 1 deletion Libraries/Animated/AnimatedEvent.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,31 @@ const invariant = require('invariant');

const {shouldUseNativeDriver} = require('./NativeAnimatedHelper');

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

export type Mapping =
| {[key: string]: Mapping, ...}
| AnimatedValue
| AnimatedValueXY;
export type EventConfig = {
listener?: ?Function,
useNativeDriver: boolean,
platformConfig?: PlatformConfig,
};

function attachNativeEvent(
viewRef: any,
eventName: string,
argMapping: $ReadOnlyArray<?Mapping>,
platformConfig: ?PlatformConfig,
): {detach: () => void} {
// Find animated values in `argMapping` and create an array representing their
// key path inside the `nativeEvent` object. Ex.: ['contentOffset', 'x'].
const eventMappings = [];

const traverse = (value, path) => {
if (value instanceof AnimatedValue) {
value.__makeNative();
value.__makeNative(platformConfig);

eventMappings.push({
nativeEventPath: path,
Expand Down Expand Up @@ -147,6 +151,7 @@ class AnimatedEvent {
_listeners: Array<Function> = [];
_attachedEvent: ?{detach: () => void, ...};
__isNative: boolean;
__platformConfig: ?PlatformConfig;

constructor(argMapping: $ReadOnlyArray<?Mapping>, config: EventConfig) {
this._argMapping = argMapping;
Expand All @@ -161,6 +166,7 @@ class AnimatedEvent {
}
this._attachedEvent = null;
this.__isNative = shouldUseNativeDriver(config);
this.__platformConfig = config.platformConfig;
}

__addListener(callback: Function): void {
Expand All @@ -181,6 +187,7 @@ class AnimatedEvent {
viewRef,
eventName,
this._argMapping,
this.__platformConfig,
);
}

Expand Down
13 changes: 13 additions & 0 deletions Libraries/Animated/AnimatedPlatformConfig.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
* @format
*/

'use strict';

export type PlatformConfig = {};
8 changes: 5 additions & 3 deletions Libraries/Animated/animations/Animation.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
'use strict';

const NativeAnimatedHelper = require('../NativeAnimatedHelper');

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

export type EndResult = {finished: boolean, ...};
Expand All @@ -20,6 +20,7 @@ export type EndCallback = (result: EndResult) => void;
export type AnimationConfig = {
isInteraction?: boolean,
useNativeDriver: boolean,
platformConfig?: PlatformConfig,
onComplete?: ?EndCallback,
iterations?: number,
};
Expand Down Expand Up @@ -65,12 +66,13 @@ class Animation {
startNativeAnimationWaitId,
);
try {
animatedValue.__makeNative();
const config = this.__getNativeAnimationConfig();
animatedValue.__makeNative(config.platformConfig);
this.__nativeId = NativeAnimatedHelper.generateNewAnimationId();
NativeAnimatedHelper.API.startAnimatingNode(
this.__nativeId,
animatedValue.__getNativeTag(),
this.__getNativeAnimationConfig(),
config,
// $FlowFixMe[method-unbinding] added when improving typing for this parameters
this.__debouncedOnEnd.bind(this),
);
Expand Down
5 changes: 5 additions & 0 deletions Libraries/Animated/animations/DecayAnimation.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const Animation = require('./Animation');

const {shouldUseNativeDriver} = require('../NativeAnimatedHelper');

import type {PlatformConfig} from '../AnimatedPlatformConfig';
import type AnimatedValue from '../nodes/AnimatedValue';
import type {AnimationConfig, EndCallback} from './Animation';

Expand Down Expand Up @@ -44,19 +45,22 @@ class DecayAnimation extends Animation {
_onUpdate: (value: number) => void;
_animationFrame: any;
_useNativeDriver: boolean;
_platformConfig: ?PlatformConfig;

constructor(config: DecayAnimationConfigSingle) {
super();
this._deceleration = config.deceleration ?? 0.998;
this._velocity = config.velocity;
this._useNativeDriver = shouldUseNativeDriver(config);
this._platformConfig = config.platformConfig;
this.__isInteraction = config.isInteraction ?? !this._useNativeDriver;
this.__iterations = config.iterations ?? 1;
}

__getNativeAnimationConfig(): {|
deceleration: number,
iterations: number,
platformConfig: ?PlatformConfig,
type: $TEMPORARY$string<'decay'>,
velocity: number,
|} {
Expand All @@ -65,6 +69,7 @@ class DecayAnimation extends Animation {
deceleration: this._deceleration,
velocity: this._velocity,
iterations: this.__iterations,
platformConfig: this._platformConfig,
};
}

Expand Down
5 changes: 5 additions & 0 deletions Libraries/Animated/animations/SpringAnimation.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const invariant = require('invariant');

const {shouldUseNativeDriver} = require('../NativeAnimatedHelper');

import type {PlatformConfig} from '../AnimatedPlatformConfig';
import type {AnimationConfig, EndCallback} from './Animation';

export type SpringAnimationConfig = {
Expand Down Expand Up @@ -92,6 +93,7 @@ class SpringAnimation extends Animation {
_onUpdate: (value: number) => void;
_animationFrame: any;
_useNativeDriver: boolean;
_platformConfig: ?PlatformConfig;

constructor(config: SpringAnimationConfigSingle) {
super();
Expand All @@ -104,6 +106,7 @@ class SpringAnimation extends Animation {
this._toValue = config.toValue;
this._delay = config.delay ?? 0;
this._useNativeDriver = shouldUseNativeDriver(config);
this._platformConfig = config.platformConfig;
this.__isInteraction = config.isInteraction ?? !this._useNativeDriver;
this.__iterations = config.iterations ?? 1;

Expand Down Expand Up @@ -162,6 +165,7 @@ class SpringAnimation extends Animation {
initialVelocity: number,
iterations: number,
mass: number,
platformConfig: ?PlatformConfig,
overshootClamping: boolean,
restDisplacementThreshold: number,
restSpeedThreshold: number,
Expand All @@ -180,6 +184,7 @@ class SpringAnimation extends Animation {
initialVelocity: this._initialVelocity ?? this._lastVelocity,
toValue: this._toValue,
iterations: this.__iterations,
platformConfig: this._platformConfig,
};
}

Expand Down
4 changes: 4 additions & 0 deletions Libraries/Animated/animations/TimingAnimation.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const Animation = require('./Animation');

const {shouldUseNativeDriver} = require('../NativeAnimatedHelper');

import type {PlatformConfig} from '../AnimatedPlatformConfig';
import type {AnimationConfig, EndCallback} from './Animation';

export type TimingAnimationConfig = {
Expand Down Expand Up @@ -65,6 +66,7 @@ class TimingAnimation extends Animation {
_animationFrame: any;
_timeout: any;
_useNativeDriver: boolean;
_platformConfig: ?PlatformConfig;

constructor(config: TimingAnimationConfigSingle) {
super();
Expand All @@ -74,6 +76,7 @@ class TimingAnimation extends Animation {
this._delay = config.delay ?? 0;
this.__iterations = config.iterations ?? 1;
this._useNativeDriver = shouldUseNativeDriver(config);
this._platformConfig = config.platformConfig;
this.__isInteraction = config.isInteraction ?? !this._useNativeDriver;
}

Expand All @@ -90,6 +93,7 @@ class TimingAnimation extends Animation {
frames,
toValue: this._toValue,
iterations: this.__iterations,
platformConfig: this._platformConfig,
};
}

Expand Down
9 changes: 5 additions & 4 deletions Libraries/Animated/nodes/AnimatedAddition.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const AnimatedNode = require('./AnimatedNode');
const AnimatedValue = require('./AnimatedValue');
const AnimatedWithChildren = require('./AnimatedWithChildren');

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

class AnimatedAddition extends AnimatedWithChildren {
Expand All @@ -27,10 +28,10 @@ class AnimatedAddition extends AnimatedWithChildren {
this._b = typeof b === 'number' ? new AnimatedValue(b) : b;
}

__makeNative() {
this._a.__makeNative();
this._b.__makeNative();
super.__makeNative();
__makeNative(platformConfig: ?PlatformConfig) {
this._a.__makeNative(platformConfig);
this._b.__makeNative(platformConfig);
super.__makeNative(platformConfig);
}

__getValue(): number {
Expand Down
7 changes: 4 additions & 3 deletions Libraries/Animated/nodes/AnimatedDiffClamp.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const AnimatedNode = require('./AnimatedNode');
const AnimatedWithChildren = require('./AnimatedWithChildren');

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

class AnimatedDiffClamp extends AnimatedWithChildren {
_a: AnimatedNode;
Expand All @@ -32,9 +33,9 @@ class AnimatedDiffClamp extends AnimatedWithChildren {
this._value = this._lastValue = this._a.__getValue();
}

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

interpolate(config: InterpolationConfigType): AnimatedInterpolation {
Expand Down
9 changes: 5 additions & 4 deletions Libraries/Animated/nodes/AnimatedDivision.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const AnimatedValue = require('./AnimatedValue');
const AnimatedWithChildren = require('./AnimatedWithChildren');

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

class AnimatedDivision extends AnimatedWithChildren {
_a: AnimatedNode;
Expand All @@ -31,10 +32,10 @@ class AnimatedDivision extends AnimatedWithChildren {
this._b = typeof b === 'number' ? new AnimatedValue(b) : b;
}

__makeNative() {
this._a.__makeNative();
this._b.__makeNative();
super.__makeNative();
__makeNative(platformConfig: ?PlatformConfig) {
this._a.__makeNative(platformConfig);
this._b.__makeNative(platformConfig);
super.__makeNative(platformConfig);
}

__getValue(): number {
Expand Down
8 changes: 5 additions & 3 deletions Libraries/Animated/nodes/AnimatedInterpolation.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ const NativeAnimatedHelper = require('../NativeAnimatedHelper');
const invariant = require('invariant');
const normalizeColor = require('../../StyleSheet/normalizeColor');

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

type ExtrapolateType = 'extend' | 'identity' | 'clamp';

export type InterpolationConfigType = {
Expand Down Expand Up @@ -317,9 +319,9 @@ class AnimatedInterpolation extends AnimatedWithChildren {
this._interpolation = createInterpolation(config);
}

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

__getValue(): number | string {
Expand Down
7 changes: 4 additions & 3 deletions Libraries/Animated/nodes/AnimatedModulo.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const AnimatedNode = require('./AnimatedNode');
const AnimatedWithChildren = require('./AnimatedWithChildren');

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

class AnimatedModulo extends AnimatedWithChildren {
_a: AnimatedNode;
Expand All @@ -26,9 +27,9 @@ class AnimatedModulo extends AnimatedWithChildren {
this._modulus = modulus;
}

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

__getValue(): number {
Expand Down
9 changes: 5 additions & 4 deletions Libraries/Animated/nodes/AnimatedMultiplication.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const AnimatedValue = require('./AnimatedValue');
const AnimatedWithChildren = require('./AnimatedWithChildren');

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

class AnimatedMultiplication extends AnimatedWithChildren {
_a: AnimatedNode;
Expand All @@ -27,10 +28,10 @@ class AnimatedMultiplication extends AnimatedWithChildren {
this._b = typeof b === 'number' ? new AnimatedValue(b) : b;
}

__makeNative() {
this._a.__makeNative();
this._b.__makeNative();
super.__makeNative();
__makeNative(platformConfig: ?PlatformConfig) {
this._a.__makeNative(platformConfig);
this._b.__makeNative(platformConfig);
super.__makeNative(platformConfig);
}

__getValue(): number {
Expand Down
Loading

0 comments on commit 4a227ce

Please sign in to comment.