반응형
Notice
Recent Posts
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Today
Total
관리 메뉴

오식랜드

[nuxt / motion] clip을 이용한 슬라이드 본문

dev-log/html·css·js

[nuxt / motion] clip을 이용한 슬라이드

개발하는 오식이 2021. 5. 4. 18:01
반응형

[nuxt] 실제 업무 중 사용한 슬라이드를 공유하려고 한다.

실제 foreigner.lawfirmy.com/ 에 적용한 슬라이드다.

 

 

Template

Nuxt에서 작업했던 슬라이드라 Nuxt의 구조를 가져왔다. html의 body라고 생각하면 된다!

구조를 보면, slide-wapper > slide-container > slide 가 있고, slide 안에 이미지와 글 공간이 마련되어 있다.

 

<template>
       <div class="slide-section">
            <div class="slide-wrapper">
                <h2>Title</h2>
                <div class="slide-container">
                <div class="slide active">
                    <img :src="img1" @click="slideEvent($event)" class="images">
                    <div class="slide-info">
                           <!-- text -->
                        <div class="button-wrapper">
                            <div class="prev-btn" @click="slideEvent($event)"></div>
                            <div class="next-btn" @click="slideEvent($event)"></div>
                        </div>
                    </div>
                </div>
                <div class="slide">
                    <img :src="img2" @click="slideEvent($event)" class="images">
                    <div class="slide-info">
                          <!-- text -->
                          <div class="button-wrapper">
                              <div class="prev-btn" @click="slideEvent($event)"></div>
                              <div class="next-btn" @click="slideEvent($event)"></div>
                          </div>
                    </div>
                </div>
                <div class="slide">
                    <img :src="img3" @click="slideEvent($event)" class="images">
                    <div class="slide-info">
                         <!-- text -->     
                         <div class="button-wrapper">
                            <div class="prev-btn" @click="slideEvent($event)"></div>
                            <div class="next-btn" @click="slideEvent($event)"></div>
                        </div>
                    </div>
                </div>
                <div class="slide-inedx">
                    <span class="now-index">1</span> / 3
                </div>
                </div>
            </div>
        </div>
</template>

태그 안의 @click은 클릭 이벤트를 바인딩 시켜준 것이다.

element.addEventListener('click', function())과 같은 의미이다.

사람 이미지와 글 아래의 좌, 우 버튼 클릭시 슬라이드가 넘어가는 이벤트를 호출한다.

 

Style

슬라이드가 absolute이면 active된 페이지에 따라 translateX값도 조정해줘야 하기 때문에 display flex를 주고, clip-path와 width값을 동시에 사용했다. 영역이 자동으로 늘어나도록!

그래서 약간 귀찮기도 했지만, 슬라이드 전부 x값을 움직이는 것 보다는 자동적일듯 해서 이 방향으로 선택했다.

clip-path에는 rect가 없어서 polygon을 이용했다.

<style lang='scss'>
 .slide-section {
   position: relative;
   width: 100%;
   display: flex;
   justify-content: center;
   align-items: center;
   
   .slide-wrapper {
     width: 60%;
     margin: 50px 0;
     
     .slide-container {
       display: flex;
       justify-content: center;
       align-items: center;
       margin-top: 50px;

      .slide {
        display: flex;
        justify-content: flex-start;
        align-items: center;
        overflow: hidden;
        width: 230px;
        height: 460px;
        transition: all 0.6s;

        .lawyer-image {
          transition: all 0.6s;
          width: 230px;
          height: 460px;
          bottom: 0;
          left: 0;
        }

      .slide-info {
        transition: all 0.3s;
        margin: 0 20px;
        overflow: hidden;
        position: absolute;
        margin-left: 250px;
        width: 350px;
        clip-path: polygon(0% 0, 0px 0%, 0px 100%, 0% 100%);

        .button-wrapper {
          display: flex;
          justify-content: flex-start;
          align-items: center;
          margin-top: 40px;

          div {
            width: 34px;
            height: 34px;
            z-index: 1;
          }

          .prev-btn {
            background: url('~assets/images/prev.png') no-repeat center;
            background-size: cover;
          }

          .next-btn {
            margin-left: 14px;
            background: url('~assets/images/next.png') no-repeat center;
            background-size: cover;
          }
        }
      }

        &.active {
           width: 60%;

          .slide-info {
            clip-path: polygon(0% 0, 100% 0%, 100% 100%, 0% 100%);
          }
        }
      }
   }
   
 }
 
</style>

 

Method

이벤트는 간단하다. 오히려 스타일 잡는게 더 오래 걸렸다ㅠㅠ

이벤트에서는 우선 클릭한 대상에 따라 nowIndex를 더하거나 빼주거나 클릭대상의 index로 바꿔준다

그리고 슬라이드를 배열로 받아 forEach에 넣어 active클래스를 모두 지워주고 nowIndex에 맞는 슬라이드에 active클래스를 추가해준다. 

 

마지막에 '.now-index'는 슬라이드가 몇번째인지 화면에 나타내줄 때 사용하면 된다

ex) 1/3 , 2/3, 3/3

innerHTML을 할 때  +1을 해준 이유는 nowIndex의  시작은 0부터 이기 때문에, 사람들이 인식할때에는 1부터 시작하게 하기 위해서이다.

<script>
export default {
  methods: {
     slideEvent(e){
            let slide = document.querySelectorAll('.slide'),
                nowActive = document.querySelector('.slide.active'),
                nowIndex = [].indexOf.call(nowActive.parentNode.children, nowActive)
            
            if(e.target.classList == 'next-btn') {
                ++nowIndex 
                if(nowIndex == lawyers.length) nowIndex = 0
            }
            if(e.target.classList == 'prev-btn'){
                --nowIndex
                if(nowIndex == -1) nowIndex = (lawyers.length -1)
            }
            if(e.target.classList == 'slide-image'){
                let parent = e.target.parentNode;
                nowIndex = [].indexOf.call(parent.parentNode.children, parent)
            }
            nowActive.classList.remove('active');
            slide[nowIndex].classList.add('active');
            
            document.querySelector('.now-index').innerHTML = (nowIndex+1);
      }
   }
}

 

반응형
Comments