이 게시물은 2020년 10월 23일 수정판입니다.
GSAP는, 웹 브라우저에서 애니메이션을 구현하기 위한 자바스크립트 라이브러리 입니다. 기존 CSS나 순수 자바스크립트보다 탁월한 퍼포먼스를 발휘할 수 있도록 최적화 된 애니메이션 전용 라이브러리이며, HTML5와 Flash 두 개의 플랫폼에서 사용할 수 있습니다.
스크롤 애니메이션 예제를 만들기 위해 제가 제작했던 워킹데드 시즌 프리뷰에서 사용된 핵심 기술이기도 한데, 라이브러리의 코어 엔진인 TweenLite를 기본으로, 개발자의 필요에 따라 다른 부수적인 플러그인을 로드해서 사용하거나 혹은, 통합 라이브러리인 TweenMax만 로드해서 사용합니다.
웹 페이지에서 애니메이션을 구현하는 양대 자바스크립트 라이브러리에는 3D 계열의 Three.js와 2D 계열의 GSAP가 주로 활용되고 있습니다.
이 문서는 GSAP에 대한 자세한 매뉴얼이 아닙니다. 개념을 빠르게 파악하고 실제 모델에서 빨리 구현하는 것을 목표로 서술하는 퀵 가이드(Quick Quide)입니다.
GSAP 웹 사이트 도처에 위치한 다운로드 링크를 통해 소스를 직접 내려받을 수 있습니다. 또한, CDN에 저장된 소스를 링크하여 사용할 수도 있습니다.
<!--CDN link for TweenMax--> <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.0/TweenMax.min.js"></script>
GSAP 대부분의 기능을 이용하려면 위와 같이 TweenMax 파일 하나만 로드하면 됩니다.
<!--CDN links for TweenLite, CSSPlugin, and EasePack--> <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.0/plugins/CSSPlugin.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.0/easing/EasePack.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.0/TweenLite.min.js"></script>
경량화, 혹은 꼭 필요한 부분만 그때그때 로드해서 사용하고 싶다면 위 처럼 핵심 코어 파일인 TweenLite 파일과 함께 부수 파일을 별도로 로드해도 됩니다.
GSAP는 기본적으로 jQuery에 의존하지 않지만, 함께 사용할 수 있습니다. jQuery 선택자(selector)와 오브젝트를 인식하며, 만일 jquery.animate() 메서드로 작성된 애니메이션을 GSAP 엔진으로 구동하고 싶다면, jquery.gsap.js 파일을 로드하면 됩니다.
<script src="js/TweenMax.min.js"></script> <script src="js/jquery.gsap.min.js"></script>
TweenLite는 모든 자바스크립트 객체의 숫자형 속성을 통해 움직임을 발생 시킬 수 있습니다(앞으로 이것을 “트윈”이라 칭합니다). 예를들어, 특정 속성의 값을 2초에 걸쳐 0에서 100으로 변화시키는 코드는 다음과 같습니다.
var obj = {myProp:0}; TweenLite.to(obj, 2, {myProp:100});
첫 번째 파라미터는 트윈 할 대상(Target)입니다. 두 번째 파라미터는 초 단위의 지속시간(duration), 세 번째는 속성(Properties)인데, 대상이 기존에 가지고 있던 속성 값과는 다른, 변화 된 값(End values)이어야 합니다. 그래야만 시작 속성에서 끝 속성으로 변화가 발생하면서, 이것이 움직임으로 표현됩니다.
위의 이야기를 실제로 풀어서, 좌표 값이 0인 square
라는 아이디의 요소를, 2초에 걸쳐 우측으로 200px만큼 이동시키는 코드에 대입해 보면 다음과 같습니다.
만일 jQuery가 이미 로드되어 있는 상태라면, 선택자를 더 간단히 사용할 수도 있습니다.
TweenLite.to("#square", 2, {left:"200px"});
여기에서 잠시, 여러분이 GSAP를 로컬 파일로 저장해서 웹 브라우저를 통해 테스트 할 수 있도록 실습 파일을 준비해 두었습니다. 아래 파일을 다운로드 받아서 index.html 파일을 웹 브라우저에서 열어보세요. 아래 예제 코드를 직접 타이핑하고 웹 브라우저를 새로고침하면서 실제 작동하는 것을 확인하세요.
이번에는 움직임의 방향성에 관련된 메서드에 대해 잠깐 살펴보겠습니다. 지금까지 예제에서 사용했던 .to()
메서드는, 기존에 스타일시트에 이미 명시되어 있는 값에서 시작하여, 트윈에 명시한 값으로 변화합니다. 예를들어, 위에서 잠깐 살펴본 우측으로 200px로 이동하는 객체는 이미 스타일시트에 기본 좌표 값으로 0이 명시되어 있다는 겁니다.
반대로, .from()
메서드는, 트윈에 명시한 값에서 스타일시트에 명시된 값으로 변화합니다. 그래서 .from() 메서드는 별도의 스타일시트 작성 없이, 한번 움직임을 줬던 객체를 역방향으로 다시 움직이게 할 때 용이합니다. 아래 예제의 경우는, 객체가 다시 좌측으로 200px 이동합니다.
TweenLite.from(myElement, 2, {left:"200px"});
스타일시트에 값을 명시하지 않고, 트윈의 .fromTo()
메서드를 사용하면 시작 값과 끝 값을 모두 명시해서 사용할 수도 있습니다. 이 경우는, 스타일시트에 값이 있더라도 무시합니다.
TweenLite.fromTo(myElement, 2, {left:0}, {left:"200px"});
이 외에도 여러가지 메서드를 사용해서 다양한 조작이 가능합니다. 에를들면, pause(), resume(), reverse(), restart() 등이 있습니다.
기본적으로, 트윈은 즉시 실행되지만, 일시적으로 실행을 멈춰 놓은 후, 원하는 때에 실행시킬 수도 있습니다. 변수 파라미터에 paused:true
를 사용하거나 인스턴스 혹은 객체에 직접 .pause()
메서드를 써도 됩니다. 아래는 파라미터에서 일시 정지를 정의하고, 객체를 클릭하면 .resume()
메서드를 통해 애니메이션이 재게되는 예제입니다.
움직임을 정의하는 트윈 자체를 myTween이라는 변수에 저장해서 사용한다는 점에 유의하세요.
var myElement = document.getElementById("square"); var myTween = TweenLite.to(myElement, 2, {left:"200px", paused:true}); myElement.onclick = function(){ myTween.resume(); }
몇 가지 특별한 속성들이 예약되어 있습니다. 예를들어 delay
같은 것들은, 트윈이 시작되기 전 일정 시간의 대기 시간을 갖게 합니다. 아래의 경우는 2초 후에 움직임이 발생하는 코드입니다.
TweenLite.to(myElement, 2, {left:"200px", delay:2});
이러한 예약된 특수 속성에는 onComplete, ease, ease, overwrite, paused, useFrames 등 다양하며, TweenLite Documentation에서 더 자세히 볼 수 있습니다.
이 중에서도 특히 자주 사용하게 되는 속성으로 두 가지가 있는데, 움직임의 앞과 뒤에 힘의 영향력을 주어 긴장감을 조절하는 ease 속성과, 애니메이션이 끝나고 난 후 특별한 이벤트를 발생시키는 onComplete 속성이 그것입니다.
ease에 대해서는 추후 조금 더 자세하게 알아보도록 하고, onComplete의 경우는 자바스크립트로 작성된 함수를 실행시킵니다. 아래의 예제는, 애니메이션이 끝나면 “Tween Finished”를 콘솔에 출력합니다.
TweenLite.to(myElement, 2, {left:"100px", delay: 2, onComplete:myFunction}); function myFunction() { console.log("Tween finished"); }
Ease는 움직임을 표현할 때 없어서는 안될 대단히 중요한 개념입니다. 사실 컴퓨터로 만든 움직임을 제외하고, 현실 세계의 모든 움직임에는 이 ease가 포함되어 있습니다.
여러분의 팔을 아래에서 머리 위로 올려 보세요. 그리고 그 모습을 슬로우 모션으로 본다고 가정하면,
이 개념이 없는 움직임은 흡사 로보트와 같이 딱딱하지만, 사실 로보트 마저도 아주 적게나마 ease 운동이 있습니다. 완전히 없을 수는 없습니다. GreenSock Ease Visualizer 페이지에서 이 ease 값을 변경해 봄으로서 직접 체감할 수 있습니다.
TweenLite에서의 기본 ease 값은 Power1.easeOut
입니다. 여기서 Power1은 이미 TweenLite에서 정의해 놓은 값으로서, 등속 운동보다는 조금 더 자연스러운 힘의 영향력을 갖습니다. 이 말이 난해하다는 것을 압니다. 일단은 그냥 “약한 정도의 힘”이라고 생각하세요.
easeOut
은, ease의 방향성입니다. Power1이라는 힘이, 움직임의 뒷 부분에 작용한다고 보면 됩니다. 따라서 첫 시작은 등속 운동으로 시작하고, 움직임이 끝날 즈음에서는 등속 운동보다 약간 느려지면서 멈춥니다. 만일 easeOut이 아니라 easeIn이었다면, 움직임의 첫 시작에서 약간 느리게 출발해서, 등속 운동으로 끝났을 겁니다.
TweenLite.to(myElement, 2, {left:"200px", ease:Power1.easeOut});
만일 움직임에서 ease를 완전히 제거하려고 한다면, 속성 값으로 ease:Linear.easeNone
을 사용하면 됩니다.
ease:Linear.easeNone
에서 Linear는 모션 그래픽이나 애니메이션에서 상당히 자주 접하게 되는 용어로서, “어떠한 변칙적인 힘의 영향력도 없는 등속 운동”으로 이해하면 됩니다. “움직임이 리니어하다”라는 의미는, 어떤 긴장감도 없이 밋밋하다, 딱딱하고 심심하다라는 표현으로 볼 수 있습니다.
여기에서 말하는 Ease In과 Out의 개념은, Adobe After Effects와 같은 키 프레임 기반의 그것과는 다릅니다. 웹에서의 모션은 키 프레임이라는 개념이 없기 때문에, 키를 중심으로 들어오는 영향력을 In, 키에서 나가는 영향력을 Out으로 생각할 필요가 없습니다. 단순히 모션의 시작이 In, 끝을 Out이라고 생각하면 됩니다.
이 부분은 간단히 읽고 지나쳐도 됩니다. GSAP는 각종 플러그인 라이브러리 파일을 이용해서 부수적인 기능을 가능케 합니다. 예를들어, 기본적으로 GSAP 구문에서 CSS를 정의하려면 아래와 같이 됩니다.
TweenLite.to(photo, 1, {css:{scaleX:0.5, rotation:30}, ease:Power3.easeOut});
하지만 CSSPlugin을 사용하면, GSAP 객체의 CSS 속성 이름과 포장 괄호를 생략하더라도 올바르게 작동합니다.
TweenLite.to(photo, 1, {scaleX:0.5, rotation:30, ease:Power3.easeOut});
GSAP에서 사용되는 메이저급 플러그인들은 TweenMax에 모두 포함되어 있습니다(CSSPlugin, RoundPropsPlugin, 그리고 BezierPlugin). 추후 더욱 다양한 기능이 필요하다면 GSAP의 플러그인 페이지를 방문하세요.
GSAP는 움직임을 제어하는 다양한 메서드를 제공합니다. pause(), resume() reverse(), restart(), seek() 등이 있으며, TweenLite Document를 통해 더 많은 메서드를 확인할 수 있습니다.
다른 여러 애니메이션 관련 JS와 마찬가지로, GSAP 역시 매우 유연한 대기열 방식 시퀀스를 지원합니다. Timeline이라 부르는 이것은 기존 CSS3의 애니메이션 처리 방법이 가지고 있는 치명적인 문제를 해소하는데, 특정 움직임이 끝난 이후부터 시작되는 one-after-the-other 방식을 채용하고 있습니다.
각 움직임간의 지점을 점프하거나 되돌릴 수 있고, 속도를 증가시키거나 감소시킬 수도 있으며, 이전에 거론한 play()
, restart()
와 같은 메서드도 모두 사용할 수 있어, 사용자 경험이 풍부한 애니메이션을 제작할 수 있습니다.
예문 코드 변경 예정
예문들과 코드를 좀 더 직관적으로 손 보느라 기사 작성이 다소 지연되고 있습니다.