이번에는 변화되는 숫자가 위에서 아래로, 아래에서 위로 움직여 변화하는 애니메이션 모션을 만들어보았습니다.
랜딩페이지에 숫자가 변화되는 애니메이션을 래퍼런스로하여 GSAP을 이용해 사용해보았습니다.
(디테일적인 면은 완전히 다르지만, 일단은 숫자가 변경되는 모습을 구현하는 것에 초점을 맞췄습니다)
또한, 이 페이지는 odometor.js를 이용한 것 같습니다.
.number-wrap
의 y(translateY)
값을 조절해 화면에 보이는 숫자가 변경되어 보이도록 합니다.0 - 9
의 li
를 한 번 더 만들어 그 numberWrap
의 y
값에 변화를 주고자 했습니다.<section id="numberCount">
<div class="Count-wrap">
<ul class="nb1">
<span class="number-wrap">
<li>0</li>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>0</li>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
</span>
</ul>
<ul class="nb2">
<span class="number-wrap">
<li>0</li>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>0</li>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
</span>
</ul>
<ul class="nb3">
<span class="number-wrap">
<li>0</li>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>0</li>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
</span>
</ul>
<ul class="nb4">
<span class="number-wrap">
<li>0</li>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>0</li>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
</span>
</ul>
</div>
</section>
모션을 만들게 되면 불필요한 HTML태그들을 생성해야 한다는 것을 이번 카운터 애니메이션을 만들면서 알게 되었습니다.
이것들을 사용할때만 생성해서 화면 상에 나타낼 수 없을까 하는 생각이 듭니다만, 실력이 부족하다는 것을 알고 있으므로, 제가 할 수 있는 최선의 방법으로 HTML과 CSS를 최대한 이용해 만들어 보았습니다.
#numberCount{
display: flex;
justify-content: center;
flex-direction : column;
width: 100%;
height: 200%;
margin-top : 50px;
text-align : center;
/* border : 3px solid red; */
}
#numberCount > .Count-wrap{
display: flex;
justify-content: center;
align-items: center;
margin-top : 50px;
}
#numberCount > .Count-wrap ul{
position: relative;
display: block;
width: 200px;
height: 100px;
/* border: 3px solid salmon; */
overflow: hidden;
}
.number-wrap{
display: block;
}
#numberCount li{
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-shrink : 1;
font-size: 100px;
/* border: 7px solid yellow; */
}
const numberWrap = document.querySelector(".number-wrap");
const number = document.querySelector(".number-wrap li");
const numberHeight = number.offsetHeight;
//gsap 애니메이션을 타이밍을 한번에 관리하기 위해 timeline을 사용했습니다.
const counterTimeline = gsap.timeline();
//numberWrap이 이동할때, 루즈하지 않도록 해주기 위해 위치 값을 변화를 크게 주기 위해 지정한 변수 : r
let r = 0;
//이동할 값 계산해주는 함수
const count = (i) => {
let rv = -(numberHeight * (i + 10 * r));
return rv;
};
//애니메이션 호출 함수
const countAnimation = (n, m, o, p) => {
counterTimeline
.add("start")
.to(
".nb1 .number-wrap",
{ y: count(n), ease: " Power1.easeOut" },
"start"
)
.to(
".nb2 .number-wrap",
{ y: count(m), ease: " Power1.easeOut" },
"start+=0.3"
)
.to(
".nb3 .number-wrap",
{ y: count(o), ease: " Power1.easeOut" },
"start+=0.5"
)
.to(
".nb4 .number-wrap",
{ y: count(p), ease: " Power1.easeOut" },
"start+=0.7"
);
//r의 값의 조건을 걸어 이동값에 변화를 줍니다.
if (r === 0) {
r++;
} else if (r == 1) {
r--;
}
};
//초기값
countAnimation(1, 9, 8, 7);
//Gsap을 이용해 해당영역에서 애니메이션이 실행되도록 설정합니다.
ScrollTrigger.create({
trigger: "#numberCount",
start: "top-=5% top",
end: "+=100%",
scroller: pageContainer,
pin: true,
markers: true,
scrub: true,
onEnter: () => {
countAnimation(2, 0, 2, 2);
//뷰포트와 start값이 위에서 아래로 스크롤할때 함수 실행
},
onLeaveBack: () => {
countAnimation(1, 9, 8, 7);
//뷰포트와 start값이 아래에서 위로 스크롤될떄 함수 실행
},
});
현재 만든 예제에는 HTML코드 상으로 보기가 안좋은 것 같단 생각이 듭니다. 반복되는 것들이 많다고 할까요.. 자바스크립트 코드 같은 경우에는 객체로 묶에 HTML에 넣어주거나, 반복되는 코드를 반복문을 돌려 실행하는 것은 어떨까하는 아쉬움이 있습니다만, 지금의 제 실력은 여기까지 인 것 같습니다.
클래스나 프로토타입를 이용해 코드를 정리하도록 공부해야 할 것 같습니다. ㅎ