본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.
본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.
이미지 로딩 중...
AI Generated
2025. 12. 29. · 3 Views
GSAP 애니메이션 라이브러리 완벽 가이드
웹 애니메이션의 표준, GSAP를 처음부터 제대로 배워봅니다. 기본 사용법부터 Timeline, Easing, Three.js 통합까지 실무에서 바로 쓸 수 있는 핵심 내용을 다룹니다.
목차
1. GSAP 설치 및 기본 개념
어느 날 김개발 씨가 웹 페이지에 멋진 애니메이션을 추가하려고 CSS transition을 사용했습니다. 하지만 복잡한 시퀀스 애니메이션을 구현하려니 코드가 엉망이 되어버렸습니다.
선배 박시니어 씨가 다가와 말했습니다. "GSAP를 한번 써보세요.
훨씬 쉬워질 거예요."
GSAP(GreenSock Animation Platform)은 웹 애니메이션을 위한 강력한 자바스크립트 라이브러리입니다. CSS나 다른 애니메이션 라이브러리보다 성능이 뛰어나고, 직관적인 API로 복잡한 애니메이션도 쉽게 구현할 수 있습니다.
전 세계 수많은 기업과 개발자들이 사용하는 웹 애니메이션의 사실상 표준입니다.
다음 코드를 살펴봅시다.
// npm 또는 CDN으로 설치
// npm install gsap
import { gsap } from "gsap";
// 기본 애니메이션: .box 요소를 2초 동안 오른쪽으로 500px 이동
gsap.to(".box", {
x: 500, // x축으로 500px 이동
duration: 2, // 2초 동안
rotation: 360, // 360도 회전
ease: "power2.out" // 부드러운 감속 효과
});
// 여러 속성을 동시에 애니메이션
gsap.to(".card", {
opacity: 0.5,
scale: 1.5,
duration: 1
});
김개발 씨는 회사에서 새로운 랜딩 페이지 프로젝트를 맡았습니다. 디자이너가 전달한 시안에는 멋진 애니메이션 효과가 가득했습니다.
스크롤하면 요소들이 부드럽게 나타나고, 버튼은 hover 시 살짝 튀어 오르고, 배경은 천천히 움직입니다. "이걸 어떻게 구현하지?" 김개발 씨는 고민에 빠졌습니다.
CSS transition으로는 한계가 있었고, requestAnimationFrame을 직접 다루기엔 너무 복잡했습니다. 바로 그때 박시니어 씨가 GSAP를 추천해 주었습니다.
"이거 한번 써보세요. 애니메이션 작업이 정말 편해질 거예요." GSAP가 필요한 이유 웹 애니메이션을 구현하는 방법은 여러 가지입니다.
CSS transition, CSS animation, 그리고 자바스크립트로 직접 제어하는 방법 등이 있습니다. 하지만 CSS만으로는 복잡한 시퀀스 애니메이션을 구현하기 어렵습니다.
"이 요소가 움직인 다음에 저 요소가 나타나고, 그 다음에 회전하고..." 같은 연속적인 동작을 CSS로 표현하려면 코드가 복잡해지고 유지보수도 힘들어집니다. 자바스크립트로 직접 requestAnimationFrame을 다루면 더 세밀한 제어가 가능하지만, 이것도 보일러플레이트 코드가 많아지고 성능 최적화를 직접 신경 써야 합니다.
GSAP의 등장 바로 이런 문제를 해결하기 위해 GSAP가 만들어졌습니다. GSAP를 사용하면 단 몇 줄의 코드로 부드럽고 복잡한 애니메이션을 구현할 수 있습니다.
성능 최적화는 라이브러리가 알아서 처리해 주고, 브라우저 호환성도 걱정할 필요가 없습니다. 무엇보다 코드가 직관적이어서 나중에 수정하기도 쉽습니다.
설치와 기본 사용법 GSAP를 시작하는 것은 매우 간단합니다. npm으로 설치하거나 CDN을 통해 바로 사용할 수 있습니다.
가장 기본이 되는 메서드는 **gsap.to()**입니다. 이것은 "특정 요소를 현재 상태에서 목표 상태로 애니메이션하라"는 의미입니다.
마치 "이 상자를 여기서 저기로 옮겨라"고 명령하는 것과 같습니다. 코드 분석 위의 코드를 한 줄씩 살펴보겠습니다.
먼저 gsap.to(".box", {...})는 ".box"라는 클래스를 가진 요소를 찾아서 애니메이션을 적용합니다. 두 번째 인자로 전달되는 객체에는 애니메이션의 목표 상태와 옵션들이 담겨 있습니다.
x: 500은 요소를 x축 방향으로 500픽셀 이동시킵니다. GSAP는 CSS의 transform: translateX()를 자동으로 사용하므로 성능이 뛰어납니다.
duration: 2는 애니메이션이 2초 동안 진행된다는 의미이고, ease는 애니메이션의 가속도 곡선을 결정합니다. gsap.to, gsap.from, gsap.fromTo의 차이 GSAP에는 세 가지 기본 메서드가 있습니다.
**gsap.to()**는 현재 상태에서 지정한 상태로 애니메이션합니다. 가장 많이 사용되는 방식입니다.
**gsap.from()**은 반대로 지정한 상태에서 현재 상태로 애니메이션합니다. 요소가 페이지에 처음 나타날 때 유용합니다.
**gsap.fromTo()**는 시작 상태와 끝 상태를 모두 명시적으로 지정할 수 있어 가장 세밀한 제어가 가능합니다. 실무 활용 사례 실제 현업에서는 어떻게 활용할까요?
예를 들어 전자상거래 사이트의 상품 카드를 구현한다고 가정해봅시다. 사용자가 마우스를 올리면 카드가 살짝 커지면서 그림자가 진해지는 효과를 주고 싶습니다.
GSAP를 사용하면 이런 인터랙션을 쉽게 구현할 수 있습니다. 많은 유명 기업들이 GSAP를 사용합니다.
Google, Microsoft, Samsung 등의 웹사이트에서 GSAP로 만들어진 애니메이션을 볼 수 있습니다. 성능 최적화 GSAP의 큰 장점 중 하나는 성능입니다.
GSAP는 내부적으로 requestAnimationFrame을 사용하고, 가능한 경우 CSS의 transform과 opacity 속성을 활용하여 GPU 가속을 받습니다. 또한 불필요한 레이아웃 재계산을 최소화하는 최적화가 내장되어 있습니다.
이런 최적화 덕분에 수백 개의 요소를 동시에 애니메이션해도 60fps를 유지할 수 있습니다. 주의사항 하지만 주의할 점도 있습니다.
초보 개발자들이 흔히 하는 실수 중 하나는 애니메이션 대상을 잘못 선택하는 것입니다. 예를 들어 width나 height를 직접 애니메이션하면 레이아웃 재계산이 발생하여 성능이 떨어집니다.
대신 scale을 사용하는 것이 좋습니다. 또한 너무 많은 요소를 동시에 애니메이션하면 아무리 GSAP라도 성능 문제가 생길 수 있습니다.
꼭 필요한 애니메이션만 적용하는 것이 중요합니다. 정리 다시 김개발 씨의 이야기로 돌아가 봅시다.
GSAP를 처음 사용해본 김개발 씨는 감탄했습니다. "와, 이렇게 간단한 코드로 이런 멋진 애니메이션을 만들 수 있다니!" GSAP의 기본 개념을 이해하면 웹 페이지에 생동감을 불어넣을 수 있습니다.
다음 장에서는 Timeline을 사용하여 더 복잡한 시퀀스 애니메이션을 만드는 방법을 배워보겠습니다.
실전 팁
💡 - transform과 opacity 속성을 애니메이션하면 최고의 성능을 얻을 수 있습니다
- 애니메이션이 끝난 후 콜백을 실행하려면 onComplete 옵션을 사용하세요
- GSAP Cheat Sheet를 북마크해 두면 개발할 때 매우 유용합니다
2. Timeline을 활용한 시퀀스 애니메이션
김개발 씨는 GSAP의 기본 사용법을 익혔습니다. 이제 여러 애니메이션을 순서대로 실행해야 하는 과제를 받았습니다.
"로고가 나타나고, 그 다음 텍스트가 나타나고, 마지막으로 버튼이 나타나야 해요." 하지만 각 애니메이션의 delay를 일일이 계산하니 코드가 복잡해졌습니다. 박시니어 씨가 다시 조언했습니다.
"Timeline을 사용하면 훨씬 관리하기 쉬워요."
Timeline은 여러 애니메이션을 시간 순서대로 관리하는 강력한 도구입니다. 마치 동영상 편집 프로그램의 타임라인처럼, 각 애니메이션을 배치하고 순서를 조정할 수 있습니다.
delay를 일일이 계산할 필요 없이 직관적으로 시퀀스를 구성할 수 있어 복잡한 애니메이션 작업이 쉬워집니다.
다음 코드를 살펴봅시다.
import { gsap } from "gsap";
// Timeline 생성
const tl = gsap.timeline({
defaults: { duration: 1, ease: "power2.out" }
});
// 순서대로 애니메이션 추가
tl.from(".logo", { opacity: 0, y: -50 })
.from(".title", { opacity: 0, x: -100 }, "-=0.5") // 0.5초 겹침
.from(".description", { opacity: 0, scale: 0.8 })
.from(".button", { opacity: 0, y: 20 });
// Timeline 제어
tl.pause(); // 일시정지
tl.play(); // 재생
tl.reverse(); // 역재생
tl.restart(); // 처음부터 다시
김개발 씨는 회사 홈페이지의 인트로 화면을 만들고 있었습니다. 디자이너의 요구사항은 명확했습니다.
"로고가 위에서 떨어지면서 나타나고, 그 다음 제목이 왼쪽에서 슬라이드되어 들어오고, 설명 텍스트가 커지면서 나타나고, 마지막으로 버튼이 아래에서 올라와야 해요." 처음에 김개발 씨는 각 애니메이션에 delay를 설정했습니다. "로고는 0초, 제목은 1초 후, 설명은 2초 후, 버튼은 3초 후..." 하지만 디자이너가 "로고 애니메이션을 0.5초 더 빠르게 해주세요"라고 요청하자 모든 delay를 다시 계산해야 했습니다.
Timeline이 필요한 이유 웹 애니메이션에서 가장 어려운 부분 중 하나가 바로 타이밍 조절입니다. 여러 애니메이션을 순차적으로 실행하려면 각각의 시작 시간을 정확히 계산해야 합니다.
첫 번째 애니메이션이 1초, 두 번째가 1.5초라면 두 번째의 delay는 1초입니다. 여기까지는 간단합니다.
하지만 중간에 하나의 duration을 수정하면 어떻게 될까요? 뒤에 있는 모든 애니메이션의 delay를 다시 계산해야 합니다.
애니메이션이 10개, 20개가 되면 관리가 불가능해집니다. 코드도 복잡해지고 버그도 생기기 쉽습니다.
Timeline의 등장 바로 이런 문제를 해결하기 위해 Timeline이 있습니다. Timeline은 마치 동영상 편집 프로그램의 타임라인과 같습니다.
각 클립(애니메이션)을 순서대로 배치하면 자동으로 시간이 계산됩니다. 중간에 하나를 수정하거나 삭제해도 나머지가 자동으로 조정됩니다.
무엇보다 코드가 직관적입니다. 위에서 아래로 읽으면 그대로 실행 순서가 됩니다.
유지보수가 쉬워지고 협업할 때도 다른 개발자가 이해하기 쉽습니다. Timeline 생성과 기본 사용 Timeline을 만드는 것은 gsap.timeline()을 호출하는 것만으로 충분합니다.
생성할 때 defaults 옵션을 설정하면 모든 자식 애니메이션에 기본값이 적용됩니다. duration이나 ease를 매번 반복해서 쓸 필요가 없어지는 것입니다.
이것은 마치 CSS의 상속과 비슷한 개념입니다. 코드 분석 위의 코드를 한 줄씩 살펴보겠습니다.
먼저 gsap.timeline()으로 Timeline 객체를 생성합니다. defaults에 설정한 duration: 1, ease: "power2.out"은 모든 애니메이션의 기본값이 됩니다.
그 다음 tl.from()을 체이닝으로 연결합니다. 첫 번째 from()은 로고를 opacity: 0, y: -50 상태에서 현재 상태로 애니메이션합니다.
즉, 투명한 상태에서 위쪽 50픽셀 위치에서 원래 위치로 떨어지면서 나타나는 효과입니다. 두 번째 from()에 주목해 보세요.
"-=0.5"라는 특별한 파라미터가 있습니다. 이것은 "이전 애니메이션이 끝나기 0.5초 전에 시작하라"는 의미입니다.
즉, 로고와 제목 애니메이션이 0.5초 동안 겹쳐서 실행됩니다. 위치 파라미터의 마법 Timeline의 진짜 강력함은 위치 파라미터에 있습니다.
기본적으로 애니메이션을 추가하면 이전 애니메이션이 끝난 직후에 시작됩니다. 하지만 세 번째 파라미터로 위치를 조정할 수 있습니다.
"-=0.5"는 0.5초 앞당기고, "+=0.5"는 0.5초 지연시킵니다. "<"는 이전 애니메이션의 시작 시점과 동시에 시작하고, ">"는 끝나는 시점과 동시에 시작합니다.
숫자로 절대 시간을 지정할 수도 있습니다. 예를 들어 2는 "Timeline 시작 후 2초 지점"을 의미합니다.
Timeline 제어 Timeline은 비디오 플레이어처럼 제어할 수 있습니다. pause()로 일시정지하고, play()로 재생하고, reverse()로 역재생할 수 있습니다.
restart()는 처음부터 다시 시작합니다. 이런 제어 메서드들은 사용자 인터랙션과 연결할 때 매우 유용합니다.
예를 들어 마우스를 올리면 애니메이션이 재생되고, 마우스를 떼면 역재생되어 원래대로 돌아가는 효과를 쉽게 만들 수 있습니다. 실무 활용 사례 실제 현업에서는 어떻게 활용할까요?
예를 들어 제품 소개 페이지를 만든다고 가정해봅시다. 스크롤하면 제품 이미지가 왼쪽에서 슬라이드되어 들어오고, 이어서 제품 설명이 나타나고, 가격과 구매 버튼이 순차적으로 나타나는 효과를 원합니다.
Timeline을 사용하면 이런 복잡한 시퀀스를 몇 줄의 코드로 깔끔하게 구현할 수 있습니다. 또한 Timeline은 중첩할 수도 있습니다.
큰 Timeline 안에 작은 Timeline을 넣어서 재사용 가능한 애니메이션 모듈을 만들 수 있습니다. 주의사항 하지만 주의할 점도 있습니다.
초보 개발자들이 흔히 하는 실수 중 하나는 Timeline을 너무 복잡하게 만드는 것입니다. 하나의 Timeline에 수십 개의 애니메이션을 넣으면 오히려 관리하기 어려워집니다.
적절히 분리하여 여러 Timeline으로 나누는 것이 좋습니다. 또한 위치 파라미터를 과도하게 사용하면 코드를 읽기 어려워질 수 있습니다.
"-=0.3", "+=0.7" 같은 값들이 많아지면 전체 흐름을 파악하기 힘듭니다. 가능한 한 기본 순차 실행을 사용하고, 꼭 필요한 곳에만 위치 파라미터를 사용하세요.
정리 다시 김개발 씨의 이야기로 돌아가 봅시다. Timeline을 사용한 후 김개발 씨의 코드는 훨씬 깔끔해졌습니다.
디자이너가 "로고 애니메이션을 더 빠르게 해주세요"라고 요청했을 때도 한 줄만 수정하면 끝이었습니다. Timeline을 제대로 활용하면 복잡한 시퀀스 애니메이션도 쉽게 관리할 수 있습니다.
여러분도 오늘 배운 내용을 프로젝트에 적용해 보세요.
실전 팁
💡 - defaults 옵션을 활용하면 반복 코드를 줄일 수 있습니다
- 위치 파라미터 "<"를 사용하면 여러 애니메이션을 동시에 시작할 수 있습니다
- Timeline에 라벨을 추가하면 특정 지점으로 쉽게 이동할 수 있습니다
3. 캐릭터 움직임 구현
김개발 씨는 이번에 미니 게임 프로젝트를 맡았습니다. 화면에 캐릭터가 있고, 버튼을 클릭하면 점프하고 달리는 애니메이션을 만들어야 했습니다.
"캐릭터가 자연스럽게 움직이려면 어떻게 해야 하지?" 고민하던 김개발 씨에게 박시니어 씨가 말했습니다. "GSAP로 캐릭터 애니메이션을 만들면 정말 생동감 넘치게 만들 수 있어요."
캐릭터 애니메이션은 게임이나 인터랙티브 웹에서 핵심적인 요소입니다. GSAP를 사용하면 점프, 달리기, 공격 같은 복잡한 동작을 자연스럽게 구현할 수 있습니다.
Timeline과 다양한 easing 함수를 조합하여 물리 법칙을 따르는 듯한 리얼한 움직임을 만들 수 있습니다.
다음 코드를 살펴봅시다.
import { gsap } from "gsap";
// 캐릭터 점프 애니메이션
function jump(character) {
const tl = gsap.timeline();
tl.to(character, {
y: -150, // 위로 150px 점프
duration: 0.4,
ease: "power2.out" // 올라갈 때는 감속
})
.to(character, {
y: 0, // 원래 위치로 착지
duration: 0.4,
ease: "power2.in" // 내려올 때는 가속
})
.to(character, {
scaleY: 0.8, // 착지 시 찌그러짐
scaleX: 1.2,
duration: 0.1
})
.to(character, {
scaleY: 1, // 원래 모양으로 복구
scaleX: 1,
duration: 0.1
});
return tl;
}
// 사용 예시
document.querySelector(".jump-btn").addEventListener("click", () => {
jump(".character");
});
김개발 씨는 화면에 귀여운 캐릭터 스프라이트를 배치했습니다. 이제 이 캐릭터가 살아 움직이게 만들어야 합니다.
단순히 위로 올라갔다 내려오는 것만으로는 부족합니다. 진짜 게임 캐릭터처럼 생동감 있게 만들고 싶었습니다.
"어떻게 하면 자연스럽게 보일까?" 김개발 씨는 실제 사람이 점프하는 모습을 떠올려 봤습니다. 올라갈 때는 점점 느려지고, 내려올 때는 점점 빨라집니다.
그리고 땅에 착지할 때는 살짝 찌그러집니다. 물리 법칙을 따르는 애니메이션 현실 세계의 움직임은 물리 법칙을 따릅니다.
공을 위로 던지면 처음에는 빠르게 올라가다가 점점 속도가 줄어들고, 최고점에 도달한 후 다시 떨어지기 시작합니다. 떨어질 때는 중력 때문에 점점 빨라집니다.
이것이 바로 자연스러운 움직임의 핵심입니다. 캐릭터 애니메이션도 마찬가지입니다.
이런 물리 법칙을 무시하고 등속 운동으로만 애니메이션하면 로봇처럼 뻣뻣해 보입니다. 사용자는 무의식적으로 이런 부자연스러움을 감지합니다.
easing이 만드는 차이 바로 이런 물리적 사실감을 주는 것이 easing 함수입니다. 올라갈 때는 "power2.out"을 사용합니다.
이것은 처음에는 빠르게 시작했다가 점점 느려지는 곡선입니다. 마치 중력에 저항하며 올라가는 것처럼 보입니다.
내려올 때는 "power2.in"을 사용합니다. 처음에는 천천히 떨어지다가 점점 빨라지는 것입니다.
이 두 가지 easing만으로도 점프 동작이 훨씬 자연스러워집니다. 코드 분석 위의 코드를 한 줄씩 살펴보겠습니다.
먼저 Timeline을 생성합니다. 점프는 여러 단계로 구성되기 때문에 Timeline이 필수입니다.
첫 번째 to()는 캐릭터를 y: -150 위치로 이동시킵니다. y가 음수라는 것은 위쪽 방향을 의미합니다.
두 번째 to()는 다시 y: 0으로 돌아옵니다. 즉 원래 위치로 착지하는 것입니다.
여기서 ease를 "power2.in"으로 바꾼 것에 주목하세요. 올라갈 때와 내려올 때의 가속도가 반대입니다.
세 번째와 네 번째 to()는 착지 효과입니다. 착지하는 순간 scaleY를 0.8로, scaleX를 1.2로 만들어서 캐릭터가 찌그러지는 효과를 줍니다.
그리고 즉시 원래대로 복구됩니다. 이 짧은 0.1초 효과가 생동감을 크게 높여줍니다.
스쿼시와 스트레치 이 착지 효과는 애니메이션의 12가지 원칙 중 하나인 스쿼시와 스트레치(Squash and Stretch)입니다. 디즈니에서 정립한 이 원칙은 물체가 움직일 때 형태가 변형되는 것을 표현합니다.
공이 바닥에 떨어지면 찌그러지고, 다시 튀어 오르면서 늘어납니다. 이것이 바로 생동감의 비결입니다.
캐릭터 애니메이션에서도 이 원칙을 적용하면 훨씬 살아있는 느낌을 줄 수 있습니다. 단순히 위치만 바꾸는 것이 아니라 형태도 함께 변형시키는 것입니다.
달리기 애니메이션 점프 외에도 다양한 동작을 구현할 수 있습니다. 달리기 애니메이션은 반복적인 움직임입니다.
scaleX를 주기적으로 변화시키면 좌우로 흔들리는 효과를 줄 수 있고, y를 살짝 변화시키면 위아래로 튀는 느낌을 줄 수 있습니다. rotation을 추가하면 몸을 숙이고 달리는 모습을 표현할 수 있습니다.
이런 작은 디테일들이 모여서 캐릭터가 살아 움직이는 것처럼 보이게 만듭니다. 실무 활용 사례 실제 현업에서는 어떻게 활용할까요?
게임뿐만 아니라 일반 웹사이트에서도 캐릭터 애니메이션을 사용합니다. 예를 들어 이커머스 사이트의 마스코트 캐릭터가 사용자의 행동에 반응하여 움직이거나, 온보딩 튜토리얼에서 가이드 캐릭터가 화면을 안내하는 경우가 있습니다.
교육용 웹사이트에서는 캐릭터가 문제를 맞췄을 때 기뻐하는 애니메이션, 틀렸을 때 슬퍼하는 애니메이션을 보여줘서 학습 동기를 높입니다. 반복 애니메이션 캐릭터가 가만히 서 있을 때도 완전히 정지하면 이상해 보입니다.
실제 사람도 가만히 서 있을 때 미세하게 움직입니다. 숨을 쉬고, 몸이 살짝 흔들리고, 눈을 깜빡입니다.
이런 idle 애니메이션을 추가하면 캐릭터가 훨씬 생생해집니다. GSAP의 repeat: -1 옵션을 사용하면 무한 반복 애니메이션을 만들 수 있습니다.
yoyo: true를 추가하면 왕복 운동을 합니다. 주의사항 하지만 주의할 점도 있습니다.
과도한 애니메이션은 오히려 산만할 수 있습니다. 캐릭터가 너무 많이 움직이거나 너무 빠르게 움직이면 사용자가 집중하기 어려워집니다.
적절한 타이밍과 강도를 찾는 것이 중요합니다. 또한 모바일 환경을 고려해야 합니다.
복잡한 캐릭터 애니메이션은 성능에 영향을 줄 수 있으므로, 모바일에서는 단순화하거나 프레임 수를 줄이는 것이 좋습니다. 정리 다시 김개발 씨의 이야기로 돌아가 봅시다.
캐릭터에 점프 애니메이션을 추가한 김개발 씨는 신기해했습니다. "이렇게 간단한 코드로 이렇게 자연스러운 움직임을 만들 수 있다니!" 캐릭터 애니메이션의 핵심은 물리 법칙과 애니메이션 원칙을 이해하는 것입니다.
GSAP는 이것을 쉽게 구현할 수 있게 도와줍니다.
실전 팁
💡 - 착지 효과를 추가하면 생동감이 크게 높아집니다
- idle 애니메이션으로 캐릭터가 살아있는 느낌을 줄 수 있습니다
- 모바일에서는 애니메이션을 단순화하여 성능을 유지하세요
4. Easing 함수 활용
김개발 씨는 애니메이션을 만들 때마다 항상 같은 ease: "power2.out"만 사용했습니다. 그러다 디자이너가 피드백을 주었습니다.
"이 버튼은 좀 더 통통 튀는 느낌으로, 저 패널은 부드럽게 미끄러지는 느낌으로 해주세요." 김개발 씨는 당황했습니다. "어떻게 다르게 만들지?" 박시니어 씨가 GSAP의 다양한 easing 함수들을 보여주며 설명했습니다.
Easing 함수는 애니메이션의 가속도 곡선을 결정하는 핵심 요소입니다. 같은 위치 변화라도 어떤 easing을 사용하느냐에 따라 완전히 다른 느낌을 줄 수 있습니다.
GSAP는 power, elastic, bounce, back 등 다양한 easing 함수를 제공하며, 각각 고유한 특성과 느낌을 가지고 있습니다.
다음 코드를 살펴봅시다.
import { gsap } from "gsap";
// Power 계열: 부드러운 가속/감속
gsap.to(".box1", { x: 300, ease: "power1.out" }); // 부드러운 감속
gsap.to(".box2", { x: 300, ease: "power2.out" }); // 중간 감속
gsap.to(".box3", { x: 300, ease: "power4.out" }); // 강한 감속
// Elastic: 탄성 효과 (스프링처럼)
gsap.to(".button", {
scale: 1.2,
ease: "elastic.out(1, 0.3)" // 파라미터로 강도 조절
});
// Bounce: 통통 튀는 효과
gsap.to(".ball", {
y: 0,
ease: "bounce.out" // 착지할 때 튀는 효과
});
// Back: 살짝 뒤로 갔다가 진행
gsap.to(".panel", {
x: 300,
ease: "back.out(1.7)" // 목표를 살짝 넘었다가 돌아옴
});
// Custom: 커스텀 베지어 곡선
gsap.to(".custom", {
x: 300,
ease: "cubic-bezier(0.68, -0.55, 0.265, 1.55)"
});
김개발 씨는 버튼 클릭 애니메이션을 만들고 있었습니다. 버튼을 클릭하면 살짝 커지는 효과를 주고 싶었습니다.
처음에는 ease: "power2.out"을 사용했는데, 디자이너가 피드백을 주었습니다. "좋은데, 좀 더 재미있는 느낌은 안 될까요?
버튼이 살짝 튀는 느낌으로요." 김개발 씨는 막막했습니다. 어떻게 "튀는 느낌"을 코드로 표현할까요?
Easing이 만드는 감성 애니메이션에서 easing은 감성을 결정하는 가장 중요한 요소입니다. 같은 A 지점에서 B 지점으로 이동하는 애니메이션이라도, 어떻게 이동하느냐에 따라 완전히 다른 느낌을 줍니다.
기계처럼 정확하게 보일 수도 있고, 유기적이고 살아있는 것처럼 보일 수도 있습니다. 마치 음악에서 같은 멜로디라도 연주 방식에 따라 슬프게도, 경쾌하게도 들리는 것과 같습니다.
Easing은 애니메이션의 리듬이자 감정입니다. Power 계열: 기본이 되는 곡선 가장 많이 사용되는 것이 power 계열입니다.
power1, power2, power3, power4로 갈수록 곡선이 가파라집니다. 숫자가 작으면 부드럽고 자연스럽고, 숫자가 크면 극적이고 강렬합니다.
대부분의 경우 power2나 power3이 가장 자연스럽습니다. in은 천천히 시작했다가 빨라지고, out은 빠르게 시작했다가 느려지고, inOut은 양쪽 모두입니다.
일반적으로 out이 가장 자연스럽게 느껴집니다. Elastic: 스프링의 탄성 elastic은 스프링처럼 튕기는 효과입니다.
목표 지점을 넘었다가 다시 돌아오기를 몇 번 반복합니다. 마치 용수철을 늘렸다가 놓았을 때의 움직임과 같습니다.
이것은 매우 강렬한 효과이므로 신중하게 사용해야 합니다. elastic.out(1, 0.3)에서 첫 번째 파라미터는 진폭(얼마나 튕길지), 두 번째는 주기(얼마나 빠르게 튕길지)를 조절합니다.
값을 조정하면 부드러운 탄성부터 격렬한 흔들림까지 다양하게 표현할 수 있습니다. Bounce: 공이 튀는 효과 bounce는 공이 바닥에 떨어져 튀는 효과입니다.
elastic과 비슷해 보이지만 다릅니다. elastic은 목표를 중심으로 양방향으로 진동하지만, bounce는 한 방향으로만 튕깁니다.
착지 애니메이션에 특히 효과적입니다. 예를 들어 위에서 떨어지는 알림 메시지를 만들 때 bounce.out을 사용하면 마치 가벼운 공이 톡톡 튀면서 착지하는 것처럼 보입니다.
재미있고 친근한 느낌을 줍니다. Back: 예상을 벗어나는 움직임 back은 목표 지점을 살짝 넘었다가 돌아오는 효과입니다.
back.out은 목표보다 약간 더 멀리 갔다가 다시 제자리로 돌아옵니다. back.in은 시작하기 전에 살짝 뒤로 갔다가 출발합니다.
마치 야구공을 던지기 전에 팔을 뒤로 당기는 것과 같은 "준비 동작"처럼 보입니다. 이것은 사용자의 시선을 끄는 데 매우 효과적입니다.
예상과 다른 움직임이 주목도를 높입니다. 코드 분석 위의 코드를 살펴보겠습니다.
각 easing 함수는 완전히 다른 느낌을 만듭니다. power는 안정적이고 professional한 느낌, elastic은 playful하고 재미있는 느낌, bounce는 경쾌하고 가벼운 느낌, back은 역동적이고 attention-grabbing한 느낌을 줍니다.
같은 scale 변화라도 어떤 easing을 사용하느냐에 따라 사용자가 받는 인상이 완전히 달라집니다. 실무에서의 선택 그렇다면 어떤 easing을 선택해야 할까요?
일반적으로 power2.out이나 power3.out이 가장 무난합니다. 대부분의 UI 애니메이션에 적합하며, 전문적이고 세련된 느낌을 줍니다.
구글, 애플 같은 회사들도 주로 이런 곡선을 사용합니다. elastic이나 bounce는 재미있고 캐주얼한 서비스에 적합합니다.
게임, 어린이 앱, 엔터테인먼트 서비스 등에서 효과적입니다. 하지만 금융이나 의료 같은 serious한 도메인에서는 부적절할 수 있습니다.
back은 특별한 강조가 필요한 요소에 사용하면 좋습니다. 중요한 버튼, 특별 이벤트 배너, 새로운 기능 소개 등에 사용하면 사용자의 시선을 효과적으로 끌 수 있습니다.
Custom Easing 필요하다면 cubic-bezier로 완전히 커스텀한 easing을 만들 수 있습니다. 하지만 대부분의 경우 GSAP가 제공하는 기본 easing으로 충분합니다.
굳이 custom을 만들기보다는 기존 easing의 파라미터를 조정하는 것이 더 효율적입니다. 일관성의 중요성 실무에서 가장 중요한 것은 일관성입니다.
한 페이지 내에서 너무 많은 종류의 easing을 섞어 쓰면 산만해 보입니다. 기본 easing을 2-3가지 정도로 정하고 일관되게 사용하는 것이 좋습니다.
예를 들어 일반 UI는 power2.out, 강조 요소는 back.out, 재미있는 요소는 elastic.out 식으로 규칙을 정하는 것입니다. 주의사항 하지만 주의할 점도 있습니다.
초보 개발자들이 흔히 하는 실수는 elastic이나 bounce를 과도하게 사용하는 것입니다. 처음에는 재미있어 보이지만, 모든 요소가 튕기고 흔들리면 오히려 피곤해집니다.
적절히 사용해야 효과적입니다. 또한 duration과 easing은 함께 고려해야 합니다.
짧은 duration에 강한 easing을 사용하면 너무 급격해 보이고, 긴 duration에 약한 easing을 사용하면 지루해 보입니다. 정리 다시 김개발 씨의 이야기로 돌아가 봅시다.
elastic.out을 적용한 버튼을 본 디자이너가 환하게 웃었습니다. "바로 이거예요!
이런 느낌이었어요!" Easing은 애니메이션의 감성을 결정합니다. 상황에 맞는 easing을 선택하면 사용자 경험이 크게 향상됩니다.
실전 팁
💡 - 일반적인 UI에는 power2.out이 가장 무난합니다
- GreenSock의 Ease Visualizer 도구로 easing을 직접 보고 선택할 수 있습니다
- 브랜드 성격에 맞는 easing을 정해 일관되게 사용하세요
5. 인터랙티브 애니메이션 제어
김개발 씨는 이번에는 사용자 인터랙션에 반응하는 애니메이션을 만들어야 했습니다. 마우스를 올리면 메뉴가 펼쳐지고, 떼면 다시 접히고, 드래그하면 따라오는 효과가 필요했습니다.
"애니메이션을 어떻게 중간에 멈추고, 되돌리고, 다시 시작하지?" 고민하던 김개발 씨에게 박시니어 씨가 말했습니다. "GSAP Timeline은 비디오 플레이어처럼 자유롭게 제어할 수 있어요."
인터랙티브 애니메이션은 사용자의 행동에 실시간으로 반응하는 애니메이션입니다. GSAP의 Timeline을 활용하면 애니메이션을 재생, 일시정지, 역재생, 특정 지점으로 이동 등 자유롭게 제어할 수 있습니다.
마우스 이벤트, 스크롤, 드래그 등 다양한 인터랙션과 연결하여 생동감 넘치는 사용자 경험을 만들 수 있습니다.
다음 코드를 살펴봅시다.
import { gsap } from "gsap";
// 메뉴 펼치기/접기 애니메이션
const menuTl = gsap.timeline({ paused: true });
menuTl
.to(".menu", { height: "auto", duration: 0.3 })
.to(".menu-item", { opacity: 1, y: 0, stagger: 0.1 }, "-=0.2");
// 마우스 이벤트로 제어
document.querySelector(".menu-btn").addEventListener("mouseenter", () => {
menuTl.play(); // 재생
});
document.querySelector(".menu-btn").addEventListener("mouseleave", () => {
menuTl.reverse(); // 역재생
});
// 프로그레스바와 연동
const progressTl = gsap.timeline({ paused: true });
progressTl.to(".loader", { width: "100%", duration: 2 });
document.querySelector(".slider").addEventListener("input", (e) => {
// 슬라이더 값에 따라 애니메이션 위치 조정 (0~1)
progressTl.progress(e.target.value / 100);
});
// 드래그 앤 드롭
gsap.utils.toArray(".draggable").forEach(elem => {
let isDragging = false;
elem.addEventListener("mousedown", () => {
isDragging = true;
gsap.to(elem, { scale: 1.1, duration: 0.2 });
});
document.addEventListener("mousemove", (e) => {
if (isDragging) {
gsap.to(elem, { x: e.clientX, y: e.clientY, duration: 0.1 });
}
});
document.addEventListener("mouseup", () => {
if (isDragging) {
isDragging = false;
gsap.to(elem, { scale: 1, duration: 0.2 });
}
});
});
김개발 씨는 드롭다운 메뉴를 만들고 있었습니다. 마우스를 올리면 메뉴가 부드럽게 펼쳐지고, 마우스를 떼면 다시 접히는 효과를 원했습니다.
처음에는 두 개의 별도 애니메이션을 만들었는데, 사용자가 애니메이션 중간에 마우스를 뗐다가 다시 올리면 이상하게 작동했습니다. "애니메이션이 끝나지 않은 상태에서 다시 시작하면 어떻게 하지?" 김개발 씨는 복잡한 상태 관리 코드를 작성하려다가 막막해졌습니다.
애니메이션 제어의 필요성 정적인 애니메이션은 한 번 재생하면 끝입니다. 하지만 인터랙티브 웹에서는 사용자의 행동에 따라 애니메이션을 실시간으로 제어해야 합니다.
사용자가 버튼에 마우스를 올렸다가 떼면 어떻게 될까요? 애니메이션이 끝나기를 기다릴 수는 없습니다.
즉시 반응해야 합니다. 중간에 멈추고, 되돌리고, 다시 시작할 수 있어야 합니다.
이것은 마치 비디오 플레이어와 같습니다. 재생, 일시정지, 되감기, 특정 시간으로 점프 등의 기능이 필요합니다.
Timeline의 제어 메서드 GSAP Timeline은 바로 이런 제어 기능을 제공합니다. **play()**는 애니메이션을 재생합니다.
**pause()**는 현재 위치에서 멈춥니다. **reverse()**는 역방향으로 재생합니다.
이것이 핵심입니다. 펼치기 애니메이션을 역재생하면 자동으로 접기 애니메이션이 되는 것입니다.
**restart()**는 처음부터 다시 시작하고, **seek()**는 특정 시간으로 이동합니다. **progress()**는 전체 진행도를 0에서 1 사이의 값으로 설정합니다.
paused: true의 마법 Timeline을 생성할 때 paused: true 옵션을 주는 것이 핵심입니다. 이렇게 하면 Timeline이 만들어지지만 자동으로 재생되지 않습니다.
대기 상태로 있다가 이벤트가 발생하면 재생됩니다. 마치 영화 DVD를 넣어두고 재생 버튼을 누를 준비를 하는 것과 같습니다.
이것 없이 Timeline을 만들면 즉시 재생되어 버립니다. 인터랙티브 애니메이션에서는 대부분 paused: true를 사용합니다.
코드 분석: 메뉴 애니메이션 위의 메뉴 코드를 살펴보겠습니다. 먼저 Timeline을 paused: true로 생성합니다.
메뉴가 펼쳐지는 애니메이션을 정의하되, 아직 실행하지는 않습니다. mouseenter 이벤트가 발생하면 play()를 호출하여 재생하고, mouseleave가 발생하면 reverse()를 호출하여 역재생합니다.
이 간단한 코드만으로 부드러운 펼치기/접기 효과가 완성됩니다. 사용자가 중간에 마우스를 떼도 자연스럽게 작동합니다.
GSAP가 현재 진행 상태를 기억하고 있다가 그 지점에서부터 역재생하기 때문입니다. Progress를 활용한 스크러빙 progress() 메서드는 매우 강력합니다.
0에서 1 사이의 값으로 애니메이션의 정확한 위치를 설정할 수 있습니다. 0은 시작, 0.5는 중간, 1은 끝입니다.
이것을 슬라이더나 스크롤과 연결하면 사용자가 애니메이션을 직접 제어할 수 있게 됩니다. 예를 들어 제품 설명 페이지에서 스크롤 위치에 따라 제품이 회전하거나, 프로그레스바에 따라 차트가 채워지는 효과를 만들 수 있습니다.
사용자가 애니메이션의 주인이 되는 것입니다. 드래그 앤 드롭 드래그 가능한 요소를 만드는 것도 간단합니다.
mousedown에서 드래그 시작, mousemove에서 위치 추적, mouseup에서 드래그 종료를 처리합니다. GSAP의 gsap.to()를 사용하면 마우스를 따라가는 움직임도 부드럽게 처리됩니다.
duration을 짧게 설정하면 즉각 반응하고, 길게 설정하면 약간의 지연이 생겨 더 부드러운 느낌을 줍니다. 이것은 마치 물속에서 움직이는 것 같은 효과를 만듭니다.
실무 활용 사례 실제 현업에서는 어떻게 활용할까요? 네비게이션 메뉴의 펼침/접힘, 모달 창의 열림/닫힘, 아코디언 패널, 탭 전환 등 거의 모든 UI 인터랙션에 사용할 수 있습니다.
단순한 CSS transition보다 훨씬 세밀하게 제어할 수 있고, 복잡한 시퀀스도 쉽게 만들 수 있습니다. 예를 들어 전자상거래 사이트의 장바구니 버튼을 클릭하면 상품이 날아가서 장바구니 아이콘으로 들어가는 애니메이션을 만들 수 있습니다.
이런 마이크로 인터랙션이 사용자 경험을 크게 향상시킵니다. 반응성 있는 애니메이션 좋은 인터랙티브 애니메이션은 즉각 반응합니다.
사용자가 버튼을 클릭했을 때 0.5초 후에 반응하면 느리게 느껴집니다. 100ms 이내에 반응해야 사용자가 "내가 제어하고 있다"고 느낍니다.
GSAP는 매우 빠르기 때문에 이런 즉각적인 반응을 구현하기에 적합합니다. 또한 애니메이션 중간에 사용자가 다시 인터랙션을 하면 자연스럽게 전환되어야 합니다.
GSAP는 이런 중단과 재시작을 부드럽게 처리합니다. 주의사항 하지만 주의할 점도 있습니다.
이벤트 리스너를 너무 많이 추가하면 메모리 누수가 발생할 수 있습니다. 특히 동적으로 생성되는 요소에 이벤트를 붙일 때는 나중에 제거하는 것도 잊지 말아야 합니다.
또한 mousemove 같은 고빈도 이벤트에서 애니메이션을 실행할 때는 성능에 주의해야 합니다. 필요하다면 throttle이나 debounce를 사용하여 호출 빈도를 제한하는 것이 좋습니다.
정리 다시 김개발 씨의 이야기로 돌아가 봅시다. Timeline의 제어 메서드를 배운 김개발 씨는 복잡한 상태 관리 코드 없이도 부드러운 인터랙티브 메뉴를 완성했습니다.
"이렇게 간단할 수가!" 애니메이션을 제어할 수 있으면 정적인 페이지가 살아있는 인터페이스로 변합니다. 사용자와 대화하는 웹을 만들 수 있습니다.
실전 팁
💡 - paused: true로 Timeline을 만들고 이벤트로 제어하세요
- reverse()를 활용하면 되돌아가는 애니메이션을 따로 만들 필요가 없습니다
- progress()로 스크롤이나 슬라이더와 연동할 수 있습니다
6. Three.js와 GSAP 통합
김개발 씨는 드디어 3D 프로젝트를 맡게 되었습니다. Three.js로 3D 모델을 화면에 띄우는 데는 성공했지만, 카메라를 부드럽게 움직이거나 오브젝트를 애니메이션하는 것이 어려웠습니다.
Three.js의 기본 애니메이션 방식은 복잡했고, 타이밍 조절도 힘들었습니다. 박시니어 씨가 조언했습니다.
"GSAP를 Three.js와 함께 쓰면 3D 애니메이션이 정말 쉬워져요."
Three.js와 GSAP의 통합은 3D 웹 개발의 강력한 조합입니다. GSAP로 Three.js의 카메라, 오브젝트, 머티리얼 속성 등을 쉽게 애니메이션할 수 있습니다.
복잡한 requestAnimationFrame 루프를 직접 관리할 필요 없이, GSAP의 직관적인 API로 부드럽고 정교한 3D 애니메이션을 구현할 수 있습니다.
다음 코드를 살펴봅시다.
import * as THREE from 'three';
import { gsap } from 'gsap';
// Three.js 기본 설정
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// 3D 큐브 생성
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
camera.position.z = 5;
// GSAP로 큐브 회전 애니메이션
gsap.to(cube.rotation, {
y: Math.PI * 2, // 360도 회전
duration: 2,
repeat: -1, // 무한 반복
ease: "none" // 등속 회전
});
// 카메라 이동 애니메이션
gsap.to(camera.position, {
z: 3,
duration: 1.5,
ease: "power2.inOut"
});
// 머티리얼 색상 변화
gsap.to(cube.material.color, {
r: 1,
g: 0,
b: 0,
duration: 2,
yoyo: true, // 왕복
repeat: -1
});
// Three.js 렌더 루프
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
animate();
// 클릭 이벤트로 큐브 점프
document.addEventListener('click', () => {
gsap.to(cube.position, {
y: 2,
duration: 0.5,
ease: "power2.out",
onComplete: () => {
gsap.to(cube.position, { y: 0, duration: 0.5, ease: "bounce.out" });
}
});
});
김개발 씨는 회사 홈페이지에 3D 제품 뷰어를 만들고 있었습니다. Three.js로 3D 모델을 불러오는 데는 성공했지만, 사용자가 버튼을 클릭하면 카메라가 부드럽게 제품을 한 바퀴 돌면서 보여주는 기능을 구현하기가 어려웠습니다.
Three.js의 Tween 라이브러리를 사용해 보았지만 복잡했고, 직접 requestAnimationFrame 안에서 계산하려니 코드가 엉망이 되었습니다. "더 쉬운 방법은 없을까?" 3D 애니메이션의 어려움 3D 애니메이션은 2D보다 복잡합니다.
카메라 위치, 회전, FOV를 동시에 조정해야 하고, 오브젝트의 position, rotation, scale을 3축(x, y, z)으로 각각 제어해야 합니다. 타이밍을 맞추고 easing을 적용하는 것도 쉽지 않습니다.
Three.js는 3D 렌더링에는 탁월하지만, 애니메이션 제어는 개발자가 직접 해야 하는 부분이 많습니다. requestAnimationFrame 안에서 시간을 추적하고, 직접 보간 계산을 하고, easing 함수를 구현해야 합니다.
GSAP가 해결하는 문제 바로 여기서 GSAP가 빛을 발합니다. GSAP는 어떤 자바스크립트 객체의 속성이든 애니메이션할 수 있습니다.
Three.js의 카메라도, 메쉬도, 머티리얼도 모두 자바스크립트 객체입니다. 따라서 GSAP로 자유롭게 애니메이션할 수 있습니다.
복잡한 수학 계산 없이, 시간 추적 없이, 단순히 gsap.to()만 호출하면 됩니다. Three.js의 렌더링 파워와 GSAP의 애니메이션 편의성이 완벽하게 결합되는 것입니다.
기본 통합 방법 통합 방법은 매우 간단합니다. Three.js의 렌더 루프는 그대로 유지합니다.
requestAnimationFrame으로 계속 화면을 갱신합니다. 하지만 애니메이션 로직은 GSAP에 맡깁니다.
GSAP가 내부적으로 속성 값을 변경하면, 렌더 루프가 그 변경사항을 화면에 반영하는 것입니다. 이것은 마치 배우(GSAP)가 연기하면 카메라맨(Three.js)이 촬영하는 것과 같습니다.
각자의 역할에 충실하면서 완벽하게 협업하는 것입니다. 코드 분석: 큐브 애니메이션 위의 코드를 살펴보겠습니다.
gsap.to(cube.rotation, {...})는 큐브의 rotation 객체를 애니메이션합니다. rotation.y를 Math.PI * 2 (360도)까지 증가시키면 큐브가 회전합니다.
repeat: -1로 무한 반복하고, ease: "none"으로 등속 회전을 만듭니다. 카메라 애니메이션도 똑같습니다.
camera.position.z를 5에서 3으로 변경하면 카메라가 오브젝트에 가까워집니다. power2.inOut easing으로 부드럽게 시작했다가 부드럽게 끝납니다.
색상 애니메이션 Three.js의 Color 객체도 애니메이션할 수 있습니다. cube.material.color는 r, g, b 속성을 가진 객체입니다.
GSAP로 이 값들을 변경하면 색상이 부드럽게 전환됩니다. yoyo: true로 왕복 애니메이션을 만들면 색상이 변했다가 다시 돌아오기를 반복합니다.
이것은 CSS에서는 할 수 없는 강력한 기능입니다. 3D 오브젝트의 머티리얼 속성을 실시간으로 애니메이션하는 것입니다.
카메라 오빗 애니메이션 실무에서 가장 많이 사용되는 것이 카메라를 오브젝트 주위로 회전시키는 애니메이션입니다. 카메라를 원형 궤도로 움직이려면 삼각함수를 사용해야 합니다.
GSAP로 각도 변수를 애니메이션하고, onUpdate 콜백에서 카메라 위치를 계산하면 됩니다. 이렇게 하면 카메라가 오브젝트를 중심으로 부드럽게 돌면서 촬영하는 효과를 만들 수 있습니다.
인터랙티브 3D 경험 클릭 이벤트와 연결하면 인터랙티브한 3D 경험을 만들 수 있습니다. 위의 코드에서 클릭하면 큐브가 점프합니다.
먼저 y: 2로 올라갔다가, onComplete 콜백에서 다시 y: 0으로 내려옵니다. 내려올 때 bounce.out easing을 사용하여 통통 튀는 효과를 줍니다.
이런 식으로 사용자 인터랙션에 반응하는 3D 애니메이션을 쉽게 만들 수 있습니다. 실무 활용 사례 실제 현업에서는 어떻게 활용할까요?
전자상거래 사이트의 3D 제품 뷰어에서 카메라를 자동으로 회전시키거나, 사용자가 버튼을 클릭하면 특정 부분을 클로즈업하는 기능을 만들 수 있습니다. 건축 시각화에서는 건물 안을 투어하는 애니메이션을 만들 수 있습니다.
게임에서는 캐릭터의 움직임, 카메라 시네마틱, UI 전환 등에 GSAP를 활용합니다. Three.js의 강력한 3D 렌더링 능력과 GSAP의 쉬운 애니메이션 제어가 만나면 무한한 가능성이 열립니다.
성능 최적화 3D 애니메이션은 성능에 민감합니다. GSAP는 매우 최적화되어 있지만, Three.js의 렌더 루프가 60fps를 유지하는 것이 중요합니다.
너무 많은 오브젝트를 동시에 애니메이션하거나, 복잡한 계산을 매 프레임마다 수행하면 프레임 드롭이 발생할 수 있습니다. 필요하지 않을 때는 renderer.setAnimationLoop(null)로 렌더링을 멈추고, 애니메이션이 필요할 때만 다시 시작하는 것도 좋은 최적화 방법입니다.
주의사항 하지만 주의할 점도 있습니다. Three.js의 렌더 루프와 GSAP의 업데이트가 별도로 동작하므로, 둘 사이의 동기화를 고려해야 합니다.
대부분의 경우 문제없지만, 매우 정밀한 타이밍이 필요한 경우 ticker를 사용하여 동기화할 수 있습니다. 또한 메모리 관리도 중요합니다.
Scene에서 제거한 오브젝트의 애니메이션도 명시적으로 kill()해야 메모리 누수를 방지할 수 있습니다. 정리 다시 김개발 씨의 이야기로 돌아가 봅시다.
GSAP를 Three.js와 결합한 후, 김개발 씨는 복잡한 3D 애니메이션을 놀랄 만큼 쉽게 구현할 수 있었습니다. "이제 3D도 무섭지 않아요!" GSAP와 Three.js의 조합은 현대 웹 3D 개발의 표준입니다.
강력한 도구들을 제대로 활용하면 놀라운 경험을 만들 수 있습니다.
실전 팁
💡 - Three.js 렌더 루프는 유지하고, 애니메이션 로직만 GSAP에 맡기세요
- onUpdate 콜백으로 복잡한 계산을 수행할 수 있습니다
- 모바일에서는 3D 오브젝트 수와 애니메이션 복잡도를 줄여 성능을 유지하세요
이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!
댓글 (0)
함께 보면 좋은 카드 뉴스
GitHub와 Vercel로 시작하는 배포 완벽 가이드
코드를 작성했다면 이제 세상에 공개할 차례입니다. GitHub에 코드를 올리고 Vercel로 배포하는 전체 과정을 실무 상황 스토리로 풀어냅니다. 초급 개발자도 따라하면서 자연스럽게 배포 프로세스를 이해할 수 있습니다.
3D 포트폴리오 웹사이트 개발 완벽 가이드
Three.js와 Blender를 활용하여 인상적인 3D 포트폴리오 웹사이트를 만드는 방법을 초급 개발자도 쉽게 이해할 수 있도록 실무 중심으로 설명합니다. 프로젝트 구조부터 접근성까지 모든 과정을 담았습니다.
Three.js 고급 코드 분석 완벽 가이드
Three.js 공식 예제를 분석하고 복잡한 씬 구조를 이해하는 방법부터 커스텀 Shader, PostProcessing, 성능 최적화, 디버깅까지 실무에서 바로 활용할 수 있는 고급 기법을 배웁니다. 초급 개발자도 쉽게 따라할 수 있도록 실무 상황 스토리와 비유로 풀어낸 가이드입니다.
Three.js 충돌 감지 완벽 가이드
3D 웹 게임에서 캐릭터가 벽을 뚫고 지나가는 문제를 해결하는 충돌 감지 기술을 배웁니다. Bounding Box부터 물리 엔진까지 실전 예제로 완벽하게 마스터해보세요.
Three.js Raycaster 상호작용 구현 완벽 가이드
Three.js의 Raycaster를 활용하여 3D 객체와의 상호작용을 구현하는 방법을 초급자 눈높이에서 설명합니다. 마우스 클릭, 터치 이벤트, 하이라이트 효과까지 실전 예제와 함께 배워봅니다.