Maintain transform order

Summary:
This diff addresses the issues raised by kmagiera in https://github.com/facebook/react-native/pull/7884. Transforms should be applied in the order they are defined, just like in `processTransform.js`. A scale applied before a translation, for instance, should give a different result than a translation applied before a scale.

We leverage CATransform3D to do the heavy lifting. A concatenated transform is passed all the way to `RCTViewPropertyMapper`. It is compared with the transform currently applied to the view, and if different, applied. The same approach is used for opacity.

I think it makes the most sense to do this diffing in `RCTViewPropertyMapper`, as opposed to creating and cleaning up an `_updatedPropsDictionary` each frame in `RCTTransformAnimatedNode` and `RCTStyleAnimatedNode`. The node should keep its full value; applying a minimal set of altered props is an optimization.  The higher up this optimization is implemented, the more assumptions it makes. e.g. that there will only ever be a sing
Closes https://github.com/facebook/react-native/pull/9050

Differential Revision: D3658139

fbshipit-source-id: ad6286762ef734084cbdf83c9bd9241190302d34
This commit is contained in:
Ryan Gomba
2016-08-02 14:23:18 -07:00
committed by Facebook Github Bot
parent b83ccb5749
commit eb96b7fabc
8 changed files with 81 additions and 70 deletions

View File

@@ -1160,21 +1160,24 @@ class AnimatedTransform extends AnimatedWithChildren {
}
__getNativeConfig(): any {
var transConfig = {};
var transConfigs = [];
this._transforms.forEach(transform => {
for (var key in transform) {
var value = transform[key];
if (value instanceof Animated) {
transConfig[key] = value.__getNativeTag();
transConfigs.push({
property: key,
nodeTag: value.__getNativeTag(),
});
}
}
});
NativeAnimatedHelper.validateTransform(transConfig);
NativeAnimatedHelper.validateTransform(transConfigs);
return {
type: 'transform',
transform: transConfig,
transforms: transConfigs,
};
}
}

View File

@@ -87,7 +87,12 @@ var TRANSFORM_WHITELIST = {
translateX: true,
translateY: true,
scale: true,
scaleX: true,
scaleY: true,
rotate: true,
rotateX: true,
rotateY: true,
perspective: true,
};
function validateProps(params: Object): void {
@@ -98,12 +103,12 @@ function validateProps(params: Object): void {
}
}
function validateTransform(config: Object): void {
for (var key in config) {
if (!TRANSFORM_WHITELIST.hasOwnProperty(key)) {
throw new Error(`Property '${key}' is not supported by native animated module`);
function validateTransform(configs: Array<Object>): void {
configs.forEach((config) => {
if (!TRANSFORM_WHITELIST.hasOwnProperty(config.property)) {
throw new Error(`Property '${config.property}' is not supported by native animated module`);
}
}
});
}
function validateStyles(styles: Object): void {