Animated.multiply and Animated.add to combine animated values

Summary:
This PR was created in response to feedback from an older PR: https://github.com/facebook/react-native/pull/2045

The `.interpolate()` API of Animated values is quite effective to accomplish transformations based on a single animated value, but currently there is a class of animations that is impossible: animations being driven by more than one value.

Usage would be like the following:

```js
getInitialState: function() {
  return {
    panY: new Animated.Value(0),
    offset: new Animated.Value(0),
  };
}
```

```js
var scale = Animated.add(panY, offset).interpolate({
  inputRange: [...],
  outputRange: [...],
});
```

I have a real use case for this, and I cannot think of any way to accomplish what I need without an API like this.

The animation I am trying to accomplish is I have a PanResponder being used to detect both x and y panning. The y-axis panning drives a 3d sroll-like animation (which we can call `panY`), and the x-axis panning is driving a "swipe-to-remove" animation (
Closes https://github.com/facebook/react-native/pull/4395

Reviewed By: svcscm

Differential Revision: D2731305

Pulled By: vjeux

fb-gh-sync-id: 3b9422f10c7e7f3b3ecd270aeed8ea92315a89e9
This commit is contained in:
Leland Richardson 2015-12-10 13:27:52 -08:00 committed by facebook-github-bot-4
parent 3cfcd401c1
commit 3eb32cbb0e
1 changed files with 83 additions and 0 deletions

View File

@ -840,6 +840,64 @@ class AnimatedInterpolation extends AnimatedWithChildren {
} }
} }
class AnimatedAddition extends AnimatedWithChildren {
_a: Animated;
_b: Animated;
constructor(a: Animated, b: Animated) {
super();
this._a = a;
this._b = b;
}
__getValue(): number {
return this._a.__getValue() + this._b.__getValue();
}
interpolate(config: InterpolationConfigType): AnimatedInterpolation {
return new AnimatedInterpolation(this, Interpolation.create(config));
}
__attach(): void {
this._a.__addChild(this);
this._b.__addChild(this);
}
__detach(): void {
this._a.__removeChild(this);
this._b.__removeChild(this);
}
}
class AnimatedMultiplication extends AnimatedWithChildren {
_a: Animated;
_b: Animated;
constructor(a: Animated, b: Animated) {
super();
this._a = a;
this._b = b;
}
__getValue(): number {
return this._a.__getValue() * this._b.__getValue();
}
interpolate(config: InterpolationConfigType): AnimatedInterpolation {
return new AnimatedInterpolation(this, Interpolation.create(config));
}
__attach(): void {
this._a.__addChild(this);
this._b.__addChild(this);
}
__detach(): void {
this._a.__removeChild(this);
this._b.__removeChild(this);
}
}
class AnimatedTransform extends AnimatedWithChildren { class AnimatedTransform extends AnimatedWithChildren {
_transforms: Array<Object>; _transforms: Array<Object>;
@ -1161,6 +1219,20 @@ type CompositeAnimation = {
stop: () => void; stop: () => void;
}; };
var add = function(
a: Animated,
b: Animated
): AnimatedAddition {
return new AnimatedAddition(a, b);
};
var multiply = function(
a: Animated,
b: Animated
): AnimatedMultiplication {
return new AnimatedMultiplication(a, b);
};
var maybeVectorAnim = function( var maybeVectorAnim = function(
value: AnimatedValue | AnimatedValueXY, value: AnimatedValue | AnimatedValueXY,
config: Object, config: Object,
@ -1521,6 +1593,17 @@ module.exports = {
*/ */
spring, spring,
/**
* Creates a new Animated value composed from two Animated values added
* together.
*/
add,
/**
* Creates a new Animated value composed from two Animated values multiplied
* together.
*/
multiply,
/** /**
* Starts an animation after the given delay. * Starts an animation after the given delay.
*/ */