Hi there,
I am creating an image slider using GSAP Draggable and React. I have added a slide counter so that when you drag or throw the slider the current slide index will display (1 of 3, 2 of 3 etc). The issue I'm running into is when I update the state during a throw (or drag) event. When the current slide update the animation (or drag) stops. I can't find a way around this and I'm not sure why it's stopping the animation. Thanks in advance for any help if anyone knows what the problem is. Here is my code:
import React, { useState, useRef, useEffect } from 'react';
import { gsap } from 'gsap';
import Draggable from 'gsap/Draggable';
import InertiaPlugin from "../gsap/InertiaPlugin";
import "../styles/components/_Carousel.scss";
import Picture from './Picture';
gsap.registerPlugin(Draggable);
gsap.registerPlugin(InertiaPlugin);
const items = [
"https://images.unsplash.com/photo-1558981822-0c0c5b070026?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=934&q=80",
"https://images.unsplash.com/photo-1558981806-ec527fa84c39?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2250&q=80",
"https://images.unsplash.com/photo-1558981420-87aa9dad1c89?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=2250&q=80"
];
const Carousel = () => {
const [curSlide, updateCurSlide] = useState(0);
const [slideCount, updateSlideCount] = useState(0);
const dragInstance = useRef(null);
const dragTarget = useRef(null);
const dragBounds = useRef(null);
const itemsRef = useRef([]);
useEffect(() => {
updateSlideCount(itemsRef.current.length);
dragInstance.current = Draggable.create(dragTarget.current, {
type:"scroll",
bounds: dragBounds,
throwProps:true,
dragClickables:true
});
// Cleanup
return () => dragInstance.current[0].kill();
}, []);
const onThrow = (slide) => {
console.log('im being thrown');
let curSlideXPos = slide.getBoundingClientRect().left;
let curSlideWidth = slide.getBoundingClientRect().width;
console.log(slide);
if (curSlideXPos < -Math.abs(curSlideWidth)) {
updateCurSlide(curSlide + 1);
}
}
useEffect(() => {
dragInstance.current[0].addEventListener("throwupdate", () => {onThrow(itemsRef.current[curSlide])});
}, [dragInstance]);
const handleLoadedImage = (img) => {
// TO DO
}
return (
<div ref={dragBounds} className="carousel">
<div>
{curSlide + 1} of {slideCount}
</div>
<div ref={dragTarget} draggable="true" onDrag={(e) => {handleOnDrag(e)}} className="carousel__stage">
{items.map((src, i) => (
<div ref={el => {itemsRef.current[i] = el}} key={i}>
<Picture srcSetLargeDesktop={src} key={i} onLoad={handleLoadedImage} />
</div>
))}
</div>
<div></div>
</div>
);
}
export default Carousel;