11. Custom Video Player
코드 분석
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hold Shift to Check Multiple Checkboxes</title>
</head>
<body>
<style>
html {
font-family: sans-serif;
background:#ffc600;
}
.inbox {
max-width:400px;
margin:50px auto;
background:white;
border-radius:5px;
box-shadow:10px 10px 0 rgba(0,0,0,0.1);
}
.item {
display:flex;
align-items:center;
border-bottom: 1px solid #F1F1F1;
}
.item:last-child {
border-bottom:0;
}
input:checked + p {
background:#F9F9F9;
text-decoration: line-through;
}
input[type="checkbox"] {
margin:20px;
}
p {
margin:0;
padding:20px;
transition:background 0.2s;
flex:1;
font-family:'helvetica neue';
font-size: 20px;
font-weight: 200;
border-left: 1px solid #D1E2FF;
}
</style>
<div class="inbox">
<div class="item">
<input type="checkbox">
<p>This is an inbox layout.</p>
</div>
<div class="item">
<input type="checkbox">
<p>Check one item</p>
</div>
<div class="item">
<input type="checkbox">
<p>Hold down your Shift key</p>
</div>
<div class="item">
<input type="checkbox">
<p>Check a lower item</p>
</div>
<div class="item">
<input type="checkbox">
<p>Everything inbetween should also be set to checked</p>
</div>
<div class="item">
<input type="checkbox">
<p>Try do it with out any libraries</p>
</div>
<div class="item">
<input type="checkbox">
<p>Just regular JavaScript</p>
</div>
<div class="item">
<input type="checkbox">
<p>Good Luck!</p>
</div>
<div class="item">
<input type="checkbox">
<p>Don't forget to tweet your result!</p>
</div>
</div>
<script>
</script>
</body>
</html>
목표
동영상의 재생, 시간이동 기능을 추가한다.
분석
- 사용할 변수들에 대해서 먼저 정리해 놓는다.
const player = document.querySelector('.player');
const video = player.querySelector('.viewer');
const progress = player. querySelector('.progress');
const progressBar = player.querySelector('.progress__filled');
const toggle = player.querySelector('.toggle');
const skipButtons = player.querySelectorAll('[data-skip]');
const ranges = player.querySelectorAll('.player__slider');
- 사용할 함수들에 대해서 정리 한다.
function togglePlay() {
const method = video.paused ? 'play' : 'pause';
video[method]();
}
function updateButton() {
const icon = this.paused ? 'go' : 'stop';
toggle.textContent = icon;
}
function scrub(e) {
const scrubTime = (e.offsetX / progress.offsetWidth) * video.duration;
video.currentTime = scrubTime;
console.log(e);
}
위에서부터 하나씩 확인해보자toggleplay()
는 method 라는 변수를 선언하고, 영상이 정지되어있을 때에는 play
, 그렇지 않을때에는 pause
값을 반환하게 하게 만들어서 그 변수를 video[]에 넣음으로써 toggleplay
가 한번 호출될 때마다, 영상을 재생 혹은 정지 시키는 방식이다.
updateButton
은 icon이라는 변수를 선언, 영상이 정지시에 go
, 아닐때에는 stop
값을 리턴한다. 그 다음 textcontent
에 따라 toggle
에다가 icon
값을 넣어주게 되고, 영상 정지 혹은 재생 시에 버튼에 go
와 stop
이라는 텍스트가 출력된다.
scrub(e)
는 scrubTime이라는 변수를 선언, 그 내용은 선택된 X축의 좌표를 progress
항목의 전체 X축 좌표로 나누고, 그 값을 비디오 전체시간을 곱해줌으로써 영상내에서의 시간 이동변수를 만들어 준다. 이를 scrub
이 호출시에 video.currentTime
에 넣어줌으로써 영상의 시간을 바꿀 수 있게 된다.
- 이벤트를 선언해준다.
video.addEventListener('click', togglePlay);
video.addEventListener('play', updateButton);
video.addEventListener('pause', updateButton);
video.addEventListener('timeupdate', handleProgress);
toggle.addEventListener('click', togglePlay);
skipButtons.forEach(button => button.addEventListener('click' , skip));
ranges.forEach(range => range.addEventListener('change', handleRangeUpdate));
ranges.forEach(range => range.addEventListener('mousemove', handleRangeUpdate));
let mousedown = false;
progress.addEventListener('click', scrub);
progress.addEventListener('mousemove', () => mousedown && scrub(e));
progress.addEventListener('mousedown', () => mousedown = true);
progress.addEventListener('mouseup', () => mousedown = false);
주목해서 볼 부분은 progress
부분인데 mousedown
의 값을 false
로 먼저 정해놓고, mousedown && scrub(e)
. 즉, 마우스가 클릭되어있는 상태에서만 mousedown
값을 true
로 리턴하게 하여 클릭한 상태로 마우스를 움직여야 scrub
이벤트가 발생하도록 하는 것이다.
마무리
영상의 시작, 정지부분이나 시간이동부분을 이렇게 보니 정말 신기했다.
주말동안 IGLS에서 SK석유화학을 다녀오느라 포스팅이 느려졌다.
갔다온 내용도 포스팅해봐야겠다.
끝.