Permalink
Browse files

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 #10721

Differential Revision: D4145744

fbshipit-source-id: dc2aa31652df0b31450556f611db43548180c7dd
  • Loading branch information...
1 parent bf2b435 commit 6535858c71bb317e125c3fcc6c991235058137e2 @ryangomba ryangomba committed with Facebook Github Bot Nov 8, 2016
@@ -764,6 +764,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
* animations. This is useful because there is no way to
* synchronously read the value because it might be driven natively.
@@ -73,6 +73,10 @@ const API = {
assertNativeAnimatedModule();
NativeAnimatedModule.flattenAnimatedNodeOffset(nodeTag);
},
+ extractAnimatedNodeOffset: function(nodeTag: number): void {
+ assertNativeAnimatedModule();
+ NativeAnimatedModule.extractAnimatedNodeOffset(nodeTag);
+ },
connectAnimatedNodeToView: function(nodeTag: number, viewTag: number): void {
assertNativeAnimatedModule();
NativeAnimatedModule.connectAnimatedNodeToView(nodeTag, viewTag);
@@ -22,6 +22,7 @@
- (void)setOffset:(CGFloat)offset;
- (void)flattenOffset;
+- (void)extractOffset;
@property (nonatomic, assign) CGFloat value;
@property (nonatomic, weak) id<RCTValueAnimatedNodeObserver> valueObserver;
@@ -35,6 +35,12 @@ - (void)flattenOffset
_offset = 0;
}
+- (void)extractOffset
+{
+ _offset += _value;
+ _value = 0;
+}
+
- (CGFloat)value
{
return _value + _offset;
@@ -225,6 +225,18 @@ - (dispatch_queue_t)methodQueue
[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
viewTag:(nonnull NSNumber *)viewTag)
{
@@ -263,6 +263,16 @@ public void execute(NativeAnimatedNodesManager animatedNodesManager) {
}
@ReactMethod
+ public void extractAnimatedNodeOffset(final int tag) {
+ mOperations.add(new UIThreadOperation() {
+ @Override
+ public void execute(NativeAnimatedNodesManager animatedNodesManager) {
+ animatedNodesManager.extractAnimatedNodeOffset(tag);
+ }
+ });
+ }
+
+ @ReactMethod
public void startAnimatingNode(
final int animationId,
final int animatedNodeTag,
@@ -157,6 +157,15 @@ public void flattenAnimatedNodeOffset(int tag) {
((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(
int animationId,
int animatedNodeTag,
@@ -40,6 +40,11 @@ public void flattenOffset() {
mOffset = 0;
}
+ public void extractOffset() {
+ mOffset += mValue;
+ mValue = 0;
+ }
+
public void onValueUpdate() {
if (mValueListener == null) {
return;

0 comments on commit 6535858

Please sign in to comment.