mirror of
https://github.com/status-im/react-native.git
synced 2025-01-27 01:40:08 +00:00
Introduced AnimatedDivision
Summary: Combining 2 animated values via addition, multiplication, and modulo are already supported, and this adds another one: division. There are some cases where an animated value needs to invert (1 / x) another animated value for calculation. An example is inverting a scale (2x --> 0.5x), e.g.: ``` const a = Animated.Value(1); const b = Animated.divide(1, a); Animated.spring(a, { toValue: 2, }).start(); ``` `b` will then follow `a`'s spring animation and produce the value of `1 / a`. The basic usage is like this: ``` <Animated.View style={{transform: [{scale: a}]}}> <Animated.Image style={{transform: [{scale: b}]}} /> <Animated.View> ``` In this example, the inner image won't get stretched at all because the parent's scaling gets cancelled out. Also added this to native animated implementation. Reviewed By: foghina, mmmulani Differential Revision: D3922891 fbshipit-source-id: 32508956c4b65b2deb7574d50a10c85b4809b961
This commit is contained in:
parent
9af620bc33
commit
0a0dd30c6a
@ -1136,6 +1136,54 @@ class AnimatedAddition extends AnimatedWithChildren {
|
||||
}
|
||||
}
|
||||
|
||||
class AnimatedDivision extends AnimatedWithChildren {
|
||||
_a: Animated;
|
||||
_b: Animated;
|
||||
|
||||
constructor(a: Animated | number, b: Animated | number) {
|
||||
super();
|
||||
this._a = typeof a === 'number' ? new AnimatedValue(a) : a;
|
||||
this._b = typeof b === 'number' ? new AnimatedValue(b) : b;
|
||||
}
|
||||
|
||||
__makeNative() {
|
||||
super.__makeNative();
|
||||
this._a.__makeNative();
|
||||
this._b.__makeNative();
|
||||
}
|
||||
|
||||
__getValue(): number {
|
||||
const a = this._a.__getValue();
|
||||
const b = this._b.__getValue();
|
||||
if (b === 0) {
|
||||
console.error('Detected division by zero in AnimatedDivision');
|
||||
}
|
||||
return a / b;
|
||||
}
|
||||
|
||||
interpolate(config: InterpolationConfigType): AnimatedInterpolation {
|
||||
return new AnimatedInterpolation(this, config);
|
||||
}
|
||||
|
||||
__attach(): void {
|
||||
this._a.__addChild(this);
|
||||
this._b.__addChild(this);
|
||||
}
|
||||
|
||||
__detach(): void {
|
||||
this._a.__removeChild(this);
|
||||
this._b.__removeChild(this);
|
||||
super.__detach();
|
||||
}
|
||||
|
||||
__getNativeConfig(): any {
|
||||
return {
|
||||
type: 'division',
|
||||
input: [this._a.__getNativeTag(), this._b.__getNativeTag()],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class AnimatedMultiplication extends AnimatedWithChildren {
|
||||
_a: Animated;
|
||||
_b: Animated;
|
||||
@ -1795,15 +1843,22 @@ type CompositeAnimation = {
|
||||
};
|
||||
|
||||
var add = function(
|
||||
a: Animated,
|
||||
b: Animated
|
||||
a: Animated | number,
|
||||
b: Animated | number,
|
||||
): AnimatedAddition {
|
||||
return new AnimatedAddition(a, b);
|
||||
};
|
||||
|
||||
var divide = function(
|
||||
a: Animated | number,
|
||||
b: Animated | number,
|
||||
): AnimatedDivision {
|
||||
return new AnimatedDivision(a, b);
|
||||
};
|
||||
|
||||
var multiply = function(
|
||||
a: Animated,
|
||||
b: Animated
|
||||
a: Animated | number,
|
||||
b: Animated | number,
|
||||
): AnimatedMultiplication {
|
||||
return new AnimatedMultiplication(a, b);
|
||||
};
|
||||
@ -2295,6 +2350,13 @@ module.exports = {
|
||||
* together.
|
||||
*/
|
||||
add,
|
||||
|
||||
/**
|
||||
* Creates a new Animated value composed by dividing the first Animated value
|
||||
* by the second Animated value.
|
||||
*/
|
||||
divide,
|
||||
|
||||
/**
|
||||
* Creates a new Animated value composed from two Animated values multiplied
|
||||
* together.
|
||||
|
14
Libraries/NativeAnimation/Nodes/RCTDivisionAnimatedNode.h
Normal file
14
Libraries/NativeAnimation/Nodes/RCTDivisionAnimatedNode.h
Normal file
@ -0,0 +1,14 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "RCTValueAnimatedNode.h"
|
||||
|
||||
@interface RCTDivisionAnimatedNode : RCTValueAnimatedNode
|
||||
|
||||
@end
|
34
Libraries/NativeAnimation/Nodes/RCTDivisionAnimatedNode.m
Normal file
34
Libraries/NativeAnimation/Nodes/RCTDivisionAnimatedNode.m
Normal file
@ -0,0 +1,34 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "RCTDivisionAnimatedNode.h"
|
||||
#import "RCTLog.h"
|
||||
|
||||
@implementation RCTDivisionAnimatedNode
|
||||
|
||||
- (void)performUpdate
|
||||
{
|
||||
[super performUpdate];
|
||||
|
||||
NSArray<NSNumber *> *inputNodes = self.config[@"input"];
|
||||
if (inputNodes.count > 1) {
|
||||
RCTValueAnimatedNode *parent1 = (RCTValueAnimatedNode *)self.parentNodes[inputNodes[0]];
|
||||
RCTValueAnimatedNode *parent2 = (RCTValueAnimatedNode *)self.parentNodes[inputNodes[1]];
|
||||
if ([parent1 isKindOfClass:[RCTValueAnimatedNode class]] &&
|
||||
[parent2 isKindOfClass:[RCTValueAnimatedNode class]]) {
|
||||
if (parent2.value == 0) {
|
||||
RCTLogError(@"Detected a division by zero in Animated.divide node");
|
||||
return;
|
||||
}
|
||||
self.value = parent1.value / parent2.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
@ -19,8 +19,9 @@
|
||||
13E501EE1D07A6C9005F35D8 /* RCTStyleAnimatedNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 13E501E31D07A6C9005F35D8 /* RCTStyleAnimatedNode.m */; };
|
||||
13E501EF1D07A6C9005F35D8 /* RCTTransformAnimatedNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 13E501E51D07A6C9005F35D8 /* RCTTransformAnimatedNode.m */; };
|
||||
13E501F01D07A6C9005F35D8 /* RCTValueAnimatedNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 13E501E71D07A6C9005F35D8 /* RCTValueAnimatedNode.m */; };
|
||||
94DAE3F91D7334A70059942F /* RCTModuloAnimatedNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 94DAE3F81D7334A70059942F /* RCTModuloAnimatedNode.m */; };
|
||||
193F64F41D776EC6004D1CAA /* RCTDiffClampAnimatedNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 193F64F31D776EC6004D1CAA /* RCTDiffClampAnimatedNode.m */; };
|
||||
5C9894951D999639008027DB /* RCTDivisionAnimatedNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 5C9894941D999639008027DB /* RCTDivisionAnimatedNode.m */; };
|
||||
94DAE3F91D7334A70059942F /* RCTModuloAnimatedNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 94DAE3F81D7334A70059942F /* RCTModuloAnimatedNode.m */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
@ -61,10 +62,12 @@
|
||||
13E501E51D07A6C9005F35D8 /* RCTTransformAnimatedNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTTransformAnimatedNode.m; sourceTree = "<group>"; };
|
||||
13E501E61D07A6C9005F35D8 /* RCTValueAnimatedNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTValueAnimatedNode.h; sourceTree = "<group>"; };
|
||||
13E501E71D07A6C9005F35D8 /* RCTValueAnimatedNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTValueAnimatedNode.m; sourceTree = "<group>"; };
|
||||
94DAE3F71D7334A70059942F /* RCTModuloAnimatedNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTModuloAnimatedNode.h; sourceTree = "<group>"; };
|
||||
94DAE3F81D7334A70059942F /* RCTModuloAnimatedNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTModuloAnimatedNode.m; sourceTree = "<group>"; };
|
||||
193F64F21D776EC6004D1CAA /* RCTDiffClampAnimatedNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTDiffClampAnimatedNode.h; sourceTree = "<group>"; };
|
||||
193F64F31D776EC6004D1CAA /* RCTDiffClampAnimatedNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTDiffClampAnimatedNode.m; sourceTree = "<group>"; };
|
||||
5C9894931D999639008027DB /* RCTDivisionAnimatedNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTDivisionAnimatedNode.h; sourceTree = "<group>"; };
|
||||
5C9894941D999639008027DB /* RCTDivisionAnimatedNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTDivisionAnimatedNode.m; sourceTree = "<group>"; };
|
||||
94DAE3F71D7334A70059942F /* RCTModuloAnimatedNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTModuloAnimatedNode.h; sourceTree = "<group>"; };
|
||||
94DAE3F81D7334A70059942F /* RCTModuloAnimatedNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTModuloAnimatedNode.m; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@ -89,6 +92,8 @@
|
||||
13E501D51D07A6C9005F35D8 /* Nodes */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
5C9894931D999639008027DB /* RCTDivisionAnimatedNode.h */,
|
||||
5C9894941D999639008027DB /* RCTDivisionAnimatedNode.m */,
|
||||
193F64F21D776EC6004D1CAA /* RCTDiffClampAnimatedNode.h */,
|
||||
193F64F31D776EC6004D1CAA /* RCTDiffClampAnimatedNode.m */,
|
||||
13E501D61D07A6C9005F35D8 /* RCTAdditionAnimatedNode.h */,
|
||||
@ -196,6 +201,7 @@
|
||||
13E501E91D07A6C9005F35D8 /* RCTAnimatedNode.m in Sources */,
|
||||
13E501EB1D07A6C9005F35D8 /* RCTInterpolationAnimatedNode.m in Sources */,
|
||||
13E501E81D07A6C9005F35D8 /* RCTAdditionAnimatedNode.m in Sources */,
|
||||
5C9894951D999639008027DB /* RCTDivisionAnimatedNode.m in Sources */,
|
||||
13E501EA1D07A6C9005F35D8 /* RCTAnimationDriverNode.m in Sources */,
|
||||
13E501EF1D07A6C9005F35D8 /* RCTTransformAnimatedNode.m in Sources */,
|
||||
13E501D41D07A644005F35D8 /* RCTViewPropertyMapper.m in Sources */,
|
||||
|
@ -16,6 +16,7 @@
|
||||
#import "RCTInterpolationAnimatedNode.h"
|
||||
#import "RCTLog.h"
|
||||
#import "RCTDiffClampAnimatedNode.h"
|
||||
#import "RCTDivisionAnimatedNode.h"
|
||||
#import "RCTModuloAnimatedNode.h"
|
||||
#import "RCTMultiplicationAnimatedNode.h"
|
||||
#import "RCTPropsAnimatedNode.h"
|
||||
@ -71,6 +72,7 @@ RCT_EXPORT_METHOD(createAnimatedNode:(nonnull NSNumber *)tag
|
||||
@"interpolation" : [RCTInterpolationAnimatedNode class],
|
||||
@"addition" : [RCTAdditionAnimatedNode class],
|
||||
@"diffclamp": [RCTDiffClampAnimatedNode class],
|
||||
@"division" : [RCTDivisionAnimatedNode class],
|
||||
@"multiplication" : [RCTMultiplicationAnimatedNode class],
|
||||
@"modulus" : [RCTModuloAnimatedNode class],
|
||||
@"transform" : [RCTTransformAnimatedNode class]};
|
||||
|
@ -0,0 +1,57 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.facebook.react.animated;
|
||||
|
||||
import com.facebook.react.bridge.JSApplicationCausedNativeException;
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
|
||||
/**
|
||||
* Animated node which takes two or more value node as an input and outputs an in-order
|
||||
* division of their values.
|
||||
*/
|
||||
/*package*/ class DivisionAnimatedNode extends ValueAnimatedNode {
|
||||
|
||||
private final NativeAnimatedNodesManager mNativeAnimatedNodesManager;
|
||||
private final int[] mInputNodes;
|
||||
|
||||
public DivisionAnimatedNode(
|
||||
ReadableMap config,
|
||||
NativeAnimatedNodesManager nativeAnimatedNodesManager) {
|
||||
mNativeAnimatedNodesManager = nativeAnimatedNodesManager;
|
||||
ReadableArray inputNodes = config.getArray("input");
|
||||
mInputNodes = new int[inputNodes.size()];
|
||||
for (int i = 0; i < mInputNodes.length; i++) {
|
||||
mInputNodes[i] = inputNodes.getInt(i);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
for (int i = 0; i < mInputNodes.length; i++) {
|
||||
AnimatedNode animatedNode = mNativeAnimatedNodesManager.getNodeById(mInputNodes[i]);
|
||||
if (animatedNode != null && animatedNode instanceof ValueAnimatedNode) {
|
||||
double value = ((ValueAnimatedNode) animatedNode).mValue;
|
||||
if (i == 0) {
|
||||
mValue = value;
|
||||
continue;
|
||||
}
|
||||
if (value == 0) {
|
||||
throw new JSApplicationCausedNativeException("Detected a division by zero in " +
|
||||
"Animated.divide node");
|
||||
}
|
||||
mValue /= value;
|
||||
} else {
|
||||
throw new JSApplicationCausedNativeException("Illegal node ID set as an input for " +
|
||||
"Animated.divide node");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -89,6 +89,8 @@ import javax.annotation.Nullable;
|
||||
node = new InterpolationAnimatedNode(config);
|
||||
} else if ("addition".equals(type)) {
|
||||
node = new AdditionAnimatedNode(config, this);
|
||||
} else if ("division".equals(type)) {
|
||||
node = new DivisionAnimatedNode(config, this);
|
||||
} else if ("multiplication".equals(type)) {
|
||||
node = new MultiplicationAnimatedNode(config, this);
|
||||
} else if ("diffclamp".equals(type)) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user