Slide in on Scroll

Woohyun Jang
5 min readOct 21, 2018

이번 포스팅에서는 사용자가 웹 브라우저를 아래로 스크롤 함에 따라 화면이 이미지의 반 이상을 볼 수 있으면 transition효과로 보이게 되는 기능을 구현해볼 것이다.

초기 코드에서 관심있게 보아야 할 부분은 크게 두 가지가 있다. 먼저 javascript로 구현된 debounce() function이다.

function debounce(func, wait = 20, immediate = true) {      
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
}

파라미터로 넘겨준 함수가 wait시간 이내에 또 다시 호출된다면 실행되지 않도록 해주는 함수로서, wait시간을 바꾸고 싶다면 두 번째 파라미터로 넘겨주면 된다.

.slide-in {      
opacity: 0;
transition: all .5s;
}
.align-left.slide-in {
transform: translateX(-30%) scale(0.95);
}
.align-right.slide-in {
transform: translateX(30%) scale(0.95);
}
.slide-in.active {
opacity: 1;
transform: translateX(0%) scale(1);
}

두 번째 포인트는 css코드 부분이다. active class가 포함되지 않은 기본 슬라이드 이미지들은 opacity가 0으로 보이지 않으며, transition 시간은 0.5초이다.

좌우 슬라이드는 각각 translateX(±30%)로 active가 된다면 제자리로 돌아올 것이다.

active class가 포함되면 opacity 1로 완전히 다시 보이게 되고 위치도 translateX(0%)로 원래대로 되돌린다.

이미 많은 부분이 구현되어 있기 때문에 우리는 스크롤 이벤트가 발생했을 때 각각의 이미지가 active일지 아닐지 판단해 갱신해주는 로직만 작성하면 된다.

먼저 학습을 위해 html파일에 모두 작성되어있던 코드를 index.js와 main.css로 각자 분리한 뒤 javascript 코드를 작성했다.

querySelector()를 통해 이미지들을 모두 가져왔다.

그 이후에는 scroll event가 발생할 때마다 일정 간격을 두고(debounce) checkSlide() function을 실행시켜준다.

checkSlide는 매 이미지들마다 slideInAt과 imageBottom두 변수를 계산해 해당 이미지가 현재 active해야 하는지 아닌지를 판별한다.

const slideInAt = (window.scrollY + window.innerHeight) - sliderImage.height / 2;const isHalfShown = slideInAt > sliderImage.offsetTop;

slideInAt은 현재 사용자 화면의 가장 아래 부분에서 해당 이미지 높이의 반 만큼 위로 올라간 지점의 y좌표이다. 이를 이미지의 가장 위 y좌표와 비교할 경우 스크롤을 통해서 이미지의 반 이상이 보이는지를 의미한다.

slideInAt을 통해 이미지의 반 이상이 현재 화면의 가장 아래부분을 지나침을 판별했다면, 이번에는 위로 이미 지나가지 않았는지를 판별해야 한다.

const imageBottom = sliderImage.offsetTop + sliderImage.height;
const isNotScrolledPast = window.scrollY < imageBottom;

슬라이드 이미지의 가장 윗부분 y좌표에서 height를 더하여 이미지의 가장 아랫부분 y좌표를 구했고, 이것이 현재 화면의 가장 윗부분을 지나쳤는지를 확인한다.

해당 조건이 모두 충족시켰을 경우. 즉,

  1. 화면의 가장 아래 부분이 이미지의 반 이상을 지나쳤고,
  2. 화면의 가장 윗 부분이 이미지의 바닥을 지나치지 않았을 경우

이미지는 active class를 추가해주게 되고, 아니면 active class를 제거한다.

완성된 화면은 다음과 같다. 사용자의 시야 안에 이미지가 들어오면 이미지는 활성화되어 보이게 되고, 아니면 아래의 이미지처럼 비활성화되어 여백으로만 보인다.

Github Source Code

--

--