Files
impress.js/src/plugins/autoplay/autoplay.js
Henrik Ingo 4bec5db356 Add autoplay plugin
The autoplay plugin will automatically advance to the next slide
after N seconds.
2017-10-30 17:07:14 +02:00

160 lines
5.3 KiB
JavaScript

/**
* 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 );