mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Summary:This change adds native animated support for Animated.interpolate Animated.interpolate allows for defining nodes that outputs an interpolated value of their input node based on the interpolation node configuration. For now native animated implementation only supports a linear interpolation for a given input and output ranges (ranges can consists of multiple segments). Native interpolation node is compatible with the JS implementation with the exception that not all attributes that can be used in JS are supported. Before we migrate interpolation node from JS->native we verify that only supported props are used. **Test Plan** Run JS tests: `npm test Libraries/Animated/src/__tests__/AnimatedNative-test.js` Run java tests: `buck test ReactAndroid/src/test/java/com/facebook/react/animated` Closes https://github.com/facebook/react-native/pull/7141 Differential Revision: D3216546 fb-gh-sync-id: 29876e33956615c6370ca4d332abe048f8dba5b8 fbshipit-source-id: 29876e33956615c6370ca4d332abe048f8dba5b8
137 lines
4.3 KiB
JavaScript
137 lines
4.3 KiB
JavaScript
/**
|
|
* Copyright (c) 2015-present, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule NativeAnimatedHelper
|
|
* @flow
|
|
*/
|
|
'use strict';
|
|
|
|
var NativeAnimatedModule = require('NativeModules').NativeAnimatedModule;
|
|
|
|
var invariant = require('fbjs/lib/invariant');
|
|
|
|
var __nativeAnimatedNodeTagCount = 1; /* used for animated nodes */
|
|
var __nativeAnimationIdCount = 1; /* used for started animations */
|
|
|
|
type EndResult = {finished: bool};
|
|
type EndCallback = (result: EndResult) => void;
|
|
|
|
/**
|
|
* Simple wrappers around NativeANimatedModule to provide flow and autocmplete support for
|
|
* the native module methods
|
|
*/
|
|
var API = {
|
|
createAnimatedNode: function(tag: number, config: Object): void {
|
|
assertNativeAnimatedModule();
|
|
NativeAnimatedModule.createAnimatedNode(tag, config);
|
|
},
|
|
connectAnimatedNodes: function(parentTag: number, childTag: number): void {
|
|
assertNativeAnimatedModule();
|
|
NativeAnimatedModule.connectAnimatedNodes(parentTag, childTag);
|
|
},
|
|
disconnectAnimatedNodes: function(parentTag: number, childTag: number): void {
|
|
assertNativeAnimatedModule();
|
|
NativeAnimatedModule.disconnectAnimatedNodes(parentTag, childTag);
|
|
},
|
|
startAnimatingNode: function(animationId: number, nodeTag: number, config: Object, endCallback: EndCallback): void {
|
|
assertNativeAnimatedModule();
|
|
NativeAnimatedModule.startAnimatingNode(animationId, nodeTag, config, endCallback);
|
|
},
|
|
stopAnimation: function(animationId: number) {
|
|
assertNativeAnimatedModule();
|
|
NativeAnimatedModule.stopAnimation(animationId);
|
|
},
|
|
setAnimatedNodeValue: function(nodeTag: number, value: number): void {
|
|
assertNativeAnimatedModule();
|
|
NativeAnimatedModule.setAnimatedNodeValue(nodeTag, value);
|
|
},
|
|
connectAnimatedNodeToView: function(nodeTag: number, viewTag: number): void {
|
|
assertNativeAnimatedModule();
|
|
NativeAnimatedModule.connectAnimatedNodeToView(nodeTag, viewTag);
|
|
},
|
|
disconnectAnimatedNodeFromView: function(nodeTag: number, viewTag: number): void {
|
|
assertNativeAnimatedModule();
|
|
NativeAnimatedModule.disconnectAnimatedNodeFromView(nodeTag, viewTag);
|
|
},
|
|
dropAnimatedNode: function(tag: number): void {
|
|
assertNativeAnimatedModule();
|
|
NativeAnimatedModule.dropAnimatedNode(tag);
|
|
},
|
|
};
|
|
|
|
/**
|
|
* Properties allowed by the native animated implementation.
|
|
*
|
|
* In general native animated implementation should support any numeric property that doesn't need
|
|
* to be updated through the shadow view hierarchy (all non-layout properties). This list is limited
|
|
* to the properties that will perform best when animated off the JS thread.
|
|
*/
|
|
var PROPS_WHITELIST = {
|
|
style: {
|
|
opacity: true,
|
|
|
|
/* legacy android transform properties */
|
|
scaleX: true,
|
|
scaleY: true,
|
|
rotation: true,
|
|
translateX: true,
|
|
translateY: true,
|
|
},
|
|
};
|
|
|
|
function validateProps(params: Object): void {
|
|
for (var key in params) {
|
|
if (!PROPS_WHITELIST.hasOwnProperty(key)) {
|
|
throw new Error(`Property '${key}' is not supported by native animated module`);
|
|
}
|
|
}
|
|
}
|
|
|
|
function validateStyles(styles: Object): void {
|
|
var STYLES_WHITELIST = PROPS_WHITELIST.style || {};
|
|
for (var key in styles) {
|
|
if (!STYLES_WHITELIST.hasOwnProperty(key)) {
|
|
throw new Error(`Style property '${key}' is not supported by native animated module`);
|
|
}
|
|
}
|
|
}
|
|
|
|
function validateInterpolation(config: Object): void {
|
|
var SUPPORTED_INTERPOLATION_PARAMS = {
|
|
inputRange: true,
|
|
outputRange: true,
|
|
};
|
|
for (var key in config) {
|
|
if (!SUPPORTED_INTERPOLATION_PARAMS.hasOwnProperty(key)) {
|
|
throw new Error(`Interpolation property '${key}' is not supported by native animated module`);
|
|
}
|
|
}
|
|
}
|
|
|
|
function generateNewNodeTag(): number {
|
|
return __nativeAnimatedNodeTagCount++;
|
|
}
|
|
|
|
function generateNewAnimationId(): number {
|
|
return __nativeAnimationIdCount++;
|
|
}
|
|
|
|
function assertNativeAnimatedModule(): void {
|
|
invariant(NativeAnimatedModule, 'Native animated module is not available');
|
|
}
|
|
|
|
module.exports = {
|
|
API,
|
|
validateProps,
|
|
validateStyles,
|
|
validateInterpolation,
|
|
generateNewNodeTag,
|
|
generateNewAnimationId,
|
|
assertNativeAnimatedModule,
|
|
};
|