-
320x100
기초편에 이어 중급편입니다.
공식 예제 중 ADVANCED에 해당하는 내용을 살펴보겠습니다 :-9
히어뤼고!
1. 섹션 와이프 (매뉴얼)
기초편에서는 단순히 아래에서 위로 올라와 고정되는 와이프였다면,
이번에는 상하좌우에서 슝 날아와 고정되는(?) 섹션 와이프를 구현해봅니다.
구현원리는 간단합니다.
너비높이 100%의 풀페이지 컨테이너를 만든 다음, 얘를 setPin으로 고정시킵니다.
그리고 그 안에 들어갈 여러 개의 섹션을 만들고 absolute 시킵니다.
그 다음에는 섹션의 위치를 -100%로 두었다가, 스크롤 되면 0% 위치로 움직이게 합니다.
여기에 GSAP을 쓰면 짱 편하니까 그렇게 작성합시다ㅋㅋㅋㅋㅋ
우선 마크업을 합니다.
<div id="container"> <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>
CSS도 작성한 다음...
#container { width: 100%; height: 100%; overflow: hidden; } .panel { position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; font-size: 60px; text-align: center; color: #fff; }
JS를 작성합니다.
var controller = new ScrollMagic.Controller(); var wipeAnimation = new TimelineMax() .fromTo(".two", 1, {x:"-100%"}, {x:"0%"} ) .fromTo(".three", 1, {y:"-100%"}, {y:"0%"} ) .fromTo(".four", 1, {x:"100%"}, {x:"0%"} ) var scene = new ScrollMagic.Scene({ triggerElement: "#container", triggerHook: "onLeave", duration: "500%" //이 값이 클 수록 천천히 덮어씀 }) .setPin("#container") .setTween(wipeAnimation) .addIndicators() .addTo(controller);
Timeline을 통해서, 각 섹션이 -100%에서 0%로 이동하는 걸 볼 수 있습니다.
여기서 체크할 점은, scene에 주어진 duration 값이 크면 클수록 스크롤을 더 많이 해야한다는 것입니다.
달리 말하면 다음 섹션이 더 천천히 스와이프 된다고 할 수도 있죠.
See the Pen ScrollMagic Demo (8) - Dynamic Section Wipe by NY KIM (@nykim_) on CodePen.
2. 섹션 슬라이드
이 다음은 섹션 슬라이드입니다. 위의 예제와 비슷하긴 하지만 좀 더 다이내-믹!한 효과를 줘보겠습니다.
원리는 동일합니다. container를 고정시키고, 섹션이 움직이도록 애니메이션을 설정하면 됩니다.
먼저 마크업입니다.
<div id="pinContainer"> <div id="slideContainer"> <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> </div>
아까와는 다르게 컨테이너가 두 개인 구조입니다.
pinContainer는 고정하고, slideContainer의 위치만 움직일 거에요.
#pinContainer { width: 100%; height: 100%; overflow: hidden; -webkit-perspective: 1000; perspective: 1000; } #slideContainer { width: 400%;// 100*4 slides height: 100%; } .panel { float: left; width: 25%; // 400/25 = 100% height: 100%; font-size: 60px; text-align: center; color: #fff; }
따라서 slideContainer는 100%*4개 섹션 = 400%만큼의 너비를 주고,
각 섹션은 그 25%의 너비를 갖도록 합니다.
그리고 자바스크립트를 작성합니다.
var controller = new ScrollMagic.Controller(); var wipeAnimation = new TimelineMax() // animate to second .to("#slideContainer", 1, { z: -180 }) .to("#slideContainer", 1, { x: "-25%" }) .to("#slideContainer", 1, { z: 0 }) // animate to third .to("#slideContainer", 1, { z: -180, delay: 0.6 }) .to("#slideContainer", 1, { x: "-50%" }) .to("#slideContainer", 1, { z: 0 }) // animate to forth .to("#slideContainer", 1, { z: -180, delay: 0.6 }) .to("#slideContainer", 1, { x: "-75%" }) .to("#slideContainer", 1, { z: 0 }) var scene = new ScrollMagic.Scene({ triggerElement: "#pinContainer", triggerHook: "onLeave", duration: "600%" //이 값이 클 수록 천천히 덮어씀 }) .setPin("#pinContainer") .setTween(wipeAnimation) .addIndicators() .addTo(controller);
#pinContainer에게 perspective를 주었으니 z값을 이용해 slideContainer에게 3D 입체 효과를 줄 수 있습니다.
마찬가지로 scene의 duration 값이 클 수록 더 많은 스크롤이 필요합니다.
See the Pen ScrollMagic Demo (9) - Dynamic Section Slide by NY KIM (@nykim_) on CodePen.
3. SVG 라인 드로잉
스크롤을 하면 SVG 라인이 그려지는 매직!
을 지금부터 만들어봅시다 XD
우선 SVG 라인 애니메이션에 대해 간단히 짚고 넘어가겠습니다.
이때 SVG는 당연하게도 stroke속성을 갖고 있어야 하는데, 우리는 이 stroke를 움직이게 만들 거니까요!
stroke-dassharray 라는 CSS 속성이 있습니다. 이 속성을 적용시키면, 선이 대쉬 형태가 되며 값만큼 간격을 갖게 됩니다.
예를 들어 path의 길이가 100이고, dasharray 값이 50이라면 path는 절반만 보입니다.
만약 'dasharray 값 = path 길이'라면 path는 온전히 보이게 됩니다. path의 길이만큼 간격을 갖게 되니까요.
한편 이때! stroke-dashoffset 이란 속성을 줘봅니다. 이는 dasharray의 시작 위치를 설정합니다.
그럼 'dasharray 값 = path 길이'일 때, 'dashoffset 값 = path 길이'라면 어떨까요? 그럼 path는 보이지 않게 됩니다 (두둥)
그래서 결국 라인 드로잉 애니메이션을 보여주려면,
'dashoffset 값 = dasharray 값 = path 길이'으로 설정한 다음, dashoffset의 값을 점점 0으로 줄여가면 됩니다.
path의 길이는 getTotalLength() 메서드를 통해 구할 수 있습니다.
그럼 직접 만들어보며 감을 익혀보죠!
우선 아무 SVG나 준비합니다. 당연히 <path d="..."/> 형태여야 합니다!
그리고 path의 길이를 구해 style로 지정하는 함수를 작성합니다.
var st = document.querySelector(".st1"); function pathPrepare(el) { var lineLength = el.getTotalLength(); el.style.strokeDasharray = lineLength; el.style.strokeDashoffset = lineLength; } pathPrepare(st);
아까 말했듯, strokeDasharray와 strokeDashoffset을 path길이와 동일하게 맞춰주었습니다.
그런 다음 라이브러리를 사용하여,
strokeDashoffset을 0으로 만듭니다.
var controller = new ScrollMagic.Controller(); var tween = new TimelineMax() .add(TweenMax.to(st, 0.9, { strokeDashoffset: 0, ease: Linear.easeNone })) .add(TweenMax.to(st, 1, { stroke: "#ffffff", ease: Linear.easeNone }), 0); var scene = new ScrollMagic.Scene({ triggerElement: "#trigger1", duration: 200, tweenChanges: true }) .setTween(tween) .addIndicators({ colorStart: "#ffffff", colorEnd: "#000000" }) .addTo(controller);
See the Pen ScrollMagic Demo (10) - SVG line animation by NY KIM (@nykim_) on CodePen.
4. 컨테이너 스크롤
body에서 스크롤하는 게 아니라, 커스텀 컨테이너 내부에 스크롤 애니메이션을 작성할 수도 있습니다.
Controller 옵션으로 {container: "컨테이너명"}을 지정하면 됩니다.
var controller = new ScrollMagic.Controller({ container: "#container" }); //....
See the Pen ScrollMagic Demo (11) - Container by NY KIM (@nykim_) on CodePen.
5. 앵커 링크 스크롤링
앵커 클릭 시 해당 지점으로 스크롤시킬 때는 GSAP의 scrollToPlugin을 이용할 수 있습니다.
플러그인으므로 추가로 가져다 써야합니다.
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/plugins/ScrollToPlugin.min.js"></script>
그리고 컨트롤러의 scrollTo를 TweenMax로 정의해줍니다.
scrollTo() 메서드에 대한 내용은 공식 문서를 참고하세요.
controller.scrollTo(function (newpos) { TweenMax.to(window, 0.5, {scrollTo: {y: newpos}}); });
그런 다음 앵커를 눌렀을 때 해당 위치로 이동하게끔 처리합니다.
원한다면 pushState()를 통해 브라우저 히스토리에 추가할 수도 있습니다.
var menu = document.querySelector("#menu"); menu.addEventListener("click", function (e) { var id = e.target.hash; e.preventDefault(); controller.scrollTo(id); if (window.history && window.history.pushState) { history.pushState("", document.title, id); } });
See the Pen ScrollMagic Demo (12) - Anchor by NY KIM (@nykim_) on CodePen.
6. 패럴렉스 스크롤
이번에는 스크롤 애니메이션에서 자주 쓰이는 패럴렉스를 배워봅니다 ;-9
배경화면이 교차되어 입체적으로 보이게 하는 방법인데,
background-position 값을 저마다 다르게 주면 됩니다.
여기 총 네 개의 배경 레이어가 있습니다.
<div id="backContainer"> <div class="back back1"></div> <div class="back back2"></div> <div class="back back3"></div> <div class="back back4"></div> </div>
그런 다음 absolute 시켜놨죠.
#backContainer { overflow-x: hidden; overflow-y: hidden; width: 100%; height: 101vh; } .back { position: absolute; width: 300%; height: 100%; background-repeat: repeat-x; }
마지막으로 타임라인을 생성하고, 백그라운드 포지션 값을 바꿔줍니다.
이때 duration으로 스크롤 길이를 조절하고, setPin으로 화면에 고정시킬 수 있습니다.
(function () { var controller = new ScrollMagic.Controller(); var tween = new TimelineMax() .add([ TweenMax.to("#backContainer .back1", 1, { backgroundPosition: "-200%", ease: Linear.easeNone }), TweenMax.to("#backContainer .back2", 1, { backgroundPosition: "-150% 0", ease: Linear.easeNone }), TweenMax.to("#backContainer .back3", 1, { backgroundPosition: "-50% 0", ease: Linear.easeNone }), TweenMax.to("#backContainer .back4", 1, { backgroundPosition: "-100% 0", ease: Linear.easeNone }) ]); var scene1 = new ScrollMagic.Scene({ duration: "1000%" }) .setTween(tween) .setPin("#backContainer") .addIndicators(); controller.addScene(scene1); }())
(이미지 출처는 요기요!)
7. 패럴렉스 섹션
이번 패럴렉스는 이미지가 아니라 섹션에 적용해보겠습니다.
이 효과를 적용하려면 부모 컨테이너가 필요합니다.
<div id="parallax1" class="parallaxParent"> <div class="background bg1"> <strong class="title">Parallax</strong> </div> </div>
그리고 부모 컨테이너의 높이는 뷰포트 전체로 정합니다.
자식 요소의 높이는 200%로 설정하되, top:-100% 값을 줘서 중앙이 보이게 합니다.
.parallaxParent { height: 100vh; overflow: hidden; } .background { height: 200%; position: relative; top: -100%; }
대략적인 구조를 그림으로 표현하면 이런 느낌이에요! 👇
이 상태에서 우리가 해줄 건, 스크롤해서 parallaxParent에 닿으면
그 자식인 background가 아래로 이동하게끔 합니다.
그럼 height가 200%여서 가려져있던 background의 윗부분이 보이겠죠?
여기에 duration을 지정해줘서 스크롤에 따라 이동하게 하면, 우리가 원하는 패럴렉스 효과를 줄 수 있습니다.
위 내용을 코드로 바꾸면 이렇게 됩니다.
(function () { var controller = new ScrollMagic.Controller({ globalSceneOptions: {triggerHook: "onEnter"} }); new ScrollMagic .Scene({triggerElement: "#parallax1", duration: "200%"}) .setTween("#parallax1 > div", {y: "40%", ease: Linear.easeNone}) .addIndicators() .addTo(controller); new ScrollMagic .Scene({triggerElement: "#parallax2", duration: "175%"}) .setTween("#parallax2 > div", {y: "30%", ease: Linear.easeNone}) .addIndicators() .addTo(controller); }())
See the Pen ScrollMagic Demo (13) - Parallax Sections by NY KIM (@nykim_) on CodePen.
이렇게 중급 편도 무사히 마쳤습니다! 🥰
728x90'Blog > JavaScript' 카테고리의 다른 글
[Inside JS] 1. 자바스크립트 데이터 타입과 연산자 (0) 2019.09.05 [JS] Transform & Mousemove (0) 2019.09.04 [ScrollMagic] 스크롤매직 라이브러리 - 기초편 (12) 2019.08.26 [JS30] Hold Shift and Check Checkboxes (0) 2019.02.27 [JS30] Dev Tools Tricks (0) 2019.02.17 댓글