인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

김민식님의 프로필 이미지
김민식

작성한 질문수

웹 애니메이션을 위한 GSAP 가이드 Part.03

OneScroll Layout (1) 관련 재질문드립니다.

해결된 질문

작성

·

86

·

수정됨

2

범샘님! 빠른 답변 및 업데이트 감사합니다,

답변해주신것처럼 section1, section4에서 스크롤문제가 발생합니다.

이 부분은 질문드리기 전에 확인한 부분이라 해결하였으나,

다만 답변해주신 두번째 경우는 제가 드린 질문의 방향과 조금 달라 재질문 드립니다.

 

section4까지 스크롤을 내린후, 다시 section3까지 스크롤을 end-section3 지점까지 올리고, 다시 section4로 스크롤 할 경우 스크롤이 작동되지 않습니다.

이 부분은 첫번째 질문 드린 경우와 비슷한 상황인거 같은데, 이번에는 반대로 스크롤하는 경우라 direction을 down으로 하는 조건문을 추가하면 되는건지, 조금 더 명확한 답변과 코드를 확인하고 싶어 다시 질문드립니다.

 

여러모로 바쁘실텐데, 감사합니다!

 

답변 1

1

범쌤 님의 프로필 이미지
범쌤
지식공유자

안녕하세요 김민식님 😀

 

말씀하신 조건을 넣어 처리해도 되지만 그렇게 하려면 더 번거로운 필터링 과정을 거쳐야 합니다.

 

4 → 3 으로 이동 후 스크롤 움직임 없이 바로 4 영역으로 이동하고 싶다면 상태를 확인해야 합니다.

 

4 영역의 상태 :

image.png

 

3 영역으로 올라갔을 때 상태 :

image.png

 

 

현재 isPlaying 값이 false이기 때문에 동작하지 않는 문제로 확인됩니다.

 

그렇다면 아까 전 방법처럼 isPlaying의 값을 true로 설정하는 방법도 있지만,

우리는 스크롤을 조금이라도 한다면 스크롤을 다시 내릴 때 onLeave 콜백이 작동된다는 사실은 알고 있습니다.

 

그렇다면, 상태를 바꾸지 않고 4 → 3 으로 이동 후 (마지막 스크롤 지점) 사용자 눈에는 보이지 않지만 아주 미세하게 스크롤을 조금이라도 해놓는다면 다시 스크롤을 내릴 때 onLeave 콜백이 동작 하지 않을까요?

 

현재 우리는 smoothscrollbar 플러그인을 사용하고 있기 때문에 해당 공식 문서를 들어가 스크롤 값을 가져오고(get) 설정하는(set) 방법을 찾아봅시다!

 

limit 메서드를 사용해 전체 스크롤 값을 가져올 수 있으며, scrollTo 메서드를 사용해 스크롤을 원하는 지점까지 이동시킬 수 있는걸 알았습니다!

 

그렇다면 적용해 봅시다!

3에 도착 후 해당 코드를 콘솔에 입력하니 아래의 그림과 같이 스크롤이 이동한 모습을 확인할 수 있습니다.

image.png


[ scollTo의 사용 방법은 scrollbar.scrollTo(x값,y값,duration값) 입니다 ]

*여기서 스크롤 인스턴스는 settings.js에 있는 전역에 노출된 scrollbar 입니다.

 

스크롤의 크기가 늘어날 수 있으므로 정적인 값이 아닌 limit을 통해 전체의 길이를 가져온 후 사용자가 인식하지 못하도록 1정도 빼서 적용시켜보겠습니다.

 

 

3번에게 아래서 위로 올라왔을 때만 실행이 되어야 하기 때문에 조건처리를 넣어 작성합니다.

최종 transition 함수의 코드는 다음과 같습니다.

function transition(index,dir){

  const {page01,page02,page03,page04} = pages;

  currentPageIndex = index;


  gsap.to('.wrapper',{
    y: -innerHeight * (index - 1),
    duration:1.5,
    ease:'expo.inOut',
    onStart:()=>{

      globalLeave()

      switch (dir === 'up' ? index + 1 : index - 1) {
        case 1: page01.leave(); return;
        case 2: page02.leave(); return;
        case 3: page03.leave(); return;
        case 4: 
          page04.leave(); 
          state.isPlaying = false;
          return;
      }
    },
    onComplete:()=>{
      state.isPlaying = true;
      
      globalEnter()

      switch (index) {
        case 1: page01.enter(); return;
        case 2: page02.enter(); return;
        case 3: 
          page03.enter(); 

          // 해당 부분 입니다.
          if(dir === 'up'){
            scrollbar.scrollTo(0,scrollbar.limit.y - 1,600)
          }
          
          state.isPlaying = false;
          state.isGoingUp = false;
          return
        ;
        case 4: page04.enter(); return;
      
      }
    }
  })
}

 

아래서 위로 올라올 경우 3에 도착 했을 때 스크롤의 값을 제일 끝에서 1만 뺀 위치로 놔둡니다.

 

 

애니메이션은 많은 부분 눈속임으로 이루어집니다. 스크롤의 과정이 필요할 경우 이런식으로 스크롤의 값을 1정도 조절하여 문제를 해결할 수 있습니다.

 

제가 알려드린 방법이 정답은 아닙니다.
민식님도 여러가지 방법들을 고민하여 여러가지 방법으로 문제를 해결해보세요 :)

 

김민식님의 프로필 이미지
김민식
질문자

감사합니다! 👍

김민식님의 프로필 이미지
김민식

작성한 질문수

질문하기