“ 지연되는 프로젝트에 인력을 더 투입하면 오히려 더 늦어진다. ”
- Frederick Philips Brooks
Mythical Man-Month 저자
안녕하세요 ヾ(≧▽≦*)o 오늘은 배경 이미지 위에 이미지를 여러장 덧대어 그 이미지가 위 아래로 움직일 수 있도록 효과를 한 번 주도록 하겠습니다.
💛완성작 입니다
이미지가 prev 버튼을 누르면 사진이 뒤로 가고, next 버튼을 누르면 사진이 앞으로 넘어가도록 설정해 주었습니다.
자바스크립트, GSAP, jQurey 세 가지를 이용해 같은 효과를 주도록 하겠습니다.
CSS 스타일
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>06. 슬라이드 이펙트</title>
<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" href="css/slider.css">
<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 { /*이미지 움직이는 영역 */
height: 450px;
width: 4800px; /*총 이미지가 4800*/
display: flex;
flex-wrap: wrap;
}
.slider { /*개별적인 이미지*/
position: relative;
width: 800px;
height: 450px;
}
.slider__btn a {
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 50px;
height: 50px;
background: #fffb00;
text-align: center;
line-height: 50px;
transition: all 0.3 ease;
}
.slider__btn a:hover{
border-radius: 50%;
background-color: #ffa970;
color: #fff;
}
.slider__btn a.prev {
left: 0;
}
.slider__btn a.next {
right: 0;
}
.slider__dot {
position: absolute;
left: 50%;
bottom: 50px;
transform: translateX(-50%);
}
.slider__dot .dot {
width: 20px;
height: 20px;
background-color: rgba(255,255,255,0.3);
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>
이번엔 양 옆 사이드에 버튼을 설정해 주었기 때문에 버튼에 css 효과를 주도록 하겠습니다.
또한 밑에 닷 버튼을 만들어 이미지가 넘어갈 때 닷 버튼도 그 이미지에 맞게 넘어갈 수 있도록 작업해 주었습니다.
HTML
<main id="main">
<div class="slider__wrap">
<div class="slider__img">
<div class="slider__inner">
<div class="slider s1"><img src="../slide/img/slideEffect01-1.jpg" alt="이미지1"></div>
<div class="slider s2"><img src="../slide/img/slideEffect02-1.jpg" alt="이미지1"></div>
<div class="slider s3"><img src="../slide/img/slideEffect03-1.jpg" alt="이미지1"></div>
<div class="slider s4"><img src="../slide/img/slideEffect04-1.jpg" alt="이미지1"></div>
<div class="slider s5"><img src="../slide/img/slideEffect05.jpg" alt="이미지1"></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-->
다음은 메인입니다.
이미지를 지정해준 다음 두 개의 버튼을 만들어 주고 이름을 각각 지정해 줍니다.
선택자
// 선택자
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 = "";
이미지의 간격이 2초동안 돌아가게 하기 위해 초기값을 2000으로 설정해 줍니다.
그 다음 이미지의 가로값을 설정해준 뒤 dot 인덱스를 빈 문자열로 출력하게 설정해 둡니다.
let sliderWidth = slider[0].offsetWidth; 이미지 가로값에서 배열로 설정해 둔 이유는 class가 slider인 요소가 여러 개 있을 수 있기 때문입니다.
따라서 slider[0]은 class가 slider인 요소들 중 첫 번째 요소를 선택하게 되며, sliderWidth 변수에는 이 요소의 너비를 나타내는 offsetWidth 속성 값이 할당됩니다.
즉, 배열을 이용한 이유는 여러 개의 요소 중 첫 번째 요소의 너비 값을 얻기 위함입니다.
닷 설정하기
function init(){
//이미지 갯수만큼 닷 메뉴 생성
slider.forEach(() => dotIndex += "<a href='#' class='dot'>이미지2</a>");
sliderDot.innerHTML = dotIndex;
//첫 번째 닷 메뉴한테 활성화 표시하기
sliderDot.firstChild.classList.add("active");
}
init();
다음은 이미지 밑에 뜨는 닷 메뉴를 설정해 줍니다.
forEach를 사용한 이유는 반복문이며 다중이기 때문에 forEach를 사용해 작업해 줍니다.
🙌 여기서 init을 사용하는 이유 🙌
init이라는 함수는 보통 초기화(initialization) 작업을 수행하는 함수입니다. JavaScript에서는 init 함수를 자주 사용하는데, 이는 HTML 문서가 로드되거나 특정 이벤트가 발생할 때 실행되도록 하는 것이 일반적입니다.
forEach 함수를 사용해 닷 인덱스에 += 연산자를 사용하여, 이전 문자열에 누적하여 문자열 "<a href='#' class='dot'>이미지2</a>"을 추가합니다. 이 문자열은 HTML 앵커(anchor) 태그를 사용하여 "이미지2"라는 텍스트를 클릭할 수 있는 링크로 만들고, class 속성이 "dot"인 CSS 클래스를 지정하는 역할을 합니다.
sliderDot.innerHTML에 dotIndex 값을 저장해 줍니다.
마지막으로 첫 이미지에 첫 닷 버튼이 실행 돼야 하니 첫 번째 자식에게 클래스 리스트 에드 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");
}
이미지 이동시키기
함수를 이용해 작업해 줍니다. gotoSlider 함수는 슬라이더를 지정 된 인덱스로 이동시키는 역할을 합니다.
이 함수는 매개변수로 이동할 이미지의 인덱스 num를 받습니다.
sliderInner 요소에서 transition 효과를 줘 모든 속성에 대해 0.4초 동안 애니메이션 효과를 적용 시켜줍니다.
sliderInner 요소에서 transform 속성을 줘 X축 방향으로 이미지를 이동시킵니다. 이동 거리는 -sliderWidth * num으로 설정됩니다. 여기서 sliderWidth는 슬라이드 요소의 너비를 나타내며 num은 이동할 이미지의 인덱스 값입니다.
다음은 현재의 인덱스에 num 값을 할당해 현재 보여지는 이미지의 인덱스를 갱신합니다.
닷메뉴 활성화 하기
닷메뉴는 여러개기 때문에 querySelectorAll을 사용해 줍니다.
dotActive도 반복문이자 다중이기 때문에 forEach를 사용해줍니다.
forEach문에서 active.classList.remove("active"));는 dotActive 배열의 모든 요소에 대해 active 클래스를 삭제합니다.
이를 통해 이전에 활성화 됐던 닷이 비활성화 됩니다.
//버튼을 클릭했을 때
sliderBtn.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);
}
});
버튼을 클릭했을 때 반복문이며 다중이기 때문에 forEach를 사용해 줍니다.
버튼을 클릭했을 때 이벤트가 발생하도록 작업하고 이전 이미지는 현재의 인덱스에 갯수를 뺀 값의 슬라이더 카운터 나머지의 값이고, 다음 이미지는 현재 인덱스에 +1을 한 뒤 카운트로 나눈 나머지 값입니다.
if문을 사용하는 이유는 버튼이 두 개 이고 어떤 작업을 할지 모르니 if문을 사용해 준 것입니다.
// dot 메뉴 클릭했을 때 넘어가기
document.querySelectorAll(".slider__dot .dot").forEach((dot, index) => {
dot.addEventListener("click", () => {
gotoSlider(index);
});
});
마지막으로 닷버튼을 누르면 이미지가 함께 넘어가도록 작업해 줍니다.
닷 또한 반복문이며 다중이기 때문에 forEach를 사용해 줍니다.
클릭했을 때 이벤트가 발생할 수 있도록 addEvent를 사용하고 슬라이더가 넘어가면 인덱스가 되도록 작업해 줍니다.
코드보기
https://github.com/leeyouna21/web2023/blob/master/javascript/slide/slideEffect06.html
'javascript' 카테고리의 다른 글
명언 자동 반복 사이트 만들기 2 (17) | 2023.04.17 |
---|---|
슬라이드이펙트 일곱 번째 (11) | 2023.04.16 |
슬라이드이펙트 다섯 번째 (12) | 2023.04.12 |
슬라이드이펙트 네 번째 (17) | 2023.04.11 |
슬라이드이펙트 첫 번째 (14) | 2023.04.10 |