Skip to content

Commit e0a6643

Browse files
committed
add 28_Video-Speed-Controller
1 parent 550e208 commit e0a6643

File tree

5 files changed

+253
-0
lines changed

5 files changed

+253
-0
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>Video Speed Scrubber</title>
6+
<link rel="stylesheet" href="style.css">
7+
</head>
8+
<body>
9+
10+
<div class="wrapper">
11+
<video class="flex" width="765" height="430" src="https://www.dropbox.com/s/nf6jfkwck1glsyo/12%20-%20flex-wrapping-and-columns.mp4?dl=1" loop controls></video>
12+
<div class="speed">
13+
<div class="speed-bar"></div>
14+
</div>
15+
</div>
16+
17+
<script>
18+
const speed = document.querySelector('.speed');
19+
const bar = speed.querySelector('.speed-bar');
20+
const video = document.querySelector('.flex');
21+
22+
function handleMove(e) {
23+
const y = e.pageY - this.offsetTop;
24+
const percent = y / this.offsetHeight;
25+
const min = 0.4;
26+
const max = 4;
27+
const height = Math.round(percent * 100) + '%';
28+
const playbackRate = percent * (max - min) + min;
29+
bar.style.height = height;
30+
bar.textContent = playbackRate.toFixed(2) + '×';
31+
video.playbackRate = playbackRate;
32+
}
33+
34+
speed.addEventListener('mousemove', handleMove);
35+
36+
</script>
37+
</body>
38+
</html>
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
<!DOCTYPE html>
2+
<html lang="zh-TW">
3+
4+
<head>
5+
<meta charset="UTF-8">
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
7+
<meta http-equiv="X-UA-Compatible" content="ie=edge">
8+
<meta name="description" content="背不起來的就寫下來吧。">
9+
<meta property="og:type" content="website">
10+
<meta property="og:title" content="Gua&#39;s Note">
11+
<meta property="og:url" content="https://guahsu.io/">
12+
<meta property="og:site_name" content="Gua&#39;s Note">
13+
<script>
14+
(function (i, s, o, g, r, a, m) {
15+
i['GoogleAnalyticsObject'] = r;
16+
i[r] = i[r] || function () {
17+
(i[r].q = i[r].q || []).push(arguments)
18+
}, i[r].l = 1 * new Date();
19+
a = s.createElement(o),
20+
m = s.getElementsByTagName(o)[0];
21+
a.async = 1;
22+
a.src = g;
23+
m.parentNode.insertBefore(a, m)
24+
})(window, document, 'script', 'https://www.google-analytics.com/analytics.js', 'ga');
25+
ga('create', 'UA-84594235-4', 'auto');
26+
ga('send', 'pageview');
27+
</script>
28+
<title>JavaScript30 - 28 - Video Speed Controller | Gua's Note</title>
29+
<link rel="stylesheet" href="style.css">
30+
</head>
31+
32+
<body class="bod">
33+
34+
<style>
35+
body {
36+
margin-top: 48px;
37+
}
38+
39+
.GuaHsu-header {
40+
position: absolute;
41+
left: 0;
42+
top: 0;
43+
width: 100%;
44+
background-color: #333;
45+
text-align: center;
46+
padding: 10px;
47+
color: #7ff3cb;
48+
font-size: 20px;
49+
font-weight: 100;
50+
z-index: 999;
51+
}
52+
53+
.GuaHsu-header span {
54+
margin: 0 5px;
55+
}
56+
57+
.GuaHsu-header a {
58+
text-decoration: none;
59+
color: unset;
60+
}
61+
</style>
62+
<div class="GuaHsu-header">
63+
<span>
64+
<a href="https://guahsu.io/categories/JavaScript30/" target="_blank">JavaScript30 心得</a>
65+
</span>
66+
<span>|</span>
67+
<span>
68+
<a href="https://github.com/guahsu/JavaScript30" target="_blank">GitHub</a>
69+
</span>
70+
</div>
71+
72+
<div class="wrapper">
73+
<video class="flex" width="765" height="430" src="https://player.vimeo.com/external/194837908.sd.mp4?s=c350076905b78c67f74d7ee39fdb4fef01d12420&profile_id=164" loop controls></video>
74+
<div class="speed">
75+
<div class="speed-bar"></div>
76+
</div>
77+
</div>
78+
79+
<script>
80+
const speed = document.querySelector('.speed');
81+
const bar = speed.querySelector('.speed-bar');
82+
const video = document.querySelector('.flex');
83+
84+
/** 滑鼠移動事件 **/
85+
function handleMove (e) {
86+
// 取得觸發點位置(滑鼠位於整頁頂端的Y軸定位-speed框到整頁頂端的距離)
87+
const y = e.pageY - this.offsetTop;
88+
// 設定百分比(y / speed框的高度)
89+
const percent = y / this.offsetHeight;
90+
const min = 0.4;
91+
const max = 4;
92+
// 用Math.round來計算取得四捨五入的百分比值
93+
const height = Math.round(percent * 100) + '%';
94+
// 取得播放速率(0.4一跳,最多4倍速)
95+
const playbackRate = percent * (max - min) + min;
96+
// 調整speed-bar的樣式高度
97+
bar.style.height = height;
98+
// 用toFixed(2)來設定最多取得小數點後兩位,顯示於speed-bar上
99+
bar.textContent = playbackRate.toFixed(2) + 'x';
100+
// 控制影片的速率
101+
video.playbackRate = playbackRate;
102+
}
103+
104+
/** 滑鼠移動 **/
105+
speed.addEventListener('mousemove', handleMove);
106+
107+
</script>
108+
</body>
109+
</html>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>Video Speed Scrubber</title>
6+
<link rel="stylesheet" href="style.css">
7+
</head>
8+
<body>
9+
10+
<div class="wrapper">
11+
<video class="flex" width="765" height="430" src="https://www.dropbox.com/s/nf6jfkwck1glsyo/12%20-%20flex-wrapping-and-columns.mp4?dl=1" loop controls></video>
12+
<div class="speed">
13+
<div class="speed-bar"></div>
14+
</div>
15+
</div>
16+
17+
<script>
18+
</script>
19+
</body>
20+
</html>
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# 28 - Video Speed Controller
2+
3+
![](https://guahsu.io/2017/10/JavaScript30-28-Video-Speed-Controller/demo28.png)
4+
5+
## **主題**
6+
製作一個可控制影片速率的拉把。
7+
8+
[[BLOG]](https://guahsu.io/2017/10/JavaScript30-28-Video-Speed-Controller) | [[DEMO]](https://guahsu.io/JavaScript30/28_Video-Speed-Controller/index-GuaHsu.html)
9+
10+
這個練習可以算是延續[「JS30紀錄&心得」11 - Custom Video Player](https://guahsu.io/2017/07/JavaScript30-11-Custom-Video-Player/)的操作,
11+
主要是把原本`input range`改成`div`的滑鼠事件監聽。
12+
13+
14+
## **步驟**
15+
### Step1. 取得頁面元素
16+
```javascript
17+
const speed = document.querySelector('.speed');
18+
const bar = speed.querySelector('.speed-bar');
19+
const video = document.querySelector('.flex');
20+
```
21+
22+
### Step2. 建立滑鼠移動監聽與事件
23+
```javascript
24+
/** 滑鼠移動事件 **/
25+
function handleMove (e) {
26+
// 取得觸發點位置(滑鼠位於整頁頂端的Y軸定位-speed框到整頁頂端的距離)
27+
const y = e.pageY - this.offsetTop;
28+
// 設定百分比(y / speed框的高度)
29+
const percent = y / this.offsetHeight;
30+
const min = 0.4;
31+
const max = 4;
32+
// 用Math.round來計算取得四捨五入的百分比值
33+
const height = Math.round(percent * 100) + '%';
34+
// 取得播放速率(0.4一跳,最多4倍速)
35+
const playbackRate = percent * (max - min) + min;
36+
// 調整speed-bar的樣式高度
37+
bar.style.height = height;
38+
// 用toFixed(2)來設定最多取得小數點後兩位,顯示於speed-bar上
39+
bar.textContent = playbackRate.toFixed(2) + 'x';
40+
// 控制影片的速率
41+
video.playbackRate = playbackRate;
42+
}
43+
```
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
2+
body {
3+
display:flex;
4+
align-items: center;
5+
justify-content: center;
6+
margin: 0;
7+
min-height: 100vh;
8+
background:#4C4C4C url('https://unsplash.it/1500/900?image=1021');
9+
background-size:cover;
10+
font-family: sans-serif;
11+
}
12+
13+
video {
14+
box-shadow:0 0 1px 3px rgba(0,0,0,0.1);
15+
}
16+
17+
.wrapper {
18+
display:flex;
19+
width:850px;
20+
}
21+
22+
.speed {
23+
display:flex;
24+
overflow: hidden;
25+
align-items:flex-start;
26+
flex:1;
27+
margin:10px;
28+
border-radius:50px;
29+
background:#efefef;
30+
box-shadow:0 0 1px 3px rgba(0,0,0,0.1);
31+
}
32+
33+
.speed-bar {
34+
display: flex;
35+
align-items: center;
36+
justify-content: center;
37+
padding:2px;
38+
width:100%;
39+
height:16.3%;
40+
background:linear-gradient(-170deg, #2376ae 0%, #c16ecf 100%);
41+
color:white;
42+
text-shadow:1px 1px 0 rgba(0,0,0,0.2);
43+
}

0 commit comments

Comments
 (0)