Permalink
Browse files

Animated.multiply and Animated.add to combine animated values

Summary:
This PR was created in response to feedback from an older PR: #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 #4395

Reviewed By: svcscm

Differential Revision: D2731305

Pulled By: vjeux

fb-gh-sync-id: 3b9422f10c7e7f3b3ecd270aeed8ea92315a89e9
  • Loading branch information...
lelandrichardson authored and facebook-github-bot-4 committed Dec 10, 2015
1 parent 3cfcd40 commit 3eb32cbb0e7baf23d62605b98a4635808374252e
Showing with 83 additions and 0 deletions.
  1. +83 −0 Libraries/Animated/src/AnimatedImplementation.js
@@ -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 {
_transforms: Array<Object>;
@@ -1161,6 +1219,20 @@ type CompositeAnimation = {
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(
value: AnimatedValue | AnimatedValueXY,
config: Object,
@@ -1521,6 +1593,17 @@ module.exports = {
*/
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.
*/

0 comments on commit 3eb32cb

Please sign in to comment.