[GSAP] 애니메이션 ScrollTrigger - 자주 묻는 질문

Lpla

·

2021. 3. 3. 21:29

반응형

gsap의 자주 묻는 질문 중에 몇 가지를 간추려 정리해봤다.

 

Most Common ScrollTrigger Mistakes

Are you guilty of any of the most common mistakes people make in their ScrollTrigger code? Creating to() logic issues Nesting ScrollTriggers inside multiple timeline tweens Using one ScrollTrigger or animation for multiple sections Forgetting to use functi

greensock.com

 

1. 애니메이션이 뷰포트 중간에서 시작하고 화면을 벗어나면 초기화하고 싶습니다.

GSAP는 스크롤트리거의 시작 지점(scroller-start)과 요소의 시작 지점(start)이 만나는 순간 애니메이션이 실행된다.

그리고 애니메이션을 초기화하고 싶을 때 toggleActions을 사용해 요소 위로 스크롤하면 초기화하도록 할 수 있다.

기본적으로 스크롤트리거의 시작 지점은 화면 최하단이라서 문제 되지 않지만 시작 지점을 중간에 둘 경우 toggleActions을 쓰면 아래와 같은 문제가 발생한다.

 

뷰포트 중간에서 시작할 경우 문제점

 

요소가 아직 화면에 보이는데도 즉시 원상태로 돌아가 버린다.

이 문제는 scrub: true 로도 해결할 수 없다.

 

scrub: true을 사용해도 안된다.

 

See the Pen ScrollTrigger reset issue - fixed with two ScrollTriggers by GreenSock (@GreenSock) on CodePen.

해결 방법은 스크롤트리거를 두 번 사용해야 한다.

하나는 애니메이션이 실행되는 트리거, 다른 하나는 애니메이션이 초기화되는 트리거이다.

 

 

2. 처음에 x:100 만큼 이동하고 잠시 후 x:100 만큼 다시 이동하고 싶습니다.

스크롤트리거를 두 번 사용하여 처음에는 x:100 만큼 이동하고 다시 x:100 만큼 이동해 총 x:200 만큼 이동하는 애니메이션을 만드려고 한다.

아래와 같이 코드를 만들면 처음 위치에서 100만큼 이동하고, 처음 위치에서 200만큼 이동하기 때문에 총 200을 이동하는 애니메이션이 된다.

 

gsap.to('h1', {
  x: 100, 
  scrollTrigger: {
    trigger: 'h1',
    start: 'top center',
    end: '150px center',
    scrub: true,
    markers: true,
    id: "1st"
  }
});

gsap.to('h1', {
  x: 200, 
  scrollTrigger: {
    trigger: 'h1',
    start: '50px center',
    end: '300px center',
    scrub: true,
    markers: true,
    id: "2nd"
  }
});

 

 

 

하지만 실제로 스크롤을 해보면 두번째 스크롤트리거에서 x는 100만큼 이동한 상태에서 100을 더 이동하는 것이 아니라 다시 0으로 되돌아가서 200만큼 이동한다.

 

이를 해결하는 몇 가지 방법이 있다.

gsap.to('h1', {
  x: 200, 
  immediateRender: false,
  scrollTrigger: {
    trigger: 'h1',
    start: '50px center',
    end: '300px center',
    scrub: true,
    markers: true,
    id: "2nd"
  }
});

가장 쉬운 방법은 두번째 트리거에 immediateRender: false 를 추가하는 것이다.

 

혹은 두번째 트리거를 gsap.to 대신 fromTo 를 사용하여 시작 위치를 정해주는 방법이 있다.

gsap.fromTo('h1', {
  x: 100
}, {
  x: 200, 
  scrollTrigger: {
    trigger: 'h1',
    start: 'center center',
    end: 'bottom top',
    scrub: true
  }
});

 

마지막은 timeLine을 사용해서 스크롤트리거를 하나의 타임라인에 연결시키는 방법이 있다.

gsap.timeline({
  scrollTrigger: {
    trigger: 'h1',
    scrub: true
  }
})
.to('h1', {
  x: 100
})
.to('h1', {
  x: 200
});

 

하지만 첫번째 방법이 가장 쉽다.

 

 

3. 모바일에서 애니메이션 효과를 사용하고 싶지 않습니다.

pc와 모바일은 화면 비율이 많이 다르기 때문에 각각 다른 애니메이션 효과를 사용하거나 모바일에서는 애니메이션 효과를 사용하고 싶지 않을 수 있다.

이땐 matchMedia()를 사용해서 해결할 수 있다.

 

See the Pen ScrollTrigger.matchMedia() Demo by GreenSock (@GreenSock) on CodePen.

 

gsap.registerPlugin(ScrollTrigger);

ScrollTrigger.saveStyles(".mobile, .desktop");

ScrollTrigger.matchMedia({
	
	"(min-width: 800px)": function() {

  }, 
  
	"(max-width: 799px)": function() {

  }, 
  
	"all": function() {

  }
  
});

기본적으로 자바스크립트의 미디어쿼리와 비슷해서 어렵지 않다.

min-width: 800px은 800px 이상일 때, max-width: 799px은 799px 이하일 때 적용된다.

"all"은 미디어쿼리와 상관 없이 모두 실행된다.

 

예시 코드를 보면 saveStyles()가 있는데 페이지가 로드되고 해당 요소의 css를 저장하는 기능이다.

이 기능이 왜 필요하냐면 gsap 애니메이션 효과는 인라인 스타일 태그로 삽입되기 때문에 css파일보다 우선 적용된다.

따라서 pc에서 애니메이션을 실행하고 모바일로 화면을 줄이게 될 경우 방금 실행된 애니메이션 때문에 요소의 css가 깨질 수 있다.

 

pc에서 애니메이션을 실행하고, m 사이즈로 줄일 경우

 

위와 똑같이 실행하더라도 인라인 태그가 사라져있다!

saveStyle은 이 인라인 태그를 없애줘서 css가 망가지는 것을 막아준다.

 

 

이상 gsap 공식 사이트에 기재된 자주 묻는 질문(자주 하는 실수) 중에 알짜배기를 골라서 정리한 내용이었다.

여기까지 이해했다면 더 이상 이론을 공부할 필요는 없다. 바로 실전에 써먹으며 배워나가면 되겠다.

 

 

반응형