Day 28 - Build a Experimental Video Speed Controller UI

前言

JS 30 是由加拿大的全端工程师 Wes Bos 免费提供的 JavaScript 简单应用课程,课程主打 No FrameworksNo CompilersNo LibrariesNo Boilerplate 在30天的30部教学影片里,建立30个JavaScript的有趣小东西。

另外,Wes Bos 也很无私地在 Github 上公开了所有 JS 30 课程的程序码,有兴趣的话可以去 fork 或下载。


本日目标

除了原本在video元素自带的影片控制器(设定controls属性),我们可以另外实作一个调节影片速度的控制介面,这个介面可以用拖拉的方式改变影片的播放速度。


解析程序码

HTML 部分

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>

JS 部分

首先,取得所有需要的元素 :

  • 宣告常数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 文件的最顶端而且没有marginpadding之类的,所以还须把取得的 y 座标减去.speed离视窗(offsetParent)顶端的距离(offsetTop)进行修正。

宣告常数percent算出目前滑鼠所在的 y 座标位置,相对於整个速度调节介面高度(this.offsetHeight)的比例,作为後续调整.speed-bar的高度和.flex影片播放速度的依据。

宣告常数maxmin作为调整影片播放速度时能达到的最大、最小倍率。

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位。

最後修改videoplaybackRate属性就完成了。

(播放速度太快或太慢均有可能导致影片部分声音消失!!!)

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()

范例网页请点此

观看完整程序码


<<:  【Day12】插槽 Portals

>>:  不只懂 Vue 语法:请示范如何使用 Vue 3 的 teleport?

Day 21 总要接受外部的刺激

人就像藤萝,他的生存靠别的东西支持,他拥抱别人,就从拥抱中得到了力量! 《iT邦帮忙铁人赛的观点》(...

Day-02 机器学习的介绍

昨天我们已经聊过了整个机器学习的大概念了,也知道深度学习和机器学习之间的关系,因此我们在这里先好好...

成为工具人应有的工具包-17 MyLastSearch

MyLastSearch 今天来看看这顾名思义就知道是要看我的搜寻纪录的工具,可以很直觉的想到用在查...

【day8】居家办公的早餐diy卷饼

对比现在忙碌的工作 开始怀念过去两个月居家办公的时光 在相对有余裕的时候下厨 挑选自己喜欢的食物 一...

Day21 javascript 阵列方法(完)

今天继续来讲阵列,想说都剩没多少,不如就一次介绍完呗,这样以後翻笔记才不会翻半天还找不到东西(大家应...