videojs-mobile-ui 1.2.0-alpha.0 → 1.2.1
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 +104 -53
- package/dist/lang/de.js +1 -3
- package/dist/lang/en.js +1 -3
- package/dist/lang/it.js +1 -3
- package/dist/videojs-mobile-ui.cjs.js +195 -43
- package/dist/videojs-mobile-ui.css +104 -2
- package/dist/videojs-mobile-ui.es.js +195 -43
- package/dist/videojs-mobile-ui.js +204 -53
- 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 +238 -170
- package/package.json +23 -13
- package/scripts/lang.js +24 -0
- package/scripts/netlify.js +16 -0
- package/scripts/postcss.config.js +29 -5
- package/scripts/readme-options.js +370 -0
- package/scripts/rollup.config.js +0 -8
- package/src/plugin.css +6 -0
- package/src/plugin.js +65 -39
- package/src/swipeFullscreen.js +122 -0
- package/src/touchOverlay.js +7 -3
- package/test/plugin.test.js +125 -18
- package/test/swipeFullscreen.test.js +365 -0
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<title>JSDoc: Source: swipeFullscreen.js</title>
|
|
6
|
+
|
|
7
|
+
<script src="scripts/prettify/prettify.js"> </script>
|
|
8
|
+
<script src="scripts/prettify/lang-css.js"> </script>
|
|
9
|
+
<!--[if lt IE 9]>
|
|
10
|
+
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
|
|
11
|
+
<![endif]-->
|
|
12
|
+
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
|
|
13
|
+
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
|
|
14
|
+
</head>
|
|
15
|
+
|
|
16
|
+
<body>
|
|
17
|
+
|
|
18
|
+
<div id="main">
|
|
19
|
+
|
|
20
|
+
<h1 class="page-title">Source: swipeFullscreen.js</h1>
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
<section>
|
|
28
|
+
<article>
|
|
29
|
+
<pre class="prettyprint source linenums"><code>/** @import Player from 'video.js/dist/types/player' */
|
|
30
|
+
/** @import Plugin from 'video.js/dist/types/plugin' */
|
|
31
|
+
/** @import {MobileUiOptions} from './plugin' */
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Sets up swiping to enter and exit fullscreen.
|
|
35
|
+
*
|
|
36
|
+
* @this {Plugin}
|
|
37
|
+
* @param {Player} player
|
|
38
|
+
* The player to initialise on.
|
|
39
|
+
* @param {MobileUiOptions} pluginOptions
|
|
40
|
+
* The options used by the mobile ui plugin.
|
|
41
|
+
*/
|
|
42
|
+
const initSwipe = (player, pluginOptions) => {
|
|
43
|
+
const {swipeToFullscreen, swipeFromFullscreen} = pluginOptions.fullscreen;
|
|
44
|
+
|
|
45
|
+
if (swipeToFullscreen) {
|
|
46
|
+
player.addClass('using-fs-swipe-up');
|
|
47
|
+
}
|
|
48
|
+
if (swipeFromFullscreen) {
|
|
49
|
+
player.addClass('using-fs-swipe-down');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
let touchStartY = 0;
|
|
53
|
+
let couldBeSwiping = false;
|
|
54
|
+
const swipeThreshold = 30;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Monitor the possible start of a swipe
|
|
58
|
+
*
|
|
59
|
+
* @param {TouchEvent} e Triggering touch event
|
|
60
|
+
*/
|
|
61
|
+
const onStart = (e) => {
|
|
62
|
+
const isFullscreen = player.isFullscreen();
|
|
63
|
+
|
|
64
|
+
if (
|
|
65
|
+
(!isFullscreen && !swipeToFullscreen) ||
|
|
66
|
+
(isFullscreen && !swipeFromFullscreen)
|
|
67
|
+
) {
|
|
68
|
+
couldBeSwiping = false;
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
touchStartY = e.changedTouches[0].clientY;
|
|
73
|
+
couldBeSwiping = true;
|
|
74
|
+
player.tech_.el().style.transition = '';
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Monitor the movement of a swipe
|
|
79
|
+
*
|
|
80
|
+
* @param {TouchEvent} e Triggering touch event
|
|
81
|
+
*/
|
|
82
|
+
const onMove = (e) => {
|
|
83
|
+
if (!couldBeSwiping) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const currentY = e.touches[0].clientY;
|
|
88
|
+
const deltaY = touchStartY - currentY;
|
|
89
|
+
const isFullscreen = player.isFullscreen();
|
|
90
|
+
|
|
91
|
+
let scale = 1;
|
|
92
|
+
|
|
93
|
+
if (!isFullscreen && deltaY > 0) {
|
|
94
|
+
// Swiping up to enter fullscreen: Zoom in (Max 1.1)
|
|
95
|
+
scale = 1 + Math.min(0.1, deltaY / 500);
|
|
96
|
+
player.tech_.el().style.transform = `scale(${scale})`;
|
|
97
|
+
} else if (isFullscreen && deltaY < 0) {
|
|
98
|
+
// Swiping down to exit fullscreen: Zoom out (Min 0.9)
|
|
99
|
+
scale = 1 - Math.min(0.1, Math.abs(deltaY) / 500);
|
|
100
|
+
player.tech_.el().style.transform = `scale(${scale})`;
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Monitor the touch end to determine a valid swipe
|
|
106
|
+
*
|
|
107
|
+
* @param {TouchEvent} e Triggering touch event
|
|
108
|
+
*/
|
|
109
|
+
const onEnd = (e) => {
|
|
110
|
+
if (!couldBeSwiping) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
couldBeSwiping = false;
|
|
114
|
+
|
|
115
|
+
player.tech_.el().style.transition = 'transform 0.3s ease-out';
|
|
116
|
+
player.tech_.el().style.transform = 'scale(1)';
|
|
117
|
+
|
|
118
|
+
if (e.type === 'touchcancel') {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const touchEndY = e.changedTouches[0].clientY;
|
|
123
|
+
const deltaY = touchStartY - touchEndY;
|
|
124
|
+
|
|
125
|
+
if (deltaY > swipeThreshold && !player.isFullscreen()) {
|
|
126
|
+
player.requestFullscreen().catch((err) => {
|
|
127
|
+
player.log.warn('Browser refused fullscreen', err);
|
|
128
|
+
});
|
|
129
|
+
} else if (deltaY < -swipeThreshold && player.isFullscreen()) {
|
|
130
|
+
player.exitFullscreen();
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
player.el().addEventListener('touchstart', onStart, { passive: true });
|
|
135
|
+
player.el().addEventListener('touchmove', onMove, { passive: true });
|
|
136
|
+
player.el().addEventListener('touchend', onEnd, { passive: true });
|
|
137
|
+
player.el().addEventListener('touchcancel', onEnd, { passive: true });
|
|
138
|
+
|
|
139
|
+
player.on('dispose', () => {
|
|
140
|
+
player.el().removeEventListener('touchstart', onStart, { passive: true });
|
|
141
|
+
player.el().removeEventListener('touchmove', onMove, { passive: true });
|
|
142
|
+
player.el().removeEventListener('touchend', onEnd, { passive: true });
|
|
143
|
+
player.el().removeEventListener('touchcancel', onEnd, { passive: true });
|
|
144
|
+
player.tech_.el().style.transform = '';
|
|
145
|
+
player.tech_.el().style.transition = '';
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
export default initSwipe;
|
|
151
|
+
</code></pre>
|
|
152
|
+
</article>
|
|
153
|
+
</section>
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
</div>
|
|
159
|
+
|
|
160
|
+
<nav>
|
|
161
|
+
<h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="TouchOverlay.html">TouchOverlay</a></li></ul><h3>Global</h3><ul><li><a href="global.html#Component">Component</a></li><li><a href="global.html#defaults">defaults</a></li><li><a href="global.html#getOrientation">getOrientation</a></li><li><a href="global.html#initSwipe">initSwipe</a></li><li><a href="global.html#mobileUi">mobileUi</a></li><li><a href="global.html#onPlayerReady">onPlayerReady</a></li></ul>
|
|
162
|
+
</nav>
|
|
163
|
+
|
|
164
|
+
<br class="clear">
|
|
165
|
+
|
|
166
|
+
<footer>
|
|
167
|
+
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.5</a> on Fri Jan 23 2026 14:03:20 GMT+0100 (Mitteleuropäische Normalzeit)
|
|
168
|
+
</footer>
|
|
169
|
+
|
|
170
|
+
<script> prettyPrint(); </script>
|
|
171
|
+
<script src="scripts/linenumber.js"> </script>
|
|
172
|
+
</body>
|
|
173
|
+
</html>
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<title>JSDoc: Source: touchOverlay.js</title>
|
|
6
|
+
|
|
7
|
+
<script src="scripts/prettify/prettify.js"> </script>
|
|
8
|
+
<script src="scripts/prettify/lang-css.js"> </script>
|
|
9
|
+
<!--[if lt IE 9]>
|
|
10
|
+
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
|
|
11
|
+
<![endif]-->
|
|
12
|
+
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
|
|
13
|
+
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
|
|
14
|
+
</head>
|
|
15
|
+
|
|
16
|
+
<body>
|
|
17
|
+
|
|
18
|
+
<div id="main">
|
|
19
|
+
|
|
20
|
+
<h1 class="page-title">Source: touchOverlay.js</h1>
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
<section>
|
|
28
|
+
<article>
|
|
29
|
+
<pre class="prettyprint source linenums"><code>/**
|
|
30
|
+
* @file touchOverlay.js
|
|
31
|
+
* Touch UI component
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
import videojs from 'video.js';
|
|
35
|
+
import window from 'global/window';
|
|
36
|
+
|
|
37
|
+
const Component = videojs.getComponent('Component');
|
|
38
|
+
const dom = videojs.dom || videojs;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* The `TouchOverlay` is an overlay to capture tap events.
|
|
42
|
+
*
|
|
43
|
+
* @extends Component
|
|
44
|
+
*/
|
|
45
|
+
class TouchOverlay extends Component {
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Creates an instance of the this class.
|
|
49
|
+
*
|
|
50
|
+
* @param {Player} player
|
|
51
|
+
* The `Player` that this class should be attached to.
|
|
52
|
+
*
|
|
53
|
+
* @param {Object} [options]
|
|
54
|
+
* The key/value store of player options.
|
|
55
|
+
*/
|
|
56
|
+
constructor(player, options) {
|
|
57
|
+
super(player, options);
|
|
58
|
+
|
|
59
|
+
this.seekSeconds = options.seekSeconds;
|
|
60
|
+
this.tapTimeout = options.tapTimeout;
|
|
61
|
+
|
|
62
|
+
// Add play toggle overlay
|
|
63
|
+
this.addChild('playToggle', {});
|
|
64
|
+
|
|
65
|
+
// Clear overlay when playback starts or with control fade
|
|
66
|
+
player.on(['playing', 'userinactive'], e => {
|
|
67
|
+
this.removeClass('show-play-toggle');
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// A 0 inactivity timeout won't work here
|
|
71
|
+
if (this.player_.options_.inactivityTimeout === 0) {
|
|
72
|
+
this.player_.options_.inactivityTimeout = 5000;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
this.enable();
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Builds the DOM element.
|
|
80
|
+
*
|
|
81
|
+
* @return {Element}
|
|
82
|
+
* The DOM element.
|
|
83
|
+
*/
|
|
84
|
+
createEl() {
|
|
85
|
+
const el = dom.createEl('div', {
|
|
86
|
+
className: 'vjs-touch-overlay',
|
|
87
|
+
// Touch overlay is not tabbable.
|
|
88
|
+
tabIndex: -1
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
return el;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Debounces to either handle a delayed single tap, or a double tap
|
|
96
|
+
*
|
|
97
|
+
* @param {Event} event
|
|
98
|
+
* The touch event
|
|
99
|
+
*
|
|
100
|
+
*/
|
|
101
|
+
handleTap(event) {
|
|
102
|
+
// Don't handle taps on the play button
|
|
103
|
+
if (event.target !== this.el_) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
event.preventDefault();
|
|
108
|
+
|
|
109
|
+
if (this.firstTapCaptured) {
|
|
110
|
+
this.firstTapCaptured = false;
|
|
111
|
+
if (this.timeout) {
|
|
112
|
+
window.clearTimeout(this.timeout);
|
|
113
|
+
}
|
|
114
|
+
this.handleDoubleTap(event);
|
|
115
|
+
} else {
|
|
116
|
+
this.firstTapCaptured = true;
|
|
117
|
+
this.timeout = window.setTimeout(() => {
|
|
118
|
+
this.firstTapCaptured = false;
|
|
119
|
+
this.handleSingleTap(event);
|
|
120
|
+
}, this.tapTimeout);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Toggles display of play toggle
|
|
126
|
+
*
|
|
127
|
+
* @param {Event} event
|
|
128
|
+
* The touch event
|
|
129
|
+
*
|
|
130
|
+
*/
|
|
131
|
+
handleSingleTap(event) {
|
|
132
|
+
this.removeClass('skip');
|
|
133
|
+
this.toggleClass('show-play-toggle');
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Seeks by configured number of seconds if left or right part of video double tapped
|
|
138
|
+
*
|
|
139
|
+
* @param {Event} event
|
|
140
|
+
* The touch event
|
|
141
|
+
*
|
|
142
|
+
*/
|
|
143
|
+
handleDoubleTap(event) {
|
|
144
|
+
const rect = this.el_.getBoundingClientRect();
|
|
145
|
+
const x = event.changedTouches[0].clientX - rect.left;
|
|
146
|
+
|
|
147
|
+
// Check if double tap is in left or right area
|
|
148
|
+
if (x < rect.width * 0.4) {
|
|
149
|
+
this.player_.currentTime(Math.max(
|
|
150
|
+
0, this.player_.currentTime() - this.seekSeconds));
|
|
151
|
+
this.addClass('reverse');
|
|
152
|
+
} else if (x > rect.width - (rect.width * 0.4)) {
|
|
153
|
+
this.player_.currentTime(Math.min(
|
|
154
|
+
this.player_.duration(), this.player_.currentTime() + this.seekSeconds));
|
|
155
|
+
this.removeClass('reverse');
|
|
156
|
+
} else {
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Remove play toggle if showing
|
|
161
|
+
this.removeClass('show-play-toggle');
|
|
162
|
+
|
|
163
|
+
// Remove and readd class to trigger animation
|
|
164
|
+
this.removeClass('skip');
|
|
165
|
+
window.requestAnimationFrame(() => {
|
|
166
|
+
this.addClass('skip');
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Enables touch handler
|
|
172
|
+
*/
|
|
173
|
+
enable() {
|
|
174
|
+
this.firstTapCaptured = false;
|
|
175
|
+
this.on('touchend', this.handleTap);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Disables touch handler
|
|
180
|
+
*/
|
|
181
|
+
disable() {
|
|
182
|
+
this.off('touchend', this.handleTap);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
Component.registerComponent('TouchOverlay', TouchOverlay);
|
|
188
|
+
export default TouchOverlay;
|
|
189
|
+
</code></pre>
|
|
190
|
+
</article>
|
|
191
|
+
</section>
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
</div>
|
|
197
|
+
|
|
198
|
+
<nav>
|
|
199
|
+
<h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="TouchOverlay.html">TouchOverlay</a></li></ul><h3>Global</h3><ul><li><a href="global.html#mobileUi">mobileUi</a></li><li><a href="global.html#onPlayerReady">onPlayerReady</a></li></ul>
|
|
200
|
+
</nav>
|
|
201
|
+
|
|
202
|
+
<br class="clear">
|
|
203
|
+
|
|
204
|
+
<footer>
|
|
205
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Tue Feb 02 2021 09:43:56 GMT+0100 (CET)
|
|
206
|
+
</footer>
|
|
207
|
+
|
|
208
|
+
<script> prettyPrint(); </script>
|
|
209
|
+
<script src="scripts/linenumber.js"> </script>
|
|
210
|
+
</body>
|
|
211
|
+
</html>
|