From 1e5d52bf0b34124adb0a36dc59daff27986fa96b Mon Sep 17 00:00:00 2001 From: Kaitlyn Lee Date: Wed, 31 Aug 2016 18:07:14 -0700 Subject: [PATCH] Improve swipable row gestures to feel more natural Summary: Modified logic and constants to make the swipable row animations feel more natural and smooth. Reviewed By: fred2028 Differential Revision: D3801391 fbshipit-source-id: d4301fe01a190803b5bc27373a9755086b6c431d --- .../Experimental/SwipeableRow/SwipeableRow.js | 30 ++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/Libraries/Experimental/SwipeableRow/SwipeableRow.js b/Libraries/Experimental/SwipeableRow/SwipeableRow.js index 922d70a25..09315ab65 100644 --- a/Libraries/Experimental/SwipeableRow/SwipeableRow.js +++ b/Libraries/Experimental/SwipeableRow/SwipeableRow.js @@ -48,7 +48,7 @@ const HORIZONTAL_FULL_SWIPE_SPEED_THRESHOLD = 0.3; // Factor to divide by to get slow speed; i.e. 4 means 1/4 of full speed const SLOW_SPEED_SWIPE_FACTOR = 4; // Time, in milliseconds, of how long the animated swipe should be -const SWIPE_DURATION = 200; +const SWIPE_DURATION = 300; /** * On SwipeableListView mount, the 1st item will bounce to show users it's @@ -58,8 +58,8 @@ const ON_MOUNT_BOUNCE_DELAY = 700; const ON_MOUNT_BOUNCE_DURATION = 400; // Distance left of closed position to bounce back when right-swiping from closed -const RIGHT_SWIPE_BOUNCE_BACK_DISTANCE = 50; -const RIGHT_SWIPE_BOUNCE_BACK_DURATION = 400; +const RIGHT_SWIPE_BOUNCE_BACK_DISTANCE = 30; +const RIGHT_SWIPE_BOUNCE_BACK_DURATION = 300; /** * Max distance of right swipe to allow (right swipes do functionally nothing). * Must be multiplied by SLOW_SPEED_SWIPE_FACTOR because gestureState.dx tracks @@ -295,6 +295,28 @@ const SwipeableRow = React.createClass({ this._animateTo(-maxSwipeDistance); }, + _animateToOpenPositionWith( + speed: number, + distMoved: number, + ): void { + /** + * Ensure the speed is at least the set speed threshold to prevent a slow + * swiping animation + */ + speed = ( + speed > HORIZONTAL_FULL_SWIPE_SPEED_THRESHOLD ? + speed : + HORIZONTAL_FULL_SWIPE_SPEED_THRESHOLD + ); + /** + * Calculate the duration the row should take to swipe the remaining distance + * at the same speed the user swiped (or the speed threshold) + */ + const duration = Math.abs((this.props.maxSwipeDistance - Math.abs(distMoved)) / speed); + const maxSwipeDistance = IS_RTL ? -this.props.maxSwipeDistance : this.props.maxSwipeDistance; + this._animateTo(-maxSwipeDistance, duration); + }, + _animateToClosedPosition(duration: number = SWIPE_DURATION): void { this._animateTo(CLOSED_LEFT_POSITION, duration); }, @@ -343,7 +365,7 @@ const SwipeableRow = React.createClass({ if (horizontalDistance < 0) { // Swiped left this.props.onOpen(); - this._animateToOpenPosition(); + this._animateToOpenPositionWith(gestureState.vx, horizontalDistance); } else { // Swiped right this._animateToClosedPosition();