[GSAP] 애니메이션 ScrollTrigger - 자주 묻는 질문
Lpla
·2021. 3. 3. 21:29
gsap의 자주 묻는 질문 중에 몇 가지를 간추려 정리해봤다.
1. 애니메이션이 뷰포트 중간에서 시작하고 화면을 벗어나면 초기화하고 싶습니다.
GSAP는 스크롤트리거의 시작 지점(scroller-start)과 요소의 시작 지점(start)이 만나는 순간 애니메이션이 실행된다.
그리고 애니메이션을 초기화하고 싶을 때 toggleActions을 사용해 요소 위로 스크롤하면 초기화하도록 할 수 있다.
기본적으로 스크롤트리거의 시작 지점은 화면 최하단이라서 문제 되지 않지만 시작 지점을 중간에 둘 경우 toggleActions을 쓰면 아래와 같은 문제가 발생한다.
요소가 아직 화면에 보이는데도 즉시 원상태로 돌아가 버린다.
이 문제는 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가 깨질 수 있다.
saveStyle은 이 인라인 태그를 없애줘서 css가 망가지는 것을 막아준다.
이상 gsap 공식 사이트에 기재된 자주 묻는 질문(자주 하는 실수) 중에 알짜배기를 골라서 정리한 내용이었다.
여기까지 이해했다면 더 이상 이론을 공부할 필요는 없다. 바로 실전에 써먹으며 배워나가면 되겠다.