Javascript_30_11


こんにちは!


Derek:)


イギリスではコロナウイルスの変種が韓国でも.始まったみたい!びっくりした😥
皆さんお家で穏やかに年末を過ごしましょう!
今日はJavascript 30の11番目のテーマで皆さんに宣伝します!
Day 11 Projectはビデオプレーヤーを編集するプロジェクトです!重いテーマ量も多いのでしっかり整理しておきます

11. Custom Video Player



n/a.ターゲット


再生、一時停止、ビデオ再生が進むにつれて、ビデオの再生量、skip、音量調整、再生速度が表示されます.
基本的なフレームワークを提供し,これらの機能のみを実装した.

Derekとwes Bos実装コード

/* Get Our Elements */
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(){
    video.paused ? video.play() : video.pause();
}

// The fact that this function is not included in "togglePlay()"
// is meaningful. We listened to the "play" and "pause" event.
function updateButton(){
    const icon = this.paused ? '►' : '❚ ❚';
    toggle.innerHTML = icon;
}

function skip(){
    video.currentTime += parseFloat(this.dataset.skip);
}

function handleRangeUpdate() {
    video[this.name] = this.value;
}

// this function have to be ran everytime.
function handleProgress(){
    const percent = (video.currentTime / video.duration) * 100;
    progressBar.style.flexBasis = `${percent}%`;
}

function scrub(e){
    const scrubTime = (e.offsetX / progress.offsetWidth) * video.duration;
    video.currentTime = scrubTime;
}

video.addEventListener("click", togglePlay);
toggle.addEventListener("click", togglePlay);

video.addEventListener("play", updateButton);
video.addEventListener("pause", updateButton);

skipButtons.forEach(btn => btn.addEventListener("click", skip));

ranges.forEach(range => range.addEventListener("change", handleRangeUpdate));
ranges.forEach(range => range.addEventListener("mousemove", handleRangeUpdate));

video.addEventListener("timeupdate", handleProgress)

let mouseDown = false;
progress.addEventListener("click", scrub);
progress.addEventListener("mousemove", (e) => mouseDown && scrub(e));

progress.addEventListener("mousedown", () => mouseDown = true);
progress.addEventListener("mouseup", () => mouseDown = false)
長くて複雑に見えます.
機能別に整理しておきましょう

1.ビデオ再生と一時停止機能


まず、ビデオ自体をクリックしたり、再生/一時停止ボタンを押したりする機能を実現する方法について説明します.
video.addEventListener("click", togglePlay);
toggle.addEventListener("click", togglePlay);

function togglePlay(){
    video.paused ? video.play() : video.pause();
}
ビデオ自体を押すか、再生ボタンを押すとtogglePlay関数を実行できます.
3つの演算子としてvideo.pausedが参加する場合、video.play()が実行され、そうでない場合、video.pause()が実行されて再生が停止される.ビデオ再生をtoggle行う関数です
以下はtogglePlay()で、ビデオを再生または一時停止し、アイコンを更新するたびに機能します.
video.addEventListener("play", updateButton);
video.addEventListener("pause", updateButton);

function updateButton(){
    const icon = this.paused ? '►' : '❚ ❚';
    toggle.innerHTML = icon;
}
video要素の場合、イベントが待機します.videoが再生または中断された場合、eventListenerが実行され、updateButtonが実行される.thisオブジェクトがvideovideoで一時停止したか否かを判定し、正しい場合は再生ボタン、または一時停止ボタンを出力する.これを3つの演算子として表します.

2.skipボタン機能


画像の右下を10秒後退したり、25秒前に移動したりする機能です.
skipButtons.forEach(btn => btn.addEventListener("click", skip));

function skip(){
    video.currentTime += parseFloat(this.dataset.skip);
}
HTMLファイルにはskipボタンが含まれています.
<button data-skip="-10" class="player__button">« 10s</button>
<button data-skip="25" class="player__button">25s »</button>
つまり、dataプロパティが使用されます.dataプロパティは最初の投稿に表示されます.ユーザーが勝手にやっていると考えられるattributeskipButtons
const skipButtons = player.querySelectorAll('[data-skip]');
querySelectorAllが使用されるため、skipButtonsevent登録はforEach構文を使用する.skipButtonsを押すと、skip()関数が実行され、this.dataset.skipパラメータが呼び出されて処理されます.
また、このパラメータはstringとして読み出されるので、parseFloat関数が適用される.
初めて見たCurrentTimeというオブジェ!

3.音量調節と再生速度調節機能


音量調整と再生速度はrange inputによって制御される.HTMLの構成は、
<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">
nameの属性を有する2つのinputが存在する.イベントは次のコードで管理されます.
ranges.forEach(range => range.addEventListener("change", handleRangeUpdate));
ranges.forEach(range => range.addEventListener("mousemove", handleRangeUpdate));

function handleRangeUpdate() {
    video[this.name] = this.value;
}
changemousemoveがあるのは、音量ボタンと再生速度ボタンをクリックすることで変更できるが、ドラッグで調整できるため、2つのeventListenerからなる.
イベントが発生した場合、handleRangeUpdate関数が実行されます.thisは呼び出しイベントのrangeであるため、this.valueをビデオ属性に入れて実施する.

4.現在の再生状態表示機能


これは、再生中にビデオが底で何回再生されたかを表示する機能です.
video.addEventListener("timeupdate", handleProgress)

// this function have to be ran everytime.
function handleProgress(){
    const percent = (video.currentTime / video.duration) * 100;
    progressBar.style.flexBasis = `${percent}%`;
}
timeUpdateの定義に従います.
currentTimeプロパティとして表示された時刻を更新する場合.
メディア限定のイベントのようですが…!メディアのMDNプロパティを変更するたびに、登録関数currentTimeが実行されます.
現在の再生時間を合計再生時間で割ってパーセンテージを計算し、handleProgress属性に直ちに変換します.

5.回生区間変動機能


「再生部分」barをクリックすると、現在の再生位置を変更したり、クリックしてドラッグしたりして変更機能を実現できます.
let mouseDown = false;

progress.addEventListener("click", scrub);
progress.addEventListener("mousemove", (e) => mouseDown && scrub(e));

progress.addEventListener("mousedown", () => mouseDown = true);
progress.addEventListener("mouseup", () => mouseDown = false);

function scrub(e){
    const scrubTime = (e.offsetX / progress.offsetWidth) * video.duration;
    video.currentTime = scrubTime;
}
まず、style関数は、イベントが発生した位置scrubの値を求め、offsetX barの水平長に分ける.除算した値に再生時間全体を乗じて、移動する再生セグメントの関数を探します.progressイベントが発生した場合は、click関数を実行するだけです.scrubイベントが発生した場合は、フラグを参照して実行してください.mousemoveはflagであり、mouseDownまたはmousedownイベントに応じて、その値はそれぞれmouseupおよびtrueである.
progress.addEventListener("mousemove", (e) => mouseDown && scrub(e));
false flagがmouseDownである場合、匿名関数内は虚偽であり、機能は一切実行されない.falsemouseDownである場合、true関数は後で実行される.
個人的にはこの方法がいいと思います.その実施は、scrub文なしで条件文を完了したようなものである.
()=>(条件1)&(条件2)
このように出現すれば,条件1が偽物であれば匿名関数を直接導出する!覚えてほしい🤗
簡単なビデオ再生ツールプロジェクトが完成しました!の目が見える道具を作るのは想像以上に面白いです.
エラーや修正が必要な場合は、いつでもフィードバックしてください.
ありがとう!🤗