From c31709c9e5879a1f6db68c04253902feda29f420 Mon Sep 17 00:00:00 2001 From: Xavier Mod Date: Fri, 25 Feb 2022 15:08:47 +0000 Subject: [PATCH 1/4] Add autoplay functionality --- README.md | 2 ++ src/carousel.js | 37 +++++++++++++++++++++++++++++++++++-- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1495136..ca8724c 100644 --- a/README.md +++ b/README.md @@ -128,6 +128,8 @@ From version **4.0.0** it has been moved to *Functional component* and fix separ | itemContainerStyle | Style for each carousel container item | View style | {} | No | | onScrollEnd | Fired while scrollview end of scrolling | Function | ()=> {} | No | | initialIndex | Initial starting focused item of list | Number | 0 | No | +| autoPlay | Adds autoplay functionality | Boolean | false | No | +| autoPlayInterval | Use with autoPlay. Sets the interval of the slides when autoPlay is activated. | Number | 4000 | No | diff --git a/src/carousel.js b/src/carousel.js index 29b174b..fe81783 100644 --- a/src/carousel.js +++ b/src/carousel.js @@ -6,7 +6,7 @@ import React, { useState, forwardRef } from 'react'; -import { Animated, StyleSheet, Dimensions, FlatList } from 'react-native'; +import { Animated, StyleSheet, Dimensions, FlatList, View } from 'react-native'; const { width: windowWidth } = Dimensions.get('window'); @@ -39,6 +39,8 @@ function Carousel(props, ref) { inActiveOpacity = 0.8, inverted = false, initialIndex = 0, + autoPlay = false, + autoPlayInterval = 4000, bounces = true, showsHorizontalScrollIndicator = false, keyExtractor = (item, index) => index.toString(), @@ -50,6 +52,7 @@ function Carousel(props, ref) { } = props; const scrollViewRef = useRef(null); const currentIndexRef = useRef(initialIndex); + const [isAutoPlay, setIsAutoPlay] = useState(autoPlay); const scrollXRef = useRef(0); const scrollXBeginRef = useRef(0); const xOffsetRef = useRef(new Animated.Value(0)); @@ -60,6 +63,16 @@ function Carousel(props, ref) { const containerStyle = [styles.container, { width: containerWidth }, style]; const dataLength = data ? data.length : 0; + let interval; + useEffect(() => { + if (isAutoPlay) { + interval = setInterval(() => { + generateAutoPlay() + }, autoPlayInterval); + } + return () => clearInterval(interval); + }, [isAutoPlay]) + useConstructor(() => { setScrollHandler(); }); @@ -111,6 +124,14 @@ function Carousel(props, ref) { }); } + function generateAutoPlay() { + if (currentIndexRef.current === data.length - 1) { + scrollToIndex(0) + } else { + scrollToIndex(currentIndexRef.current + 1) + } + } + function handleOnScrollBeginDrag() { onScrollBeginDrag && onScrollBeginDrag(); scrollXBeginRef.current = scrollXRef.current; @@ -134,6 +155,16 @@ function Carousel(props, ref) { } } + function handleTouchStart() { + setIsAutoPlay(false); + console.log('begin drag'); + } + + function handleTouchEnd() { + setIsAutoPlay(true); + console.log('finish drag'); + } + function getItemTotalMarginBothSide() { const compensatorOfSeparatorByScaleEffect = (1 - inActiveScale) * itemWidth; return separatorWidth - compensatorOfSeparatorByScaleEffect / 2; @@ -254,6 +285,8 @@ function Carousel(props, ref) { {...otherProps} ref={scrollViewRef} data={data} + onTouchStart={handleTouchStart} + onTouchEnd={handleTouchEnd} style={containerStyle} horizontal={true} inverted={inverted} @@ -272,4 +305,4 @@ function Carousel(props, ref) { ); } -export default forwardRef(Carousel); +export default forwardRef(Carousel); \ No newline at end of file From e08c974865b9ec5a313cd5e4e01dcc95600a3ba6 Mon Sep 17 00:00:00 2001 From: Xavier Mod Date: Fri, 25 Feb 2022 15:16:28 +0000 Subject: [PATCH 2/4] Remove console logs --- src/carousel.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/carousel.js b/src/carousel.js index fe81783..285b7bc 100644 --- a/src/carousel.js +++ b/src/carousel.js @@ -157,12 +157,10 @@ function Carousel(props, ref) { function handleTouchStart() { setIsAutoPlay(false); - console.log('begin drag'); } function handleTouchEnd() { setIsAutoPlay(true); - console.log('finish drag'); } function getItemTotalMarginBothSide() { From 76cca0a10f8228578b350015af9dd61ecb156491 Mon Sep 17 00:00:00 2001 From: Xavier Mod Date: Fri, 25 Feb 2022 15:19:08 +0000 Subject: [PATCH 3/4] Forgot about unmounting. sorted. --- src/carousel.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/carousel.js b/src/carousel.js index 285b7bc..7c5ecf5 100644 --- a/src/carousel.js +++ b/src/carousel.js @@ -65,12 +65,15 @@ function Carousel(props, ref) { let interval; useEffect(() => { - if (isAutoPlay) { - interval = setInterval(() => { - generateAutoPlay() - }, autoPlayInterval); + if (!isAutoPlay) { + return; + } + interval = setInterval(() => { + generateAutoPlay() + }, autoPlayInterval); + return () => { + clearInterval(interval); } - return () => clearInterval(interval); }, [isAutoPlay]) useConstructor(() => { From 5a97333abf8184a49bceaafdaa3a52b15c3e75d6 Mon Sep 17 00:00:00 2001 From: Xavier Mod Date: Fri, 25 Feb 2022 15:31:47 +0000 Subject: [PATCH 4/4] tidy up --- src/carousel.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/carousel.js b/src/carousel.js index 7c5ecf5..cc5ed36 100644 --- a/src/carousel.js +++ b/src/carousel.js @@ -6,7 +6,7 @@ import React, { useState, forwardRef } from 'react'; -import { Animated, StyleSheet, Dimensions, FlatList, View } from 'react-native'; +import { Animated, StyleSheet, Dimensions, FlatList } from 'react-native'; const { width: windowWidth } = Dimensions.get('window'); @@ -128,11 +128,9 @@ function Carousel(props, ref) { } function generateAutoPlay() { - if (currentIndexRef.current === data.length - 1) { - scrollToIndex(0) - } else { - scrollToIndex(currentIndexRef.current + 1) - } + scrollToIndex( + (currentIndexRef.current + 1) % (data.length - 1) + ); } function handleOnScrollBeginDrag() { @@ -306,4 +304,4 @@ function Carousel(props, ref) { ); } -export default forwardRef(Carousel); \ No newline at end of file +export default forwardRef(Carousel);