aboutsummaryrefslogtreecommitdiffstats
path: root/src/js
diff options
context:
space:
mode:
authorSam Potts <sam@potts.es>2019-01-29 21:33:16 +1100
committerSam Potts <sam@potts.es>2019-01-29 21:33:16 +1100
commitfa4868a26da7f433df98fff97f8d0acb7e33ce4a (patch)
tree78da59e6894704893cc70fb6af4608b6bf84650c /src/js
parent6bf6c3f0f482f59cb1a40c90cf5f859a5b0d11b8 (diff)
downloadplyr-fa4868a26da7f433df98fff97f8d0acb7e33ce4a.tar.lz
plyr-fa4868a26da7f433df98fff97f8d0acb7e33ce4a.tar.xz
plyr-fa4868a26da7f433df98fff97f8d0acb7e33ce4a.zip
Fix listeners for preview thumbs when changing source
Diffstat (limited to 'src/js')
-rw-r--r--src/js/listeners.js36
-rw-r--r--src/js/plugins/previewThumbnails.js169
-rw-r--r--src/js/source.js7
3 files changed, 131 insertions, 81 deletions
diff --git a/src/js/listeners.js b/src/js/listeners.js
index ae9277a5..68a83d0b 100644
--- a/src/js/listeners.js
+++ b/src/js/listeners.js
@@ -740,6 +740,42 @@ class Listeners {
controls.updateSeekTooltip.call(player, event),
);
+ // Preview thumbnails plugin
+ // TODO: Really need to work on some sort of plug-in wide event bus or pub-sub for this
+ this.bind(elements.progress, 'mousemove touchmove', event => {
+ const { previewThumbnails } = player;
+
+ if (previewThumbnails && previewThumbnails.loaded) {
+ previewThumbnails.startMove(event);
+ }
+ });
+
+ // Hide thumbnail preview - on mouse click, mouse leave, and video play/seek. All four are required, e.g., for buffering
+ this.bind(elements.progress, 'mouseleave click', () => {
+ const { previewThumbnails } = player;
+
+ if (previewThumbnails && previewThumbnails.loaded) {
+ previewThumbnails.endMove(false, true);
+ }
+ });
+
+ // Show scrubbing preview
+ this.bind(elements.progress, 'mousedown touchstart', event => {
+ const { previewThumbnails } = player;
+
+ if (previewThumbnails && previewThumbnails.loaded) {
+ previewThumbnails.startScrubbing(event);
+ }
+ });
+
+ this.bind(elements.progress, 'mouseup touchend', event => {
+ const { previewThumbnails } = player;
+
+ if (previewThumbnails && previewThumbnails.loaded) {
+ previewThumbnails.endScrubbing(event);
+ }
+ });
+
// Polyfill for lower fill in <input type="range"> for webkit
if (browser.isWebkit) {
Array.from(getElements.call(player, 'input[type="range"]')).forEach(element => {
diff --git a/src/js/plugins/previewThumbnails.js b/src/js/plugins/previewThumbnails.js
index 2bb9cedc..6f6b87f5 100644
--- a/src/js/plugins/previewThumbnails.js
+++ b/src/js/plugins/previewThumbnails.js
@@ -1,5 +1,5 @@
import { createElement } from '../utils/elements';
-import { on, once } from '../utils/events';
+import { once } from '../utils/events';
import fetch from '../utils/fetch';
import is from '../utils/is';
import { formatTime } from '../utils/time';
@@ -72,7 +72,8 @@ class PreviewThumbnails {
constructor(player) {
this.player = player;
this.thumbnails = [];
- this.lastMousemoveEventTime = Date.now();
+ this.loaded = false;
+ this.lastMouseMoveTime = Date.now();
this.mouseDown = false;
this.loadedImages = [];
@@ -81,9 +82,7 @@ class PreviewThumbnails {
scrubbing: {},
};
- if (this.enabled) {
- this.load();
- }
+ this.load();
}
get enabled() {
@@ -91,18 +90,23 @@ class PreviewThumbnails {
}
load() {
- // Turn off the regular seek tooltip
- this.player.config.tooltips.seek = false;
+ // Togglethe regular seek tooltip
+ if (this.player.elements.display.seekTooltip) {
+ this.player.elements.display.seekTooltip.hidden = this.enabled;
+ }
- this.getThumbnails().then(() => {
- // Initiate DOM listeners so that our preview thumbnails can be used
- this.listeners();
+ if (!this.enabled) {
+ return;
+ }
+ this.getThumbnails().then(() => {
// Render DOM elements
this.render();
// Check to see if thumb container size was specified manually in CSS
this.determineContainerAutoSizing();
+
+ this.loaded = true;
});
}
@@ -165,96 +169,101 @@ class PreviewThumbnails {
});
}
- /**
- * Setup hooks for Plyr and window events
- */
- listeners() {
- // Mouse hover over seek bar
- on.call(this.player, this.player.elements.progress, 'mousemove', event => {
- // Wait until media has a duration
- if (this.player.media.duration) {
- // Calculate seek hover position as approx video seconds
- const clientRect = this.player.elements.progress.getBoundingClientRect();
- const percentage = (100 / clientRect.width) * (event.pageX - clientRect.left);
- this.seekTime = this.player.media.duration * (percentage / 100);
-
- if (this.seekTime < 0) {
- // The mousemove fires for 10+px out to the left
- this.seekTime = 0;
- }
+ startMove(event) {
+ if (!this.loaded) {
+ return;
+ }
- if (this.seekTime > this.player.media.duration - 1) {
- // Took 1 second off the duration for safety, because different players can disagree on the real duration of a video
- this.seekTime = this.player.media.duration - 1;
- }
+ if (!is.event(event) || !['touchmove', 'mousemove'].includes(event.type)) {
+ return;
+ }
- this.mousePosX = event.pageX;
+ // Wait until media has a duration
+ if (!this.player.media.duration) {
+ return;
+ }
- // Set time text inside image container
- this.elements.thumb.time.innerText = formatTime(this.seekTime);
+ if (event.type === 'touchmove') {
+ // Calculate seek hover position as approx video seconds
+ this.seekTime = this.player.media.duration * (this.player.elements.inputs.seek.value / 100);
+ } else {
+ // Calculate seek hover position as approx video seconds
+ const clientRect = this.player.elements.progress.getBoundingClientRect();
+ const percentage = (100 / clientRect.width) * (event.pageX - clientRect.left);
+ this.seekTime = this.player.media.duration * (percentage / 100);
+
+ if (this.seekTime < 0) {
+ // The mousemove fires for 10+px out to the left
+ this.seekTime = 0;
+ }
- // Download and show image
- this.showImageAtCurrentTime();
+ if (this.seekTime > this.player.media.duration - 1) {
+ // Took 1 second off the duration for safety, because different players can disagree on the real duration of a video
+ this.seekTime = this.player.media.duration - 1;
}
- });
- // Touch device seeking - performs same function as above
- on.call(this.player, this.player.elements.progress, 'touchmove', () => {
+ this.mousePosX = event.pageX;
+
+ // Set time text inside image container
+ this.elements.thumb.time.innerText = formatTime(this.seekTime);
+ }
+
+ // Download and show image
+ this.showImageAtCurrentTime();
+ }
+
+ endMove() {
+ this.toggleThumbContainer(false, true);
+ }
+
+ startScrubbing(event) {
+ // Only act on left mouse button (0), or touch device (event.button is false)
+ if (event.button === false || event.button === 0) {
+ this.mouseDown = true;
// Wait until media has a duration
if (this.player.media.duration) {
- // Calculate seek hover position as approx video seconds
- this.seekTime = this.player.media.duration * (this.player.elements.inputs.seek.value / 100);
+ this.toggleScrubbingContainer(true);
+ this.toggleThumbContainer(false, true);
// Download and show image
this.showImageAtCurrentTime();
}
- });
+ }
+ }
- // Hide thumbnail preview - on mouse click, mouse leave, and video play/seek. All four are required, e.g., for buffering
- on.call(this.player, this.player.elements.progress, 'mouseleave click', () => {
- this.toggleThumbContainer(false, true);
- });
+ finishScrubbing() {
+ this.mouseDown = false;
+
+ // Hide scrubbing preview. But wait until the video has successfully seeked before hiding the scrubbing preview
+ if (Math.ceil(this.lastTime) === Math.ceil(this.player.media.currentTime)) {
+ // The video was already seeked/loaded at the chosen time - hide immediately
+ this.toggleScrubbingContainer(false);
+ } else {
+ // The video hasn't seeked yet. Wait for that
+ once.call(this.player, this.player.media, 'timeupdate', () => {
+ // Re-check mousedown - we might have already started scrubbing again
+ if (!this.mouseDown) {
+ this.toggleScrubbingContainer(false);
+ }
+ });
+ }
+ }
+
+ /**
+ * Setup hooks for Plyr and window events
+ */
+ listeners() {
+ // Hide thumbnail preview - on mouse click, mouse leave (in listeners.js for now), and video play/seek. All four are required, e.g., for buffering
this.player.on('play', () => {
this.toggleThumbContainer(false, true);
});
+
this.player.on('seeked', () => {
this.toggleThumbContainer(false);
});
- // Show scrubbing preview
- on.call(this.player, this.player.elements.progress, 'mousedown touchstart', event => {
- // Only act on left mouse button (0), or touch device (event.button is false)
- if (event.button === false || event.button === 0) {
- this.mouseDown = true;
- // Wait until media has a duration
- if (this.player.media.duration) {
- this.toggleScrubbingContainer(true);
- this.toggleThumbContainer(false, true);
-
- // Download and show image
- this.showImageAtCurrentTime();
- }
- }
- });
- on.call(this.player, this.player.media, 'timeupdate', () => {
- this.timeAtLastTimeupdate = this.player.media.currentTime;
- });
- on.call(this.player, this.player.elements.progress, 'mouseup touchend', () => {
- this.mouseDown = false;
-
- // Hide scrubbing preview. But wait until the video has successfully seeked before hiding the scrubbing preview
- if (Math.ceil(this.timeAtLastTimeupdate) === Math.ceil(this.player.media.currentTime)) {
- // The video was already seeked/loaded at the chosen time - hide immediately
- this.toggleScrubbingContainer(false);
- } else {
- // The video hasn't seeked yet. Wait for that
- once.call(this.player, this.player.media, 'timeupdate', () => {
- // Re-check mousedown - we might have already started scrubbing again
- if (!this.mouseDown) {
- this.toggleScrubbingContainer(false);
- }
- });
- }
+ this.player.on('timeupdate', () => {
+ this.lastTime = this.player.media.currentTime;
});
}
diff --git a/src/js/source.js b/src/js/source.js
index 337c949c..0173cc9e 100644
--- a/src/js/source.js
+++ b/src/js/source.js
@@ -125,11 +125,16 @@ const source = {
ui.build.call(this);
}
+ // Load HTML5 sources
if (this.isHTML5) {
- // Load HTML5 sources
this.media.load();
}
+ // Reload thumbnails
+ if (this.previewThumbnails) {
+ this.previewThumbnails.load();
+ }
+
// Update the fullscreen support
this.fullscreen.update();
},