“ 지연되는 프로젝트에 인력을 더 투입하면 오히려 더 늦어진다. ”
이미지를 여러개 배치하여 움직이게 하는 슬라이드 이펙트를 만들어 보도록 합니다.
HTML
<header id="header">
<h1>Javascript slider Effect01</h1>
<p>슬라이드 이펙트01</p>
<ul>
<li class="active"><a href="sliderEffect01.html">1</a></li>
<li><a href="sliderEffec02.html">2</a></li>
<li><a href="sliderEffec03.html">3</a></li>
<li><a href="sliderEffec04.html">4</a></li>
<li><a href="sliderEffec05.html">5</a></li>
<li><a href="sliderEffec06.html">6</a></li>
</ul>
</header>
<!-- //header -->
<main id="main">
<div class="slider__wrap">
<div class="slider__img">
<div class="slider"><img src="./img/Effect_bg01-min.jpg" alt="이미지 1"></div>
<div class="slider"><img src="./img/Effect_bg06-min.jpg" alt="이미지 2"></div>
<div class="slider"><img src="./img/Effect_bg02-min.jpg" alt="이미지 3"></div>
<div class="slider"><img src="./img/Effect_bg08-min.jpg" alt="이미지 4"></div>
<div class="slider"><img src="./img/Effect_bg09-min.jpg" alt="이미지 5"></div>
</div>
</div>
</main>
<!-- //main -->
<footer id="footer">
<a href="mailto:jo0132@naver.com">jo0132@naver.com</a>
</footer>
<!-- //footer -->
헤더와 풋터는 기존 마우스 이펙트와 동일하게 하며
메인부분을 slider__wrap으로 슬라이드를 감싸고
slider__img로 이미지를 한번에 감쌉니다.
이미지를 단독으로 사용하지 않고 .slider의 div를 사용하여 효과를 부여합니다.
CSS
.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 {
position: absolute;
left: 0;
top: 0;
transition: all 0.3s;
}
.slider::before {
position: absolute;
left: 5px;
top: 5px;
background: rgba(0,0,0,0.4);
color: #fff;
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: '이미지4';}
.slider:nth-child(1) {z-index: 5;}
.slider:nth-child(2) {z-index: 4;}
.slider:nth-child(3) {z-index: 3;}
.slider:nth-child(4) {z-index: 2;}
.slider:nth-child(5) {z-index: 1;}
- .slider__wrap: 슬라이더를 감싸는 부모 요소로, 화면 전체 높이(100vh)에 가운데 정렬되도록(display: flex; align-items: center; justify-content: center;) 설정되어 있습니다.
- .slider__img: 슬라이더의 이미지를 감싸는 요소로, 고정된 크기(width: 800px; height: 450px;)로 설정되어 있고, 넘치는 부분은 숨김 처리(overflow: hidden;)되어 있습니다.
- .slider: 각각의 슬라이드 이미지를 나타내는 요소로, position: absolute;로 설정되어 있어 부모 요소인 .slider__img를 기준으로 위치가 조정됩니다. 슬라이드간의 전환 효과를 위해(transition: all 0.3s;) 모든 속성에 대한 전환 효과가 설정되어 있습니다.
- .slider::before: 슬라이드 이미지 위에 이미지의 설명을 나타내는 요소로, position: absolute;로 설정되어 이미지 상단 왼쪽(left: 5px; top: 5px;)에 위치하고, 배경색(background)과 글자색(color)이 설정되어 있습니다. 슬라이드 이미지별로 content 속성을 이용하여 이미지 설명이 설정되어 있습니다.
- .slider:nth-child(n)::before: :nth-child() 선택자를 이용하여 각각의 슬라이드 이미지에 대한 설명을 나타내는 부분으로, n에는 해당 슬라이드의 순서를 입력하고, ::before는 해당 요소의 내용을 가상 요소로 설정하는 것을 의미합니다.
- .slider:nth-child(n): :nth-child() 선택자를 이용하여 각각의 슬라이드 이미지에 대한 스타일을 설정하는 부분으로, n에는 해당 슬라이드의 순서를 입력합니다. z-index 속성을 이용하여 각 슬라이드의 쌓임 순서를 설정할 수 있습니다. 순서가 높을수록(z-index: 5;) 위에 쌓이게 되며, 낮을수록(z-index: 1;) 아래에 쌓이게 됩니다.
SCRIPT
const sliderWrap = document.querySelector(".slider__wrap");
const sliderImg = sliderWrap.querySelector(".slider__img");
const slider = sliderWrap.querySelectorAll(".slider"); // slider를 배열로 받으므로 하나하나 선택할경우 배열로 선택 가능하다.
let currentIndex = 0; // 현재 보이는 이미지
let slidercount = slider.length; //이미지 갯수
let sliderInterval = 3000;
setInterval(()=>{
//0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 //currentIndex
//1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 //nextIndex
let nextIndex = (currentIndex + 1) % slidercount; //처음 스타트는 currentIndex = 0로 시작되어 +1을 하여 nextIndex를 구합니다.
//이때 4다음 0이 오기위해 lenght까지 오게되면 다시 돌아가기 위해 % slidercount를 사용하여 0으로 돌아갑니다.
slider[currentIndex].style.opacity = "0"; // 현재 이미지
slider[nextIndex].style.opacity = "1"; //다음 이미지
currentIndex = nextIndex; // nextIndex(=1)을 currentIndex(=0)에 값 추가 그렇게 되면 1초마다 값이 추가되어 1초마다 값이 달라집니다.
},sliderInterval) //1초마다 동작
// slider[0].style.opacity = "0"; //첫번째 이미지 안보이게
// slider[1].style.opacity = "1"; //두번째 이미지 보이게
// slider[1].style.opacity = "0"; //두번째 이미지 안보이게
// slider[2].style.opacity = "1"; //세번째 이미지 보이게
// slider[2].style.opacity = "0"; //두번째 이미지 안보이게
// slider[3].style.opacity = "1"; //세번째 이미지 보이게
// slider[3].style.opacity = "0"; //세번째 이미지 안보이게
// slider[4].style.opacity = "1"; //네번째 이미지 보이게
// slider[4].style.opacity = "0"; //네번째 이미지 안보이게
// slider[0].style.opacity = "1"; //첫번째 이미지 보이게
먼저 .slider__wrap는 sliderWrap으로
.slider__img는 sliderImg로
.slider는 slider로 선택자를 상수로 저장합니다.
그리고
currentIndex라는 현재의 이미지의 값을 먼저0으로 저장합니다.
slidercount에는 slider.lenght를 저장하여 이미지의 총 갯수를 저장합니다.
다음으로 sliderInterval이라는 변수에 3000ms(3초)를 지정하여 전환하는 시간을 지정합니다.
setInterval 함수를 사용하여 안에
nextIndex라는 변수에 현재 값의 +1을 하여 저장하여 다음이미지의 값을 저장합니다.
이 때 slider을 배열로 받았기 때문에 slider의 배열의 인덱스 값을 각각currentIndex, nextIndex의 값을 넣고 style에 opeacity을 주어 0은 안보이게 1은 보이게 지정합니다.
그 후 nextIndex에 currentIndex 값을 저장하여 값을 키워서 다음이미지의 효과를 줍니다.
이것을 sliderInterval인 3초마다 실행합니다.
GSAP
<script>
setInterval(()=>{
let nextIndex = (currentIndex + 1) % slidercount;
gsap.to(slider[currentIndex], { duration: 1, opacity: 0 });
gsap.to(slider[nextIndex], { duration: 1, opacity: 1 });
currentIndex = nextIndex;
},sliderInterval)
</script>
GSAP의 to() 메서드를 사용하여 현재 슬라이드의 투명도를 0으로 애니메이션하고, 다음 슬라이드의 투명도를 1로 애니메이션합니다. 애니메이션의 지속시간은 1초입니다. animateSlider() 함수는 setInterval()을 사용하여 매 sliderInterval 밀리초마다 호출되며, 현재 슬라이드와 다음 슬라이드의 인덱스를 업데이트하고 애니메이션을 적용합니다.
jQrery
<script>
setInterval(()=>{
let nextIndex = (currentIndex + 1) % slidercount;
$(".slider").eq(currentIndex).animate({ opacity: 0 },1000);
$(".slider").eq(nextIndex).animate({ opacity: 1 },1000);
currentIndex = nextIndex;
},sliderInterval);
</script>
$ 기호를 사용하여 jQuery 라이브러리를 표현합니다. eq() 메서드는 현재 슬라이드와 다음 슬라이드 요소를 인덱스를 기준으로 선택하고, animate() 메서드를 사용하여 선택된 요소들의 투명도를 애니메이션으로 변경합니다. animateSlider() 함수는 sliderInterval 간격으로 호출되며, 현재 슬라이드와 다음 슬라이드의 인덱스를 업데이트하고 애니메이션을 적용합니다.