gsap를 이용해서 스크롤시 내가 원하는 영역에서 이벤트가 발생하고 해당영역을 벗어나면 다시 이벤트가 나타나는걸 작성했는데 원하는대로 안됨ㅠ
내가 처음 작성한것
1. gsap를 이용
ScrollTrigger.create({ trigger: ".project-area", // .project-area에 트리거 설정 start: "top top", // .project-area의 상단이 뷰포트 상단에 닿으면 시작 end: "bottom top", // .project-area의 하단이 뷰포트 상단에 닿으면 종료 toggleActions: "play none none reverse", // 실행: play, 복귀: reverse onEnter: () => { gsap.to("#header", { opacity: 0, y: -20, duration: 0.2 }); // 헤더 숨김 }, onLeaveBack: () => { gsap.to("#header", { opacity: 1, y: 0, duration: 0.2 }); // 헤더 복귀 } });
내가 생각한 해결법
1. 부모한데 300vh를 줘서 스크롤할 높이값을 준다. -> 실패
2. end를 100%를 줘서 전체 높이값을 잡도록한다 -> 여전히 못잡음
onEnter: () => { gsap.to("#header", { opacity: 0, y: -20, duration: 0.2 }); // 헤더 숨김 }, onLeave: () => { gsap.to("#header", { opacity: 1, y: 0, duration: 0.2 }); // 헤더 복귀 (project-area 벗어날 때) }, onEnterBack: () => { gsap.to("#header", { opacity: 0, y: -20, duration: 0.2 }); // 다시 project-area로 진입 시 숨김 }, onLeaveBack: () => { gsap.to("#header", { opacity: 1, y: 0, duration: 0.2 }); // 위로 벗어나면 복귀 }
-> 여전히 못잡음
👀 4. invalidateOnRefresh 트리거 재계산 -> 안먹음x
let lastScroll = 0; $(window).scroll(function () { const currScroll = $(this).scrollTop(); // 현재 스크롤 위치 const projectAreaOffset = $(".project-area").offset().top; // .project-area의 상단 위치 const projectAreaHeight = $(".project-area").outerHeight(); // .project-area의 높이 const projectAreaEnd = projectAreaOffset + projectAreaHeight; // .project-area의 하단 위치 // 스크롤이 .project-area에 있을 때만 동작 if (currScroll >= projectAreaOffset && currScroll <= projectAreaEnd) { if (currScroll > lastScroll) { // 아래로 스크롤 gsap.to(".header", { opacity: 0, duration: 0.1 }); } else { // 위로 스크롤 gsap.to(".header", { opacity: 1, duration: 0.1 }); } } else { // .project-area를 벗어나면 헤더를 항상 보이게 설정 gsap.to(".header", { opacity: 1, duration: 0.1 }); } lastScroll = currScroll; // 마지막 스크롤 위치 갱신 });
해결!
하지만 새로운 문제 project-area를 벗어나고 다시 스크롤을 위로 올려서 영역에 들어가면
그대로 존재😢
let isInProjectArea = false;를 이요해서 영역에 들어갔는지 여부를 추적하면 된다!!!
if (curr >= projectAreaOffset && curr <= projectAreaEnd) { if (!isInProjectArea) { // .project-area에 처음 진입한 경우 $(".header").fadeOut(); isInProjectArea = true; // .project-area 내부로 상태 갱신 } } else { // .project-area를 벗어나면 헤더를 다시 표시 if (isInProjectArea) { $(".header").fadeIn(); isInProjectArea = false; // .project-area 외부로 상태 갱신 } }
두 번 선언하는 이유는 퍼포먼스 최적화와 정확한 동작 보장 때문
1. $(window).scroll 내부에서 선언
스크롤 이벤트 내부에서 위치와 크기를 다시 계산하는 이유는 $(".project-area")의 위치나 크기가 스크롤 중에 동적으로 변경될 가능성이 있기 때문입니다.
2. 전역 변수 및 resize 이벤트
.project-area의 위치와 크기가 고정된 경우. 반복적으로 계산하지 않고 성능을 최적화.
1. 전역 변수 + resize 이벤트
상황: .project-area의 위치와 크기가 대부분 고정되어 있고, 브라우저 창 크기 변경 시만 업데이트가 필요할 때.
장점: 스크롤 이벤트를 가볍게 만들고, 성능을 최적화.
2. 스크롤 이벤트 내부에서 계산
상황: .project-area의 위치나 크기가 스크롤 도중 동적으로 변경될 가능성이 있을 때.
장점: 위치와 크기의 정확성을 보장.
3. 둘을 함께 사용하는 이유
기본적으로 전역 변수와 resize 이벤트를 사용해 성능을 최적화.
하지만 특정 상황에서는 스크롤 이벤트 내에서도 실시간으로 값을 재계산해야 동작의 정확성을 보장.