[Javascript] 자동 롤링 배너를 만들어보자!

seoyeon·2022년 12월 29일
10

한동안 업무에 치여 블로그를 통 적지 못했다.. 가뜩이나 일정이 짧은데 디자인이 빡세게 나와서 3일 내내 야근을 했다..😭 그래도 고생한만큼 결과물도 괜찮게 나오고 이번 플젝으로 인해 새로운 기술도 많이 알게 되었다. 그래서 이번 블로그는 새로 알게된 기술들을 정리해 볼 생각이다!

🔅 우선 첫번째로 무한으로 자동 롤링되는 배너 구현하기! 🔅

1. 자바스크립트로 무한 롤링 배너 구현

흐르는 배너 효과가 필요하다고 해서 어떻게 구현을 하면 좋을지 구글링을 하다가 찾아낸 방법!
두개의 똑같은 배너를 이용해 무한으로 돌아가는듯이 보이게 해주는 것인데요, 우선 결과물을 봅시다! 👀

위와 같이 무한 롤링배너를 만들어 볼거에요!
(디자인은 유출이 불가능해서 제가 임의로 만들었습니다 🥲)

❓ 작동 방식

무한 롤링 배너는 원본배너와 복제배너를 한 방향으로 이동시켜주면서 배너 2개가 번갈아가며 뷰포트에 나타나는 형식으로 실제 화면상에서 보이는 동작은 하나의 배너가 무한 롤링하는 것처럼 보이게 됩니다.

✔ 배너 길이가 배너 표시 영역보다는 길어야 자연스러운 배너 롤링이 구현됩니다!

❗ 작동 순서

애니메이션 초기 상태
원본배너와 복제한 복제배너를 나란히 정렬합니다.

배너 너비만큼 배너1, 배너2 왼쪽으로 이동
css 키프레임을 이용해 왼쪽으로 쭈욱 이동하고 종료하는 애니메이션을 추가합니다.

배너1 애니메이션이 종료되면서 배너2 뒤쪽으로 이동
배너1(원본배너)이 화면상에서 나갈때 뒤를 따라오던 배너2(복제배너)가 화면상에 보이게 됩니다. 이때 배너1이 화면상에서 완전히 나가게 되면 배너2 뒤쪽으로 이동을 시킵니다. 이러한 방식이 무한으로 반복되면서 무한 배너 롤링이 만들어 집니다.

🖥 코드 작성

HTML

<div class="wrap"> <!-- 배너표시영역 -->
	<div class="rolling-list"> <!-- 원본배너 -->
		<ul>
			<li>
				<div class="image-wrap"><img src="./img/img_banner1.svg" alt=""></div>
				<div class="desc">
					<strong>First Banner</strong>
                    <span>Lorem ipsum dolor sit amet, consectetur adipisicing elit.<br/>
					Neque cumque ratione provident nulla veniam nihil quaerat, illum officiis hic.<br/> 
					Laborum in eos possimus, quo ullam nobis nam nemo fuga ipsam?</span>
                </div>
			</li>
			<li>
				<div class="image-wrap"><img src="./img/img_banner2.svg" alt=""></div>
				<div class="desc">
					<strong>Second Banner</strong>
					<span>Lorem ipsum dolor sit amet, consectetur adipisicing elit.<br/>
                    Neque cumque ratione provident nulla veniam nihil quaerat, illum officiis hic.<br/>
					Laborum in eos possimus, quo ullam nobis nam nemo fuga ipsam?</span>
				</div>
			</li>
			<li>
				<div class="image-wrap"><img src="./img/img_banner3.svg" alt=""></div>
				<div class="desc">
					<strong>Third Banner</strong>
					<span>Lorem ipsum dolor sit amet, consectetur adipisicing elit.<br/>
					Neque cumque ratione provident nulla veniam nihil quaerat, illum officiis hic.<br/>
					Laborum in eos possimus, quo ullam nobis nam nemo fuga ipsam?</span>
				</div>
			</li>
			<li>
				<div class="image-wrap"><img src="./img/img_banner4.svg" alt=""></div>
				<div class="desc">
					<strong>Fourth Banner</strong>
					<span>Lorem ipsum dolor sit amet, consectetur adipisicing elit.<br/>
					Neque cumque ratione provident nulla veniam nihil quaerat, illum officiis hic.<br/>
					Laborum in eos possimus, quo ullam nobis nam nemo fuga ipsam?</span>
				</div>
			</li>
		</ul>
	</div>
</div>

CSS

.wrap { 
  display: flex; 
  overflow: hidden;
}
.wrap .rolling-list ul { 
	display: flex;
}
.wrap .rolling-list ul li { 
	width: 589px; 
	height: 276px; 
    box-sizing: border-box; 
    border-radius: 20px; 
    margin: 0 16px; 
    padding: 46px 31px; 
    display: flex; 
    align-items: center; 
    flex-shrink: 0; 
}
.wrap .rolling-list ul li:nth-child(1) { 
	background-color: #F8E1E3;
}
.wrap .rolling-list ul li:nth-child(2) { 
	background-color: #FFEAB5; 
}
.wrap .rolling-list ul li:nth-child(3) { 
	background-color: #D3E7DC;
}
.wrap .rolling-list ul li:nth-child(4) { 
	background-color: #A6C1E8;
}
.wrap .rolling-list ul li:nth-child(even) {
	margin-top: 80px;
}
.wrap .rolling-list ul li .image-wrap { 
	padding-right: 32px; 
    width: 156px; 
    flex-shrink: 0; 
}
.wrap .rolling-list ul li .image-wrap > img { 
	width: 100%;
}
.wrap .rolling-list ul li .desc { 
	font-family: 'BMJUA';
}
.wrap .rolling-list ul li .desc strong { 
	display: block; 
    font-size: 24px; 
    margin-bottom: 24px;
}
.wrap .rolling-list ul li .desc span { 
	font-size: 18px;
    line-height: 1.2;
}

배너 초기 상태 완성! ⤵

무한 롤링을 위해 clonNode() 메소드를 이용해 원본 배너를 복제해 줍니다.

Script

// 롤링 배너 복제본 생성
let roller = document.querySelector('.rolling-list');
roller.id = 'roller1'; // 아이디 부여

let clone = roller.cloneNode(true)
// cloneNode : 노드 복제. 기본값은 false. 자식 노드까지 복제를 원하면 true 사용
clone.id = 'roller2';
document.querySelector('.wrap').appendChild(clone); // wrap 하위 자식으로 부착

document.querySelector('#roller1').style.left = '0px';
document.querySelector('#roller2').style.left = document.querySelector('.rolling-list ul').offsetWidth + 'px';
// offsetWidth : 요소의 크기 확인(margin을 제외한 padding값, border값까지 계산한 값)

roller.classList.add('original');
clone.classList.add('clone');

복제가 잘 된 모습을 확인하실 수 있습니다! 🙌
이제 css 키프레임 애니메이션으로 무한 루프를 구현해 보겠습니다.

.rolling-list.original {
	animation: rollingleft1 33s linear infinite;
}
.rolling-list.clone {
	animation: rollingleft2 33s linear infinite;
}

@keyframes rollingleft1 {
	0% { transform: translateX(0); }
	50% { transform: translateX(-100%); }
	50.01% { transform: translateX(100%); }
	100% { transform: translateX(0); }
}

@keyframes rollingleft2 {
	0% { transition: translateX(0); }
	100% { transform: translateX(-200%); }
}

원본 배너와 복제 배너에 키프레임 애니메이션을 추가해서 무한 루프를 구현합니다.
✔ 원본 배너와 복제 배너의 시작 위치가 다르기 때문에 애니메이션을 두개 만들어서 이동 좌표를 각각 설정해줍니다.
✔ 애니메이션이 50% 진행됐을때 배너가 가려져서 안보이게 되는 위치만큼 이동한 후, 50.01% 시점에 뷰포트 너머의 오른쪽 위치로 이동시켜 줍니다.

이해를 돕기 위해 그림으로 확인해 보겠습니다!

0% : 배너1, 배너2 왼쪽으로 이동 애니메이션

50% : 배너1은 뷰포트 너머로 가려지게 됨

50.01% : 배너1 오른쪽 뷰포트 너머로 이동

100% : 원래의 위치로 이동

애니메이션을 무한으로 설정해 무한 롤링 배너가 완성 되었습니다! 🤗

✨ 결과물

2. marquee.js 플러그인으로 구현

이번에는 marquee.js 플러그인을 사용해서 위와 같은 텍스트 자동 롤링 효과를 만들어 보겠습니다!

🖥 코드 작성

HTML

<div class="marquee-wrap">
Lorem ipsum dolor sit amet, consectetur adipisicing elit.
Neque cumque ratione provident nulla veniam nihil quaerat,
illum officiis hic. Laborum in eos possimus,
quo ullam nobis nam nemo fuga ipsam?
</div>

CSS

<style>
  .marquee-wrap {
    width: 500px;
    height: 20px;
    border: 1px solid #ddd;
    overflow: hidden;
  }
</style>

Script

<script type="text/javascript">
  	$(document).ready(function(){
		$('.marquee-wrap').marquee();
	});
</script>

marquee.js 플러그인을 추가합니다.

<script src="./js/jquery-3.6.0.min.js"></script>
<script src="./js/jquery.marquee.min.js"></script>

✨ 결과물

완성! 참 쉽죠? 🎨
옵션도 추가해 봅시다!

<script type="text/javascript">
  	$(document).ready(function(){
		$('.marquee-wrap').marquee({
            speed: 80, // 속도
            gap: 100, // 간격
            delayBeforeStart: 0, // 시작 delay값
            direction: 'left', // 방향
            duplicated: true, // 선택 영역 복제
            pauseOnHover: true // hover시 일시중지 여부
        });
	});
</script>

speed : 자동롤링 속도
gap : 간격, duplicated 옵션이 설정된 경우에만 작동. 기본값 20
delayBeforeStart : 애니메이션을 시작하기 전의 delay값. 기본값 1000
direction : 움직이는 방향. 기본값 left*
duplicated : 연속흐름 효과를 표시하기 위해 선택 영역 복제. 기본값 false (보통은 텍스트가 컨테이너보다 짧은 경우에만 사용)
pauseOnHover :마우스를 올리면 일시중지, 기본값은 false

🌈 direction 옵션으로 세로방향 자동롤링도 가능합니다!

<script type="text/javascript">
  	$(document).ready(function(){
		$('.marquee-wrap').marquee({
            direction: 'up',
            speed: 1000
        });
	});
</script>

direction : left / right / up / down 으로 커스텀 가능

구글링을 하다가 자동 롤링 플러그인을 모아놓은 사이트 발견! ⤵
10 Best Marquee-like Content Scrolling Plugins In JavaScript (2022 Update)
참고하셔도 좋을 거 같아요 👍

정리

나는 첫 번째 방법으로 구현을 했는데 뒤늦게 더 찾아보니 플러그인이 다양하게 있고 옵션 설정도 쉽게 가능해서 좀 더 빨리 알았더라면 하는 아쉬움이 있다😢

포폴을 만들 때는 직접 구현하는게 좋지만 실제 업무를 할 때는 비교적 짧은 시간 안에 작업물을 만들어내야 해서.. 플러그인을 사용하는게 더 효율적인 느낌이랄까?

그래도 직접 구현을 함으로써 자바스크립트 예습을 한 셈이니 좋게 생각하자!


📄 참고자료

2개의 댓글

comment-user-thumbnail
2023년 11월 28일

혹시 역방향 롤링이 필요하신 분이 있을 것 같아 적자면
1. rollingleft1 keyframe 의 0%와 50%, 50.01%와 100% 를 서로 바꾼다
2. rollingleft2 의 0%와 100% 를 바꾼다
3. .rolling-list.clone 의 animation-delay를 animation 의 1/2 만큼 준다
위와 같이 변경하면 역방향 롤링이 됩니다

좋은 글 잘 봤습니다~

1개의 답글