import React, { Component } from 'react' import { Animated, Dimensions, Easing, PanResponder, SafeAreaView, StyleSheet, Text, View } from 'react-native' import { connect } from 'react-redux' import FastImage from 'react-native-fast-image' // Actions & Selectors import { setCurrComp, setNextComp, setPrevComp } from '../actions' import { getCurrComp, getNextComp, getPrevComp } from '../selectors/comps' import { getActiveProject } from '../selectors/projects' import { wait } from '../../../utils' import slides from '../../../json/workSlides.json' class WorkComps extends Component { screenWidth = Dimensions.get('window').width screenHeight = Dimensions.get('window').height imageWidth = this.screenWidth * .8 imageHeight = this.imageWidth * 1.4125 slideTransY = new Animated.Value(0) backgroundOpacity = new Animated.Value(1) slideOpacity = new Animated.Value(1) prevSlideZ = new Animated.Value(0) nextSlideZ = new Animated.Value(0) _handleSwipeLeft = async () => { await this.props.setPrevComp(0) await this.props.setCurrComp(0), await this.props.setNextComp(1) this.props.navigation.navigate('WorkProjects') } _handleSwipeNotCompleted = () => { Animated.timing(this.backgroundOpacity, { toValue: 1, duration: 200, easing: Easing.ease }).start() Animated.timing(this.slideOpacity, { toValue: 1, duration: 100 }).start() Animated.timing(this.slideTransY, { toValue: 0, duration: 200, easing: Easing.bezier(.72,.35,.24,.97) }).start() } _panResponder = PanResponder.create({ onStartShouldSetPanResponder: () => true, onPanResponderMove: (evt, { dy }) => { this.slideTransY.setValue((dy) * .1) this.backgroundOpacity.setValue( 1 - (Math.abs(dy) / this.screenHeight) * .7) this.slideOpacity.setValue( 1 - ((Math.abs(dy) / this.screenHeight) * 2)) this.prevSlideZ.setValue( dy > 0 ? 99 : 9 ) this.nextSlideZ.setValue( dy > 0 ? 9 : 99 ) }, onPanResponderRelease: (evt, { dx, dy, vx, vy }) => { const { screenHeight, screenWidth } = this const { currComp, activeProject } = this.props const comps = slides[this.props.activeProject].comps if (Math.abs(dx) >= screenWidth * .4) { if (dx > 0) { this._handleSwipeLeft() } } else if (currComp === 0 && dy > 0) { this._handleSwipeNotCompleted() } else if ( currComp === comps.endOfSlides && dy < 0) { this._handleSwipeNotCompleted() } else if (Math.abs(vy) >= .5 || Math.abs(dy) >= 0.2 * screenHeight) { if (dy > 0) { this._handleSwipeDownComplete(dy) } else if (dy < 0) { this._handleSwipeUpComplete(dy) } } else { this._handleSwipeNotCompleted() } }, }); _handleSwipeUpComplete = async () => { const { activeProject, prevComp, currComp, nextComp, setPrevComp, setCurrComp, setNextComp } = this.props const comps = slides[this.props.activeProject].comps const { endOfSlides } = comps if (currComp < endOfSlides) { setCurrComp(nextComp) } Animated.timing(this.backgroundOpacity, { toValue: 1, duration: 300, }).start() this.slideOpacity.setValue(0) this.slideTransY.setValue(50) Animated.timing(this.slideTransY, { toValue: 0, duration: 300, }).start() Animated.timing(this.slideOpacity, { toValue: 1, duration: 300 }).start() await wait(300) let newNextComp if (nextComp === endOfSlides) { newNextComp = nextComp } else { newNextComp = nextComp + 1 } setPrevComp(currComp) setNextComp(newNextComp) } _handleSwipeDownComplete = async () => { const { prevComp, currComp, nextComp, setPrevComp, setCurrComp, setNextComp } = this.props const comps = slides[this.props.activeProject].comps setCurrComp(prevComp) Animated.timing(this.backgroundOpacity, { toValue: 1, duration: 300, }).start() this.slideOpacity.setValue(0) this.slideTransY.setValue(-50) Animated.timing(this.slideTransY, { toValue: 0, duration: 300, }).start() Animated.timing(this.slideOpacity, { toValue: 1, duration: 300 }).start() await wait(300) let newPrevComp if (prevComp === 0) { newPrevComp = prevComp } else { newPrevComp = prevComp - 1 } setPrevComp(newPrevComp) setNextComp(currComp) } render() { const { prevComp, currComp, nextComp, activeProject } = this.props const { backgroundOpacity, imageHeight, imageWidth, slideTransY, nextSlideZ, prevSlideZ, screenHeight, screenWidth, slideOpacity } = this const themeColor = slides[activeProject].themeColor const comps = slides[activeProject].comps return ( {comps[currComp].title} {comps[currComp].subtitle} ) } } const styles = StyleSheet.create({ wrap: { flex: 1, }, safeAreaView: { height: '100%', position: 'absolute', width: '100%', zIndex: 99999999999, }, panel: { justifyContent: 'flex-end', position: 'absolute', zIndex: 99999, paddingHorizontal: '8%' }, title: { color: '#fff', fontSize: 22, fontFamily: 'Barlow-Bold', marginBottom: 14, textAlign: 'center', }, subtitle: { color: '#fff', fontSize: 14, fontFamily: 'Barlow-Medium', lineHeight: 20, marginBottom: 20, textAlign: 'center' }, }) const mapStateToProps = state => ({ activeProject: getActiveProject(state), currComp: getCurrComp(state), nextComp: getNextComp(state), prevComp: getPrevComp(state), }) const mapDispatchToProps = dispatch => ({ setCurrComp: (index) => dispatch(setCurrComp(index)), setNextComp: (index) => dispatch(setNextComp(index)), setPrevComp: (index) => dispatch(setPrevComp(index)) }) export default connect(mapStateToProps, mapDispatchToProps)(WorkComps)