Javascript Slider Effect 05

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

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
이미지1
이미지2
이미지3
이미지4
이미지5
이미지6
이미지7
이미지8
이미지9
prev next
소스 보기
Javascript
HTML
CSS
const sliderWrap = document.querySelector('.slider__wrap');
const sliderImg = document.querySelector('.slider__img');
const sliderInner = document.querySelector('.slider__inner');
const slider = document.querySelectorAll('.slider');
const sliderBtn = document.querySelector('.slider__btn');
const sliderBtnPrev = sliderBtn.querySelector('.prev');
const sliderBtnNext = sliderBtn.querySelector('.next');
const sliderDot = document.querySelector('.slider__dot');

let currentIndex = 0;
let sliderCount = slider.length;
let sliderWidth = sliderImg.offsetWidth; // 이미지 가로 값

// 이미지 총 길이 넣기
sliderInner.style.width = (sliderWidth * sliderCount) + "px";

let dotIndex = "";
function init() {
	slider.forEach((el, index) => dotIndex += `<a href="#" class="dot">이미지${index + 1}</a>`);
	sliderDot.innerHTML = dotIndex;

	// 첫 번째 닷 버튼한테 활성화 표시
	sliderDot.firstElementChild.classList.add('active');
}
init();

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


	// 두번째 이미지 --> 두번째 닷 클래스 추가
	// 1. 닷메뉴 클래스 모두 삭제
	// 2. 해당 이미지 해당 닷 메뉴 클래스 추가
	const sliderDotAs = sliderDot.querySelectorAll('a');
	sliderDotAs.forEach((a) => a.classList.remove('active'));
	sliderDotAs[num].classList.add('active');


}
// 버튼 클릭시
document.querySelectorAll(".slider__btn a").forEach((btn, index) => {
	btn.addEventListener("click", () => {
		let prevIndex = (currentIndex + (sliderCount - 1)) % sliderCount;
		let nextIndex = (currentIndex + 1) % sliderCount;

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


// 닷 버튼 클릭했을 때
document.querySelectorAll(".slider__dot .dot").forEach((dot, index) => {
	dot.addEventListener("click", () => {
		gotoSlider(index);
	});
})
<main id="main">
	<section id="sliderType01">
		<div class="slider__wrap">
			<div class="slider__img">
				<div class="slider__inner">
					<div class="slider" role="group" aria-label="1/9">
						<img src="../assets/img/effect_img01.jpg" alt="이미지1" />
					</div>
					<div class="slider" role="group" aria-label="2/9">
						<img src="../assets/img/effect_img04.jpg" alt="이미지2" />
					</div>
					<div class="slider" role="group" aria-label="3/9">
						<img src="../assets/img/effect_img02.jpg" alt="이미지3" />
					</div>
					<div class="slider" role="group" aria-label="4/9">
						<img src="../assets/img/effect_img03.jpg" alt="이미지4" />
					</div>
					<div class="slider" role="group" aria-label="5/9">
						<img src="../assets/img/effect_img07.jpg" alt="이미지5" />
					</div>
					<div class="slider" role="group" aria-label="6/9">
						<img src="../assets/img/effect_img08.jpg" alt="이미지6" />
					</div>
					<div class="slider" role="group" aria-label="7/9">
						<img src="../assets/img/effect_img01.jpg" alt="이미지7" />
					</div>
					<div class="slider" role="group" aria-label="8/9">
						<img src="../assets/img/effect_img10.jpg" alt="이미지8" />
					</div>
					<div class="slider" role="group" aria-label="9/9">
						<img src="../assets/img/effect_img05.jpg" alt="이미지9" />
					</div>
				</div>
			</div>
			<div class="slider__btn">
				<a href="#" class="prev" role="button" aria-label="왼쪽 이미지">prev</a>
				<a href="#" class="next" role="button" aria-label="오른쪽 이미지">next</a>
			</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>
<!-- //main -->
/* 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: 8800px; --> js로 이미지 추가되도 전체넓이 가변되게끔! */
	/* 4000px --> 4800px  : 총이미지가 6개로 변경*/
	height: 450px;
	position: relative;
}

.slider {
	/* 개별적인 이미지 */
	position: relative;
	width: 800px;
	height: 450px;
}

.slider::before {
	position: absolute;
	left: 5px;
	top: 5px;
	background: rgba(0, 0, 0, 0.4);
	color: white;
	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: "이미지6";
}

.slider:nth-child(7)::before {
	content: "이미지7";
}

.slider:nth-child(8)::before {
	content: "이미지8";
}

.slider:nth-child(9)::before {
	content: "이미지9";
}

@media (max-width: 800px) {
	.slider__img {
		width: 400px;
		height: 225px;
	}
}

.slider__btn a {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	width: 50px;
	height: 50px;
	background: rgba(0, 0, 0, 0.4);
	border-radius: 10px;
	text-align: center;
	transition: all 0.2s;
	line-height: 48px;
	display: block;
	font-size: 0.9rem;
	color: rgba(255, 255, 255, 1);
	opacity: 0.7;
}

.slider__btn a.prev {
	left: 0;
}

.slider__btn a.next {
	right: 0;
}

.slider__btn a:hover {
	/* text-shadow: -1px 0 #8545f3, 0 1px #9359f7, 1px 0 #8545f3, 0 -1px #413be1; */
	border: 1px solid rgba(187, 127, 255, 0.6);
	box-shadow: inset 0px 0px 5px aquamarine;
	opacity: 1;
	transition: opacity 0.5s ease;
}

.slider__dot {
	position: absolute;
	left: 50%;
	transform: translateX(-50%);
	bottom: 20px;
	margin: 2px;
}

.slider__dot .dot {
	display: inline-block;
	width: 20px;
	height: 20px;
	background: rgba(0, 0, 0, 0.4);
	border-radius: 50%;
	text-indent: -9999px;
	transition: all 0.3s;
	margin: 5px;
}

.slider__dot .dot.active {
	/* background: #000; */
	color: rgb(187, 127, 255);
	border-color: rgba(187, 127, 255, 0.6);
	box-shadow: -1px 1px 2px aquamarine;
	background: rgba(0, 0, 0, 0.4);
	/* position: relative; */
	transition: all 2s ease;
}

.slider__dot .dot.active {
	/* background: #000; */
	color: rgb(187, 127, 255);
	border-color: rgba(187, 127, 255, 0.6);
	box-shadow: -1px 1px 2px aquamarine;
	position: relative;
}

.slider__dot .dot.active::after {
	position: absolute;
	top: 0%;
	left: 00%;
	/* transform: translate(-50%, -50%); */
	content: '';
	width: 20px;
	height: 20px;
	border-radius: 50%;
	background: rgba(0,0,0,0);
	z-index: -1;
	border: 1px solid rgba(187, 127, 255, 0.6);
	box-shadow: -1px 1px 10px aquamarine;
	animation: rotate 3s linear infinite;
	pointer-events: none; 

}
.slider__dot .dot.active::before {
	position: absolute;
	top: 0%;
	left: 00%;
	/* transform: translate(-50%, -50%); */
	content: '';
	width: 20px;
	height: 20px;
	border-radius: 50%;
	background: rgba(0,0,0,0);
	z-index: -1;
	border: 1px solid  rgba(0, 162, 255, 0.534);
	box-shadow: -1px 1px 10px rgba(0, 162, 255, 0.534);
	animation: rotate2 7s linear infinite;
	pointer-events: none; 

}

@keyframes rotate {
	0% {
		transform: rotate(0deg);
	}
	100% {
		transform: rotate(359deg);
	}
}
@keyframes rotate2 {
	0% {
		transform: rotate(359deg);
	}
	100% {
		transform: rotate(0deg);
	}
}