<video>
를 커스텀해보자
원래
<video controls>
와 같이
controls attribute를 주면 위와 같이 브라우저 기본 비디오 UI를 제공해준다.
이 UI를 입맛대로 커스텀하려면, 하나부터 열까지 다 뜯어고쳐야한다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>HTML Video Player</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="player">
<video class="player__video viewer" src="652333414.mp4"></video>
<div class="player__controls">
<div class="progress">
<div class="progress__filled"></div>
</div>
<button class="player__button toggle" title="Toggle Play">►</button>
<input
type="range"
name="volume"
class="player__slider"
min="0"
max="1"
step="0.05"
value="1"
/>
<input
type="range"
name="playbackRate"
class="player__slider"
min="0.5"
max="2"
step="0.1"
value="1"
/>
<button data-skip="-10" class="player__button">« 10s</button>
<button data-skip="25" class="player__button">25s »</button>
</div>
</div>
<script src="scripts.js"></script>
</body>
</html>
const video = document.querySelector('.viewer');
const progress = document.querySelector('.progress');
const progressBar = document.querySelector('.progress__filled');
const toggle = document.querySelector('.toggle');
const volume = document.querySelectorAll('.player__slider')[0];
const playbackRate = document.querySelectorAll('.player__slider')[1];
const skipButtons = document.querySelectorAll('[data-skip]');
/* function */
function playVideo() {
const method = video.paused ? 'play' : 'pause';
video[method]();
}
// toggle icon 변경
function updateButton() {
const icon = this.paused ? '►' : '❚ ❚';
toggle.innerHTML = icon;
}
function updateVolume(e) {
video.volume = this.value;
}
function updatePlaybackRate() {
video.playbackRate = this.value;
}
function handleSkip() {
const value = this.dataset.skip;
video.currentTime += parseFloat(value);
}
function handleProgressBar(e) {
const percent = (video.currentTime / video.duration) * 100;
progressBar.style.flexBasis = `${percent}%`;
}
function scrubVideo(e) {
video.currentTime =
video.duration * (e.offsetX / progress.getBoundingClientRect().width);
}
/* EventListener */
video.addEventListener('click', playVideo);
video.addEventListener('play', updateButton);
video.addEventListener('pause', updateButton);
video.addEventListener('timeupdate', handleProgressBar);
toggle.addEventListener('click', playVideo);
volume.addEventListener('mousemove', updateVolume);
playbackRate.addEventListener('mousemove', updatePlaybackRate);
skipButtons.forEach((skipButton) => {
skipButton.addEventListener('click', handleSkip);
});
let mousedown;
progress.addEventListener('click', scrubVideo);
progress.addEventListener('mousemove', (e) => mousedown && scrubVideo(e));
progress.addEventListener('mousedown', () => (mousedown = true));
progress.addEventListener('mouseup', () => (mousedown = false));
progress bar를 클릭중인 마우스로 잡고 끌어 당기는 행위
function scrubVideo(e) {
video.currentTime =
video.duration * (e.offsetX / progress.getBoundingClientRect().width);
}
let mousedown;
progress.addEventListener('click', scrubVideo);
progress.addEventListener('mousemove', (e) => mousedown && scrubVideo(e));
progress.addEventListener('mousedown', () => (mousedown = true));
progress.addEventListener('mouseup', () => (mousedown = false));
mousedown
전역변수를 이용해서,
mousedown, mouseup, mousemove event
handler를 등록해서 적용한다.
mousedown이 true일때만 scrubVideo
를 수행한다.
Bracket notation
Element안 속성(메소드)을 대괄호로 접근
function playVideo() {
const method = video.paused ? 'play' : 'pause';
video[method]();
}
video[method]();
다음과 같이 Bracket notation
방법으로 Element안의 속성을 접근할 수 있다.
보통은 video.play()
, video.pause()
와 같이
Dot notation
방법으로 접근한다