메인페이지 page.tsx에 있는 useEffect 로직 커스텀훅으로 작성
useVideoLoaded.ts
import { useEffect, useRef, useState } from "react"
const useVideoLoaded = () => {
const videoRef = useRef<HTMLVideoElement | null>(null);
const [videoLoaded, setVideoLoaded] = useState<boolean>(false);
useEffect(() => {
if (videoRef.current) {
const videoElement = videoRef.current;
const checkVideoLoaded = () => {
if (videoElement.readyState >= 3) {
setVideoLoaded(true);
}
};
checkVideoLoaded();
}
}, []);
return { videoRef, videoLoaded }
}
export default useVideoLoaded
useSlideAnimation.ts
import { useEffect } from 'react';
import gsap from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';
gsap.registerPlugin(ScrollTrigger);
type Planet = {
id: string;
planet_img: string;
price?: number;
};
const useSlideAnimation = (
videoLoaded: boolean,
planets: Planet[],
currentSlide: number,
visiblePlanetsCount: number,
planetsRef: React.RefObject<(HTMLDivElement | null)[]>
) => {
useEffect(() => {
const animatePlanets = () => {
const radius = 500; // 고리 반경
const angleStep = (2 * Math.PI) / planets.length; // 각 행성 사이의 각도
planetsRef.current?.forEach((planetElement, index) => {
if (planetElement) {
const adjustedIndex =
(index + (planets.length - Math.floor(visiblePlanetsCount / 2))) %
planets.length;
const angle = (adjustedIndex - currentSlide) * angleStep; // 각 행성의 위치 계산
const xPos = radius * Math.sin(angle); // x 좌표
const yPos = 0; // y 좌표
const zPos = radius * Math.cos(angle); // z 좌표
const isVisible =
(index >= currentSlide &&
index < currentSlide + visiblePlanetsCount) || // visiblePlanetsCount 개수만큼 행성이 보이도록 조건식
(index < currentSlide &&
index + planets.length < currentSlide + visiblePlanetsCount);
const isActive =
index ===
(currentSlide + Math.floor(visiblePlanetsCount / 2)) %
planets.length;
const scale = isActive ? 2 : 1;
const zIndex = isActive ? 10 : 0;
const opacity = isVisible ? (isActive ? 1 : 0.5) : 0;
gsap.to(planetElement, {
x: xPos,
y: yPos,
z: zPos,
scale: scale,
zIndex: zIndex,
opacity: opacity,
duration: 1,
ease: 'power2.inOut',
});
// 디버깅을 위한 로그 추가
const planet = planets[index]; // planets 배열의 요소 가져오기
const tourPrice: number | undefined = planet.price;
console.log(`Planet ${planet.id} - Price: ${tourPrice}`);
}
});
};
if (videoLoaded && planets.length > 0) {
animatePlanets();
}
ScrollTrigger.refresh();
}, [currentSlide, videoLoaded, planets]);
};
export default useSlideAnimation;
useScrollTrigger.ts
import { useEffect } from 'react';
import gsap from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';
gsap.registerPlugin(ScrollTrigger);
const useScrollTrigger = (
videoLoaded: boolean,
sectionRef: React.RefObject<HTMLDivElement>
) => {
useEffect(() => {
if (videoLoaded && sectionRef.current) {
ScrollTrigger.create({
trigger: sectionRef.current,
start: 'top top',
pin: true,
pinSpacing: false,
scrub: true,
});
ScrollTrigger.refresh();
}
}, [videoLoaded, sectionRef]);
};
export default useScrollTrigger;