본문 바로가기
Javascript응용_Effect

Slider EFfect 07

by 코딩대원 2022. 10. 23.

슬라이드 이펙트

이번 시간에는 이미지 슬라이드(버튼, 닷메뉴, 무한, 플레이 버튼, 정지 버튼, 자동 플레이) 효과에 대해 알아보겠습니다.


슬라이드 07

슬라이드 이펙트 모든 기능이 구현된 종합세트입니다. 6번 예제와 대체로 비슷하지만 닷메뉴가 이미지 이동에 따라 같이 이동하고 auto 플레이가 가능하며,
mouseenter, mouseleave에 반응하여 마우스 위치에 따라 슬라이드가 멈췄다가 진행했다가 합니다.

01. HTML 코드


    <main id="main">
    <section id="sliderType07">
        <div class="slider__wrap">
            <div class="slider__img">
                <div class="slider__inner">
                    <div class="slider s1"><span>이미지1</span><img src="../assets/img/effect_bg13@2x-min.jpg" alt="이미지1"></div>
                    <div class="slider s2"><span>이미지2</span><img src="../assets/img/effect_bg14@2x-min.jpg" alt="이미지1"></div>
                    <div class="slider s3"><span>이미지3</span><img src="../assets/img/effect_bg15@2x-min.jpg" alt="이미지1"></div>
                    <div class="slider s4"><span>이미지4</span><img src="../assets/img/effect_bg16@2x-min.jpg" alt="이미지1"></div>
                    <div class="slider s5"><span>이미지5</span><img src="../assets/img/effect_bg17@2x-min.jpg" alt="이미지1"></div>
  
                </div>
            </div>
            <div class="slider__btn">
                <button href="#" class="prev">prev</button>   
                <button href="#" class="next">next</button>
            </div>
            <div class="slider__dot">
                <!-- <a href="" class="dot active">이미지1</a>
                <a href="" class="dot">이미지2</a>
                <a href="" class="dot">이미지3</a>
                <a href="" class="dot">이미지4</a>
                <a href="" class="dot">이미지5</a> -->
            </div>
        </div>
    </section>
  </main>

02. CSS 코드


    @import url('https://webfontworld.github.io/NanumBarunGothic/NanumBarunGothic.css');
        
    .slider__wrap {
        width: 100%;
        height: 100vh;
        display: flex;
        align-items: center;
        justify-content: center;
    }
    .slider__img {           /* 이미지 보이는 영역 */
        position: relative;
        width: 800px;
        height: 450px;
        overflow: hidden;
    }
    .slider__inner {         /* 이미지를 감싸고 있는 부모 : 움직이는 부분 */
        display: flex;
        flex-wrap: wrap;
        width: 10000px;
        height: 450px;
        position: relative;
        left: -800px;
    }
    .slider__inner.transition {
        transition: all 0.3s;
    }
    .slider {                /* 개별적인 이미지 */
        position: relative;
        width: 800px;
        height: 450px;
    }
    .slider span {
        position: absolute;
        left: 5px;
        top: 5px;
        background: rgba(0,0,0,0.4);
        color: #fff;
        padding: 5px 10px;
    }
    /* .slider:nth-child(1)::before {content: '이미지1'}
    .slider:nth-child(2)::before {content: '이미지2'}
    .slider:nth-child(3)::before {content: '이미지3'}
    .slider:nth-child(4)::before {content: '이미지4'}
    .slider:nth-child(5)::before {content: '이미지5'}
    .slider:nth-child(6)::before {content: '이미지1'} */

    @media (max-width: 800px){
        .slider__img {
            width: 400px;
            height: 225px;
        }
    }
    .slider__btn button {
        position: absolute;
        top: 50%;
        transform: translateY(-50%);
        width: 50px;
        height: 50px;
        background: rgba(0, 0, 0, 0.4);
        text-align: center;
        line-height: 50px;
        transition: all 0.2s;
        display: block;
        color: #fff;
        pointer-events: auto;
        border: 0;
        cursor: pointer;
    }
    .slider__btn.disable button {
        /* pointer-events: none; */
    }
    .slider__btn button:hover {
        background: rgba(43, 21, 248, 0.616);
        color: rgba(245, 71, 18, 0.993);
    }
    .slider__btn button.prev {
        left: 0;
        border-radius: 50%;
    }
    .slider__btn button.next {
        right: 0;
        border-radius: 50%;
    }
    .slider__dot {
        position: absolute;
        left: 50%;
        transform: translateX(-50%);
        bottom: 20px;
    }
    .slider__dot .dot {
        width: 20px;
        height: 20px;
        background: rgba(0,0,0,0.4);
        display: inline-block;
        border-radius: 50%;
        text-indent: -9999px;
        transition: all 0.3s;
        margin: 3px;
    }
    .slider__dot .dot.active {
        background: rgba(255,255,255,0.9);
    }
    .slider__dot .play {
        display: none;
    }
    .slider__dot .play.show {
        display: inline-block;
        width: 20px;
        height: 20px;
        margin-left: 7px;
        vertical-align: 3px;
        border-left: 16px solid #fff;
        border-top: 10px solid transparent;
        border-bottom: 10px solid transparent;
    }
    .slider__dot .stop {
        display: none;
    }
    .slider__dot .stop.show {
        display: block;
        margin-left: 7px;
        display: inline-block;
        width: 16px;
        height: 20px;
        vertical-align: 3px;
        position: relative;
    }
    .slider__dot .stop::before {
        content: '';
        width: 5px;
        height: 20px;
        background: #fff;
        position: absolute;
        left: 0;
        top: 0;
    }
    .slider__dot .stop::after {
        content: '';
        width: 5px;
        height: 20px;
        background: #fff;
        position: absolute;
        right: 0;
        top: 0;
    } 

03. JS 코드

첫번째 이미지와 마지막 이미지를 복사하는 등 6번과 비슷한 흐름으로 진행되지만 좀 더 복잡합니다.
autoPlay 등 자동플레이에 필요한 함수가 좀 더 추가되고, 닷메뉴와 마우스 반응 관련해서 함수를 좀 더 추가했습니다.


    const sliderWrap = document.querySelector(".slider__wrap");              //전체 영역
    const sliderImg = document.querySelector(".slider__img");                //보여지는 영역
    const sliderInner = document.querySelector(".slider__inner");            //움직이는 영역 
    const slider = document.querySelectorAll(".slider");                     //각각 이미지
    const sliderDot = document.querySelector(".slider__dot");                //닷 메뉴
    const sliderBtn = document.querySelector(".slider__btn");                //버튼
    const sliderBtnPrev = document.querySelector(".slider__btn .prev");      //왼쪽 버튼
    const sliderBtnNext = document.querySelector(".slider__btn .next");      //오른쪽 버튼
    const sliderBtnPlay = document.querySelector(".slider__dot .play");      //플레이 버튼
    const sliderBtnStop = document.querySelector(".slider__dot .stop");      //정지 버튼

    let currentIndex = 0,                           // 현재 이미지
        sliderLength = slider.length,               // 슬라이더 갯수
        sliderWidth = slider[0].offsetWidth,        // 이미지의 X축 크기
        sliderFirst = slider[0]                     // 첫번째 이미지
        sliderLast = slider[sliderLength - 1],      // 마지막 이미지
        cloneFirst = sliderFirst.cloneNode(true),   // 첫번째 이미지 복사
        cloneLast = sliderLast.cloneNode(true),     // 마지막 이미지 복사
        dotIndex = "",
        interval = 3000,
        sliderTimer = "";

        let dotActive = document.querySelectorAll(".slider__dot .dot");

    function init(){
        imgClone();     //이미지 복사
        createDot();    //닷 버튼 생성
        // autoPlay();     //자동 재생
    }
    init();

    function autoPlay(){
        sliderTimer = setInterval(()=>{
            let intervalNum = currentIndex + 1;
            gotoSlider(intervalNum)

            if(intervalNum > 4){
                let dotActive = document.querySelectorAll(".slider__dot .dot");
                dotActive.forEach(el => el.classList.remove("active"));
                dotActive[0].classList.add("active");
            } else {
                let dotActive = document.querySelectorAll(".slider__dot .dot");
                dotActive.forEach(el => el.classList.remove("active"));
                dotActive[intervalNum].classList.add("active");
            }
        }, interval)
    }

    function stopPlay(){
        clearInterval(sliderTimer)
    }

    function imgClone(){
        sliderInner.appendChild(cloneFirst)
        sliderInner.insertBefore(cloneLast, sliderFirst);
    }

    function createDot(){
        for(let i=1; i<=sliderLength; i++){
            dotIndex += "<a href='#' class='dot'></a>";
        }

        
        dotIndex += "<a href='#' class='play show'></a>";
        dotIndex += "<a href='#' class='stop'></a>";
        

        sliderDot.innerHTML = dotIndex;
        sliderDot.firstElementChild.classList.add("active");

    }

    function gotoSlider(index){
        sliderInner.classList.add("transition");
        let posInitial = sliderInner.offsetLeft;    // -800

        sliderInner.style.left = -sliderWidth * (index + 1) + "px";

        currentIndex = index;

    }

    function checkIndex(){
        sliderInner.classList.remove("transition");

        // 마지막 이미지
        if(currentIndex == sliderLength){
            sliderInner.style.left = -(1 * sliderWidth) + "px";
            currentIndex = 0;
            
        }

        // 처음 이미지
        if(currentIndex == -1){
            sliderInner.style.left = -(sliderLength * sliderWidth) + "px";
            currentIndex = sliderLength -1 ;
        }
    }

    sliderBtnPrev.addEventListener("click", ()=>{
        let prevIndex = currentIndex -1;
        gotoSlider(prevIndex);

        console.log(prevIndex)

        if(prevIndex < 0){
            let dotActive = document.querySelectorAll(".slider__dot .dot");
            dotActive.forEach(el => el.classList.remove("active"));
            dotActive[4].classList.add("active");
        } else {
            let dotActive = document.querySelectorAll(".slider__dot .dot");
            dotActive.forEach(el => el.classList.remove("active"));
            dotActive[prevIndex].classList.add("active");
        }

    });

    document.querySelectorAll(".slider__dot .dot").forEach((dot, index)=>{
        dot.addEventListener("click", ()=>{
            let dotActive = document.querySelectorAll(".slider__dot .dot");
            dotActive.forEach(el => el.classList.remove("active"));
            dotActive[index].classList.add("active");
            gotoSlider(index);
        })
    });

    sliderBtnNext.addEventListener("click", ()=>{
        let nextIndex = currentIndex +1;
        gotoSlider(nextIndex);

        if(nextIndex < 5) {
            let dotActive = document.querySelectorAll(".slider__dot .dot");
            dotActive.forEach(el => el.classList.remove("active"));
            dotActive[nextIndex].classList.add("active");
        } else {
            let dotActive = document.querySelectorAll(".slider__dot .dot");
            dotActive.forEach(el => el.classList.remove("active"));
            dotActive[0].classList.add("active");
        }
        
    });

    document.querySelector(".slider__dot .play").addEventListener("click", ()=>{

        document.querySelector(".slider__dot .stop").classList.add("show")
        document.querySelector(".slider__dot .play").classList.remove("show")
        autoPlay();         
    });

    document.querySelector(".slider__dot .stop").addEventListener("click", ()=>{

        document.querySelector(".slider__dot .stop").classList.remove("show")
        document.querySelector(".slider__dot .play").classList.add("show")
        stopPlay();
    });


    // sliderInner.addEventListener("mouseenter", stopPlay);
    // sliderInner.addEventListener("mouseleave", autoPlay);
    sliderInner.addEventListener("transitionend", checkIndex);

'Javascript응용_Effect' 카테고리의 다른 글

Slider Effect 06  (1) 2022.10.21
Search Effect 07  (1) 2022.10.21
Game Effect 01  (2) 2022.10.18
Search Effect06  (0) 2022.10.18
Slider Effect 05  (0) 2022.10.14

댓글


HTML
CSS

JAVASCRIPT

자세히 보기