Animated Turtle

Javascript

슬라이드 효과 만들기(썸네일 + 버튼)

훙구 2023. 4. 14. 15:00

...

728x90
반응형

썸네일 이미지와 버튼이 있는 슬라이드 효과 만들기

이번에는 버튼과 썸네일 이미지가 있는 슬라이드 효과를 만들어보도록 하겠습니다.

 

HTML 작성하기

<main id="main">
    <div class="slider__wrap">
        <div class="slider__img"></div>
        <div class="slider__thumb"></div>
        <div class="slider__btn">
            <a href="#" class="prev" title="이전이미지">prev</a>
            <a href="#" class="next" title="다음이미지">next</a>
        </div>
    </div>
</main>

변경된 HTML 알아보기

  • 이번에는 스크립트를 통해 이미지를 넣어줄 것이기 때문에 slider__image 부분을 비워놨습니다.
  • 썸네일이 들어갈 slider__thumb 부분에도 같은 이미지를 스크립트를 통해 넣어주기 위해 비워놨습니다.

CSS 작성하기

/* slider__wrap */
.slider__wrap {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    width: 800px;
    height: 450px;
    box-shadow: 0 50px 100px rgba(0, 0, 0, 0.4);
}
.slider__img {
    position: relative;
    width: 100%;
    height: 100%;
    overflow: hidden;
}
.slider__img img {
    position: absolute;
    width: 100%;
    height: 100%;
    object-fit: cover;
    opacity: 0;
    transform: scale(1.1);
    transition: all 500ms ease-in-out;
}
.slider__img img.active {
    opacity: 1;
    transform: scale(1);
}
.slider__thumb {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, 140px);
    width: 100px;
    display: flex;
    justify-content: center;
    gap: 10px;
}
.slider__thumb img {
    cursor: pointer;
    border: 2px solid transparent;
}
.slider__thumb img.active {
    cursor: pointer;
    border: 2px solid #fff;
}
.slider__btn a {
    position: absolute;
    top: 0;
    width: 40px;
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 12px;
    color: #fff;
    background-color: rgba(0, 0, 0, 0.2);
    transition: all 300ms ease-in-out;
}
.slider__btn a.next {
    right: 0;
}
.slider__btn a:hover {
    background-color: rgba(0, 0, 0, 0.5);
    font-size: 14px;
}

CSS 정리해보기

  • 기본적으로 이미지에 opacity(투명도)의 값을 0으로 설정해 보이지 않게 해주고 scale을 약간 더 크게 만들어줍니다.
  • 이미지 class에 active가 붙을 경우 투명도를 1로 설정하여 나타나게 하며 scale을 본래 크기로 돌리며 살짝 작아지는 효과를 만들어줍니다.
  • slider__thumb의 img의 border에 transparent의 값을 주어 완전 투명하게 만들어줍니다.
  • slider__thumb의 class에 active가 붙으면 border 의 색을 흰색으로 만듭니다.
  • 양 쪽의 btn에도 속성과 hover효과를 주었습니다.

Javscript 작성하기

let images = [
    "img/sliderEffect06-min.jpg",
    "img/sliderEffect07-min.jpg",
    "img/sliderEffect08-min.jpg",
    "img/sliderEffect09-min.jpg",
    "img/sliderEffect10-min.jpg"
]

function imageSlider(parent, images){
    let currentIndex = 0;

    // 선택자
    let slider = {
        parent : parent,
        images : parent.querySelector(".slider__img"),
        thumnails : parent.querySelector(".slider__thumb"),
        prevBtn : parent.querySelector(".slider__btn .prev"),
        nextBtn : parent.querySelector(".slider__btn .next")
    };

    // 이미지 출력하기
    slider.images.innerHTML = images.map((image, index) => {
        return `<img src="${image}" alt="이미지${index}">`
    }).join("");

    // 이미지 활성화(active) 하기
    let imageNodes = slider.images.querySelectorAll("img");
    imageNodes[currentIndex].classList.add("active");

    // 썸네일 이미지 출력하기
    slider.thumnails.innerHTML = slider.images.innerHTML

    // 썸네일 활성화(active) 하기
    let thumnailNodes = slider.thumnails.querySelectorAll("img");
    thumnailNodes[currentIndex].classList.add("active");

    // 썸네일 이미지 클릭하기
    thumnailNodes.forEach((e, i) => {
        e.addEventListener("click", () => {
            slider.thumnails.querySelector("img.active").classList.remove("active");
            thumnailNodes[i].classList.add("active");

            imageNodes[currentIndex].classList.remove("active");
            currentIndex = i;
            imageNodes[i].classList.add("active");
        });
    });


    // 왼쪽 버튼 클릭
    slider.prevBtn.addEventListener("click", () => {
        // active 지우기
        imageNodes[currentIndex].classList.remove("active");
        thumnailNodes[currentIndex].classList.remove("active");

        // 순서 설정
        currentIndex--;
        if(currentIndex < 0) currentIndex = images.length - 1;

        // 이미지 active
        imageNodes[currentIndex].classList.add("active");

        // 썸네일 active
        thumnailNodes[currentIndex].classList.add("active");

    });

    // 오른쪽 버튼 클릭
    slider.nextBtn.addEventListener("click", () => {
        // active 지우기
        imageNodes[currentIndex].classList.remove("active");
        thumnailNodes[currentIndex].classList.remove("active");

        // 순서 설정
        currentIndex = (currentIndex + 1) % images.length;

        // 이미지 active
        imageNodes[currentIndex].classList.add("active");

        // 썸네일 active
        thumnailNodes[currentIndex].classList.add("active");
    });
};

imageSlider(document.querySelector(".slider__wrap"), images)

Javascript 정리해보기

  • 사용할 이미지의 경로를 images라는 배열에 저장합니다.

 

  • imageSlider(parent, images) 함수
  • 현재 이미지의 index값에 사용할 currentIndex 변수를 만들어 0을 저장합니다.
  • 선택자를 객체형식으로 slider에 저장합니다.
  • // 이미지 출력
  • slider.images ( slider__img )에 innerHTML을 사용해 다음의 내용을 넣어줍니다.
  • images.map((image, index) => { (images배열의 map을 사용하여 배열형태로 출력)
  •   return `<img src="${image}" alt="이미지${index}">` }).join(" ");
  • (현재 map 메서드에서의 image는 images의 각 요소를 뜻하므로 이미지의 경로가 됩니다.)
  • // 이미지에 active 추가
  • imageNodes 변수를 만들어 slider.images에 넣어준 img 태그들을 저장합니다. (다수)
  • imageNodes의 currentIndex 번째 요소의 classList에 active를 추가합니다.
  • // 썸네일 이미지 출력
  • slider.thumnails ( slider__thumb )에 innerHTML을 사용해 동일한 이미지를 넣어줍니다. (slider.images.innerHTML 사용)
  • // 썸네일에 active 추가
  • thumnailNodes 변수를 만들어 slider.thumb에 넣어준 img 태그들을 저장합니다. (다수)
  • thumnailNodes의 currentIndex 번째 요소의 classList에 active를 추가합니다.
  • // 썸네일 이미지 클릭하기
  • thumnailNodes.forEach((e, i) => { ( slider.thumnails 에 넣어준 다수의 이미지) 에 forEach를 사용합니다.
  •   각각의 요소에 addEventListener를 통해 클릭 이벤트를 넣어줍니다.
  •   slider.thumnails의 요소 중 class에 active가 있는 img태그의 classList에서 active를 제거합니다.
  •   thumnailNodes의 i 번째 요소의 classList에 active를 추가합니다. ( 기존 active 지우고 현재 index에 active 추가)
  •   마찬가지로 imageNodes중 기존의 active class를 지우고 currentIndex 번째의 이미지에 active class를 추가합니다. }
  • // 왼쪽 버튼(prev) 클릭
  • slider.prevbtn에 addEventListener를 통해 다음의 클릭 이벤트를 넣어줍니다.
  • imageNodes의 currentIndex의 classList에서 active를 제거합니다.
  • thumnailNodes의 currentIndex의 classList에서 active를 제거합니다.
  • currentIndex에 --연산을 해줍니다.
  • currentIndex가 0보다 작다면 currentIndex에 images.length - 1 을 저장합니다. ( 4 3 2 1 0 4 3 2 1 0 4 .....)
  • imageNodes와 thumnailNodes의 currentIndex 번째 요소의 classList에 active를 추가합니다.
  • // 오른쪽 버튼(next) 클릭
  • prev 버튼 클릭과 거의 동일하지만 currentIndex에 (currentIndex + 1) % image.length를 저장하는 것이 다릅니다.
  • ( 0 1 2 3 4 0 1 2 3 4 0 1 .....)

 

 

 

이상으로 썸네일 이미지와 버튼이 있는 슬라이드 효과를 만들어 보았습니다 !

728x90
반응형