Created
June 18, 2024 03:18
-
-
Save WarrenBuffering/81bee55e16e69b035a70f6d0fa2bd097 to your computer and use it in GitHub Desktop.
Revisions
-
WarrenBuffering created this gist
Jun 18, 2024 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,329 @@ 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 ( <View style={[styles.wrap]}> <Animated.View style={{ backgroundColor: themeColor, opacity: backgroundOpacity, height: screenHeight, position: 'absolute', width: screenWidth, zIndex: prevSlideZ, justifyContent: 'flex-end', alignItems: 'center' }}> <View style={{ height: screenHeight * .6 }}> <FastImage source={{ uri: comps[prevComp].img }} style={[ styles.image, { height: imageHeight, width: imageWidth } ]} /> </View> </Animated.View> <Animated.View style={{ backgroundColor: themeColor, opacity: backgroundOpacity, height: screenHeight, position: 'absolute', width: screenWidth, zIndex: nextSlideZ, justifyContent: 'flex-end', alignItems: 'center' }}> <View style={{ height: screenHeight * .6 }}> <FastImage source={{ uri: comps[nextComp].img }} style={[ styles.image, { height: imageHeight, width: imageWidth } ]} /> </View> </Animated.View> <Animated.View style={{ backgroundColor: themeColor, opacity: backgroundOpacity, height: screenHeight, position: 'absolute', width: screenWidth, zIndex: 9999, justifyContent: 'flex-end', alignItems: 'center' }}> <View style={{ height: screenHeight * .6 }}> <FastImage source={{ uri: comps[currComp].img }} style={[ styles.image, { height: imageHeight, width: imageWidth } ]} /> </View> </Animated.View> <SafeAreaView style={styles.safeAreaView}> <Animated.View style={[ styles.panel, { transform: [{ translateY: slideTransY }], height: screenHeight, paddingBottom: screenHeight * .65, opacity: slideOpacity, width: screenWidth, }]} {...this._panResponder.panHandlers} > <View> <Text style={styles.title}>{comps[currComp].title}</Text> <Text style={styles.subtitle}>{comps[currComp].subtitle}</Text> </View> </Animated.View> </SafeAreaView> </View> ) } } 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)