diff --git a/index.d.ts b/index.d.ts index dee80d9..f077853 100644 --- a/index.d.ts +++ b/index.d.ts @@ -47,6 +47,13 @@ declare interface Props { */ preventSwipe?: string[] + /** + * The card return animation type. Valid arguments are `'standard'`, `'slow'`, `'none'`. + * + * @default 'standard' + */ + backAnimationType?: string; + /** * What method to evaluate what direction to throw the card on release. 'velocity' will evaluate direction based on the direction of the swiping movement. 'position' will evaluate direction based on the position the card has on the screen like in the app tinder. * If set to position it is recommended to manually set swipeThreshold based on the screen size as not all devices will accommodate the default distance of 300px and the default native swipeThreshold is 1px which most likely is undesirably low. diff --git a/index.js b/index.js index 4848af7..6b46d9e 100644 --- a/index.js +++ b/index.js @@ -21,6 +21,14 @@ const physics = { animateBack: { friction: 10, tension: 200 + }, + animateSlow: { + friction: 50, + tension: 200 + }, + none: { + friction: 0, + tension: 0 } } @@ -54,13 +62,6 @@ const animateOut = async (gesture, setSpringTarget, windowHeight, windowWidth) = ) } -const animateBack = (setSpringTarget) => { - // translate back to the initial position - return new Promise((resolve) => { - setSpringTarget.start({ xyrot: [0, 0, 0], config: physics.animateBack, onRest: resolve }) - }) -} - const getSwipeDirection = (property) => { if (Math.abs(property.x) > Math.abs(property.y)) { if (property.x > settings.swipeThreshold) { @@ -83,7 +84,19 @@ const AnimatedDiv = animated.div const TinderCard = React.forwardRef( ( - { flickOnSwipe = true, children, onSwipe, onCardLeftScreen, className, preventSwipe = [], swipeRequirementType = 'velocity', swipeThreshold = settings.swipeThreshold, onSwipeRequirementFulfilled, onSwipeRequirementUnfulfilled }, + { + flickOnSwipe = true, + backAnimationType = 'standard', + children, + onSwipe, + onCardLeftScreen, + className, + preventSwipe = [], + swipeRequirementType = 'velocity', + swipeThreshold = settings.swipeThreshold, + onSwipeRequirementFulfilled, + onSwipeRequirementUnfulfilled + }, ref ) => { const { width, height } = useWindowSize() @@ -94,6 +107,26 @@ const TinderCard = React.forwardRef( settings.swipeThreshold = swipeThreshold + const getBackAnimationType = () => { + if (backAnimationType === 'standard') { + return physics.animateBack; + } else if (backAnimationType === 'slow') { + return physics.animateSlow; + } + return physics.none; + } + + const animateBack = (setSpringTarget) => { + // translate back to the initial position + return new Promise((resolve) => { + setSpringTarget.start({ + xyrot: [0, 0, 0], + config: getBackAnimationType(), + onRest: resolve + }) + }) + } + React.useImperativeHandle(ref, () => ({ async swipe (dir = 'right') { if (onSwipe) onSwipe(dir) diff --git a/index.native.js b/index.native.js index 980a1e4..d9b9162 100644 --- a/index.native.js +++ b/index.native.js @@ -22,6 +22,14 @@ const physics = { animateBack: { friction: 10, tension: 200 + }, + animateSlow: { + friction: 50, + tension: 200 + }, + none: { + friction: 0, + tension: 0 } } @@ -57,13 +65,6 @@ const animateOut = async (gesture, setSpringTarget) => { ) } -const animateBack = (setSpringTarget) => { - // translate back to the initial position - return new Promise((resolve) => { - setSpringTarget.current[0].start({ x: 0, y: 0, rot: 0, config: physics.animateBack, onRest: resolve }) - }) -} - const getSwipeDirection = (property) => { if (Math.abs(property.x) > Math.abs(property.y)) { if (property.x > settings.swipeThreshold) { @@ -86,7 +87,19 @@ const AnimatedView = animated(View) const TinderCard = React.forwardRef( ( - { flickOnSwipe = true, children, onSwipe, onCardLeftScreen, className, preventSwipe = [], swipeRequirementType = 'velocity', swipeThreshold = settings.swipeThreshold, onSwipeRequirementFulfilled, onSwipeRequirementUnfulfilled }, + { + flickOnSwipe = true, + backAnimationType = 'standard', + children, + onSwipe, + onCardLeftScreen, + className, + preventSwipe = [], + swipeRequirementType = 'velocity', + swipeThreshold = settings.swipeThreshold, + onSwipeRequirementFulfilled, + onSwipeRequirementUnfulfilled + }, ref ) => { const [{ x, y, rot }, setSpringTarget] = useSpring(() => ({ @@ -97,6 +110,26 @@ const TinderCard = React.forwardRef( })) settings.swipeThreshold = swipeThreshold + const getBackAnimationType = () => { + if (backAnimationType === 'standard') { + return physics.animateBack; + } else if (backAnimationType === 'slow') { + return physics.animateSlow; + } + return physics.none; + } + + const animateBack = (setSpringTarget) => { + // translate back to the initial position + return new Promise((resolve) => { + setSpringTarget.start({ + xyrot: [0, 0, 0], + config: getBackAnimationType(), + onRest: resolve + }) + }) + } + React.useImperativeHandle(ref, () => ({ async swipe (dir = 'right') { if (onSwipe) onSwipe(dir) diff --git a/readme.md b/readme.md index d2775e2..2c23939 100644 --- a/readme.md +++ b/readme.md @@ -104,6 +104,14 @@ Callback that will be executed when a `TinderCard` has left the screen. It will An array of directions for which to prevent swiping out of screen. Valid arguments are `'left'`, `'right'`, `'up'` and `'down'`. +### `backAnimationType` + +- optional +- type: `string` +- default: `standard` + +The card return animation type. Valid arguments are `'standard'`, `'slow'`, `'none'`. + ### `swipeRequirementType` - optional