본문 바로가기
Vuejs_JS_CSS(3)

자바스크립트 관련 - 무한 슬라이드, requestAnimationFrame

by 꿀이다 2022. 9. 23.
반응형

자바스크립트와 css를 사용해서 무한 슬라이드, requestAnimationFrame, cancelAnimationFrame

간단히 왼쪽에서 오른쪽으로 무한하게 움직이지만 해당 영역에 마우스를 가져가면 멈추고, 영역에서 나가면 다시 움직이는  슬라이드 효과를 만들어보자.

 

html 
<div id="slide" v-cloak>
  <!-- 마우스가 slide 되는 영역에 위치하면 멈추고, 나가면 다시 움직임 -->
  <div class="slide_box" @mouseenter="slideMove(true)" @mouseleave="slideMove(false)">

    <!-- 무한하게 가로로 slide 되는 영역(왼쪽에서 오른쪽으로) -->
    <div class="slider_area" :style="'transform:translateX('+ slideinfo.leftx +'%)'">

      <!--
        slide 되는 영역의 컨텐츠가 있는 영역.
        js에서 복제되어 하나 더 이어서 배치될 예정.
        (예: <div class="slider_wrap"></div><div class="slider_wrap"></div>)
      -->
      <div class="slider_wrap">
        <div class="exbox"></div>
        <div class="exbox"></div>
        <div class="exbox"></div>
        <div class="exbox"></div>
      </div>

    </div>

  </div>
</div>

 

css
/* slide가 되려고 컨텐츠들 가로 정렬 */
.slider_area{display:flex;}/* translateX가 0%가 되면 다시 -50%로 가도록 */
.slider_wrap{display:flex;}

 

js(vue)
const {createApp, ref, computed, onMounted} = Vue;
const slide = {
  setup() {
    // ref() 를 사용하면 js에선 .value로 찾아감(예: slideinfo.value.leftx). dom에는 .value 없음(예: slideinfo.leftx)
    // reactive() 는 항상 .value 필요없음
    const slideinfo = ref({
      percent: 0,
      aniId: null,
      leftx: -50,// .slider_wrap이 하나 더 복제되어 이어 붙어서 slide가 무한히 되도록 .slider_area의 x위치를 -50% 로 이동
    })

    // 왼쪽에서 오른쪽으로 계속 이동
    leftMove =() => {
      slideinfo.value.leftx = -50 + (slideinfo.value.percent += 0.03);
      slideinfo.value.aniId = slideinfo.value.percent && requestAnimationFrame(leftMove);

      // slide 영역의 x위치가 0%보다 크고, %가 50보다 크면
      if(slideinfo.value.leftx > 0 && slideinfo.value.percent > 50){
        // 다시 0%에서 시작
        slideinfo.value.percent = 0;
      }
    }

    // 계속 움직이는 영역에
    const slideMove = (bo) => {
      // 마우스를 가져가면 멈춤
      if(bo) {
        cancelAnimationFrame(slideinfo.value.aniId);
      }
      // 마우스가 벗어나면 다시 움직임
      else {
        requestAnimationFrame(leftMove);
      }
    }

    onMounted(() => {
      // .slider_wrap 복제
      let cloneSlider = document.querySelector(".slider_wrap").cloneNode(true);

      // .slider_area에 복제된거 넣음(prepend : 앞에 붙임,  append : 뒤에 붙임)
      document.querySelector(".slider_area").append(cloneSlider);

      // 왼쪽에서 오른쪽으로 계속 이동
      requestAnimationFrame(leftMove);
    })

    return {
      slideinfo, slideMove,
    }
  }
};
createApp(slide).mount("#slide");

 

- 끝 -

반응형

댓글