๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
EFFECT

[EFFECT] ์Šฌ๋ผ์ด๋“œ ํšจ๊ณผ - ์ด๋ฏธ์ง€ ์Šฌ๋ผ์ด๋“œ(๋ฒ„ํŠผ, dot๋ฉ”๋‰ด, ๋ฌดํ•œ, ์ž๋™ํ”Œ๋ ˆ์ด ์ •์ง€๋ฒ„ํŠผ, ์ž๋™ํ”Œ๋ ˆ์ด ๋ฒ„ํŠผ)

by _ํ† ๋งคํ†  2022. 10. 24.
728x90

์Šฌ๋ผ์ด๋“œ ์ดํŽ™ํŠธ - ์ด๋ฏธ์ง€ ์Šฌ๋ผ์ด๋“œ(๋ฒ„ํŠผ, dot๋ฉ”๋‰ด, ๋ฌดํ•œ์œผ๋กœ ์›€์ง์ด๊ธฐ, ์ž๋™ํ”Œ๋ ˆ์ด ์ •์ง€๋ฒ„ํŠผ, ์ž๋™ํ”Œ๋ ˆ์ด ๋ฒ„ํŠผ)

์ด๋ฒˆ ์‹œ๊ฐ„์—๋Š” ์ง€๊ธˆ๊นŒ์ง€ ํ–ˆ๋˜ ์Šฌ๋ผ์ด๋“œ ์‹ค์Šต์„ ๋ชจ๋‘ ์‘์šฉํ•œ ์ตœ์ข…์ ์ธ ์Šฌ๋ผ์ด๋“œ๋ฅผ ๊ตฌํ˜„ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๐Ÿฅน ๋ชจ๋‘ ๊ณ ์ƒ๋งŽ์œผ์…จ์Šต๋‹ˆ๋‹ค! ๐Ÿซ ๐Ÿซ ๐Ÿ”ฅ


#1. HTML / CSS ์„ค์ •ํ•˜๊ธฐ

! HTML TIP !
๊ฐ ์ด๋ฏธ์ง€๋งˆ๋‹ค css์„ค์ •์„ ์ฃผ๊ธฐ ์œ„ํ•ด ๋”ฐ๋กœ ๋ถ€๋ชจ๋ฅผ 2๋ฒˆ ๊ฐ์‹ธ์„œ ๋ฌถ์–ด์ค๋‹ˆ๋‹ค.
๋˜ํ•œ ๋ฒ„ํŠผ ์•„๋ž˜ ๋‹ท๋ฉ”๋‰ด์™€ ์žฌ์ƒ์ •์ง€๋ฒ„ํŠผ ๊ตฌ์กฐ๋Š” ์Šคํฌ๋ฆฝํŠธ๋กœ ๊ตฌํ˜„ํ•  ๊ฒƒ์ด๋ฏ€๋กœ ์ฃผ์„์ฒ˜๋ฆฌ๋ฅผ ํ•ด์ค๋‹ˆ๋‹ค.

โœ๏ธ HTML ์Šคํฌ๋ฆฝํŠธ ๋ณด๊ธฐ
<section id="sliderType07">
    <div class="slider__wrap">
        <div class="slider__img">
            <div class="slider__inner">
                <div class="slider s1" role="group" aria-label="1/5">
                    <span>์ด๋ฏธ์ง€1</span>
                    <img src="../assets/img/Mountian_bg01.jpg" alt="์ด๋ฏธ์ง€6">
                </div>
                <div class="slider s2" role="group" aria-label="2/5">
                    <span>์ด๋ฏธ์ง€2</span>
                    <img src="../assets/img/Mountian_bg02.jpg" alt="์ด๋ฏธ์ง€7">
                </div>
                <div class="slider s3" role="group" aria-label="3/5">
                       <span>์ด๋ฏธ์ง€3</span>
                    <img src="../assets/img/Mountian_bg03.jpg" alt="์ด๋ฏธ์ง€8">
                </div>
                <div class="slider s4" role="group" aria-label="4/5">
                       <span>์ด๋ฏธ์ง€4</span>
                    <img src="../assets/img/Mountian_bg04.jpg" alt="์ด๋ฏธ์ง€9">
                </div>
                <div class="slider s5" role="group" aria-label="5/5">
                       <span>์ด๋ฏธ์ง€5</span>
                    <img src="../assets/img/Mountian_bg05.jpg" alt="์ด๋ฏธ์ง€10">
                </div>
            </div>
        </div>

        <div class="slider__btn">
            <button href="#" class="prev" role="button" aria-label="์™ผ์ชฝ ์ด๋ฏธ์ง€">prev</button>
            <button href="#" class="next" role="button" aria-label="์˜ค๋ฅธ์ชฝ ์ด๋ฏธ์ง€">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>
            <a href="#" class="play">์žฌ์ƒ</a>
            <a href="#" class="stop">์ •์ง€5</a> -->
        </div>
    </div>
</section>

! CSS TIP !
1. ์ด๋ฏธ์ง€๋ฅผ ๊ฐ€๋กœ๋กœ ์—ฐ๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ํฌ์ง€์…˜์„ relative๋กœ ์„ค์ •ํ•˜๊ณ  ์˜์—ญ์—์„œ ๋ฒ—์–ด๋‚˜๋Š” ์ด๋ฏธ์ง€๋ฅผ ์•ˆ๋ณด์ด๊ฒŒ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด overflow: hidden์„ ์„ค์ •ํ•ด์ค๋‹ˆ๋‹ค.
2. ์ด๋ฏธ์ง€ ๊ฐ€๋กœ ๊ฐ’์€ ์ด๋ฏธ์ง€๊ฐ€ ์ž˜๋ฆฌ์ง€ ์•Š๋Š” ์„ ์—์„œ ์ตœ๋Œ€๋กœ ์„ค์ •ํ•ด์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค. 3. pointer-events: none์„ ํ†ตํ•ด ๋ฒ„ํŠผ์ด ์—ฐ์†์œผ๋กœ ๋ˆŒ๋ฆฌ์ง€์•Š๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

โœ๏ธ CSS ์Šคํฌ๋ฆฝํŠธ ๋ณด๊ธฐ
/* slider */
.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; /* ์Šคํฌ๋ฆฝํŠธ๋กœ ์ฒ˜๋ฆฌํ•  ๊ฒƒ์ด๋ฏ€๋กœ ์•ˆ๊นจ์ง€๊ฒŒ ๋” width๊ฐ’ ์ฃผ๋ฉด ๋จ */
    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;
}

@media(max-width : 800px){
    .slider__img {
        width: 400px;
        height: 250px;
    }
    .slider {
        width: 400px;
        height: 250px;
    }
}
/* ์Šฌ๋ผ์ด๋“œ ๋ฒ„ํŠผ ์—ฐ์†์œผ๋กœ ๋ˆ„๋ฅผ ์ˆ˜ ์—†๊ฒŒ ํ•˜๊ธฐ 01 */
.slider__btn.disable {
    pointer-events: none;   
}

.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 button:hover {
    border-radius: 50px;
    background: rgba(38, 52, 103, 0.4);
}
.slider__btn button.prev {
    left: 0;
}
.slider__btn button.next {
    right: 0;
}
.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;
    /* display: inline-block; */
    width: 23px;
    height: 20px;
    margin-left: 7px;
    vertical-align: -4px;

    border-left: 14px solid #fff;
    border-top: 10px solid transparent;
    border-bottom: 10px solid transparent;
}
.slider__dot .stop {
    display: none;
    /* display: inline-block; */
    width: 16px;
    height: 20px;
    vertical-align: -4px;
    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;
}
.slider__dot .show {
    display: inline-block;
}

#2. JAVASCRIPT : ์Šคํฌ๋ฆฝํŠธ ์งœ๊ธฐ

cloneFirst = sliderFirst.cloneNode(true) / cloneLast = sliderLast.cloneNode(true)๋ฅผ ํ†ตํ•ด ์ฒซ๋ฒˆ์งธ ์ด๋ฏธ์ง€์™€ ๋งˆ์ง€๋ง‰ ์ด๋ฏธ์ง€๋ฅผ ๋ณต์‚ฌํ•ด์ค๋‹ˆ๋‹ค.
setInterval ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ์ž๋™ ์Šฌ๋ผ์ด๋“œ๋ฅผ ๊ตฌํ˜„ํ•ด์ค๋‹ˆ๋‹ค. ๋˜ํ•œ clearInterval๋ฅผ ํ†ตํ•ด ์ž๋™ ํ”Œ๋ ˆ์ด๋ฅผ ๋ฉˆ์ถ”๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. ๊ทธ ์™ธ ์„ธ๋ถ€์ ์ธ ๋ถ€๋ถ„๋“ค์€ ์ฝ”๋“œ์™€ ์ฃผ์„์„ ๋ณด๋ฉฐ ์•Œ์•„๋ด…์‹œ๋‹ค!

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,      //์Šฌ๋ผ์ด๋” ๊ฐ€๋กœ ๊ฐ’
    sliderFirst = slider[0],                  //์ฒซ๋ฒˆ์งธ ์ด๋ฏธ์ง€
    sliderLast = slider[sliderLength -1],     //๋งˆ์ง€๋ง‰ ์ด๋ฏธ์ง€
    cloneFirst = sliderFirst.cloneNode(true), //์ฒซ๋ฒˆ์งธ ์ด๋ฏธ์ง€ ๋ณต์‚ฌ
    cloneLast = sliderLast.cloneNode(true);   //๋งˆ์ง€๋ง‰ ์ด๋ฏธ์ง€ ๋ณต์‚ฌ
let dotIndex = ""; //๋‹ท ์ƒ์„ฑ์‹œํ‚ฌ ๋ฌธ์ž์—ด
let interval = 3000;
let sliderTimer = "";


function init(){
    imgClone();     // ์ด๋ฏธ์ง€ ๋ณต์‚ฌ ๋ฐ”๋กœ ์‹คํ–‰์‹œํ‚ค๊ธฐ
    createDot();    // ๋‹ท ๋ฒ„ํŠผ ์ƒ์„ฑ์‹œํ‚ค๊ธฐ
    // autoPlay();     // ์ž๋™ํ”Œ๋ ˆ์ด
}
init();



// ์ž๋™ํ”Œ๋ ˆ์ด ํ•จ์ˆ˜
function autoPlay(){
    sliderTimer = setInterval(() => {
        let intervalNum = currentIndex + 1; //๋งค๊ฐœ๋ณ€์ˆ˜ ๊ฐ’
        gotoSlider(intervalNum);
    }, interval);
}

function stopPlay(){
    clearInterval(sliderTimer);
}

// ์ด๋ฏธ์ง€ ๋ณต์‚ฌ ํ•จ์ˆ˜
function imgClone(){
    sliderInner.appendChild(cloneFirst);
    sliderInner.insertBefore(cloneLast, sliderFirst);
}

// ๋‹ท ๋ฒ„ํŠผ ์ƒ์„ฑ ํ•จ์ˆ˜
function createDot(){
    for(let i=0; i<sliderLength; i++){
        dotIndex += "<a href='#' class='dot'>์ด๋ฏธ์ง€1</a>";
    }
    dotIndex += "<a href='#' class='play show'></a>";
    dotIndex += "<a href='#' class='stop'></a>";

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

    //๋‹ท ๋ฒ„ํŠผ ์›€์ง์ด๊ธฐ
    // sliderDot.forEach((e, i) => {cu
    //     if(e.classList.){}
    // });
    const dotActive = document.querySelectorAll(".slider__dot .dot");
    document.querySelectorAll(".slider__dot .dot").forEach((dot, index)=>{
        dot.addEventListener("click", ()=>{
            dotActive.forEach(el => el.classList.remove("active"));
            dotActive[index].classList.add("active");
            gotoSlider(index);
        });
    });
}



// ์Šฌ๋ผ์ด๋“œ ํ•จ์ˆ˜
function gotoSlider(index){
    sliderInner.classList.add("transition");
    let posInitial = sliderInner.offsetLeft; // -800px

    // if(direction == -1){
    //     // sliderInner.style.left = "800px"; //์™ผ์ชฝ์œผ๋กœ 800๋งŒํผ ์›€์ง์ด๊ธฐ
    //     //๋ถ€๋ชจ๋ฐ•์Šค offsetLeft๊ฐ’์„ ๊ตฌํ•˜์—ฌ ๋”ํ•˜๋Š” ์ด์œ ๋Š”? sliderWidth๋Š” ์Šฌ๋ผ์ด๋” ํ•˜๋‚˜๋งŒ์˜ ๊ฐ€๋กœ๊ฐ’์ด๊ธฐ ๋•Œ๋ฌธ์— ์ด๋™์‹œ ๋Š˜์–ด๋‚˜๊ฑฐ๋‚˜ ์ค„์–ด๋“œ๋Š” ๊ฐ’์„ ๊ตฌํ•  ์ˆ˜ ์—†๋‹ค ๋•Œ๋ฌธ์— ๊ทธ ์Šฌ๋ผ์ด๋”๋ฅผ ๊ฐ์‹ธ๋Š” ๋ถ€๋ชจ๋ฐ•์Šค์˜ ๊ฐ€๋กœ๊ฐ’์„ ๊ตฌํ•˜์—ฌ ๋Š˜์–ด๋‚˜๋Š” ๊ฐ’ ๋งŒํผ ๊ธธ์ด๋ฅผ ๋”ํ•˜์—ฌ ์ถ”๊ฐ€์‹œํ‚จ ๊ฒƒ ์ด๋‹ค.
    //     sliderInner.style.left = (posInital + sliderWidth) + "px"; //์™ผ์ชฝ์œผ๋กœ ์Šฌ๋ผ์ด๋” ๊ฐ€๋กœ๊ฐ’๋งŒํผ ์›€์ง์ด๊ธฐ. ์Šฌ๋ผ์ด๋”์˜ ๋ถ€๋ชจ๋ฐ•์Šค์˜ ์™ผ์ชฝ๊ฐ’์„ ๋”ํ•œ ์ด์œ ๋Š”?
    //     currentIndex --;

    // }else if(direction == 1){

    //     // sliderInner.style.left = "-800px";                
    //     sliderInner.style.left = (posInital - sliderWidth) + "px";               
    //     currentIndex ++;
    // }
    
    // ์œ„ ์‹์„ ๊ฐ„ํŽธํ•˜๊ฒŒ ์ž‘์—…
    sliderInner.style.left = -sliderWidth * (index + 1) + "px";

    currentIndex = index;
}

// ์ˆœ๊ฐ„์ด๋™ ํ•จ์ˆ˜
function checkIndex(){
    //์Šฌ๋ผ์ด๋“œ๊ฐ€ ๋๋‚˜๋ฉด transition ํด๋ž˜์Šค๋ฅผ ๋‹ค์‹œ ์ง€์›Œ์„œ transitionํšจ๊ณผ๊ฐ€ ๋‚˜์˜ค์ง€ ์•Š๋„๋ก ํ•˜๊ณ  ์ด๋ฏธ์ง€ ์ˆœ๊ฐ„์ด๋™ ์‹œํ‚ค๊ธฐ
    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); //๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌ
});
sliderBtnNext.addEventListener("click" ,() => {
    let nextIndex = currentIndex + 1;
    gotoSlider(nextIndex); //๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌ
});
document.querySelector(".slider__dot .play").addEventListener("click", () => {
    document.querySelector(".play").classList.remove("show");
    document.querySelector(".stop").classList.add("show");
    autoPlay(); 
});
document.querySelector(".slider__dot .stop").addEventListener("click", () => {
    document.querySelector(".stop").classList.remove("show");
    document.querySelector(".play").classList.add("show");
    stopPlay(); 
});
sliderInner.addEventListener("transitionend", checkIndex);

#3. ๊ฒฐ๊ณผ ๋ณด๊ธฐ ๐ŸŽ‰

728x90

๋Œ“๊ธ€


Lucky Charms Rainbow
js
html
css