...
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
반응형