해당 포스팅은 유튜브에 업로드된 '맛있는 코딩'님의 강좌를 들으며 공부한 내용들입니다.
텍스트 스크롤 애니메이션 구현하기
1. 텍스트가 끊김 없이 무한으로 흐른다.
2. 스크롤하면 더 빨리 흐른다.
이 두 가지 문제 각각의 경우 모두 흐른다는 공통점이 있습니다.
이를 같이 해결하기 위해서 흐르게 만들어주는 let count = 0이라는 변수를 만들어 해결해 보겠습니다.
1. 텍스트가 끊김 없이 무한으로 흐른다.
다음과 같이 화면의 너비를 초과하는 element에 텍스트가 있습니다.
먼저 똑같은 텍스트를 뒤에 이어 붙여 길이를 2배로 만들어줍니다.
그리고 텍스트를 왼쪽으로 흐르게 하는 속성은
css의 transform: translateX라는 속성으로 변경시켜 줄 건데
이때 사용되는 값을 -count px로 이동시켜 줄 거예요.
우선 스스로 재호출 시키며 반복하는 재귀함수를 만들고
여기에 count를 넣어 -1씩 계속 값을 더해주고
그 변경된 count값을 translateX에 넣어줍니다.
그렇게 count값이 계속 변하다가 count 값이 -100이 되었습니다.
왼쪽으로 -100px만큼 이동이 된 것입니다.
element 가로길이의 절반만큼 왼쪽으로 이동하려면 count값이 얼마가 되어야 할까요??
element의 절반만큼 이동했다는 뜻은 element.scrollWidth의 절반만큼 이동했다는 뜻이니까
count값이 element.scrollWidth / 2 일 때입니다.
바로 그때 count를 0으로 바꿔주게 되면 스스로 계속 돌고 있는 재귀함수에 의해
translateX값은 0이 되고 element는 처음 상태로 다시 돌아오게 됩니다.
그리고 우리 눈에는 처음으로 돌아온 걸로 보이지 않고 계속 이동 중인 것으로 보이게 됩니다.
이렇게 첫 번째 문제는 해결이 되었습니다.
2. 스크롤하면 더 빨리 흐른다.
스크롤을 할 때마다 더 빨리 이동시켜 주기 위해서는 우선 scroll함수를 선언해 줍니다.
마우스 휠을 돌릴 때마다 scroll함수가 실행되니까 그때마다 count값을 적당히 더 많이 붙여주면 되겠죠?
그럼 휠을 돌릴 때마다 텍스트가 더 빨리 이동하는 것처럼 보이게 될 겁니다.
예제
기본 html 작성 후 텍스트는 javascript로 넣어줍니다.
<div class="cover">
<p class="first-parallel"></p>
</div>
<div class="cover">
<p class="second-parallel"></p>
</div>
const pTag1 = document.querySelector('.first-parallel');
const pTag2 = document.querySelector('.second-parallel');
const textArr1 = 'Yummy Tasty Delicious Useful Coding Yummy Yummmmy Yummmmmmmmmy yum'.split(' ');
const textArr2 = 'Chicken Hamburger Pizza Salad Sushi Bibimbab Gimbab JJajangmyeon'.split(' ');
텍스트의 공백(' ')을 split처리하면 배열의 띄어쓰기 기준으로 단어가 담깁니다.
똑같은 내용을 배열 뒤에 push해준 다음에 각각의 단어를 for문으로 돌며
단어 뒤에 띄어쓰기 네 번 처리를 한 후 각각의 p태그 안에 넣어줍니다.
function initTexts(element, textArray) {
textArray.push(...textArray);
for (let i = 0; i < textArray.length; i++) {
element.innerText += `${textArray[i]}\u00A0\u00A0\u00A0\u00A0`; // \u00A0 공백문자
}
}
initTexts(pTag1, textArr1);
initTexts(pTag2, textArr2);
텍스트를 담았으니 나머지 css처리를 해줍니다.
html,
body {
background-color: #000;
width: 100%;
overflow-x: hidden;
}
.cover {
width: 100vw;
margin-bottom: 10rem;
display: flex;
}
.cover:nth-child(1) {
margin-top: 10vh;
transform: rotate(-2deg);
background-color: #ff3796;
}
.cover:nth-child(2) {
transform: rotate(2deg);
background-color: #5800ff;
justify-content: flex-end;
}
p {
display: flex;
padding: 3rem 0;
font-size: 5rem;
}
두 번째 p태그만 flex-end 처리를 해주고 스크립트로 translateX를 반대 방향으로 주겠습니다.
animate라는 재귀 함수를 만드는데 translateX처리는 따로 marqueeText라는 함수로 빼서 처리해 줍니다.
let count1 = 0;
let count2 = 0;
function marqueeText(count, element, direction){
if(count > element.scrollWidth / 2){
element.style.transform = `translateX(0)`;
count = 0;
}
element.style.transform = `translateX(${count * direction}px)`;
return count
}
function animate(){
count1++;
count2++;
count1 = marqueeText(count1, pTag1, -1);
count2 = marqueeText(count2, pTag2, 1);
window.requestAnimationFrame(animate);
}
animate();
count가 element의 절반값 이상이라면
count를 0으로 만들고 element도 원위치시켜놓고
그게 아니라면 count에 direction을 곱한 만큼 이동시켜 주고
count를 return 시켜 animate 함수에 반영되도록 해줍니다.
그리고 requestAnimationFrame에 다시 animate를 넣고
animate를 실행시키면 텍스트가 끊김 없이 무한 반복 됩니다.
이제 스크롤 함수를 만들고 적당한 값을 스크롤시마다 더해주게 합니다.
window.addEventListener('scroll',()=>{
count1 +=15;
count2 +=15;
})
See the Pen Scroll text marquee effect using pure javascript by Evan Jin (진경성) (@rudtjd2548) on CodePen.
'JavaScript' 카테고리의 다른 글
[JavaScript] 마우스를 부드럽게 따라오는 커서 이펙트 구현해보기 - Lerp활용(선형 보간법) (0) | 2023.08.04 |
---|---|
[JavaScript] svg path 스크롤 애니메이션(2) (0) | 2023.07.21 |
[JavaScript] svg path 스크롤 애니메이션(1) - stroke-dasharray, stroke-dashoffset (0) | 2023.07.20 |
[JavaScript] 빈 배열 만들기 fill() (0) | 2023.07.10 |
[JavaScript] if문 중첩 줄이기 (0) | 2023.07.10 |