Add extractOffset to Animated
Summary: `flattenOffset` has proven extremely useful, especially when dealing with pan responders and other gesture based animations, but I've also found a number of use cases for the inverse. This diff introduces `extractOffset`, which sets the offset value to the base value, and resets the base value to zero. A common use case would be to extractOffset onGrant and flattenOffset onRelease. Closes https://github.com/facebook/react-native/pull/10721 Differential Revision: D4145744 fbshipit-source-id: dc2aa31652df0b31450556f611db43548180c7dd
This commit is contained in:
parent
bf2b435322
commit
6535858c71
|
@ -763,6 +763,18 @@ class AnimatedValue extends AnimatedWithChildren {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the offset value to the base value, and resets the base value to zero.
|
||||||
|
* The final output of the value is unchanged.
|
||||||
|
*/
|
||||||
|
extractOffset(): void {
|
||||||
|
this._offset += this._value;
|
||||||
|
this._value = 0;
|
||||||
|
if (this.__isNative) {
|
||||||
|
NativeAnimatedAPI.extractAnimatedNodeOffset(this.__getNativeTag());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an asynchronous listener to the value so you can observe updates from
|
* Adds an asynchronous listener to the value so you can observe updates from
|
||||||
* animations. This is useful because there is no way to
|
* animations. This is useful because there is no way to
|
||||||
|
|
|
@ -73,6 +73,10 @@ const API = {
|
||||||
assertNativeAnimatedModule();
|
assertNativeAnimatedModule();
|
||||||
NativeAnimatedModule.flattenAnimatedNodeOffset(nodeTag);
|
NativeAnimatedModule.flattenAnimatedNodeOffset(nodeTag);
|
||||||
},
|
},
|
||||||
|
extractAnimatedNodeOffset: function(nodeTag: number): void {
|
||||||
|
assertNativeAnimatedModule();
|
||||||
|
NativeAnimatedModule.extractAnimatedNodeOffset(nodeTag);
|
||||||
|
},
|
||||||
connectAnimatedNodeToView: function(nodeTag: number, viewTag: number): void {
|
connectAnimatedNodeToView: function(nodeTag: number, viewTag: number): void {
|
||||||
assertNativeAnimatedModule();
|
assertNativeAnimatedModule();
|
||||||
NativeAnimatedModule.connectAnimatedNodeToView(nodeTag, viewTag);
|
NativeAnimatedModule.connectAnimatedNodeToView(nodeTag, viewTag);
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
- (void)setOffset:(CGFloat)offset;
|
- (void)setOffset:(CGFloat)offset;
|
||||||
- (void)flattenOffset;
|
- (void)flattenOffset;
|
||||||
|
- (void)extractOffset;
|
||||||
|
|
||||||
@property (nonatomic, assign) CGFloat value;
|
@property (nonatomic, assign) CGFloat value;
|
||||||
@property (nonatomic, weak) id<RCTValueAnimatedNodeObserver> valueObserver;
|
@property (nonatomic, weak) id<RCTValueAnimatedNodeObserver> valueObserver;
|
||||||
|
|
|
@ -35,6 +35,12 @@
|
||||||
_offset = 0;
|
_offset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)extractOffset
|
||||||
|
{
|
||||||
|
_offset += _value;
|
||||||
|
_value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
- (CGFloat)value
|
- (CGFloat)value
|
||||||
{
|
{
|
||||||
return _value + _offset;
|
return _value + _offset;
|
||||||
|
|
|
@ -225,6 +225,18 @@ RCT_EXPORT_METHOD(flattenAnimatedNodeOffset:(nonnull NSNumber *)nodeTag)
|
||||||
[valueNode flattenOffset];
|
[valueNode flattenOffset];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RCT_EXPORT_METHOD(extractAnimatedNodeOffset:(nonnull NSNumber *)nodeTag)
|
||||||
|
{
|
||||||
|
RCTAnimatedNode *node = _animationNodes[nodeTag];
|
||||||
|
if (![node isKindOfClass:[RCTValueAnimatedNode class]]) {
|
||||||
|
RCTLogError(@"Not a value node.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RCTValueAnimatedNode *valueNode = (RCTValueAnimatedNode *)node;
|
||||||
|
[valueNode extractOffset];
|
||||||
|
}
|
||||||
|
|
||||||
RCT_EXPORT_METHOD(connectAnimatedNodeToView:(nonnull NSNumber *)nodeTag
|
RCT_EXPORT_METHOD(connectAnimatedNodeToView:(nonnull NSNumber *)nodeTag
|
||||||
viewTag:(nonnull NSNumber *)viewTag)
|
viewTag:(nonnull NSNumber *)viewTag)
|
||||||
{
|
{
|
||||||
|
|
|
@ -262,6 +262,16 @@ public class NativeAnimatedModule extends ReactContextBaseJavaModule implements
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ReactMethod
|
||||||
|
public void extractAnimatedNodeOffset(final int tag) {
|
||||||
|
mOperations.add(new UIThreadOperation() {
|
||||||
|
@Override
|
||||||
|
public void execute(NativeAnimatedNodesManager animatedNodesManager) {
|
||||||
|
animatedNodesManager.extractAnimatedNodeOffset(tag);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@ReactMethod
|
@ReactMethod
|
||||||
public void startAnimatingNode(
|
public void startAnimatingNode(
|
||||||
final int animationId,
|
final int animationId,
|
||||||
|
|
|
@ -157,6 +157,15 @@ import javax.annotation.Nullable;
|
||||||
((ValueAnimatedNode) node).flattenOffset();
|
((ValueAnimatedNode) node).flattenOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void extractAnimatedNodeOffset(int tag) {
|
||||||
|
AnimatedNode node = mAnimatedNodes.get(tag);
|
||||||
|
if (node == null || !(node instanceof ValueAnimatedNode)) {
|
||||||
|
throw new JSApplicationIllegalArgumentException("Animated node with tag " + tag +
|
||||||
|
" does not exists or is not a 'value' node");
|
||||||
|
}
|
||||||
|
((ValueAnimatedNode) node).extractOffset();
|
||||||
|
}
|
||||||
|
|
||||||
public void startAnimatingNode(
|
public void startAnimatingNode(
|
||||||
int animationId,
|
int animationId,
|
||||||
int animatedNodeTag,
|
int animatedNodeTag,
|
||||||
|
|
|
@ -40,6 +40,11 @@ import javax.annotation.Nullable;
|
||||||
mOffset = 0;
|
mOffset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void extractOffset() {
|
||||||
|
mOffset += mValue;
|
||||||
|
mValue = 0;
|
||||||
|
}
|
||||||
|
|
||||||
public void onValueUpdate() {
|
public void onValueUpdate() {
|
||||||
if (mValueListener == null) {
|
if (mValueListener == null) {
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Reference in New Issue