한쪽 방향으로 계속 이동하는 텍스트, 무한롤링 공지사항, 대시보드 한 줄 정보, animation, requestAnimationFrame - css + javascript + html
한쪽 방향으로 계속 이동되지만 마우스를 가져가면 멈추고, 마우스가 나가면 다시 이동하는 효과
css 버전 - animation
html
<div class="wrap">
<div class="txt_box" @mouseenter="stopNoti(true)" @mouseleave="stopNoti(false)">
<a href="공지1">공지1</a>
<a href="공지2">공지2</a>
<a href="공지3">공지3</a>
</div>
</div>
css
/* dlsplay:flex 한 이유는 .txt_box가 복제되어서 들어가서 라인을 맞추려고 */
.wrap{
display:flex;
width:1000px;
overflow:hidden;
}
.txt_box{
display:flex;
align-items:center;
animation:leftToRight 20s linear infinite;
}
/* 마우스가 오버되면 정지 */
.txt_box.on{
animation-play-state:paused;
}
/*
왼쪽에서 오른쪽 이동.
javascript에서 .txt_box를 복제해서 넣어서 -100% -> 0%.
*/
@keyframes leftToRight {
from{
transform:translateX(-100%);
}
to{
transform:translateX(0%);
}
}
......
js
// 이동되는 영역 복제해서 넣기
let cloneBox = document.querySelector(".txt_box").cloneNode(true);
document.querySelector(".wrap").append(cloneBox);
// 왼쪽에서 오른쪽으로(css 정의) 이동하기
stopNoti = (bl) => {
// 멈춤
if (bl) {
document.querySelectorAll(".txt_box").forEach((ele, idx) => {
ele.classList.add("on");
})
}
// 이동하기
else {
document.querySelectorAll(".txt_box").forEach((ele, idx) => {
ele.classList.remove("on");
})
}
}
js 버전 - requestAnimationFrame
html
<div id="rolling" v-cloak>
<div class=" move_box" @mouseenter="moveStop(true)" @mouseleave="moveStop(false)">
<div class="move_area" :style="'transform:translateX('+ info.leftx +'%)'">
<div class="move_wrap">
<a href="공지1">공지1</a>
<a href="공지2">공지2</a>
<a href="공지3">공지3</a>
</div>
</div>
</div>
</div>
css
/* dlsplay:flex 한 이유는 .move_wrap이 복제되어서 들어가서 라인을 맞추려고 */
.move_area{display:flex;}
......
js (vuejs 사용)
const {createApp, reactive, computed, onMounted} = Vue;
const smove = {
setup() {
// ref() 를 사용하면 js에선 .value로 찾아감(예: info.value.leftx)
// : dom에는 .value 없음(예: info.leftx)
// reactive() 는 항상 .value 불필요
const info = reactive({
percent: 0,
aniId: null,
leftx: -50,// .move_wrap이 하나 더 복제되어서. move_area의 x위치를 -50% 로 이동
})
// 왼쪽에서 오른쪽으로 계속 이동
leftMove = () => {
info.leftx = -50 + (info.percent += 0.03);
info.aniId = info.percent && requestAnimationFrame(leftMove);
// 이동하는 영역의 x위치가 0%보다 크고, 50%가 넘어가면
if(info.leftx > 0 && info.percent > 50){
// 다시 0%에서 시작
info.percent = 0;
}
}
// 계속 움직이는 영역에
const moveStop = (bo) => {
// 마우스를 가져가면 멈춤
if(bo) {
cancelAnimationFrame(info.aniId);
}
// 마우스가 벗어나면 다시 움직임
else {
requestAnimationFrame(leftMove);
}
}
onMounted(() => {
// .move_wrap 복제
let cloneWrap = document.querySelector(".move_wrap").cloneNode(true);
// .move_area에 복제된거 넣음(prepend : 앞에 붙임, append : 뒤에 붙임)
document.querySelector(".move_area").append(cloneWrap);
// 왼쪽에서 오른쪽으로 계속 이동
requestAnimationFrame(leftMove);
})
return {
info, moveStop,
}
}
};
createApp(smove).mount("#rolling");
메인 화면이나 대시보드 같은데서 공지사항 같은 한 줄 정보를 끊임없이 보여주는 효과로 사용할 수 있는게 두개 있다.
하나는 css의 animation 속성이고, 다른 하나는 javascript의 requestAnimationFrame이다.
둘 다 적용해보고 좀 더 편하게 사용가능 한 것으로 선택해보자.
끝.