sequence slider two sides rotation

This commit is contained in:
2024-04-26 12:26:14 +05:00
parent dac5e3bf71
commit 7946031eb8
+70 -123
View File
@@ -9,6 +9,7 @@ import { Transition } from "react-transition-group";
// import ChevronLeftIcon from "./icons/ChevronLeftIcon";
import ChevronRightIcon from "./icons/ChevronRightIcon";
import { useSwipeable } from "react-swipeable";
import ChevronLeftIcon from "./icons/ChevronLeftIcon";
interface SequenceSliderProps {
path: string;
@@ -52,147 +53,86 @@ const marks = [
];
function SequenceSlider({ path }: SequenceSliderProps) {
const [selectedImageIndex, setSelectedImageIndex] = useState<number>(0);
// const selectedImageIndexRef = useRef(selectedImageIndex);
const [selectedImageRightIndex, setSelectedRightImageIndex] =
useState<number>(0);
const [selectedImageLeftIndex, setSelectedImageLeftIndex] =
useState<number>(0);
const [isAnimate, setIsAnimate] = useState<boolean>(false);
const keyframes: number[] = [0, 60, 120, 180, 240, 300];
const [keyframeIndex, setKeyframeIndex] = useState<number>(0);
const handlers = useSwipeable({
trackMouse: true,
onSwipedLeft: () => !isAnimate && next(),
// onSwipedRight: () => console.log("right"),
onSwipedRight: () => !isAnimate && prev(),
});
// const [movementX, setMovementX] = useState<number>(0);
// const [touchPositionX, setTouchPositionX] = useState<number>();
const [loadedImages, setLoadedImages] = useState<number>(0);
function handleLoad() {
setLoadedImages((prev) => prev + 1);
}
// function animate() {
// const obj = { selectedImageIndex };
// function getDirection() {
// const targetFrame =
// obj.selectedImageIndex < arrayLength / 2 ? "left" : "right";
// return targetFrame;
// }
// function getDuration() {
// const direction = getDirection();
// let duration;
// if (direction === "left") {
// duration = selectedImageIndex / 90;
// } else {
// duration = (arrayLength - selectedImageIndex) / 90;
// }
// return duration;
// }
// gsap.to(obj, {
// selectedImageIndex: getDirection() === "left" ? 0 : arrayLength,
// duration: getDuration(),
// ease: "power1.inOut",
// onUpdate: () => {
// console.log("data", obj.selectedImageIndex);
// setSelectedImageIndex(Math.round(obj.selectedImageIndex));
// },
// });
// }
// useEffect(() => {
// if (selectedImageIndex === 360) {
// setSelectedImageIndex(0);
// }
// onChange && onChange(selectedImageIndex);
// }, [selectedImageIndex]);
// function handleMouseMove(e: React.MouseEvent) {
// if (e.buttons !== 1) return; // 1 - left mouse button, 2 - right mouse button
// setMovementX(e.movementX);
// }
// function handleTouchStart(e: React.TouchEvent) {
// setTouchPositionX(e.touches[0].clientX);
// }
// function handleTouchMove(e: React.TouchEvent) {
// if (!touchPositionX) {
// setTouchPositionX(e.touches[0].clientX);
// return;
// }
// const newTouchPositionX = e.touches[0].clientX;
// setMovementX((newTouchPositionX - touchPositionX) * 2);
// setTouchPositionX(e.touches[0].clientX);
// }
// useEffect(() => {
// if (!touchPositionX) return;
// console.log("touchPositionX", touchPositionX);
// }, [touchPositionX]);
// useEffect(() => {
// console.log("movementX", movementX);
// if (movementX < 0) {
// console.log("next");
// const newSelectedImageIndex =
// selectedImageIndex + Math.round(Math.abs(movementX) / 5);
// if (newSelectedImageIndex > arrayLength - 1) {
// setSelectedImageIndex(0);
// } else {
// setSelectedImageIndex(newSelectedImageIndex);
// }
// } else if (movementX > 0) {
// console.log("prev");
// const newSelectedImageIndex =
// selectedImageIndex - Math.round(Math.abs(movementX) / 5);
// if (newSelectedImageIndex < 0) {
// setSelectedImageIndex(arrayLength - 1);
// } else {
// setSelectedImageIndex(newSelectedImageIndex);
// }
// }
// }, [movementX]);
function animate() {
const obj = { selectedImageIndex };
function animateToRight() {
const obj = { selectedImageIndex: selectedImageRightIndex };
gsap.to(obj, {
selectedImageIndex: selectedImageIndex + 60,
selectedImageIndex: selectedImageRightIndex + 60,
duration: 0.75,
ease: "power1.inOut",
onUpdate: () => {
const roundedIndex = Math.round(obj.selectedImageIndex);
if (roundedIndex === arrayLength) {
setSelectedImageIndex(0);
setSelectedRightImageIndex(0);
setSelectedImageLeftIndex(0);
} else {
setSelectedImageIndex(roundedIndex);
setSelectedRightImageIndex(roundedIndex);
setSelectedImageLeftIndex(arrayLength - roundedIndex);
}
},
onComplete: () => setIsAnimate(false),
onComplete: () => {
setIsAnimate(false);
},
});
}
function animateToLeft() {
const obj = { selectedImageIndex: selectedImageLeftIndex };
gsap.to(obj, {
selectedImageIndex: selectedImageLeftIndex + 60,
duration: 0.75,
ease: "power1.inOut",
onUpdate: () => {
const roundedIndex = Math.round(obj.selectedImageIndex);
if (roundedIndex === arrayLength || roundedIndex === 0) {
setSelectedRightImageIndex(0);
setSelectedImageLeftIndex(0);
} else {
setSelectedImageLeftIndex(roundedIndex);
setSelectedRightImageIndex(arrayLength - roundedIndex);
}
},
onComplete: () => {
setIsAnimate(false);
},
});
}
function next() {
setIsAnimate(true);
animate();
animateToRight();
}
function prev() {
setIsAnimate(true);
animateToLeft();
}
useEffect(() => {
if (keyframes.includes(selectedImageIndex)) {
console.log(setKeyframeIndex(keyframes.indexOf(selectedImageIndex)));
if (keyframes.includes(selectedImageRightIndex)) {
console.log(setKeyframeIndex(keyframes.indexOf(selectedImageRightIndex)));
}
}, [selectedImageIndex]);
}, [selectedImageRightIndex]);
const [width, setWidth] = useState<number>();
const [top, setTop] = useState<number>();
@@ -218,26 +158,31 @@ function SequenceSlider({ path }: SequenceSliderProps) {
style={{ width: `${width}px`, height: `${width}px`, top: `-${top}px` }}
>
{Array.from({ length: arrayLength }).map((_, index) => (
<img
key={index}
width={`${width}px`}
height={`${width}px`}
src={`${path}/${index + 1}.${isMobile ? "jpg" : "jpg"}`}
alt=""
className={`absolute t select-none pointer-events-none ${
index === selectedImageIndex ? "opacity-100" : "opacity-0"
}`}
onLoad={handleLoad}
/>
<>
<img
key={index}
width={`${width}px`}
height={`${width}px`}
src={`${path}/${index + 1}.${isMobile ? "jpg" : "jpg"}`}
alt=""
className={`absolute t select-none pointer-events-none ${
index === selectedImageRightIndex ? "opacity-100" : "opacity-0"
}`}
onLoad={handleLoad}
/>
</>
))}
</div>
{/* <button
className="p-3 bg-[#0079C2] hover:bg-[#0069A8] rounded-full transition-colors absolute left-6 top-[calc(50%-24px)] z-50"
<button
disabled={isAnimate}
className={`p-3 bg-[#0079C2] hover:bg-[#0069A8] rounded-full transition-colors absolute left-6 top-[calc(50%-24px)] z-50 ${
isAnimate ? "opacity-50" : "opacity-100"
}`}
onClick={prev}
>
<ChevronLeftIcon />
</button> */}
</button>
<button
disabled={isAnimate}
className={`p-3 bg-[#0079C2] hover:bg-[#0069A8] rounded-full transition-all absolute right-6 top-[calc(50%-24px)] z-50 ${
@@ -267,7 +212,9 @@ function SequenceSlider({ path }: SequenceSliderProps) {
>
<div
className={`transition-opacity duration-75 ${
keyframes.includes(selectedImageIndex) ? "opacity-100" : "opacity-0"
keyframes.includes(selectedImageRightIndex)
? "opacity-100"
: "opacity-0"
}`}
>
<MainMarksContainer marks={marks} keyframeIndex={keyframeIndex} />