ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Video Speed Controller UI
    Web/JS30 2020. 12. 27. 22:03
    반응형

    오늘은 예전에 배웠던 내용들을 섞어서 만든 예제인 듯하다.

    HTML5 비디오와 마우스 이벤트를 가지고 비디오의 배속을 조절하는 기능을 만들어 보는 아주 간단한 예제이다.

    <div class="wrapper">
      <video class="flex" width="765" height="430" 
      	src="http://clips.vorwaerts-gmbh.de/VfE_html5.mp4" loop controls></video>
      <div class="speed">
      	<div class="speed-bar">1×</div>
      </div>
    </div>

    우선, 우리가 조작하고자 하는 요소들을 변수에 담아보자.

    일단 마우스로 조작해야하는 부분은 오른쪽에 보라색으로 그라데이션이 들어가있는 부분이다.

    흰 배경은 'speed'라는 클래스를 가진 div 태그이고,

    보라색 그라데이션 부분은 'speed-bar'라는 클래스를 가진 div 태그이다.

    이 둘을 각각 'speed'라는 변수와 'bar'라는 변수에 담아준다.

     

    그리고 저 스피드바를 이용해서 우리가 조작하게 될 대상은 비디오 태그의 배속이기 때문에

    비디오 태그 역시나 'video'라는 변수에다가 담아주도록 한다.

     

    우리가 mousemove 이벤트를 발생시키는 공간은 speed-bar가 아니고

    흰 배경, 즉 speed이기 때문에 거기에다가 이벤트 리스너를 붙여주도록 한다.

    const speed = document.querySelector('.speed');
    const bar = speed.querySelector('.speed-bar');
    const video = document.querySelector('.flex');
    
    speed.addEventListener('mousemove', handleMove);

    이제 handleMove 함수를 만들어보자.

    우선, 흰 배경에서 중요한 건 마우스의 y좌표이다.

    위아래로 움직이면서 비디오의 배속이 조절되기 때문에 마우스의 x좌표는 상관없고, y좌표가 중요하다.

    바로 이전 예제에서도 나왔듯이, 흰 배경 내부를 기준으로 마우스의 y좌표를 잡기 위해서는

    마우스의 pageY 좌표에서 흰 배경의 offsetTop을 빼주면 된다.

     

    그리고 전체 흰 배경의 크기 중에서 현재 마우스의 y 좌표가 어느 정도의 위치에 와있는지를

    퍼센트로 나타내기 위해서, 계산했던 y좌표를 흰 배경의 전체 높이로 나눠주면 된다.

    function handleMove(e) {
      const y = e.pageY - this.offsetTop;
      const percent = y / this.offsetHeight;
    }

    percent라는 변수에 담았지만, 아직은 소숫점 숫자에 불과하다.

    이 percent라는 변수는 흰 배경에서 보라색 그라데이션 부분이 차지하는 높이를 나타내기 때문에

    해당 div의 높이를 퍼센티지로 나타내기 위해서는 실제로 백분위 숫자로 만들어줘야 한다.

    그래서 percent 숫자에다가 100을 곱하고, 반올림해서 0~100 사이의 백분위 숫자로 만들어준다.

     

    그리고 bar의 height를 그대로 height(백분위수)로 지정해주면 된다.

    function handleMove(e) {
      const y = e.pageY - this.offsetTop;
      const percent = y / this.offsetHeight;
      const height = Math.round(percent * 100) + '%';
      bar.style.height = height;
    }

    이제 최소값과 최대값을 제한해 줄 차례이다.

    최소값과 최대값이 필요한 이유는 비디오가 무한정으로 느려질 수 없고, 무한정으로 빨라질 수도 없기 때문이다.

    비디오의 배속이 0%라거나 음수가 되는 건 말이 안되기 때문에 제한을 걸어줘야 한다.

    여기서는 최소 배속을 0.4x, 최대 배속을 4x로 잡아주기로 하고, 이를 변수에 담아준다.

    function handleMove(e) {
      const y = e.pageY - this.offsetTop;
      const percent = y / this.offsetHeight;
      const height = Math.round(percent * 100) + '%';
      bar.style.height = height;
      const min = 0.4;
      const max = 4;
    }

    여기서 우리가 해야할 것은, 동영상의 배속이 위에서 구해뒀던 percent에 비례하게끔 만들어줘야 한다는 것이다.

    (흰 배경에서 보라색 부분이 늘어나는 만큼, 혹은 줄어드는만큼 동영상의 속도도 늘어나고 줄어들어야 하므로)

    그리고 최소 배속을 0.4배, 최대 배속을 4배로 제한을 해줘야 한다.

    이를 위해서는 min, max, percent를 이용해서 다음과 같이 약간의 계산을 해주면 된다.

    function handleMove(e) {
      const y = e.pageY - this.offsetTop;
      const percent = y / this.offsetHeight;
      const height = Math.round(percent * 100) + '%';
      bar.style.height = height;
      const min = 0.4;
      const max = 4;
      const playbackRate = percent * (max - min) + min;
      bar.textContent = playbackRate;
    }

    percent가 0과 1 사이의 숫자이므로, (max - min)을 곱해줘서

    해당 변수의 범위를 0과 (max - min) 사이로 만들어주고, 거기다가 min을 더해줬다.

    그러면 playbackRate 변수는 0.4와 4 사이의 범위를 가지는 변수가 된다.

    (min ~ min + (max - min) = 0.4 ~ 4)

     

    그리고 bar의 textContent를 playbackRate로 설정해줬다.

    소수점이 너무 길어서 숫자가 제대로 보이지 않으므로, 숫자의 표기를 고쳐주도록 하자.

    (소수점 둘째자리까지만 나오게 toFixed(2)를 해주고, 끝에 'x'를 붙여서 배속임을 나타냈다)

    그리고 실질적으로 동영상의 배속이 playbackRate에 비례하게끔 설정을 해주자.

    function handleMove(e) {
      const y = e.pageY - this.offsetTop;
      const percent = y / this.offsetHeight;
      const height = Math.round(percent * 100) + '%';
      bar.style.height = height;
      const min = 0.4;
      const max = 4;
      const playbackRate = percent * (max - min) + min;
      bar.textContent = playbackRate.toFixed(2) + 'x';
      video.playbackRate = playbackRate;
    }

    그러면 최종적으로 다음과 같은 깔끔한 동영상 배속 기능이 완성된다.

    전체 자바스크립트 코드

    <script>
      const speed = document.querySelector('.speed');
      const bar = speed.querySelector('.speed-bar');
      const video = document.querySelector('.flex');
    
      function handleMove(e) {
        const y = e.pageY - this.offsetTop;
        const percent = y / this.offsetHeight;
        const min = 0.4;
        const max = 4;
        const height = Math.round(percent * 100) + '%';
        const playbackRate = percent * (max - min) + min;
        bar.style.height = height;
        bar.textContent = playbackRate.toFixed(2) + 'x';
        video.playbackRate = playbackRate;
      }
    
      speed.addEventListener('mousemove', handleMove);
    </script>
    
    반응형

    'Web > JS30' 카테고리의 다른 글

    Whack a Mole Game 🎮  (0) 2021.01.02
    Countdown Timer ⏱  (0) 2021.01.02
    Click and Drag to Scroll  (0) 2020.12.26
    Stripe Follow Along Nav  (0) 2020.12.26
    Event Capture, Propagation, Bubbling and Once  (0) 2020.12.24

    댓글

Designed by Tistory.