From 1481a370fc450989658c72e59a0056a67548ee00 Mon Sep 17 00:00:00 2001 From: Dolav Soker Date: Thu, 19 Oct 2017 17:43:51 +0300 Subject: [PATCH 1/5] Add a return value to onDrag callback. Add targetSnapPointId to onDrag callback. targetSnapPointId - For end state, the string id of the target point in the snapPoints array (assuming it was provided). Otherwise, empty string. The value is the snap point id which is the destination of the object. --- PROPS.md | 1 + .../java/com/wix/interactable/Events.java | 3 ++- .../wix/interactable/InteractableView.java | 6 +++--- .../interactable/InteractableViewManager.java | 4 ++-- lib/ios/Interactable/InteractableView.m | 20 ++++++++++--------- 5 files changed, 19 insertions(+), 15 deletions(-) diff --git a/PROPS.md b/PROPS.md index 1f57a327..d69ef7f4 100644 --- a/PROPS.md +++ b/PROPS.md @@ -158,6 +158,7 @@ Optional, a function called whenever the user starts or stops dragging the view. * `state` - `start` or `end`, whether the user started or finished dragging. * `x` - The horizontal position of the view (relative to the center). * `y` - The vertical position of the view (relative to the center). +* `targetSnapPointId` - For `end` state, the string `id` of the target point in the `snapPoints` array (assuming it was provided). Otherwise, empty string. #### `onAlert` (function) diff --git a/lib/android/src/main/java/com/wix/interactable/Events.java b/lib/android/src/main/java/com/wix/interactable/Events.java index edd64289..3002e6a7 100644 --- a/lib/android/src/main/java/com/wix/interactable/Events.java +++ b/lib/android/src/main/java/com/wix/interactable/Events.java @@ -80,12 +80,13 @@ public static class onDrag extends Event { WritableMap eventData; - public onDrag(int viewTag, String state, float x, float y) { + public onDrag(int viewTag, String state, float x, float y, String targetSnapPointId) { super(viewTag); eventData = Arguments.createMap(); eventData.putString("state", state); eventData.putDouble("x", PixelUtil.toDIPFromPixel(x)); eventData.putDouble("y", PixelUtil.toDIPFromPixel(y)); + eventData.putString("targetSnapPointId", targetSnapPointId); } @Override diff --git a/lib/android/src/main/java/com/wix/interactable/InteractableView.java b/lib/android/src/main/java/com/wix/interactable/InteractableView.java index 8c1c491b..8c6b8dd0 100644 --- a/lib/android/src/main/java/com/wix/interactable/InteractableView.java +++ b/lib/android/src/main/java/com/wix/interactable/InteractableView.java @@ -279,7 +279,7 @@ private ReactRootView getReactRoot() { private void startDrag(MotionEvent ev) { PointF currentPosition = getCurrentPosition(); - listener.onDrag("start",currentPosition.x, currentPosition.y); + listener.onDrag("start",currentPosition.x, currentPosition.y, ''); this.dragStartLocation = new PointF(ev.getX(),ev.getY()); this.animator.removeTempBehaviors(); this.animator.setDragging(true); @@ -304,12 +304,12 @@ private void handleEndOfDrag() { if (this.dragWithSprings != null) toss = this.dragWithSprings.toss; PointF currentPosition = getCurrentPosition(); - listener.onDrag("end",currentPosition.x, currentPosition.y); PointF projectedCenter = new PointF(getTranslationX() + toss*velocity.x, getTranslationY() + toss*velocity.y); InteractablePoint snapPoint = InteractablePoint.findClosestPoint(snapPoints,projectedCenter); + listener.onDrag("end",currentPosition.x, currentPosition.y, snapPoint.id); addTempSnapToPointBehavior(snapPoint); addTempBounceBehaviorWithBoundaries(this.boundaries); @@ -547,6 +547,6 @@ public interface InteractionListener { void onSnap(int indexOfSnapPoint, String snapPointId); void onAlert(String alertAreaId, String alertType); void onAnimatedEvent(float x, float y); - void onDrag(String state, float x, float y); + void onDrag(String state, float x, float y, String targetSnapPointId); } } diff --git a/lib/android/src/main/java/com/wix/interactable/InteractableViewManager.java b/lib/android/src/main/java/com/wix/interactable/InteractableViewManager.java index f5ade08f..d0a07afb 100644 --- a/lib/android/src/main/java/com/wix/interactable/InteractableViewManager.java +++ b/lib/android/src/main/java/com/wix/interactable/InteractableViewManager.java @@ -179,8 +179,8 @@ public void onAnimatedEvent(float x, float y) { } @Override - public void onDrag(String state, float x, float y) { - eventDispatcher.dispatchEvent(new Events.onDrag(interactableView.getId(),state, x, y)); + public void onDrag(String state, float x, float y, String targetSnapPointId) { + eventDispatcher.dispatchEvent(new Events.onDrag(interactableView.getId(),state, x, y, targetSnapPointId)); } } } diff --git a/lib/ios/Interactable/InteractableView.m b/lib/ios/Interactable/InteractableView.m index 0e613237..2472e07e 100644 --- a/lib/ios/Interactable/InteractableView.m +++ b/lib/ios/Interactable/InteractableView.m @@ -286,7 +286,7 @@ - (void)reportAlertEvent } } -- (void)reportDragEvent:(NSString*)state +- (void)reportDragEvent:(NSString*)state targetSnapPointId:(NSString*)targetSnapPointId { if (self.onDrag) { @@ -294,7 +294,8 @@ - (void)reportDragEvent:(NSString*)state self.onDrag(@{ @"state": state, @"x": @(deltaFromOrigin.x), - @"y": @(deltaFromOrigin.y) + @"y": @(deltaFromOrigin.y), + @"targetSnapPointId":targetSnapPointId }); } } @@ -308,7 +309,7 @@ - (void)handlePan:(UIPanGestureRecognizer *)pan [self cancelCurrentReactTouch]; self.dragStartCenter = self.center; [self setTempBehaviorsForDragStart]; - [self reportDragEvent:@"start"]; + [self reportDragEvent:@"start" targetSnapPointId:@""]; } CGPoint translation = [pan translationInView:self]; @@ -319,8 +320,8 @@ - (void)handlePan:(UIPanGestureRecognizer *)pan pan.state == UIGestureRecognizerStateFailed || pan.state == UIGestureRecognizerStateCancelled) { - [self setTempBehaviorsForDragEnd]; - [self reportDragEvent:@"end"]; + InteractablePoint* point = [self setTempBehaviorsForDragEnd]; + [self reportDragEvent:@"end" targetSnapPointId:point.id]; } } @@ -403,21 +404,22 @@ - (void)setTempBehaviorsForDragStart self.dragBehavior = [self addTempDragBehavior:self.dragWithSpring]; } -- (void)setTempBehaviorsForDragEnd +- (InteractablePoint*)setTempBehaviorsForDragEnd { [self.animator removeTempBehaviors]; self.dragBehavior = nil; - + CGPoint velocity = [self.animator getTargetVelocity:self]; if (self.horizontalOnly) velocity.y = 0; if (self.verticalOnly) velocity.x = 0; CGFloat toss = self.dragToss; CGPoint projectedCenter = CGPointMake(self.center.x + toss*velocity.x, self.center.y + toss*velocity.y); - + InteractablePoint *snapPoint = [InteractablePoint findClosestPoint:self.snapPoints toPoint:projectedCenter withOrigin:self.origin]; if (snapPoint) [self addTempSnapToPointBehavior:snapPoint]; - + [self addTempBounceBehaviorWithBoundaries:self.boundaries]; + return snapPoint; } // MARK: - Behaviors From 6e4c0ba661fefd6e3359f108c857e5a401c007a0 Mon Sep 17 00:00:00 2001 From: Lev Vidrak Date: Sun, 22 Oct 2017 17:41:35 +0300 Subject: [PATCH 2/5] fix error --- .../src/main/java/com/wix/interactable/InteractableView.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/android/src/main/java/com/wix/interactable/InteractableView.java b/lib/android/src/main/java/com/wix/interactable/InteractableView.java index 8c6b8dd0..44b3e4d6 100644 --- a/lib/android/src/main/java/com/wix/interactable/InteractableView.java +++ b/lib/android/src/main/java/com/wix/interactable/InteractableView.java @@ -279,7 +279,7 @@ private ReactRootView getReactRoot() { private void startDrag(MotionEvent ev) { PointF currentPosition = getCurrentPosition(); - listener.onDrag("start",currentPosition.x, currentPosition.y, ''); + listener.onDrag("start",currentPosition.x, currentPosition.y, ""); this.dragStartLocation = new PointF(ev.getX(),ev.getY()); this.animator.removeTempBehaviors(); this.animator.setDragging(true); From de356a2851957780055857399a77cc2ce2aad149 Mon Sep 17 00:00:00 2001 From: Lev Date: Sun, 22 Oct 2017 17:51:46 +0300 Subject: [PATCH 3/5] 0.1.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1a00762e..a0ff0d36 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-interactable", - "version": "0.1.3", + "version": "0.1.4", "description": "High performance interactable views in React Native", "license": "MIT", "author": "Tal Kol ", From 954d2891a4465a989c2daafcfbadf3a59f6a5b12 Mon Sep 17 00:00:00 2001 From: Jonathan Adler Date: Tue, 24 Oct 2017 19:11:25 +0300 Subject: [PATCH 4/5] added onStop event for Android + example in RowActions for using the event --- .../java/com/wix/interactable/Events.java | 20 +++++++++++ .../wix/interactable/InteractableView.java | 4 ++- .../interactable/InteractableViewManager.java | 6 ++++ real-life-example/src/RowActions1.js | 35 ++++++++++++++++--- 4 files changed, 60 insertions(+), 5 deletions(-) diff --git a/lib/android/src/main/java/com/wix/interactable/Events.java b/lib/android/src/main/java/com/wix/interactable/Events.java index 3002e6a7..c3f86a58 100644 --- a/lib/android/src/main/java/com/wix/interactable/Events.java +++ b/lib/android/src/main/java/com/wix/interactable/Events.java @@ -99,4 +99,24 @@ public void dispatch(RCTEventEmitter rctEventEmitter) { rctEventEmitter.receiveEvent(getViewTag(), getEventName(), eventData); } } + + public static class onStop extends Event { + + WritableMap eventData; + + public onStop(int viewTag, float x, float y) { + super(viewTag); + eventData = Arguments.createMap(); + eventData.putDouble("x", PixelUtil.toDIPFromPixel(x)); + eventData.putDouble("y", PixelUtil.toDIPFromPixel(y)); + } + + @Override + public String getEventName() { return "onStop"; } + + @Override + public void dispatch(RCTEventEmitter rctEventEmitter) { + rctEventEmitter.receiveEvent(getViewTag(), getEventName(), eventData); + } + } } diff --git a/lib/android/src/main/java/com/wix/interactable/InteractableView.java b/lib/android/src/main/java/com/wix/interactable/InteractableView.java index 44b3e4d6..c90485fa 100644 --- a/lib/android/src/main/java/com/wix/interactable/InteractableView.java +++ b/lib/android/src/main/java/com/wix/interactable/InteractableView.java @@ -99,7 +99,8 @@ public void setEventListener(InteractionListener listener) { @Override public void onAnimatorPause() { - + PointF currentPosition = getCurrentPosition(); + listener.onStop(currentPosition.x, currentPosition.y); } @Override @@ -548,5 +549,6 @@ public interface InteractionListener { void onAlert(String alertAreaId, String alertType); void onAnimatedEvent(float x, float y); void onDrag(String state, float x, float y, String targetSnapPointId); + void onStop(float x, float y); } } diff --git a/lib/android/src/main/java/com/wix/interactable/InteractableViewManager.java b/lib/android/src/main/java/com/wix/interactable/InteractableViewManager.java index d0a07afb..5c72bae7 100644 --- a/lib/android/src/main/java/com/wix/interactable/InteractableViewManager.java +++ b/lib/android/src/main/java/com/wix/interactable/InteractableViewManager.java @@ -151,6 +151,7 @@ public Map getExportedCustomDirectEventTypeConstants() { .put("onAlert", MapBuilder.of("registrationName", "onAlert")) .put("onAnimatedEvent", MapBuilder.of("registrationName", "onAnimatedEvent")) .put("onDrag", MapBuilder.of("registrationName", "onDrag")) + .put("onStop", MapBuilder.of("registrationName", "onStop")) .build(); } @@ -182,6 +183,11 @@ public void onAnimatedEvent(float x, float y) { public void onDrag(String state, float x, float y, String targetSnapPointId) { eventDispatcher.dispatchEvent(new Events.onDrag(interactableView.getId(),state, x, y, targetSnapPointId)); } + + @Override + public void onStop(float x, float y) { + eventDispatcher.dispatchEvent(new Events.onStop(interactableView.getId(), x, y)); + } } } diff --git a/real-life-example/src/RowActions1.js b/real-life-example/src/RowActions1.js index ba4d341f..4b44e216 100644 --- a/real-life-example/src/RowActions1.js +++ b/real-life-example/src/RowActions1.js @@ -1,5 +1,5 @@ import React, { Component } from 'react'; -import { StyleSheet, View, Text, Animated, TouchableOpacity, Slider, Dimensions } from 'react-native'; +import { StyleSheet, View, Text, Animated, TouchableOpacity, TouchableHighlight, Slider, Dimensions } from 'react-native'; import Interactable from 'react-native-interactable'; const Screen = Dimensions.get('window'); @@ -80,8 +80,10 @@ class Row extends Component { constructor(props) { super(props); this._deltaX = new Animated.Value(0); + this.state = {isMoving: false, position: 1}; } render() { + const activeOpacity = this.state.position !== 1 ? 0.5 : 1; return ( @@ -152,22 +154,47 @@ class Row extends Component { this.interactableElem = el} horizontalOnly={true} snapPoints={[ {x: 75, damping: 1-this.props.damping, tension: this.props.tension}, {x: 0, damping: 1-this.props.damping, tension: this.props.tension}, {x: -150, damping: 1-this.props.damping, tension: this.props.tension} ]} + onSnap={this.onSnap.bind(this)} + onDrag={this.onDrag.bind(this)} + onStop={this.onStopMoving.bind(this)} dragToss={0.01} animatedValueX={this._deltaX}> - - {this.props.children} - + + + {this.props.children} + + ); } + onSnap({nativeEvent}) { + const { index } = nativeEvent; + this.setState({position: index}); + } + onRowPress() { + const { isMoving, position } = this.state; + if (!isMoving && position !== 1) { + this.interactableElem.snapTo({index: 1}); + } + } + onDrag({nativeEvent}) { + const { state } = nativeEvent; + if (state === 'start') { + this.setState({isMoving: true}); + } + } + onStopMoving() { + this.setState({isMoving: false}); + } onButtonPress(name) { alert(`Button ${name} pressed`); } From 0945b7a30c1ac34a7c26cf34259903ffe330e4f7 Mon Sep 17 00:00:00 2001 From: Lev Date: Wed, 1 Nov 2017 14:08:58 +0200 Subject: [PATCH 5/5] 0.1.6 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a0ff0d36..b9e87fa9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-interactable", - "version": "0.1.4", + "version": "0.1.6", "description": "High performance interactable views in React Native", "license": "MIT", "author": "Tal Kol ",