JS 30 是由加拿大的全端工程師 Wes Bos 免費提供的 JavaScript 簡單應用課程,課程主打 No Frameworks
、No Compilers
、No Libraries
、No Boilerplate
在30天的30部教學影片裡,建立30個JavaScript的有趣小東西。
另外,Wes Bos 也很無私地在 Github 上公開了所有 JS 30 課程的程式碼,有興趣的話可以去 fork 或下載。
除了原本在video
元素自帶的影片控制器(設定controls
屬性),我們可以另外實作一個調節影片速度的控制介面,這個介面可以用拖拉的方式改變影片的播放速度。
div(.wrapper
)是我們整個的影片播放器,下面可拆作兩部分,一個是 video(.flex
)和自帶的預設控制介面(啟用controls
),另一個是我們這次要實作出的影片速度調節介面 div(.speed
)。
<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
放入取得的速度調節介面(.speed
)。bar
放入取得的速度調節介面內部的子元素(.speed-bar
)。video
放入取得的video
元素(.flex
)。const speed = document.querySelector('.speed');
const bar = document.querySelector('.speed-bar');
const video =document.querySelector('.flex');
在speed
註冊mousemove event listener
監聽是否有滑鼠在speed
上移動,有的話就用後方的function()
作為event handler
。
在event handler
裡,我們要先取得的是滑鼠在內部移動時的 y 座標(e.pageY
,相對整個 HTML 文件頂部而言),又因為我們無法保證速度調節介面(.speed
)是在 HTML 文件的最頂端而且沒有margin
、padding
之類的,所以還須把取得的 y 座標減去.speed
離視窗(offsetParent
)頂端的距離(offsetTop
)進行修正。
宣告常數percent
算出目前滑鼠所在的 y 座標位置,相對於整個速度調節介面高度(this.offsetHeight
)的比例,作為後續調整.speed-bar
的高度和.flex
影片播放速度的依據。
宣告常數max
、min
作為調整影片播放速度時能達到的最大、最小倍率。
speed.addEventListener('mousemove', function(e){
//we can't assume that speed is on the top
const y = e.pageY - this.offsetTop;
const percent = y / this.offsetHeight;
const min = 0.4;
const max = 4;
});
宣告常數height
,用Math.round(percent*100)+'%'
,將剛剛算出的比例換成百分比的形式。
宣告常數playbackRate
計算現在的比例(percent
)換算成的速度倍率。
將.speed-bar
的高度設為我們算出的高度百分比(height
),然後再把它的文字內容換成現在的速度倍率(ex. 1.2x
)。toFixed()
幫我們把算出的速度倍率(playbackRate
)取到小數點後1位。
最後修改video
的playbackRate
屬性就完成了。
(播放速度太快或太慢均有可能導致影片部分聲音消失!!!)
speed.addEventListener('mousemove', function(e){
/*上略...*/
const height = Math.round(percent*100)+'%';
const playbackRate = percent * (max-min) + min;
bar.style.height = height;
bar.textContent = playbackRate.toFixed(1)+'x';
video.playbackRate = playbackRate;
});
HTMLElement.offsetTop
HTMLMediaElement.playbackRate
HTMLElement.offsetHeight
Number.prototype.toFixed()
Math.round()