Skip to content

Commit

Permalink
Merge pull request #124 from galio-org/Components/Deck-Swiper
Browse files Browse the repository at this point in the history
Components/deck swiper
  • Loading branch information
palingheorghe authored Sep 11, 2019
2 parents b47d687 + 2ee16d8 commit 35f40c9
Show file tree
Hide file tree
Showing 2 changed files with 139 additions and 0 deletions.
137 changes: 137 additions & 0 deletions src/DeckSwiper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
import React from 'react';
import {
StyleSheet,
Dimensions,
Animated,
PanResponder,
} from 'react-native';
import PropTypes from 'prop-types';

import Block from './Block';

const { width: SCREEN_WIDTH } = Dimensions.get('screen');

function DeckSwiper({
onSwipeRight,
onSwipeLeft,
focusedElementStyle,
nextElementStyle,
components,
style
}) {
const [currentIndex, setCurrentIndex] = React.useState(0);
const position = new Animated.ValueXY();

const rotate = position.x.interpolate({
inputRange: [-SCREEN_WIDTH / 2, 0, SCREEN_WIDTH / 2],
outputRange: ["-10deg", "0deg", "10deg"],
extrapolate: "clamp"
});

const rotateAndTranslate = {
transform: [
{
rotate: rotate
},
...position.getTranslateTransform()
]
};

const nextCardOpacity = position.x.interpolate({
inputRange: [-SCREEN_WIDTH / 2, 0, SCREEN_WIDTH / 2],
outputRange: [1, 0, 1],
extrapolate: "clamp"
});

const nextCardScale = position.x.interpolate({
inputRange: [-SCREEN_WIDTH / 2, 0, SCREEN_WIDTH / 2],
outputRange: [1, 0.8, 1],
extrapolate: "clamp"
});

const panResponder = PanResponder.create({
onStartShouldSetPanResponder: (evt, gestureState) => true,
onPanResponderMove: (evt, gestureState) => {
position.setValue({ x: gestureState.dx, y: gestureState.dy });
},
onPanResponderRelease: (evt, gestureState) => {
if(gestureState.dx > 110) {
Animated.spring(position, {
toValue: { x: SCREEN_WIDTH + 100, y: gestureState.dy }
}).start(() => {
setCurrentIndex(currentIndex + 1);
});
if(onSwipeRight) onSwipeRight();
}else if(gestureState.dx < -110) {
Animated.spring(position, {
toValue: { x: -SCREEN_WIDTH - 100, y: gestureState.dy }
}).start(() => {
setCurrentIndex(currentIndex + 1);
});
if(onSwipeLeft) onSwipeLeft();
}else{
Animated.spring(position, {
toValue: { x: 0, y: 0 },
friction: 4
}).start();
}
},
});

React.useEffect(() => {
position.setValue({ x: 0, y: 0 });
}, [currentIndex]);

function renderComponents(components) {
return components.map((item, i) => {
if(i < currentIndex) {
return null
}else if(i == currentIndex){
return (
<Animated.View
key={i}
style={[
rotateAndTranslate,
{
...StyleSheet.absoluteFillObject
},
focusedElementStyle
]}
{...panResponder.panHandlers}
>
{item}
</Animated.View>
);
}else{
return (
<Animated.View
key={i}
style={[{
opacity: nextCardOpacity,
transform: [{ scale: nextCardScale }],
...StyleSheet.absoluteFillObject
}, nextElementStyle]}
>
{item}
</Animated.View>
);
}
}).reverse();
}
return (
<Block flex center style={[{ width: SCREEN_WIDTH * 0.7 }, style]}>
{renderComponents(components)}
</Block>
);
}

DeckSwiper.propTypes = {
components: PropTypes.array.isRequired,
onSwipeRight: PropTypes.func,
onSwipeLeft: PropTypes.func,
focusedElementStyle: PropTypes.any,
nextElementStyle: PropTypes.any,
style: PropTypes.any
}

export default DeckSwiper;
2 changes: 2 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Block from './Block';
import Button from './Button';
import Card from './Card';
import Checkbox from './Checkbox';
import DeckSwiper from './DeckSwiper';
import Icon from './Icon';
import Input from './Input';
import NavBar from './NavBar';
Expand All @@ -21,6 +22,7 @@ export {
Button,
Card,
Checkbox,
DeckSwiper,
Icon,
Input,
NavBar,
Expand Down

0 comments on commit 35f40c9

Please sign in to comment.