diff options
Diffstat (limited to 'src/js')
-rw-r--r-- | src/js/plyr.js | 195 |
1 files changed, 120 insertions, 75 deletions
diff --git a/src/js/plyr.js b/src/js/plyr.js index 3d78c58c..5c9e329e 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -39,8 +39,9 @@ duration: null, displayDuration: true, iconPrefix: 'icon', - click: true, - tooltips: { + clickToPlay: true, + hideControls: true, + tooltips: { controls: false, seek: true }, @@ -83,6 +84,7 @@ hover: 'plyr--hover', tooltip: 'plyr__tooltip', hidden: 'plyr__sr-only', + hideControls: 'plyr--hide-controls', isIos: 'plyr--is-ios', isTouch: 'plyr--is-touch', captions: { @@ -91,8 +93,7 @@ }, fullscreen: { enabled: 'plyr--fullscreen-enabled', - active: 'plyr--fullscreen-active', - hideControls: 'plyr--fullscreen--hide-controls' + active: 'plyr--fullscreen-active' }, tabFocus: 'tab-focus' }, @@ -102,14 +103,13 @@ fullscreen: { enabled: true, fallback: true, - hideControls: true, allowAudio: false }, storage: { enabled: true, key: 'plyr' }, - controls: ['restart', 'rewind', 'play', 'fast-forward', 'current-time', 'duration', 'mute', 'volume', 'captions', 'fullscreen'], + controls: ['play-large', 'play', 'progress', 'current-time', 'mute', 'volume', 'captions', 'fullscreen'], i18n: { restart: 'Restart', rewind: 'Rewind {seektime} secs', @@ -390,6 +390,30 @@ return false; } + // Debounce + // deBouncer by hnldesign.nl + // based on code by Paul Irish and the original debouncing function from John Hann + // http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/ + function _debounce(func, threshold, execAsap) { + var timeout; + return function debounced () { + var obj = this, args = arguments; + function delayed () { + if (!execAsap) { + func.apply(obj, args); + } + timeout = null; + } + if (timeout) { + clearTimeout(timeout); + } + else if (execAsap) { + func.apply(obj, args); + } + timeout = setTimeout(delayed, threshold || 100); + }; + } + // Bind event function _on(element, events, callback) { if (element) { @@ -634,27 +658,20 @@ // Build the default HTML function _buildControls() { - // Open and add the progress and seek elements - var html = [ - '<div class="plyr__controls">', - '<div class="plyr__progress">', - '<label for="seek{id}" class="plyr__sr-only">Seek</label>', - '<input id="seek{id}" class="plyr__progress--seek" type="range" min="0" max="100" step="0.1" value="0" data-plyr="seek">', - '<progress class="plyr__progress--played" max="100" value="0">', - '<span>0</span>% ' + config.i18n.played, - '</progress>', - '<progress class="plyr__progress--buffer" max="100" value="0">', - '<span>0</span>% ' + config.i18n.buffered, - '</progress>']; + // Create html array + var html = []; - // Seek tooltip - if (config.tooltips.seek) { - html.push('<span class="plyr__tooltip">00:00</span>'); + // Larger overlaid play button + if (_inArray(config.controls, 'play-large')) { + html.push( + '<button type="button" data-plyr="play" class="plyr__play-large">', + '<svg><use xlink:href="#' + config.iconPrefix + '-play" /></svg>', + '<span class="plyr__sr-only">' + config.i18n.play + '</span>', + '</button>' + ); } - // Close progress - html.push('</div>', - '<span class="plyr__controls--left">'); + html.push('<div class="plyr__controls">'); // Restart button if (_inArray(config.controls, 'restart')) { @@ -676,7 +693,8 @@ ); } - // Play/pause button + // Play Pause button + // TODO: This should be a toggle button really? if (_inArray(config.controls, 'play')) { html.push( '<button type="button" data-plyr="play">', @@ -700,6 +718,28 @@ ); } + // Progress + if (_inArray(config.controls, 'progress')) { + // Create progress + html.push('<span class="plyr__progress">', + '<label for="seek{id}" class="plyr__sr-only">Seek</label>', + '<input id="seek{id}" class="plyr__progress--seek" type="range" min="0" max="100" step="0.1" value="0" data-plyr="seek">', + '<progress class="plyr__progress--played" max="100" value="0">', + '<span>0</span>% ' + config.i18n.played, + '</progress>', + '<progress class="plyr__progress--buffer" max="100" value="0">', + '<span>0</span>% ' + config.i18n.buffered, + '</progress>'); + + // Seek tooltip + if (config.tooltips.seek) { + html.push('<span class="plyr__tooltip">00:00</span>'); + } + + // Close + html.push('</span>'); + } + // Media current time display if (_inArray(config.controls, 'current-time')) { html.push( @@ -720,12 +760,6 @@ ); } - // Close left controls - html.push( - '</span>', - '<span class="plyr__controls--right">' - ); - // Toggle mute button if (_inArray(config.controls, 'mute')) { html.push( @@ -768,10 +802,7 @@ } // Close everything - html.push( - '</span>', - '</div>' - ); + html.push('</div>'); return html.join(''); } @@ -801,11 +832,6 @@ // Setup focus trap _focusTrap(); - - // Set control hide class hook - if (config.fullscreen.hideControls) { - _toggleClass(plyr.container, config.classes.fullscreen.hideControls, true); - } } } @@ -1171,7 +1197,7 @@ // Setup tooltips if (config.tooltips.controls) { - var labels = _getElements(config.selectors.labels + ' .' + config.classes.hidden); + var labels = _getElements([config.selectors.controls.wrapper, ' ', config.selectors.labels, ' .', config.classes.hidden].join('')); for (var i = labels.length - 1; i >= 0; i--) { var label = labels[i]; @@ -1190,7 +1216,7 @@ // Buttons plyr.buttons = {}; plyr.buttons.seek = _getElement(config.selectors.buttons.seek); - plyr.buttons.play = _getElement(config.selectors.buttons.play); + plyr.buttons.play = _getElements(config.selectors.buttons.play); plyr.buttons.pause = _getElement(config.selectors.buttons.pause); plyr.buttons.restart = _getElement(config.selectors.buttons.restart); plyr.buttons.rewind = _getElement(config.selectors.buttons.rewind); @@ -1234,7 +1260,7 @@ _log('It looks like there is a problem with your controls html', true); // Restore native video controls - _toggleControls(true); + _toggleNativeControls(true); return false; } @@ -1246,7 +1272,7 @@ } // Toggle native controls - function _toggleControls(toggle) { + function _toggleNativeControls(toggle) { if(toggle) { plyr.media.setAttribute('controls', ''); } @@ -1267,7 +1293,9 @@ // If there's a play button, set label if (plyr.supported.full && plyr.buttons.play) { - plyr.buttons.play.setAttribute('aria-label', label); + for (var i = plyr.buttons.play.length - 1; i >= 0; i--) { + plyr.buttons.play[i].setAttribute('aria-label', label); + } } // Set iframe title @@ -1755,6 +1783,8 @@ function _checkPlaying() { _toggleClass(plyr.container, config.classes.playing, !plyr.media.paused); _toggleClass(plyr.container, config.classes.stopped, plyr.media.paused); + + _toggleControls(plyr.media.paused); } // Toggle fullscreen @@ -1813,10 +1843,7 @@ _toggleState(plyr.buttons.fullscreen, plyr.isFullscreen); // Hide on entering full screen - if (config.fullscreen.hideControls) { - //_toggleClass(plyr.controls, config.classes.hover, false); - _showControls(true); - } + _toggleControls(false); // Trigger an event _triggerEvent(plyr.container, plyr.isFullscreen ? 'enterfullscreen' : 'exitfullscreen'); @@ -2151,24 +2178,44 @@ } // Show the player controls in fullscreen mode - function _showControls(force) { - // We're only worried about fullscreen - if (!plyr.isFullscreen) { + function _toggleControls(toggle) { + if (!config.hideControls) { return; } + var isMouseMove = false; + + // Default to false if no boolean + if(typeof toggle !== "boolean") { + if(toggle && toggle.type) { + isMouseMove = toggle.type === 'mousemove'; - // Set shown class - _toggleClass(plyr.container, config.classes.hover, true); + toggle = _inArray(['mousemove','mouseenter'], toggle.type); + } + else { + toggle = false; + } + } // Clear timer every movement window.clearTimeout(plyr.timers.hover); // If the mouse is not over the controls, set a timeout to hide them - plyr.timers.hover = window.setTimeout(function() { - if (!plyr.controls.mouseover || (force === true)) { - _toggleClass(plyr.container, config.classes.hover, false); - } - }, 2000); + if(toggle) { + _toggleClass(plyr.container, config.classes.hideControls, false); + } + + // If toggle is false or if we're playing (regardless of toggle), then + // set the timer to hide the controls + if(toggle === false || !plyr.media.paused) { + plyr.timers.hover = window.setTimeout(function() { + // If the mouse is over the controls, bail + if(plyr.controls.active) { + return; + } + + _toggleClass(plyr.container, config.classes.hideControls, true); + }, isMouseMove ? 2000 : 500); + } } // Add common function to retrieve media source @@ -2449,13 +2496,14 @@ // Seek tooltip _on(plyr.progress.container, 'mouseenter mouseleave mousemove', _updateSeekTooltip); - // Toggle controls visibility based on mouse movement and location - var hoverTimer, isMouseOver = false; + // Toggle controls visibility based on mouse movement + if (config.hideControls) { + _on(plyr.container, 'mouseenter mouseleave', _toggleControls); + _on(plyr.container, 'mousemove', _debounce(_toggleControls, 500, true)); - if (config.fullscreen.hideControls) { - // Keep an eye on the mouse location in relation to controls - _on(plyr.controls, 'mouseenter mouseleave', function(event) { - plyr.controls.mouseover = (event.type === 'mouseenter'); + // Watch for cursor over controls so they don't hide when trying to interact + _on(plyr.controls, 'mouseenter mouseleave', function(event) { + plyr.controls.active = (event.type === 'mouseenter'); }); } } @@ -2495,7 +2543,10 @@ _on(plyr.media, 'waiting canplay seeked', _checkLoading); // Click video - if (config.click) { + if (config.clickToPlay) { + // Set cursor + plyr.videoContainer.style.cursor = "pointer"; + _on(plyr.media, 'click', function() { if (plyr.media.paused) { _play(); @@ -2510,12 +2561,6 @@ }); } - // Listen for mouse move to show controls - if (config.fullscreen.hideControls) { - // Show the controls on mouse move - _on(plyr.media, 'mousemove', _showControls); - } - // Proxy events to container _on(plyr.media, config.events.join(' '), function(event) { _triggerEvent(plyr.container, event.type); @@ -2581,7 +2626,7 @@ } // Restore native video controls - _toggleControls(true); + _toggleNativeControls(true); // Clone the media element to remove listeners // http://stackoverflow.com/questions/19469881/javascript-remove-all-event-listeners-of-specific-type @@ -2679,7 +2724,7 @@ _remove(_getElement(config.selectors.controls.wrapper)); // Restore native controls - _toggleControls(true); + _toggleNativeControls(true); // Bail return; @@ -2706,7 +2751,7 @@ _mediaListeners(); // Remove native controls - _toggleControls(); + _toggleNativeControls(); // Setup fullscreen _setupFullscreen(); |