Add autoplay plugin
The autoplay plugin will automatically advance to the next slide after N seconds.
This commit is contained in:
159
src/plugins/autoplay/autoplay.js
Normal file
159
src/plugins/autoplay/autoplay.js
Normal file
@@ -0,0 +1,159 @@
|
||||
/**
|
||||
* Autoplay plugin - Automatically advance slideshow after N seconds
|
||||
*
|
||||
* Copyright 2016 Henrik Ingo, henrik.ingo@avoinelama.fi
|
||||
* Released under the MIT license.
|
||||
*/
|
||||
/* global clearTimeout, setTimeout, document */
|
||||
|
||||
( function( document ) {
|
||||
"use strict";
|
||||
|
||||
var autoplayDefault = 0;
|
||||
var currentStepTimeout = 0;
|
||||
var api = null;
|
||||
var timeoutHandle = null;
|
||||
var root = null;
|
||||
var util;
|
||||
|
||||
// On impress:init, check whether there is a default setting, as well as
|
||||
// handle step-1.
|
||||
document.addEventListener( "impress:init", function( event ) {
|
||||
util = event.detail.api.lib.util;
|
||||
|
||||
// Getting API from event data instead of global impress().init().
|
||||
// You don't even need to know what is the id of the root element
|
||||
// or anything. `impress:init` event data gives you everything you
|
||||
// need to control the presentation that was just initialized.
|
||||
api = event.detail.api;
|
||||
root = event.target;
|
||||
|
||||
// Element attributes starting with "data-", become available under
|
||||
// element.dataset. In addition hyphenized words become camelCased.
|
||||
var data = root.dataset;
|
||||
|
||||
if ( data.autoplay ) {
|
||||
autoplayDefault = util.toNumber( data.autoplay, 0 );
|
||||
}
|
||||
|
||||
var toolbar = document.querySelector( "#impress-toolbar" );
|
||||
if ( toolbar ) {
|
||||
addToolbarButton( toolbar );
|
||||
}
|
||||
|
||||
api.lib.gc.addCallback( function() {
|
||||
clearTimeout( timeoutHandle );
|
||||
} );
|
||||
|
||||
// Note that right after impress:init event, also impress:stepenter is
|
||||
// triggered for the first slide, so that's where code flow continues.
|
||||
}, false );
|
||||
|
||||
// If default autoplay time was defined in the presentation root, or
|
||||
// in this step, set timeout.
|
||||
var reloadTimeout = function( event ) {
|
||||
var step = event.target;
|
||||
currentStepTimeout = util.toNumber( step.dataset.autoplay, autoplayDefault );
|
||||
if ( status === "paused" ) {
|
||||
setAutoplayTimeout( 0 );
|
||||
} else {
|
||||
setAutoplayTimeout( currentStepTimeout );
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener( "impress:stepenter", function( event ) {
|
||||
reloadTimeout( event );
|
||||
}, false );
|
||||
|
||||
document.addEventListener( "impress:substep:stepleaveaborted", function( event ) {
|
||||
reloadTimeout( event );
|
||||
}, false );
|
||||
|
||||
/**
|
||||
* Set timeout after which we move to next() step.
|
||||
*/
|
||||
var setAutoplayTimeout = function( timeout ) {
|
||||
if ( timeoutHandle ) {
|
||||
clearTimeout( timeoutHandle );
|
||||
}
|
||||
|
||||
if ( timeout > 0 ) {
|
||||
timeoutHandle = setTimeout( function() { api.next(); }, timeout * 1000 );
|
||||
}
|
||||
setButtonText();
|
||||
};
|
||||
|
||||
/*** Toolbar plugin integration *******************************************/
|
||||
var status = "not clicked";
|
||||
var toolbarButton = null;
|
||||
|
||||
// Copied from core impress.js. Good candidate for moving to a utilities collection.
|
||||
var triggerEvent = function( el, eventName, detail ) {
|
||||
var event = document.createEvent( "CustomEvent" );
|
||||
event.initCustomEvent( eventName, true, true, detail );
|
||||
el.dispatchEvent( event );
|
||||
};
|
||||
|
||||
var makeDomElement = function( html ) {
|
||||
var tempDiv = document.createElement( "div" );
|
||||
tempDiv.innerHTML = html;
|
||||
return tempDiv.firstChild;
|
||||
};
|
||||
|
||||
var toggleStatus = function() {
|
||||
if ( currentStepTimeout > 0 && status !== "paused" ) {
|
||||
status = "paused";
|
||||
} else {
|
||||
status = "playing";
|
||||
}
|
||||
};
|
||||
|
||||
var getButtonText = function() {
|
||||
if ( currentStepTimeout > 0 && status !== "paused" ) {
|
||||
return "||"; // Pause
|
||||
} else {
|
||||
return "▶"; // Play
|
||||
}
|
||||
};
|
||||
|
||||
var setButtonText = function() {
|
||||
if ( toolbarButton ) {
|
||||
|
||||
// Keep button size the same even if label content is changing
|
||||
var buttonWidth = toolbarButton.offsetWidth;
|
||||
var buttonHeight = toolbarButton.offsetHeight;
|
||||
toolbarButton.innerHTML = getButtonText();
|
||||
if ( !toolbarButton.style.width ) {
|
||||
toolbarButton.style.width = buttonWidth + "px";
|
||||
}
|
||||
if ( !toolbarButton.style.height ) {
|
||||
toolbarButton.style.height = buttonHeight + "px";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var addToolbarButton = function( toolbar ) {
|
||||
var html = '<button id="impress-autoplay-playpause" ' + // jshint ignore:line
|
||||
'title="Autoplay" class="impress-autoplay">' + // jshint ignore:line
|
||||
getButtonText() + "</button>"; // jshint ignore:line
|
||||
toolbarButton = makeDomElement( html );
|
||||
toolbarButton.addEventListener( "click", function() {
|
||||
toggleStatus();
|
||||
if ( status === "playing" ) {
|
||||
if ( autoplayDefault === 0 ) {
|
||||
autoplayDefault = 7;
|
||||
}
|
||||
if ( currentStepTimeout === 0 ) {
|
||||
currentStepTimeout = autoplayDefault;
|
||||
}
|
||||
setAutoplayTimeout( currentStepTimeout );
|
||||
} else if ( status === "paused" ) {
|
||||
setAutoplayTimeout( 0 );
|
||||
}
|
||||
} );
|
||||
|
||||
triggerEvent( toolbar, "impress:toolbar:appendChild",
|
||||
{ group: 10, element: toolbarButton } );
|
||||
};
|
||||
|
||||
} )( document );
|
||||
Reference in New Issue
Block a user