“ 지연되는 프로젝트에 인력을 더 투입하면 오히려 더 늦어진다. ”
- Frederick Philips Brooks
Mythical Man-Month 저자
설명:
이번에는 연속으로 위로 움직이는 슬라이드 효과를 만들어 봤습니다.
왼쪽으로 움직이는 슬라이드 효과와 다른 점이 몇 가지 없습니다.
간략하게 설명하면, 움직이는 축을 가로 즉, x 축에서 세로인 y 축으로 바꾸면 됩니다.
그렇게 바꾼 축을 실행하려면, 스타일 시트에서 한 display : flex; 설정을 해제하고,
선택자 중에서 이미의 가로 값을 세로 값으로 바꿔서 쓰면 됩니다.
스타일 시트, 선택자, javascript, gsap 그리고 jquery 를 순서대로 설명하겠습니다.
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 {
/* display: flex; */
flex-wrap: wrap;
width: 4800px; /* 총 이미지 4800px */
height: 450px;
}
/* 개별적인 이미지 영역 */
.slider {
position: relative;
width: 800px;
height: 450px;
}
보이는 것처럼 이전에 썼던 스타일 시트와이 차이점은 없습니다.
움직이는 이미지 영역을 뜻하는 slider__inner 의 display : flex; 설정을 해제했습니다.
이 설정을 해제해야 이미지가 세로로 이어져서 나오기 때문입니다.
script - 선택자
//선택자
const sliderWrap = document.querySelector(".slider__wrap");
const sliderImg = sliderWrap.querySelector(".slider__img"); //보여지는 영역
const sliderInner = sliderWrap.querySelector(".slider__inner"); //움직이는 영역
const slider = sliderWrap.querySelectorAll(".slider"); //개별 이미지
let currentIndex = 0; //현재 보이는 이미지, 첫 번째라서 0
let sliderCount = slider.length; //이미지 갯수
let sliderInterval = 3000; //이미지 변경되는 간격 시간
let sliderWidth = slider[0].offsetHeight; //이미지 세로값
let sliderClone = sliderInner.firstElementChild.cloneNode(true); //첫 번째(firstElementChild) 이미지 복사(cloneNode(true))
선택자도 이전과 다른 점은 이미지 가로 값을 나타내는 offsetWidth 대신에 세로 값을 나타내는 offsetHeight 를 썼다는 점입니다.
offsetWidth 과 offsetHeight 는 높이와 너비를 구할 때 가장 많이 쓰이는 속성으로 padding, border 값을 포함한 컨텐츠의 높이를 가져옵니다. 이 때 margin은 포함하지 않습니다.
script - javascript
//복사한 첫 번째 이미지 마지막에 붙여넣기
sliderInner.appendChild(sliderClone);
function sliderEffect(){
currentIndex++;
sliderInner.style.transition = "all 0.6s";
sliderInner.style.transform = "translateY(-"+ sliderWidth * currentIndex +"px)";
//마지막 이미지에 위치했을 때
if(currentIndex == sliderCount){
setTimeout(() => {
sliderInner.style.transition = "0s";
sliderInner.style.transform = "translateY(0px)";
}, 700);
currentIndex = 0;
}
}
setInterval(sliderEffect, sliderInterval);
translateY 로 y 축 즉, 세로 축을 중심으로 이동을 하게 만들었습니다.
appendChild() 는 Node 인터페이스의 메소드이고, 선택한 요소 안에 자식요소를 추가합니다.
기본적으로 appendChild 를 통해 요소를 삽입하면 맨뒤에 위치하게 됩니다.
appendChild() 메소드를 사용하면 지정된 상위 노드의 하위노드 목록 마지막에 노드를 추가할 수 있습니다.
이 메서드를 이용하면 첫 번째 이미지를 마지막에 넣어서 연속적으로 이미지가 나오도록 할 수 있습니다.
setTimeout() 는 어떤 코드를 바로 실행하지 않고 일정 시간 기다린 후 실행해야하는 경우에 사용합니다.
setTimeout() 함수는 첫 번째 인자로 실행할 코드를 담고 있는 함수를 받고, 두번째 인자로 지연 시간을 밀리초(ms) 단위로 받습니다.
script - gsap
gsap.registerPlugin(TweenMax);
function sliderEffect(){
currentIndex++;
TweenMax.to(sliderInner, 0.6, {y: -sliderWidth * currentIndex, ease: Power2.easeInOut});
//마지막 이미지에 위치했을 때
if(currentIndex == sliderCount){
setTimeout(() => {
TweenMax.to(sliderInner, 0, {y: 0});
}, 700);
currentIndex = 0;
}
}
setInterval(sliderEffect, sliderInterval);
GSAP 는The GreenSock Animation Platform (줄여서 GSAP)는 프론트엔드 개발자와 디자이너들이 쉽게 사용할 수 있는 아주 강력한 타임라인기반의 애니메이션 자바스크립트 라이브러리 입니다.
애니메이션 시퀀스에 관련해서 CSS의 keyframe과 animation 보다 더 정밀한 컨트롤을 할 수 있어요.
TweenMax 는 GSAP의 기본적인 애니메이션입니다.
트윈맥스에서 가장 기본적으로 사용하는 것은 TweenMax.to() 입니다.
.to()는 일반적으로 .animate() 라고 생각하면 됩니다.
트윈맥스는 TweenMax.to(target, duration, {vars}); 의 파라미터를 가지고 있습니다.
- target : 대상(인자)
- duration : 지속시간 (몇초동안)
- vars : 대상에 부여할 키값
script - jquery
// sliderInner 변수에 해당하는 jQuery 객체 생성
var $sliderInner = $(sliderInner);
// sliderClone 변수에 해당하는 jQuery 객체 생성
var $sliderClone = $(sliderClone);
// sliderInner에 sliderClone을 추가
$sliderInner.append($sliderClone);
function sliderEffect(){
currentIndex++;
$sliderInner.css({
transition: "all 0.6s",
transform: "translateY(-"+ sliderWidth * currentIndex +"px)"
});
//마지막 이미지에 위치했을 때
if(currentIndex == sliderCount){
setTimeout(() => {
$sliderInner.css({
transition: "0s",
transform: "translateY(0px)"
});
}, 700);
currentIndex = 0;
}
}
setInterval(sliderEffect, sliderInterval);
jquery 도 마찬가지로 x 축을 y 축으로 바꿔주면 연속으로 위로 움직이는 슬라이드를 만들 수 있습니다.