videojs-mobile-ui 0.7.0 → 0.9.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +114 -46
- package/dist/videojs-mobile-ui.cjs.js +275 -223
- package/dist/videojs-mobile-ui.css +2 -2
- package/dist/videojs-mobile-ui.es.js +270 -217
- package/dist/videojs-mobile-ui.js +278 -265
- package/dist/videojs-mobile-ui.min.js +2 -2
- package/docs/api/TouchOverlay.html +964 -0
- package/docs/api/fonts/OpenSans-Bold-webfont.eot +0 -0
- package/docs/api/fonts/OpenSans-Bold-webfont.svg +1830 -0
- package/docs/api/fonts/OpenSans-Bold-webfont.woff +0 -0
- package/docs/api/fonts/OpenSans-BoldItalic-webfont.eot +0 -0
- package/docs/api/fonts/OpenSans-BoldItalic-webfont.svg +1830 -0
- package/docs/api/fonts/OpenSans-BoldItalic-webfont.woff +0 -0
- package/docs/api/fonts/OpenSans-Italic-webfont.eot +0 -0
- package/docs/api/fonts/OpenSans-Italic-webfont.svg +1830 -0
- package/docs/api/fonts/OpenSans-Italic-webfont.woff +0 -0
- package/docs/api/fonts/OpenSans-Light-webfont.eot +0 -0
- package/docs/api/fonts/OpenSans-Light-webfont.svg +1831 -0
- package/docs/api/fonts/OpenSans-Light-webfont.woff +0 -0
- package/docs/api/fonts/OpenSans-LightItalic-webfont.eot +0 -0
- package/docs/api/fonts/OpenSans-LightItalic-webfont.svg +1835 -0
- package/docs/api/fonts/OpenSans-LightItalic-webfont.woff +0 -0
- package/docs/api/fonts/OpenSans-Regular-webfont.eot +0 -0
- package/docs/api/fonts/OpenSans-Regular-webfont.svg +1831 -0
- package/docs/api/fonts/OpenSans-Regular-webfont.woff +0 -0
- package/docs/api/global.html +957 -0
- package/docs/api/index.html +159 -0
- package/docs/api/plugin.js.html +221 -0
- package/docs/api/scripts/linenumber.js +25 -0
- package/docs/api/scripts/prettify/Apache-License-2.0.txt +202 -0
- package/docs/api/scripts/prettify/lang-css.js +2 -0
- package/docs/api/scripts/prettify/prettify.js +28 -0
- package/docs/api/styles/jsdoc-default.css +358 -0
- package/docs/api/styles/prettify-jsdoc.css +111 -0
- package/docs/api/styles/prettify-tomorrow.css +132 -0
- package/docs/api/swipeFullscreen.js.html +173 -0
- package/docs/api/touchOverlay.js.html +211 -0
- package/index.html +206 -65
- package/package.json +19 -16
- package/src/plugin.css +21 -3
- package/src/plugin.js +32 -59
- package/src/swipeFullscreen.js +117 -0
- package/src/touchOverlay.js +62 -56
- package/test/plugin.test.js +128 -20
- package/test/swipeFullscreen.test.js +365 -0
package/index.html
CHANGED
|
@@ -1,69 +1,194 @@
|
|
|
1
|
-
<!
|
|
1
|
+
<!DOCTYPE html>
|
|
2
2
|
<html>
|
|
3
|
+
|
|
3
4
|
<head>
|
|
4
|
-
<meta charset="utf-8"
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1"
|
|
5
|
+
<meta charset="utf-8" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
7
|
<title>videojs-mobile-ui Demo</title>
|
|
7
|
-
<link href="
|
|
8
|
-
<link href="dist/
|
|
8
|
+
<link href="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20height%3D%2224px%22%20viewBox%3D%220%20-960%20960%20960%22%20width%3D%2224px%22%20fill%3D%22%231f1f1f%22%3E%3Cpath%20d%3D%22M419-80q-28%200-52.5-12T325-126L124-381q-8-9-7-21.5t9-20.5q20-21%2048-25t52%2011l74%2045v-328q0-17%2011.5-28.5T340-760q17%200%2029%2011.5t12%2028.5v200h299q50%200%2085%2035t35%2085v160q0%2066-47%20113T640-80H419Zm60-520q-17%200-28.5-11.5T439-640q0-2%205-20%208-14%2012-28.5t4-31.5q0-50-35-85t-85-35q-50%200-85%2035t-35%2085q0%2017%204%2031.5t12%2028.5q3%205%204%2010t1%2010q0%2017-11%2028.5T202-600q-11%200-20.5-6T167-621q-13-22-20-47t-7-52q0-83%2058.5-141.5T340-920q83%200%20141.5%2058.5T540-720q0%2027-7%2052t-20%2047q-5%209-14%2015t-20%206Z%22%2F%3E%3C%2Fsvg%3E" rel="icon" type="image/x-icon" />
|
|
9
|
+
<link href="node_modules/video.js/dist/video-js.css" rel="stylesheet" />
|
|
10
|
+
<link href="dist/videojs-mobile-ui.css" rel="stylesheet" />
|
|
9
11
|
<style>
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
.testEl {
|
|
13
|
+
width: 10%;
|
|
14
|
+
height: 10%;
|
|
15
|
+
position: absolute;
|
|
16
|
+
top: 0;
|
|
17
|
+
pointer-events: none;
|
|
18
|
+
display: none;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
body {
|
|
22
|
+
font-size: 16px;
|
|
23
|
+
line-height: 1.4;
|
|
24
|
+
margin-bottom: 60px;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.video-container {
|
|
28
|
+
width: 100vw;
|
|
29
|
+
margin-left: calc(50% - 50vw);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
video-js:fullscreen .vjs-control-bar {
|
|
33
|
+
font-size: 1.1em;
|
|
34
|
+
padding-bottom: 20px;
|
|
35
|
+
height: calc(3em + 20px);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
#demoOptions {
|
|
39
|
+
|
|
40
|
+
ul {
|
|
41
|
+
list-style: none;
|
|
42
|
+
padding: 0;
|
|
43
|
+
margin: 0;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
li {
|
|
47
|
+
margin-bottom: 10px;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
label {
|
|
51
|
+
min-height: 44px;
|
|
52
|
+
/* Apple/Google tap target guidance */
|
|
53
|
+
cursor: pointer;
|
|
54
|
+
font-family: ui-monospace, 'Courier New', Courier, monospace;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/* Text inputs */
|
|
58
|
+
input[type="text"],
|
|
59
|
+
input[type="email"],
|
|
60
|
+
input[type="number"],
|
|
61
|
+
input[type="password"],
|
|
62
|
+
textarea {
|
|
63
|
+
width: 90%;
|
|
64
|
+
padding: 10px 12px;
|
|
65
|
+
font-size: 16px;
|
|
66
|
+
/* Prevents iOS zoom */
|
|
67
|
+
border: 1px solid #ccc;
|
|
68
|
+
border-radius: 6px;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/* Checkboxes (simple but usable) */
|
|
72
|
+
input[type="checkbox"] {
|
|
73
|
+
width: 20px;
|
|
74
|
+
height: 20px;
|
|
75
|
+
flex-shrink: 0;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/* Optional: subtle focus style */
|
|
79
|
+
input:focus,
|
|
80
|
+
textarea:focus {
|
|
81
|
+
outline: none;
|
|
82
|
+
border-color: #007aff;
|
|
83
|
+
/* iOS blue */
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/* Optional: slightly separate groups */
|
|
87
|
+
li+li {
|
|
88
|
+
border-top: 1px solid #eee;
|
|
89
|
+
padding-top: 8px;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
button {
|
|
93
|
+
font-size: 16px;
|
|
94
|
+
margin-bottom: 10px;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
18
97
|
</style>
|
|
19
98
|
</head>
|
|
99
|
+
|
|
20
100
|
<body>
|
|
21
|
-
<
|
|
22
|
-
|
|
23
|
-
<
|
|
24
|
-
|
|
101
|
+
<h1>videojs-mobile-ui test page.</h1>
|
|
102
|
+
<div class="video-container">
|
|
103
|
+
<video-js id="videojs-mobile-ui-player" class="video-js vjs-default-skin vjs-fluid" controls playsinline>
|
|
104
|
+
<source src="https://d2zihajmogu5jn.cloudfront.net/bipbop-advanced/bipbop_16x9_variant.m3u8"
|
|
105
|
+
type="application/x-mpegurl" />
|
|
106
|
+
</video-js>
|
|
107
|
+
</div>
|
|
25
108
|
<ul>
|
|
26
109
|
<li><a href="test/">Run unit tests in browser.</a></li>
|
|
27
|
-
<li><a href="docs/api/">Read generated docs.</a></li>
|
|
28
110
|
</ul>
|
|
29
111
|
<h2>Options</h2>
|
|
30
|
-
<
|
|
31
|
-
<
|
|
32
|
-
<
|
|
33
|
-
|
|
34
|
-
<li
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
<
|
|
112
|
+
<div id="demoOptions">
|
|
113
|
+
<p>Reload to apply changed options.</p>
|
|
114
|
+
<button id="reload">Reload with options</button>
|
|
115
|
+
<ul id="options">
|
|
116
|
+
<li>
|
|
117
|
+
<h3>fullscreen:</h3>
|
|
118
|
+
</li>
|
|
119
|
+
<ul>
|
|
120
|
+
<li>
|
|
121
|
+
<input type="checkbox" data-section="fullscreen" id="enterOnRotate" /> <label for="enterOnRotate">enterOnRotate</label>
|
|
122
|
+
</li>
|
|
123
|
+
<li>
|
|
124
|
+
<input type="checkbox" data-section="fullscreen" id="exitOnRotate" />
|
|
125
|
+
<label for="exitOnRotate">exitOnRotate</label>
|
|
126
|
+
</li>
|
|
127
|
+
<li>
|
|
128
|
+
<input type="checkbox" data-section="fullscreen" id="lockOnRotate" />
|
|
129
|
+
<label for="lockOnRotate">lockOnRotate</label>
|
|
130
|
+
</li>
|
|
131
|
+
<li>
|
|
132
|
+
<input type="checkbox" data-section="fullscreen" id="alwaysLockToLandscape" />
|
|
133
|
+
<label for="alwaysLockToLandscape">alwaysLockToLandscape</label>
|
|
134
|
+
</li>
|
|
135
|
+
<li>
|
|
136
|
+
<input type="checkbox" data-section="fullscreen" id="swipeToFullscreen" />
|
|
137
|
+
<label for="swipeToFullscreen">swipeToFullscreen</label>
|
|
138
|
+
</li>
|
|
139
|
+
<li>
|
|
140
|
+
<input type="checkbox" data-section="fullscreen" id="swipeFromFullscreen" />
|
|
141
|
+
<label for="swipeFromFullscreen">swipeFromFullscreen</label>
|
|
142
|
+
</li>
|
|
143
|
+
<li>
|
|
144
|
+
<input type="checkbox" data-section="fullscreen" id="fullscreenDisabled" />
|
|
145
|
+
<label for="disabled">disabled</label>
|
|
146
|
+
</li>
|
|
147
|
+
</ul>
|
|
148
|
+
<li>
|
|
149
|
+
<h3>touchControls:</h3>
|
|
150
|
+
</li>
|
|
151
|
+
<ul>
|
|
152
|
+
<li>
|
|
153
|
+
<input type="number" data-section="touchControls" id="seekSeconds" />
|
|
154
|
+
<label for="seekSeconds">seekSeconds</label>
|
|
155
|
+
</li>
|
|
156
|
+
<li>
|
|
157
|
+
<input type="number" data-section="touchControls" id="tapTimeout" />
|
|
158
|
+
<label for="tapTimeout">tapTimeout</label>
|
|
159
|
+
</li>
|
|
160
|
+
<li>
|
|
161
|
+
<input type="checkbox" data-section="touchControls" id="disableOnEnd" />
|
|
162
|
+
<label for="disableOnEnd">disableOnEnd</label>
|
|
163
|
+
</li>
|
|
164
|
+
<li>
|
|
165
|
+
<input type="checkbox" data-section="touchControls" id="touchControlsDisabled" />
|
|
166
|
+
<label for="disabled">disabled</label>
|
|
167
|
+
</li>
|
|
168
|
+
</ul>
|
|
38
169
|
</ul>
|
|
39
|
-
|
|
40
|
-
<ul>
|
|
41
|
-
<li><input type="number" data-section="touchControls" id="seekSeconds">seekSeconds</li>
|
|
42
|
-
<li><input type="number" data-section="touchControls" id="tapTimeout">tapTimeout</li>
|
|
43
|
-
<li><input type="checkbox" data-section="touchControls" id="disableOnEnd">disableOnEnd</li>
|
|
44
|
-
<li><input type="checkbox" data-section="touchControls" id="touchControlsDisabled">disabled</li>
|
|
45
|
-
</ul>
|
|
46
|
-
</ul>
|
|
47
|
-
<button id="reload">Reload with options</button>
|
|
170
|
+
</div>
|
|
48
171
|
<ul id="log"></ul>
|
|
49
172
|
<script src="node_modules/video.js/dist/video.js"></script>
|
|
50
173
|
<script src="dist/videojs-mobile-ui.js"></script>
|
|
51
174
|
<script>
|
|
52
|
-
(function(window, videojs) {
|
|
175
|
+
(function (window, videojs) {
|
|
53
176
|
var options = {
|
|
54
177
|
fullscreen: {
|
|
55
178
|
enterOnRotate: true,
|
|
56
179
|
exitOnRotate: true,
|
|
57
180
|
lockOnRotate: true,
|
|
58
|
-
|
|
59
|
-
|
|
181
|
+
alwaysLockToLandscape: false,
|
|
182
|
+
swipeToFullscreen: false,
|
|
183
|
+
swipeFromFullscreen: false,
|
|
184
|
+
disabled: false,
|
|
60
185
|
},
|
|
61
186
|
touchControls: {
|
|
62
187
|
seekSeconds: 10,
|
|
63
188
|
tapTimeout: 300,
|
|
64
189
|
disableOnEnd: false,
|
|
65
|
-
disabled: false
|
|
66
|
-
}
|
|
190
|
+
disabled: false,
|
|
191
|
+
},
|
|
67
192
|
};
|
|
68
193
|
|
|
69
194
|
var url = new URL(window.location);
|
|
@@ -73,8 +198,8 @@
|
|
|
73
198
|
|
|
74
199
|
console.log(JSON.stringify(options, null, 2));
|
|
75
200
|
|
|
76
|
-
Object.keys(options).forEach(function(section) {
|
|
77
|
-
Object.keys(options[section]).forEach(function(prop) {
|
|
201
|
+
Object.keys(options).forEach(function (section) {
|
|
202
|
+
Object.keys(options[section]).forEach(function (prop) {
|
|
78
203
|
const val = options[section][prop];
|
|
79
204
|
|
|
80
205
|
if (prop === 'disabled') {
|
|
@@ -82,46 +207,62 @@
|
|
|
82
207
|
}
|
|
83
208
|
|
|
84
209
|
if (typeof val === 'boolean') {
|
|
85
|
-
document.getElementById(prop).checked = val;
|
|
210
|
+
document.getElementById(prop).checked = val;
|
|
86
211
|
}
|
|
87
212
|
if (typeof val === 'number') {
|
|
88
|
-
document.getElementById(prop).value = val;
|
|
213
|
+
document.getElementById(prop).value = val;
|
|
89
214
|
}
|
|
90
215
|
});
|
|
91
216
|
});
|
|
92
217
|
|
|
93
|
-
document
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
218
|
+
document
|
|
219
|
+
.getElementById('options')
|
|
220
|
+
.querySelectorAll('input')
|
|
221
|
+
.forEach(function (opt) {
|
|
222
|
+
opt.addEventListener('change', function () {
|
|
223
|
+
if (this.type === 'checkbox') {
|
|
224
|
+
const param = this.id.endsWith('Disabled')
|
|
225
|
+
? 'disabled'
|
|
226
|
+
: this.id;
|
|
97
227
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
228
|
+
options[this.getAttribute('data-section')][param] =
|
|
229
|
+
this.checked;
|
|
230
|
+
} else {
|
|
231
|
+
options[this.getAttribute('data-section')][this.id] =
|
|
232
|
+
parseFloat(this.value);
|
|
233
|
+
}
|
|
234
|
+
console.log(options);
|
|
235
|
+
});
|
|
103
236
|
});
|
|
104
|
-
});
|
|
105
237
|
|
|
106
|
-
document
|
|
107
|
-
|
|
238
|
+
document
|
|
239
|
+
.getElementById('reload')
|
|
240
|
+
.addEventListener('click', function () {
|
|
241
|
+
url.searchParams.set('options', JSON.stringify(options));
|
|
108
242
|
|
|
109
|
-
|
|
110
|
-
|
|
243
|
+
window.location = url.href;
|
|
244
|
+
});
|
|
111
245
|
|
|
112
|
-
window.addEventListener('orientationchange', function() {
|
|
246
|
+
window.addEventListener('orientationchange', function () {
|
|
113
247
|
var el = document.createElement('li');
|
|
114
|
-
var message =
|
|
115
|
-
|
|
248
|
+
var message =
|
|
249
|
+
new Date().toTimeString().split(' ')[0] + ' ' + window.orientation;
|
|
250
|
+
message +=
|
|
251
|
+
screen && screen.orientation
|
|
252
|
+
? ' ' + screen.orientation.type + ' ' + screen.orientation.angle
|
|
253
|
+
: '';
|
|
116
254
|
el.textContent = message;
|
|
117
255
|
console.log(message);
|
|
118
256
|
document.getElementById('log').appendChild(el);
|
|
119
257
|
});
|
|
120
258
|
|
|
121
|
-
var testPlayer = window.testPlayer = videojs(
|
|
122
|
-
|
|
259
|
+
var testPlayer = (window.testPlayer = videojs(
|
|
260
|
+
'videojs-mobile-ui-player'
|
|
261
|
+
));
|
|
262
|
+
testPlayer.endscreen = function () { };
|
|
123
263
|
testPlayer.mobileUi(options);
|
|
124
|
-
}(window, window.videojs)
|
|
264
|
+
})(window, window.videojs);
|
|
125
265
|
</script>
|
|
126
266
|
</body>
|
|
127
|
-
|
|
267
|
+
|
|
268
|
+
</html>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "videojs-mobile-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0-beta.3",
|
|
4
4
|
"description": "Mobile tap controls and fullscreen on rotate for Video.js",
|
|
5
5
|
"main": "dist/videojs-mobile-ui.cjs.js",
|
|
6
6
|
"module": "dist/videojs-mobile-ui.es.js",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"watch": "npm-run-all -p watch:*",
|
|
32
32
|
"watch:css": "npm run build:css -- -w",
|
|
33
33
|
"watch:js": "npm run build:js -- -w",
|
|
34
|
-
"prepublishOnly": "npm-run-all build-prod && vjsverify --verbose"
|
|
34
|
+
"prepublishOnly": "npm-run-all build-prod && vjsverify --verbose --skip-es-check"
|
|
35
35
|
},
|
|
36
36
|
"engines": {
|
|
37
37
|
"node": ">=14",
|
|
@@ -68,24 +68,27 @@
|
|
|
68
68
|
"README.md": "doctoc --notitle"
|
|
69
69
|
},
|
|
70
70
|
"dependencies": {
|
|
71
|
-
"global": "^4.4.0"
|
|
72
|
-
|
|
71
|
+
"global": "^4.4.0"
|
|
72
|
+
},
|
|
73
|
+
"peerDependencies": {
|
|
74
|
+
"video.js": "^6 || ^7"
|
|
73
75
|
},
|
|
74
76
|
"devDependencies": {
|
|
75
|
-
"@babel/runtime": "^7.
|
|
76
|
-
"@videojs/generator-helpers": "~2.0
|
|
77
|
-
"
|
|
78
|
-
"
|
|
79
|
-
"
|
|
77
|
+
"@babel/runtime": "^7.28.6",
|
|
78
|
+
"@videojs/generator-helpers": "~3.2.0",
|
|
79
|
+
"husky": "^8.0.3",
|
|
80
|
+
"jsdoc": "^4.0.5",
|
|
81
|
+
"karma": "^6.4.4",
|
|
82
|
+
"postcss": "^8.5.6",
|
|
80
83
|
"postcss-cli": "^8.3.1",
|
|
81
|
-
"rollup": "^2.
|
|
82
|
-
"sinon": "^
|
|
84
|
+
"rollup": "^2.79.2",
|
|
85
|
+
"sinon": "^14.0.1",
|
|
86
|
+
"video.js": "^7.21.7",
|
|
83
87
|
"videojs-generate-karma-config": "~8.0.0",
|
|
84
|
-
"videojs-generate-postcss-config": "
|
|
85
|
-
"videojs-generate-rollup-config": "
|
|
86
|
-
"videojs-generator-verify": "
|
|
88
|
+
"videojs-generate-postcss-config": "^3.0.1",
|
|
89
|
+
"videojs-generate-rollup-config": "^7.0.2",
|
|
90
|
+
"videojs-generator-verify": "^4.1.3",
|
|
87
91
|
"videojs-languages": "^2.0.0",
|
|
88
|
-
"videojs-standard": "^
|
|
89
|
-
"husky": "^6.0.0"
|
|
92
|
+
"videojs-standard": "^9.1.0"
|
|
90
93
|
}
|
|
91
94
|
}
|
package/src/plugin.css
CHANGED
|
@@ -14,9 +14,9 @@
|
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
.video-js {
|
|
17
|
+
.video-js.vjs-mobile-ui {
|
|
18
18
|
|
|
19
|
-
&.vjs-has-started .vjs-touch-overlay {
|
|
19
|
+
&.vjs-has-started:not(.vjs-ad-playing) .vjs-touch-overlay {
|
|
20
20
|
position: absolute;
|
|
21
21
|
pointer-events: auto;
|
|
22
22
|
top: 0;
|
|
@@ -30,16 +30,28 @@
|
|
|
30
30
|
|
|
31
31
|
&.skip {
|
|
32
32
|
opacity: 0;
|
|
33
|
-
animation: fadeAndScale 0.
|
|
33
|
+
animation: fadeAndScale 0.8s linear;
|
|
34
34
|
background-repeat: no-repeat;
|
|
35
35
|
background-position: 80% center;
|
|
36
36
|
background-size: 10%;
|
|
37
37
|
background-image: url('data:image/svg+xml;utf8,<svg fill="%23FFFFFF" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M4 18l8.5-6L4 6v12zm9-12v12l8.5-6L13 6z"/><path d="M0 0h24v24H0z" fill="none"/></svg>');
|
|
38
|
+
|
|
39
|
+
&:after {
|
|
40
|
+
content: attr(data-skip-text);
|
|
41
|
+
position: absolute;
|
|
42
|
+
top: 60%;
|
|
43
|
+
left: 70%;
|
|
44
|
+
}
|
|
38
45
|
}
|
|
39
46
|
|
|
40
47
|
&.skip.reverse {
|
|
41
48
|
background-position: 20% center;
|
|
42
49
|
background-image: url('data:image/svg+xml;utf8,<svg fill="%23FFFFFF" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M11 18V6l-8.5 6 8.5 6zm.5-6l8.5 6V6l-8.5 6z"/><path d="M0 0h24v24H0z" fill="none"/></svg>');
|
|
50
|
+
|
|
51
|
+
&:after {
|
|
52
|
+
right: 70%;
|
|
53
|
+
left: unset;
|
|
54
|
+
}
|
|
43
55
|
}
|
|
44
56
|
|
|
45
57
|
.vjs-play-control {
|
|
@@ -83,4 +95,10 @@
|
|
|
83
95
|
display: none;
|
|
84
96
|
}
|
|
85
97
|
|
|
98
|
+
&:not(:fullscreen).using-fs-swipe-up,
|
|
99
|
+
&:fullscreen.using-fs-swipe-down {
|
|
100
|
+
touch-action: none;
|
|
101
|
+
overflow: hidden;
|
|
102
|
+
}
|
|
103
|
+
|
|
86
104
|
}
|
package/src/plugin.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import videojs from 'video.js';
|
|
2
2
|
import {version as VERSION} from '../package.json';
|
|
3
3
|
import './touchOverlay.js';
|
|
4
|
+
import initSwipe from './swipeFullscreen.js';
|
|
4
5
|
import window from 'global/window';
|
|
5
6
|
|
|
6
7
|
// Default options for the plugin.
|
|
@@ -9,7 +10,9 @@ const defaults = {
|
|
|
9
10
|
enterOnRotate: true,
|
|
10
11
|
exitOnRotate: true,
|
|
11
12
|
lockOnRotate: true,
|
|
12
|
-
|
|
13
|
+
lockToLandscapeOnEnter: false,
|
|
14
|
+
swipeToFullscreen: false,
|
|
15
|
+
swipeFromFullscreen: false,
|
|
13
16
|
disabled: false
|
|
14
17
|
},
|
|
15
18
|
touchControls: {
|
|
@@ -21,6 +24,7 @@ const defaults = {
|
|
|
21
24
|
};
|
|
22
25
|
|
|
23
26
|
const screen = window.screen;
|
|
27
|
+
const registerPlugin = videojs.registerPlugin || videojs.plugin;
|
|
24
28
|
|
|
25
29
|
/**
|
|
26
30
|
* Gets 'portrait' or 'lanscape' from the two orientation APIs
|
|
@@ -48,9 +52,6 @@ const getOrientation = () => {
|
|
|
48
52
|
return 'portrait';
|
|
49
53
|
};
|
|
50
54
|
|
|
51
|
-
// Cross-compatibility for Video.js 5 and 6.
|
|
52
|
-
const registerPlugin = videojs.registerPlugin || videojs.plugin;
|
|
53
|
-
|
|
54
55
|
/**
|
|
55
56
|
* Add UI and event listeners
|
|
56
57
|
*
|
|
@@ -58,23 +59,12 @@ const registerPlugin = videojs.registerPlugin || videojs.plugin;
|
|
|
58
59
|
* @param {Player} player
|
|
59
60
|
* A Video.js player object.
|
|
60
61
|
*
|
|
61
|
-
* @param {
|
|
62
|
+
* @param {MobileUiOptions} [options={}]
|
|
62
63
|
* A plain object containing options for the plugin.
|
|
63
64
|
*/
|
|
64
65
|
const onPlayerReady = (player, options) => {
|
|
65
66
|
player.addClass('vjs-mobile-ui');
|
|
66
67
|
|
|
67
|
-
if (options.fullscreen.iOS) {
|
|
68
|
-
videojs.log.warn('videojs-mobile-ui: `fullscreen.iOS` is deprecated. Use Video.js option `preferFullWindow` instead.');
|
|
69
|
-
if (videojs.browser.IS_IOS && videojs.browser.IOS_VERSION > 9 &&
|
|
70
|
-
!player.el_.ownerDocument.querySelector('.bc-iframe')) {
|
|
71
|
-
player.tech_.el_.setAttribute('playsinline', 'playsinline');
|
|
72
|
-
player.tech_.supportsFullScreen = function() {
|
|
73
|
-
return false;
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
68
|
if (!options.touchControls.disabled) {
|
|
79
69
|
|
|
80
70
|
if (options.touchControls.disableOnEnd || typeof player.endscreen === 'function') {
|
|
@@ -104,20 +94,26 @@ const onPlayerReady = (player, options) => {
|
|
|
104
94
|
return;
|
|
105
95
|
}
|
|
106
96
|
|
|
97
|
+
if (options.fullscreen.swipeToFullscreen || options.fullscreen.swipeFromFullscreen) {
|
|
98
|
+
initSwipe(player, options);
|
|
99
|
+
}
|
|
100
|
+
|
|
107
101
|
let locked = false;
|
|
108
102
|
|
|
109
103
|
const rotationHandler = () => {
|
|
110
104
|
const currentOrientation = getOrientation();
|
|
111
105
|
|
|
112
106
|
if (currentOrientation === 'landscape' && options.fullscreen.enterOnRotate) {
|
|
113
|
-
if (player.paused()
|
|
114
|
-
player.requestFullscreen()
|
|
115
|
-
|
|
107
|
+
if (!player.paused() && !player.isFullscreen()) {
|
|
108
|
+
player.requestFullscreen().catch((err) => {
|
|
109
|
+
player.log.warn('Browser refused fullscreen request:', err);
|
|
110
|
+
});
|
|
111
|
+
if ((options.fullscreen.lockOnRotate || options.fullscreen.lockToLandscapeOnEnter) &&
|
|
116
112
|
screen.orientation && screen.orientation.lock) {
|
|
117
113
|
screen.orientation.lock('landscape').then(() => {
|
|
118
114
|
locked = true;
|
|
119
|
-
}).catch((
|
|
120
|
-
videojs.log('Browser refused orientation lock:',
|
|
115
|
+
}).catch((err) => {
|
|
116
|
+
videojs.log.warn('Browser refused orientation lock:', err);
|
|
121
117
|
});
|
|
122
118
|
}
|
|
123
119
|
}
|
|
@@ -143,15 +139,21 @@ const onPlayerReady = (player, options) => {
|
|
|
143
139
|
screen.orientation.onchange = null;
|
|
144
140
|
});
|
|
145
141
|
}
|
|
146
|
-
|
|
147
|
-
player.on('fullscreenchange', _ => {
|
|
148
|
-
if (!player.isFullscreen() && locked) {
|
|
149
|
-
screen.orientation.unlock();
|
|
150
|
-
locked = false;
|
|
151
|
-
}
|
|
152
|
-
});
|
|
153
142
|
}
|
|
154
143
|
|
|
144
|
+
player.on('fullscreenchange', _ => {
|
|
145
|
+
if (player.isFullscreen() && options.fullscreen.lockToLandscapeOnEnter && getOrientation() === 'portrait') {
|
|
146
|
+
screen.orientation.lock('landscape').then(()=>{
|
|
147
|
+
locked = true;
|
|
148
|
+
}).catch((e) => {
|
|
149
|
+
videojs.log('Browser refused orientation lock:', e);
|
|
150
|
+
});
|
|
151
|
+
} else if (!player.isFullscreen() && locked) {
|
|
152
|
+
screen.orientation.unlock();
|
|
153
|
+
locked = false;
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
|
|
155
157
|
player.on('ended', _ => {
|
|
156
158
|
if (locked === true) {
|
|
157
159
|
screen.orientation.unlock();
|
|
@@ -161,39 +163,10 @@ const onPlayerReady = (player, options) => {
|
|
|
161
163
|
};
|
|
162
164
|
|
|
163
165
|
/**
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
* Adds a monile UI for player control, and fullscreen orientation control
|
|
166
|
+
* Adds a mobile UI for player control, and fullscreen orientation control
|
|
167
167
|
*
|
|
168
168
|
* @function mobileUi
|
|
169
|
-
* @param {Object} [options={}]
|
|
170
|
-
* Plugin options.
|
|
171
|
-
* @param {boolean} [options.forceForTesting=false]
|
|
172
|
-
* Enables the display regardless of user agent, for testing purposes
|
|
173
|
-
* @param {Object} [options.fullscreen={}]
|
|
174
|
-
* Fullscreen options.
|
|
175
|
-
* @param {boolean} [options.fullscreen.disabled=false]
|
|
176
|
-
* If true no fullscreen handling except the *deprecated* iOS fullwindow hack
|
|
177
|
-
* @param {boolean} [options.fullscreen.enterOnRotate=true]
|
|
178
|
-
* Whether to go fullscreen when rotating to landscape
|
|
179
|
-
* @param {boolean} [options.fullscreen.exitOnRotate=true]
|
|
180
|
-
* Whether to leave fullscreen when rotating to portrait (if not locked)
|
|
181
|
-
* @param {boolean} [options.fullscreen.lockOnRotate=true]
|
|
182
|
-
* Whether to lock orientation when rotating to landscape
|
|
183
|
-
* Unlocked when exiting fullscreen or on 'ended'
|
|
184
|
-
* @param {boolean} [options.fullscreen.iOS=false]
|
|
185
|
-
* Deprecated: Whether to disable iOS's native fullscreen so controls can work
|
|
186
|
-
* @param {Object} [options.touchControls={}]
|
|
187
|
-
* Touch UI options.
|
|
188
|
-
* @param {boolean} [options.touchControls.disabled=false]
|
|
189
|
-
* If true no touch controls are added.
|
|
190
|
-
* @param {int} [options.touchControls.seekSeconds=10]
|
|
191
|
-
* Number of seconds to seek on double-tap
|
|
192
|
-
* @param {int} [options.touchControls.tapTimeout=300]
|
|
193
|
-
* Interval in ms to be considered a doubletap
|
|
194
|
-
* @param {boolean} [options.touchControls.disableOnEnd=false]
|
|
195
|
-
* Whether to disable when the video ends (e.g., if there is an endscreen)
|
|
196
|
-
* Never shows if the endscreen plugin is present
|
|
169
|
+
* @param {Object} [options={}] Plugin options
|
|
197
170
|
*/
|
|
198
171
|
const mobileUi = function(options = {}) {
|
|
199
172
|
if (options.forceForTesting || videojs.browser.IS_ANDROID || videojs.browser.IS_IOS) {
|