[Vanilla JS] html, css, js 슬라이더 구현하기

Kim Dong Hyun·2023년 5월 20일
0

Front-End

목록 보기
3/4

HTML

  <div class="slider_bar">
    <div class="slider_button">
      <span id="slider_per">0%</span>
      <img src="{src}" id="slider" />
    </div>
  </div>

간단하게 slider bar 위에 button을 놓았다. img는 button 안에 위치한다.
span 요소는 눌렀을 때 몇 퍼센트인지 나타내기 위함이다.



CSS

.slider_bar {
  display: flex;
  position: fixed;
  right: 5%;
  top: 35%;
  bottom: 20%;
  width: 2%;
  height: 40%;
  background: linear-gradient(to bottom, 
    rgba(176, 196, 238, 1) 20%,
    rgba(176, 196, 238, 0.75) 35%,
    rgba(176, 196, 238, 0.5) 60%,
    rgba(176, 196, 238, 0.25) 85%,
    rgba(176, 196, 238, 0) 100%);
  border-radius: 20px;
  justify-content: center;
}

.slider_bar img {
  height: 30px;
  width: 30px;
  -webkit-user-select: none;
  -khtml-user-select: none;
  -moz-user-select: none;
  -o-user-select: none;
  user-select: none;
}

.slider_bar span {
  display: none;
  position: absolute;
  left: -50px;
  width: 40px;
  height: 30px;
  border-radius: 10px;
  color: #FFFFFF;
  background-color: #8e8989;
  padding: 0 auto;
  align-items: center;
  justify-content: center;
  font-weight: 400;
  transition-duration: all 2s;
}

.slider_button {
  display: flex;
  width: 40px;
  height: 40px;
  position: absolute;
  bottom: 0;
  border-radius: 50%;
  background-color: #FFFFFF;
  text-align: center;
  font-weight: 900;
  color: gray;
  line-height: 7px;
  justify-content: center;
  align-items: center;

  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none
}

css의 중요한 점은, slider button의 bottom값을 주어서 slider bar에서 얼마나 떨어져 있냐를 기록하는 것이다. 나머지는 자유롭게 설정하면 된다.



JS

var slider_button = document.getElementsByClassName("slider_button")[0];
var percent = document.getElementById('slider_per');


//터치가 시작될 때
slider_button.addEventListener("touchstart", (e) => {
  percent.style.display = "flex";  // 터치가 시작되면 퍼센트 보이기
  startPoint = e.touches[0].pageY; // 터치가 시작되는 위치 저장
});




//터치가 움직일 때
slider_button.addEventListener("touchmove", (e) => {

  //원래 bottom 값
  let origin = parseInt(getComputedStyle(slider_button).bottom.slice(0, -2));
  //최고 높이
  let max_height = parseInt(getComputedStyle(slider_bar).height);
  //시작 지점과 사용자 터치와의 사이 값
  diff = parseInt(startPoint - e.touches[0].pageY);
  
  //
  if (((origin + (diff - pre)) > 0) && ((origin + (diff - pre)) <= max_height)) {
    slider_button.style.bottom = origin + (diff - pre) + "px"; // 원래 값 + (차이 - 이전 값)
    // + 슬라이더가 올라갈 때 생길 변화를 여기에
  }

  pre = diff; // 이전 값 저장

  // bottom 값
  let bottom_height = parseInt(getComputedStyle(slider_button).bottom);
  // 퍼센트 값 변경
  percent.innerText = parseInt(bottom_height / parseInt(max_height) * 100) + "%";
});


//터치가 끝났을 때
slider_button.addEventListener("touchend", (e) => {
  pre = 0;   //이전 값을 0으로 초기화
  percent.style.display = "none"; //퍼센트 값 가리기
});
  1. 터치가 시작되면 시작된 값을 저장한다.

  2. 터치가 움직이면, 터치 시작 점과 현재 사용자가 터치하고 있는 Y값을 비교하고, 그 차이를 저장한다.
  3. 다음을 검사한다 :
    3-1. 원래 bottom 값 + (차이 - 이전 값) 이 0보다 큰지
    3-2. 원래 bottom 값 + (차이 - 이전 값) 이 최고 높이보다 작은 지
    -> 한 마디로 슬라이더 버튼이 있을 위치가 슬라이더 바 안에 있어도 되는지를 검사한다.
  4. 검사가 통과되면 슬라이더 버튼의 bottom 값을 원래 값 + (차이 - 이전 값) px만큼으로 설정한다.
  5. 이전 값 변수에 현재 값을 저장한다.

  6. 터치가 끝나면, 이전 값을 0으로 초기화하고, 퍼센트 값을 가린다.

내 경험 상 이렇게 구현하는게 가장 깔끔하게 움직이고 작동하는 것 같다. 😂

0개의 댓글