diff options
| author | Sam Potts <sam@potts.es> | 2019-01-29 21:33:16 +1100 | 
|---|---|---|
| committer | Sam Potts <sam@potts.es> | 2019-01-29 21:33:16 +1100 | 
| commit | fa4868a26da7f433df98fff97f8d0acb7e33ce4a (patch) | |
| tree | 78da59e6894704893cc70fb6af4608b6bf84650c /src | |
| parent | 6bf6c3f0f482f59cb1a40c90cf5f859a5b0d11b8 (diff) | |
| download | plyr-fa4868a26da7f433df98fff97f8d0acb7e33ce4a.tar.lz plyr-fa4868a26da7f433df98fff97f8d0acb7e33ce4a.tar.xz plyr-fa4868a26da7f433df98fff97f8d0acb7e33ce4a.zip | |
Fix listeners for preview thumbs when changing source
Diffstat (limited to 'src')
| -rw-r--r-- | src/js/listeners.js | 36 | ||||
| -rw-r--r-- | src/js/plugins/previewThumbnails.js | 169 | ||||
| -rw-r--r-- | src/js/source.js | 7 | 
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();              }, | 
