sequence slider two sides rotation
This commit is contained in:
@@ -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} />
|
||||
|
||||
Reference in New Issue
Block a user