-
320x100
전부터 계속 써보고 싶었던 ScrollMagic 라이브러리!!! 를 드디어 공부해봅니다 (꺅)
참고한 글은 아래와 같습니다.
- Building Interactive Scrolling Websites with ScrollMagic.js [링크]
1. 초기 설정
우선 아묻따 ScrollMagic을 도입해줍니다.
CDN은 아래와 같습니다.
<script src="//cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.7/ScrollMagic.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.7/plugins/debug.addIndicators.min.js"></script>
저 debug로 시작되는 파일은 화면에 인디케이터를 표시해주는데, 덕분에 좀 더 수월하게 작업이 가능합니다.
이 라이브러리는 jQuery도 지원해주는 거 같던데 여기선 그냥 바닐라로 작성하겠습니다ㅎㅎ
그리고 수려한 애니메이션 제작을 도와줄 GSAP도 도입합니다.
<script src="//cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.5/plugins/animation.gsap.js"></script>
GSAP 이외에 Velocity도 지원하고 있지만, 이 글에 따르면 GSAP이 좀 더 크로스브라우징이 잘 되어 있다고 합니다.
그러니 여기서는 GSAP을 써봅시다! 어... 사실 얘밖에 쓸 줄 모르는 거긴 한데요오오...
2. ScrollMagic의 동작원리
동작원리라는 제목만 보면 되게 어려울 거 같은데, 간단히 쓰자면 이렇습니다.
[1] ScrollMagic 컨트롤러 생성
[2] Animation 오브젝트 생성
[3] Scene 오브젝트 생성
[4] Animation 오브젝트(2번)를 Scene 오브젝트(3번)에 추가
[5] Scene Object(3번)를 ScrollMaig 컨트롤러(1번)에 추가
써놓고 보니 복잡한 거 같은데,
그냥 이런 느낌입니다 👇
3. 간단한 동작 만들어보기
일단 테스트용으로 html, css 파일을 만듭니다.
마크업과 스타일링은 적당히 해줍니다 :9
See the Pen ScrollMagic Demo (1) by NY KIM (@nykim_) on CodePen.
자, 그럼 위 원리대로 우선은 ScrollMagic Controller를 하나 만들어야겠죠?
new 키워드를 이용해 새로운 인스턴스를 생성합니다.
var controller = new ScrollMagic.Controller();
두 번째는 Animation Object 생성입니다.
GSAP을 설치했으니 애니메이션을 손쉽게 작성할 수 있습니다.
var tween1 = TweenMax.to('#animate1', 0.5, { backgroundColor: "#333333", scale: 2.5, rotation: 360, x: 130 });
세 번째 할 일은?
Scene Object를 생성하는 일이였습니다.
var scene = new new ScrollMagic.Scene();
그 다음은 Animation Object를 Scene Object에 추가해야 합니다.
setTween()
메서드를 사용하고, 인자로 우리가 작성한 애니메이션을 쏙 넣어줍니다.var scene = new ScrollMagic.Scene().setTween(tween1);
마지막 할 일은 Scene Object를 ScrollMaig Controller에 추가하는 거였죠.
addTo() 인자로 우리가 작성했던 컨트롤러를 지정합니다.
var scene = new ScrollMagic.Scene() .setTween(tween1) .addTo(controller);
그리고 가장 중요한 마무리! 이 scene이 일어날 트리거를 지정해줘야 합니다.
여기서는 #trigger1이라는 요소에 닿으면 애니메이션이 발생하도록 하겠습니다.
triggerElement: "#trigger1"
과 같이 작성하면 됩니다.var scene = new ScrollMagic.Scene({ triggerElement: "#trigger1" }) .setTween(tween1) .addTo(controller);
여기까지만 하면 스크롤에 따라 애니메이션이 작동합니다! (오오어어엌)
하지만 디버깅을 위해 인디케이터를 추가할게요.
addIndicators()
로 추가할 수 있으며, 옵션으로 이름을 지정할 수도 있습니다.var scene = new ScrollMagic.Scene({ triggerElement: "#trigger1" }) .setTween(tween1) .addTo(controller) .addIndicators({ name: "1" });
테스트해보면, #trigger1의 윗부분에 닿는 순간 애니메이션이 작동하는 걸 알 수 있습니다.
(짝짝짝)
한편,
offset
값을 줘서 실제 트리거보다 빠르게/느리게 애니메이션을 작동시킬 수도 있습니다.아래는 offset으로 150 값을 준 모습입니다.
var scene = new ScrollMagic.Scene({ triggerElement: "#trigger1", offset: 150 }) .setTween(tween1) .addTo(controller) .addIndicators({ name: "1" });
duration
값을 지정하면 애니메이션이 얼마나 긴 시간동안 재생될지 설정할 수 있습니다.이 값이 작을수록 애니메이션은 더 빨리 끝날 거고, 클수록 더 늦게 끝납니다.
아래 이미지는 duration 값을 각각 40, 100으로 지정하고 같은 지점에서 스크롤을 멈춘 모습입니다.
전자의 경우 애니메이션이 더 많이 재생된 것을 볼 수 있습니다.
이때 duration을 100%로 지정하면, 뷰포트 높이에 따라 유동적으로 end의 위치가 정해집니다. (공식 문서 링크)
아무튼 잘 돌아가니 좋네요!!
4. 애니메이션 반복시키기
TweenMax의 유용한 기능 중 하나는
yoyo
인데요, 애니메이션의 반복 재생을 도와줍니다.fromTo()
메서드에repeat: -1
값을 준다면 무한한 애니메이션 재생이 가능합니다.var tweenYoyo = TweenMax.fromTo("#animate1", 0.6, { backgroundColor: "#333333", scale: 1, }, { scale: 2.5, backgroundColor: "#dc143c", x: 100, rotation: 360, repeat: -1, yoyo: true }) var scene = new ScrollMagic.Scene({ triggerElement: "#trigger1", duration: 150 }) .setTween(tweenYoyo) .addTo(controller) .addIndicators({ name: "1" });
실행시켜보면 원이 커지면서 색이 바뀌는 애니메이션이 계속 반복되는 걸 볼 수 있습니다.
다만 스크롤 지점이 트리거 요소보다 위에 있다면 (=즉, #trigger1에 닿지 않았다면) 애니메이션은 멈춰버립니다.
또한 duration을 지정한 경우, 그 범위를 넘어가도 애니메이션은 중지됩니다.
See the Pen ScrollMagic Demo (2) by NY KIM (@nykim_) on CodePen.
5. 연속적인 애니메이션 재생
이번에는
staggerFromTo()
메서드를 이용해 연속적인 애니메이션을 만들어보겠습니다.staggerFrom 또는 staggerFromTo의 작성 방법은 아래 공식 문서를 통해 확인할 수 있습니다.
- https://greensock.com/docs/TimelineMax/staggerFrom
- https://greensock.com/docs/TimelineMax/staggerFromTo()
var tweenStagger = TweenMax.staggerFromTo('.icon', 0.4, { scale: 0.85, }, { backgroundColor: "#dc143c", scale: 1.2, rotation: 360 }, 0.3 ); var scene = new ScrollMagic.Scene({ triggerElement: "#trigger1", duration: 150 }) .setTween(tweenStagger) .addTo(controller) .addIndicators({ name: "1" });
위 코드에서 '.icon'은 targets이며(배열 또는 CSS 셀렉터로 지정),
'0.4'는 duration, '{}'는 각각 fromVars와 toVars, 마지막으로 '0.3'은 stagger(각 트윈 사이의 간격)를 지정한 것입니다.
See the Pen ScrollMagic Demo (3) by NY KIM (@nykim_) on CodePen.
6. 클래스 토글 / 다수 애니메이션 재생
이번에는 클래스 토글하는 법과 다수의 애니메이션을 재생하는 법을 실험해봅시다!
먼저, 클래스를 붙였다 떼었다 하는 작업은 간단합니다.
TweenMax를 쓴다면
{className: "+={클래스명}"}
만 해주면 되고,아니면 그냥
.setClassToggle()
메서드를 써주면 되거든요. 그럼 전능하신 매직스크롤님이 다 해주십니다 허허허여기선 setClassToggle 메서드를 써보겠습니다.
들어가야하는 첫 번째 인자는 '클래스를 붙일 대상', 두 번째 인자는 '붙일 클래스 이름'입니다.
다수의 애니메이션을 재생하는 것도 간단해요!
Animation Object를 여러 개 생성하면 됩니다.
//... var tween1 = TweenMax.to('#animate1', 0.3, { color: "#60c5ba", scale: 4, y: 10, rotation: 360 }); var tween2 = TweenMax.to('#animate2', 0.3, { color: "#ffc952", scale: 4, y: 10, rotation: 360 }); var tween3 = TweenMax.to('#animate3', 0.3, { color: "#6a60a9", scale: 4, y: 10, rotation: 360 }); //...
그리고 Scene Object도 여러 개 작성한 다음 각각 이어주면 됩니다.
(function () { var controller = new ScrollMagic.Controller({ globalSceneOptions: { duration: 436 } }); var tween1 = TweenMax.to('#animate1', 0.3, { color: "#60c5ba", scale: 4, y: 10, rotation: 360 }); var tween2 = TweenMax.to('#animate2', 0.3, { color: "#ffc952", scale: 4, y: 10, rotation: 360 }); var tween3 = TweenMax.to('#animate3', 0.3, { color: "#6a60a9", scale: 4, y: 10, rotation: 360 }); var scene1 = new ScrollMagic.Scene({ triggerElement: "#trigger1" }) .setClassToggle('.info1', 'active') .setTween(tween1) .addTo(controller) .addIndicators({ name: "1" }); var scene2 = new ScrollMagic.Scene({ triggerElement: "#trigger2" }) .setClassToggle('.info2', 'active') .setTween(tween2) .addTo(controller) .addIndicators({ name: "2" }); var scene3 = new ScrollMagic.Scene({ triggerElement: "#trigger3" }) .setClassToggle('.info3', 'active') .setTween(tween3) .addTo(controller) .addIndicators({ name: "3" }); }())
See the Pen ScrollMagic Demo (4) by NY KIM (@nykim_) on CodePen.
7. 요소 고정시키기
스크롤 할 때마다 요소가 따라오게 하려면 어떻게 할까요?
정답은...
setPin()
메서드를 써줍니다!특정 지점 이후로는 따라오지 않게 하려면 duration을 지정해주면 됩니다.
//... var controller = new ScrollMagic.Controller(); var scene1 = new ScrollMagic.Scene({ triggerElement: "#trigger1", duration: 700, offset: 165 }) .setPin("#pin1") .addIndicators({name: "1 (duration: 700)"}) .addTo(controller); //...
8. CSS를 활용하여 요소 드러내고 숨기기
이번에는 스크롤 이벤트에 아주아주아주 잘 쓰이는, 요소를 드러내고 숨기는 애니메이션입니다.
그 왜 있잖아요, 스크롤 하면 요소가 페이드인 되는 그런 거 말이죠 ;-9
요소가 trigger에 걸리면 visible 클래스가 붙도록 처리하겠습니다.
이건 아까 배운
setClassToggle()
메서드를 쓰면 되죠.우선 CSS를 작성하고...
.animation1 { color: #fff; padding: 40px; font-size: 50px; background-color: crimson; box-shadow: 3px 14px 30px #ddd; transform: translateY(30px); opacity: 0; &.visible { opacity: 1; transform: translateY(0); transition: all 1.1s; } }
scene object를 하나 작성합니다.
var scene = new ScrollMagic.Scene({ triggerElement: "#trigger1", //트리거 설정 triggerHook: 0 }) .setClassToggle("#animate1", "visible") .addTo(controller) .addIndicators({ name: "1" });
보면 못보던 옵션이 있네요. 바로
triggerHook
입니다.이건 viewport에 대해 상대적으로 어느 시점에서 보여줄 건지를 설정합니다.
0~1 사이의 숫자를 입력하며, 문자열도 가능합니다.
- "onEnter" => 1
- "onCenter" => 0.5
- "onLeave" => 0
디폴트는 onCenter(0.5)이며, 자세한 건 공식 문서를 참고하세요!
자, 그럼 백문이 불여일견. 우선은 값을 0으로 지정해봅니다.
테스트해봤더니... 파란색 인디케이터가 맨 위에 붙어있는 걸 볼 수 있습니다.
그래서 한참을 내려서 초록색 인디케이터가 뷰포트에서 사라질 때야 setClassToggle이 발생합니다.
반면에 값을 1로 해두면 어떨까요? 이건 onEnter죠.
따라서 초록색 인디케이터가 뷰포트에 들어오는 시점에 setClassToggle이 발생합니다.
그래서 파란색 인디케이터는 맨 아래에 붙어있습니다.
테스트해보니 이 값은 0.8~0.9 사이가 가장 적당한 거 같아요!
굿굿!!
이번에는 연속적으로 주르르륵 나타나는 걸 만들어보겠습니다.
GSAP의 stagger 기능을 써도 되지만, 여기서는 for문을 사용할게요!
내용은 간단합니다. for문 안에 scene을 넣고, 각 요소가 트리거가 되게끔 합니다.
var revealElements = document.getElementsByClassName("animation2"); for (var i=0; i<revealElements.length; i++) { var scene2 = new ScrollMagic.Scene({ triggerElement: revealElements[i], //각 요소가 트리거가 됨 offset: 50, triggerHook: 0.9 }) .setClassToggle(revealElements[i], "visible") //해당 요소에 클래스 토글 .addTo(controller) .addIndicators({name: "(box) " + (i+1), colorStart:"#F6B352", colorTrigger:"#F6B352"}); }
See the Pen ScrollMagic Demo (6) by NY KIM (@nykim_) on CodePen.
9. 섹션 와이프
다음은 스크롤하면 다음 섹션이 스르륵 올라와 덮는 효과를 만들어보겠습니다.
역시 생각보다 내용은 간단(?!)합니다.
Trigger Hook이 맨 위에 있다가, 섹션이 Hook에 닿으면(=완전히 스크롤되면) 화면에 고정시켜버리는 거죠.
이때는 아까 배웠던 setPin()을 사용하면 됩니다.
<div class="wrap"> <div class="top"> ScrollMagic Demo !!! </div> <section class="panel one"> <b>ONE</b> </section> <section class="panel two"> <b>TWO</b> </section> <section class="panel three"> <b>THREE</b> </section> <section class="panel four"> <b>FOUR</b> </section> </div>
먼저 네 개의 섹션을 마크업 한 다음,
width:100%; height:100%;
값을 줘서 화면에 꽉 차게 만들어줍니다.이후 Controller를 생성하고, 각 section에게 for문을 돌립니다.
var controller = new ScrollMagic.Controller(); var slides = document.querySelectorAll("section.panel"); for (var i=0; i<slides.length; i++) { var scene = new ScrollMagic.Scene() .addIndicators() .addTo(controller); }
아까 말했듯이, triggerHook은 맨 위에 있어야 합니다.
Controller에 global option으로 작성합니다.
이때 스트링으로 'onLeave'라 써도 되고, 숫자로 0이라 써도 상관 없습니다 :>
명확한 계산을 위해 duration은 100%로 지정합니다.
var controller = new ScrollMagic.Controller({ globalSceneOptions: { triggerHook: 'onLeave', duration: "100%" } }); var slides = document.querySelectorAll("section.panel"); for (var i=0; i<slides.length; i++) { var scene = new ScrollMagic.Scene() .addIndicators() .addTo(controller); }
triggerElements는 섹션 각각이 되겠죠.
그래서 이 섹션의 가장 윗부분이 triggerHook에 닿으면 setPin을 시켜줍니다.
var controller = new ScrollMagic.Controller({ globalSceneOptions: { triggerHook: 'onLeave', duration: "100%" } }); var slides = document.querySelectorAll("section.panel"); for (var i=0; i<slides.length; i++) { var scene = new ScrollMagic.Scene({ triggerElement: slides[i] }) .setPin(slides[i]) .addIndicators() .addTo(controller); }
자, 이렇게 해놓고 테스트해보면...
뭔가 이상합니다 (뜨든)
스크롤을 좀 많이 해야 다음 섹션이 올라오거든요.
왜냐하면 pin되어 있는 동안에는 다음 요소가 밀려나있도록 스크롤매직이 설정해놨기 때문입니다. (공식 문서 링크)
duration이 지정된 경우 그만큼 요소가 pin되어야 하니까요.
실제로 콘솔을 열어 확인해보면, spacer가 저절로 생성된 것을 볼 수 있습니다.
따라서 pushFollowers를 false로 지정해놓습니다.
var controller = new ScrollMagic.Controller({ globalSceneOptions: { triggerHook: 'onLeave', duration: "100%" } }); var slides = document.querySelectorAll("section.panel"); for (var i=0; i<slides.length; i++) { var scene = new ScrollMagic.Scene({ triggerElement: slides[i] }) .setPin(slides[i], {pushFollowers: false}) .addIndicators() .addTo(controller); }
이제 부드럽게 잘 먹히네요!
See the Pen ScrollMagic Demo (7) by NY KIM (@nykim_) on CodePen.
10. 가로 스크롤
가로로 스크롤할 때도 스크롤매직을 사용할 수 있습니다.
Controller에
{vertical: false}
옵션을 주면 됩니다. 끗.다만 가로 스크롤이기 때문에, 정말 '가로로' 스크롤 해야지만 볼 수 있습니다.
세로로 스크롤 했을 때 가로로 보여지는 형태가 아님에 주의!
See the Pen ScrollMagic Demo (8) - Horizontal Scroll by NY KIM (@nykim_) on CodePen.
스크롤매직 기초편은 여기서 끝~!! :-D
728x90'Blog > JavaScript' 카테고리의 다른 글
[JS] Transform & Mousemove (0) 2019.09.04 [ScrollMagic] 스크롤매직 라이브러리 - 중급편 (4) 2019.08.27 [JS30] Hold Shift and Check Checkboxes (0) 2019.02.27 [JS30] Dev Tools Tricks (0) 2019.02.17 [JS30] HTML Canvas (0) 2019.02.15 댓글