외부 라이브러리
라이브러리는 Zepto와 anime.js를 이용했다.
Zepto는 편리하게 엘리먼트를 선택하기 위해서이고, anime.js는 편하게 loop를 설정하기 위하여 이용했다. css animation을 꼭 이용해보고 싶었지만, css에 변수를 어떻게 전달할지에 대한 마땅한 대책이 떠오르지 않아서 애니메이션 라이브러리를 이용했다.
아래 전체 코드에서 확인할 테지만, head 태그 부분에서 스크립트를 불러올 수 있도록 했다.
전체 코드
아래 Result
를 눌러보면 바로 결과를 확인할 수 있다.
구현 흐름
- DOM을 관리할 수 있는 자바스크립트 라이브러리를 이용해 (여기서는 zepto이다.) 텍스트 및 데이터들을 불러온다.
- 텍스트를 실제로 화면에 띄운 다음에, 가로 사이즈를 측정한다.
- 배너 전체 너비가 다 채워질 때까지 텍스트를 복제한다. 정확히는 (배너 전체 너비 + 텍스트 하나의 너비)가 다 채워져야 한다. 왜냐하면 텍스트가 움직이는 만큼에도 텍스트가 채워져 있어야 하기 때문이다.
- 텍스트를 일정한 속도로 이동시키고, 이동된
x
가 텍스트 너비만큼 이동되는 순간 0으로 초기화시킨다. 이를 무제한 반복한다. (실제로는 자바스크립트에서 매 렌더링 프레임마다 특정 코드를 실행시키는 것이 번거로워서 무한루프 기능이 있는 자바스크립트 애니메이션 라이브러리인anime.js
를 이용했다.)
실제 구현시 유의사항
Zepto(function($) {
$(window).on('load', function() {
$.each($(".ezkorry-roller"), function(index, item) {
...
});
})
});
배너에 돌릴 텍스트의 가로 사이즈를 구할 때, DOMContentLoaded
이벤트는 단순히 DOM 구조가 완료되었을 때 실행되므로, 실제 폰트가 아닌 기본 폰트로 적용된 상태에서 가로 길이를 구하기 때문에 우리의 의도에 살짝 빗나간다. 실제 폰트가 적용되었을 때 가로 길이를 구할 수 있도록 load
이벤트를 이용한다.
.ezkorry-roller {
overflow: hidden;
white-space: nowrap;
}
가장 바깥 쪽 div
요소 (위 예제에서는 .ezkorry-roller
)의 내용에 대해 스크롤이 생기지 않도록 overflow: hidden; white-space: nowrap;
의 내용으로 css를 적용해주었다.
const wrapper = $("<div />", { class:"ezkorry-roller-wrapper"});
const roller = $(item);
roller.append(wrapper);
const span = roller.find('span').first();
wrapper.append(span);
실제 텍스트인 span
과 div.ezkorry-roller
사이에 div.ezkorry-roller-wrapper
를 놓은 이유는, 이 요소에다가 움직이는 애니메이션을 먹일 것이기 때문이다. 기존의 구조에서는 애니메이션을 먹일 요소가 마땅히 없다.
const span_width = span.get(0).offsetWidth;
const max_width = roller.width() + span_width;
let inner_width = span_width;
while(max_width > inner_width) {
wrapper.append(span.clone());
inner_width += span_width;
}
anime({
targets: '.ezkorry-roller-wrapper',
translateX: {
value: '-=' + span_width + 'px',
duration: 3000
},
loop: true,
easing: 'linear'
});
핵심 부분이다. span_width
는 텍스트 하나의 길이이고, max_width
채워야 할 전체 너비를 나타내며, inner_width
는 while
내부를 돌기 위한 조건 변수로 두었다. 그리고 애니메이션은 anime.js
를 이용해서 무한으로 오른쪽에서 왼쪽으로 돌도록 만들었다.
후기
간단한 동작이라 라이브러리를 찾지 않고 직접 구현했다. 그러나 여전히 zepto나 anime.js의 라이브러리 사용법을 찾는다고 적지 않은 시간을 할애했다. 두 라이브러리는 앞으로도 두고두고 쓸 것 같으니 뭐 이정도 선에서 깔끔하게 구현한 걸 만족한다.