Winnie The Pooh Bear 슬라이더 이펙트 : 이미지 슬라이드 (버튼, 닷메뉴)

배움기록/JAVASCRIPT

슬라이더 이펙트 : 이미지 슬라이드 (버튼, 닷메뉴)

코딩은 처음이라 2023. 4. 13. 22:07

“ 지연되는 프로젝트에 인력을 더 투입하면 오히려 더 늦어진다. ”

- Frederick Philips Brooks
Mythical Man-Month 저자
728x90
반응형

슬라이더 이펙트 : 이미지 슬라이드 (버튼, 닷메뉴)

 

 

 

 

 

💜 슬라이더 이펙트 06

코드 보기 / 완성 화면

 

버튼을 눌러 이미지를 바꿀 수 있게 작업해줬습니다.

 

 

style

<style>
    /* slider__wrap */
    .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: 4800px;    /* 총 이미지 4800 */
        height: 450px;
    }
    .slider {             /* 개별적인 이미지 */
        position: relative;
        width: 800px;
        height: 450px;
    }
    .slider__btn a {
        position: absolute;
        top: 50%;
        transform: translateY(-50%);
        width: 50px;
        height: 50px;
        line-height: 50px;
        text-align: center;
        background-color: #ffffff;
        transition: all 0.3s ease;
    }
    .slider__btn a:hover {
        border-radius: 50%;
        background-color: rgba(241, 95, 85, 1);
        color: #1405e9;
    }
    .slider__btn a.prev {
        left: 0;
    }
    .slider__btn a.next {
        right: 0;
    }
    .slider__dot {
        position: absolute;
        left: 50%;
        bottom: 30px;
        transform: translateX(-50%);
    }
    .slider__dot .dot {
        width: 20px;
        height: 20px;
        background-color: rgba(255, 255, 255, 0.103);
        display: inline-block;
        border-radius: 50%;
        text-indent: -9999px;
        transition: all 0.3s;
        margin: 2px;
    }
    .slider__dot .dot.active {
        background-color: rgba(255, 255, 255, 1);
    }
</style>

가로와 세로 크기를 정해두고

overflow 속성으로  이미지를 감춥니다.

 

sliderInner 이미지가 움직이는 영역을 감사는 부모 요소에 대한 스타일을 정의

해당 요소는 가로 4800px, 세로 450px 크기로 설정

display속성으로 flexbox 레이아웃을 사용

 

개별적인 이미지의 크기를 정해주고 position 속성으로 상대적인 위치를 지정

 

버튼에 대한 스타일을 지정

hover시에는 배경색과 테두리 모양이 변경되게 해줬습니다.

 

개별적인 페이지 닷에 대한 설정도 해주고

애니메이션효과도 추가해줬습니다.

 

HTML

<body class="img02 bg05 font03">
<header id="header">
    <h1>Javascript Slider Effect06</h1>
    <p>06. 슬라이드 이펙트 : 이미지 슬라이드(버튼, 닷메뉴)<p>
    <ul>
        <li><a href="sliderEffect01.html">1</a></li> 
        <li><a href="sliderEffect02.html">2</a></li> 
        <li><a href="sliderEffect03.html">3</a></li> 
        <li><a href="sliderEffect04.html">4</a></li> 
        <li><a href="sliderEffect05.html">5</a></li> 
        <li class="active"><a href="sliderEffect06.html">6</a></li>
        <li><a href="sliderEffect07.html">7</a></li> 

    </ul>
</header>
<!-- //header -->

<main id="main">
    <div class="slider__wrap">
        <div class="slider__img">
            <div class="slider__inner">
                <div class="slider s1"><img src="./img/sliderEffect04-min.jpg" alt="이미지1"></div>
                <div class="slider s2"><img src="./img/sliderEffect06-min.jpg" alt="이미지2"></div>
                <div class="slider s3"><img src="./img/sliderEffect10-min.jpg" alt="이미지3"></div>
                <div class="slider s4"><img src="./img/sliderEffect01-min.jpg" alt="이미지4"></div>
                <div class="slider s5"><img src="./img/sliderEffect08-min.jpg" alt="이미지5"></div>
            </div>
        </div>
        <div class="slider__btn">
            <a href="#" class="prev" title="이전이미지">prev</a>
            <a href="#" class="next" title="다음이미지">next</a>
        </div>
        <div class="slider__dot">
            <!-- <a href="#" class="active dot">이미지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>
</main>
<!-- //main -->

여기서는 닷 메뉴를 주석처리해주고

스크립트에서 처리해줍니다.

 

script

// 선택자
const sliderWrap = document.querySelector(".slider__wrap");
const sliderImg = sliderWrap.querySelector(".slider__img");      //보여지는 영역
const sliderInner = sliderWrap.querySelector(".slider__inner");  //움직이는 영역
const slider = sliderWrap.querySelectorAll(".slider");           //개별 이미지
const sliderDot = sliderWrap.querySelector(".slider__dot");      //닷 메뉴
const sliderBtn = sliderWrap.querySelectorAll(".slider__btn a"); //버튼  

let currentIndex = 0;                     //현재 보이는 이미지
let sliderCount = slider.length;          //이미지 갯수
let sliderInterval = 2000;                //이미지 변경 간격 시간
let sliderWidth = slider[0].offsetWidth;  //이미지 가로값
let dotIndex = "";

이미지와 닷버튼의 선택자를 만들어주고

 

currentIndex로 현재 보여지는 이미지를 0으로 초기화해주고,

sliderCount를 slider.length로 불러와주고,

sliderInterval로 시간 설정해주고,

sliderWidth로 이미지의 가로값을 불러와줍니다.

 

 

닷메뉴 만들기

function init(){
    //이미지 갯수만큼 닷 메뉴 생성
    slider.forEach(() => dotIndex += "<a href='#' class='dot'>이미지</a>");
    sliderDot.innerHTML = dotIndex;

    //첫번째 닷 메뉴한테 활성화 표시하기
    sliderDot.firstChild.classList.add("active");

}
init();

초기화 작업을 수행하는 init()함수를 사용해 닷메뉴를 만들어줍니다.

 

먼저 이미지 갯수만큼 단 메뉴를 생성해줍니다.

slier변수에 이미지 슬라이드의 이미지들이 담겨있고,

dotIndex라는 변수에 HTML 문자열로 구성된 닷 메뉴를 생성

 

forEach()메소드를 사용해 silder 변수의 각 이미지에 대해 한 번씩 반복하면서 dotIndex 변수에 <a href='#' class='dot'>이미지</a> 문자열을 추가

 

firstChild.classList.add("active")로 첫번째 닷 메뉴에 활성화표시를 해줍니다.

 

 

이미지 이동시키기

//이미지 이동시키기
function gotoSlider(num){
    sliderInner.style.transition = "all 400ms";
    sliderInner.style.transform = "translateX("+ -sliderWidth * num +"px)";
    currentIndex = num;

    //닷 메뉴 활성화하기
    let dotActive = document.querySelectorAll(".slider__dot .dot");
    dotActive.forEach(active => active.classList.remove("active"));
    dotActive[num].classList.add("active");
}

sliderInner 요소의 transtion 속성을 all400ms로 설정해 이미지 이동에 애니메이션 효과를 부여

 

sliderInner 요소의 transform 속성을 변경해 해당 이미지로 이동

 

이때  translateX()함수를 사용해 이미지를 좌우로 이동시켜 num 매개변수를 이용해 이동할 이미지의 인덱스 값을 계산

 

현재 슬라이더 인덱스를num으로 설정하고, 닷 메뉴 중 현재 활성화된 메뉴를 찾아 비활성화 처리 후

num에 해당하는 인덱스의 닷 메뉴를 활성화 처리

 

querySelectorAll()함수를 사용해 닷 메뉴를 모두 선택한 후 forEach() 함수를 사용해 닷 메뉴에 대해 반복적으로 처리

 

classList.remove()함수를 사용해 모든 닷 메뉴의 active 클래스를 제거

num에 해당하는 인덱스 값을 가지는 닷 메뉴에 active 클래스를 추가해 활성화된 닷 메뉴를 표시

 

버튼을 클릭했을 때

//버튼을 클릭했을 때
sliderBtn.forEach((btn, index) => {
    btn.addEventListener("click", () => {
        let prevIndex = (currentIndex + (sliderCount-1)) % sliderCount;  //0 4 3 2 1 0 4 3 2 1 
        let nextIndex = (currentIndex + 1) % sliderCount;   //1 2 3 4 0 1 2 3 4 0

        if(btn.classList.contains("prev")){
            gotoSlider(prevIndex);
        } else {
            gotoSlider(nextIndex);
        }
    });
});

두개의 버튼 요소를 가져와 forEach루프를 실행

두번째 인자로 현재 요소의 인덱스를 받아올 수 있습니다.

 

이전, 다음 버튼을 클릭했을 때 콜백함수를 등록

함수 안에 prevIndex와 nextIndex 변수를 정의

현재 인덱스를 기준으로 이전, 다음 슬라이드 인덱스를 계산

 

이번버튼을 클릭했을 때 현재 인덱스에서 1을 뺀 값을 계산, 이때 음수값이 나올 수 있으므로 sliderCount -1을 더해준 후, 

전체 슬라이드 개수로 나눠서 나머지 값을 구하면 인덱스가 0일 때 이전 슬라이드는 맨 뒤 슬라이드가 되고, 그 외에는 현재 인덱스에서 1을 뺀 값이 됩니다.

 

다음 버튼을 클릭 했을 때, 현재 인덱스에서 1을 더한 값을 계산

전체 슬라이드 개수로 나눠 나머지값을 구해주면 인덱스가 전체 슬라이드 개수를 초과하지 않도록 해줌

 

각각의 버튼에 함수를 호출

각각 이전 슬라이드와 다음 슬라이드가 인덱스가 된다.

 

닷 클릭

//닷 클릭했을 때
document.querySelectorAll(".slider__dot .dot").forEach((dot, index) => {
    dot.addEventListener("click", () => {
        gotoSlider(index);
    })
});

documenet.querySelectorAll로 모든 닷메뉴를 선택하고,

forEach문을 사용해 각각의 닷 메뉴에 이벤트를 추가합니다.

 

이벤트 리스너 함수에는 gotoSlider 함수를 호출해 해당 인덱스의 이미지로 이동

index는 클릭한 닷 메뉴의 인덱스이며 gotoSlider 함수의 인자로 전달됩니다.

 

즉, 닷 메뉴를 클릭하면 해당 이미지로 슬라이드가 이동하고, 클릭 한 닷 메뉴는 활성화 표시가 됩니다.

 

 

반응형