fallback to JS Animation if native animated is not present

Summary: This should be a temporary migration path until we enable native animated everywhere, instead of crashing the app if the module is missing. This would present a yellow box with an instruction to add RCTAnimation module to the app

Reviewed By: yungsters

Differential Revision: D4112938

fbshipit-source-id: 56db7801063e9de16a3ff251bf1f0e4f6e3ea7c0
This commit is contained in:
Kevin Gozali 2016-11-01 23:55:21 -07:00 committed by Facebook Github Bot
parent 4082a54649
commit 3237ade34f
2 changed files with 35 additions and 10 deletions

View File

@ -14,11 +14,11 @@
var InteractionManager = require('InteractionManager');
var Interpolation = require('Interpolation');
var NativeAnimatedHelper = require('NativeAnimatedHelper');
var React = require('React');
var Set = require('Set');
var SpringConfig = require('SpringConfig');
var ViewStylePropTypes = require('ViewStylePropTypes');
var NativeAnimatedHelper = require('NativeAnimatedHelper');
var findNodeHandle = require('react/lib/findNodeHandle');
var flattenStyle = require('flattenStyle');
@ -32,6 +32,26 @@ type EndCallback = (result: EndResult) => void;
var NativeAnimatedAPI = NativeAnimatedHelper.API;
var warnedMissingNativeAnimated = false;
function shouldUseNativeDriver(config: AnimationConfig | EventConfig): boolean {
if (config.useNativeDriver &&
!NativeAnimatedHelper.isNativeAnimatedAvailable()) {
if (!warnedMissingNativeAnimated) {
console.warn(
'Animated: `useNativeDriver` is not supported because the native ' +
'animated module is missing. Falling back to JS-based animation. To ' +
'resolve this, add `RCTAnimation` module to this app, or remove ' +
'`useNativeDriver`.'
);
warnedMissingNativeAnimated = true;
}
return false;
}
return config.useNativeDriver || false;
}
// Note(vjeux): this would be better as an interface but flow doesn't
// support them yet
class Animated {
@ -251,7 +271,7 @@ class TimingAnimation extends Animation {
this._duration = config.duration !== undefined ? config.duration : 500;
this._delay = config.delay !== undefined ? config.delay : 0;
this.__isInteraction = config.isInteraction !== undefined ? config.isInteraction : true;
this._useNativeDriver = config.useNativeDriver !== undefined ? config.useNativeDriver : false;
this._useNativeDriver = shouldUseNativeDriver(config);
}
__getNativeAnimationConfig(): any {
@ -360,7 +380,7 @@ class DecayAnimation extends Animation {
super();
this._deceleration = config.deceleration !== undefined ? config.deceleration : 0.998;
this._velocity = config.velocity;
this._useNativeDriver = config.useNativeDriver !== undefined ? config.useNativeDriver : false;
this._useNativeDriver = shouldUseNativeDriver(config);
this.__isInteraction = config.isInteraction !== undefined ? config.isInteraction : true;
}
@ -479,7 +499,7 @@ class SpringAnimation extends Animation {
this._initialVelocity = config.velocity;
this._lastVelocity = withDefault(config.velocity, 0);
this._toValue = config.toValue;
this._useNativeDriver = config.useNativeDriver !== undefined ? config.useNativeDriver : false;
this._useNativeDriver = shouldUseNativeDriver(config);
this.__isInteraction = config.isInteraction !== undefined ? config.isInteraction : true;
var springConfig;
@ -2105,8 +2125,8 @@ var stagger = function(
type Mapping = {[key: string]: Mapping} | AnimatedValue;
type EventConfig = {
listener?: ?Function;
useNativeDriver?: bool;
listener?: ?Function,
useNativeDriver?: bool,
};
class AnimatedEvent {
@ -2120,7 +2140,7 @@ class AnimatedEvent {
) {
this._argMapping = argMapping;
this._listener = config.listener;
this.__isNative = config.useNativeDriver || false;
this.__isNative = shouldUseNativeDriver(config);
if (this.__isNative) {
invariant(!this._listener, 'Listener is not supported for native driven events.');

View File

@ -19,11 +19,11 @@ const invariant = require('fbjs/lib/invariant');
let __nativeAnimatedNodeTagCount = 1; /* used for animated nodes */
let __nativeAnimationIdCount = 1; /* used for started animations */
type EndResult = {finished: bool};
type EndResult = {finished: boolean};
type EndCallback = (result: EndResult) => void;
type EventMapping = {
nativeEventPath: Array<string>;
animatedValueTag: number;
nativeEventPath: Array<string>,
animatedValueTag: number,
};
let nativeEventEmitter;
@ -178,6 +178,10 @@ function assertNativeAnimatedModule(): void {
invariant(NativeAnimatedModule, 'Native animated module is not available');
}
function isNativeAnimatedAvailable(): boolean {
return !!NativeAnimatedModule;
}
module.exports = {
API,
validateProps,
@ -187,6 +191,7 @@ module.exports = {
generateNewNodeTag,
generateNewAnimationId,
assertNativeAnimatedModule,
isNativeAnimatedAvailable,
get nativeEventEmitter() {
if (!nativeEventEmitter) {
nativeEventEmitter = new NativeEventEmitter(NativeAnimatedModule);