Compare commits

...

38 Commits
master ... dev

Author SHA1 Message Date
Hakim El Hattab d761adf002 smooth reset of auto-slide progress, fix overlapping repaint calls 11 years ago
Hakim El Hattab 2736945385 don't increase body height to try and hide address bar, caused issues in ios 7 safari 11 years ago
Hakim El Hattab dd08b86a0f don't show auto slide controls if there's only one slide 11 years ago
Hakim El Hattab 68318407a8 resume auto-sliding when autoSlide config value changes 11 years ago
Hakim El Hattab cfb78d2ee8 replay when auto-slide controls are clicked on last slide 11 years ago
Hakim El Hattab 49cfd05022 fix css syntax error 11 years ago
Hakim El Hattab f318928281 fix playback controls in ie10 11 years ago
Hakim El Hattab fbbffb6f23 add auto-slide instructions to readme 11 years ago
Hakim El Hattab 2de43199ef minor tweaks and comments 11 years ago
Hakim El Hattab 29c5af84be support moz and webkit prefixed requestAnimationFrame 11 years ago
Hakim El Hattab 6aaf88aae7 auto-slide playback updates, fix tap action, hide during overview 11 years ago
Hakim El Hattab abf33e55b0 functional playback control for auto sliding 11 years ago
Hakim El Hattab 356a1cf3b7 group feature detection results in 'features' object, test for canvas and requestAnimationFrame 11 years ago
Hakim El Hattab 9fa1382508 foundation for playback component 11 years ago
Hakim El Hattab e14f5a95da prioritize closing preview when ESC is pressed 11 years ago
Hakim El Hattab 88d84e4551 override any value throguh query, deserialize values of getQueryHash #641 11 years ago
Hakim El Hattab b455b0281d support for svg background images #632 11 years ago
Hakim El Hattab 942724238f better check for arrays in markdown plugin 11 years ago
Hakim El Hattab f8fed1358a remove accidentally checked in files 11 years ago
Hakim El Hattab bbad51e891 use named link for fragments #621 11 years ago
Hakim El Hattab 8f3b14193e Merge branch 'patch-1' of https://github.com/webpro/reveal.js into dev 11 years ago
Hakim El Hattab 421e52d6fb shell highlight #642 11 years ago
Hakim El Hattab e94f62a58f add autoSlideStoppable config value, allows autoSlide to be aborted on user input 11 years ago
Hakim El Hattab 1421934fde code style 11 years ago
Hakim El Hattab a143861478 Merge branch 'focus-body-on-visibility-change' of https://github.com/rexxars/reveal.js into dev 11 years ago
Hakim El Hattab ac1dbd9d61 remove unused head.js in barebones example #616 11 years ago
Hakim El Hattab 9a7fbd6cd1 Merge branch 'master' of github.com:hakimel/reveal.js into dev 11 years ago
Lars Kappert 275efa061a Property 'length' is not a variable. 11 years ago
Espen Hovlandsdal 6043756b2e Focus body when page visibility changes to ensure keyboard shortcuts are usable 11 years ago
Hakim El Hattab 059311923b serve remotes js from s3 #611 11 years ago
Hakim El Hattab 1cfb4fc242 remove extravagant comment 11 years ago
Hakim El Hattab 86216ac645 use 'url()'-free path when specifying parallax image, refactor so that parallax is applied to background class, remove unused attributes #595 11 years ago
Hakim El Hattab 36061b43ba update the parallax background when the window resizes #595 11 years ago
Hakim El Hattab 8399e828db move parallax code to separate method #595 11 years ago
Hakim El Hattab 347a907041 update code style to match rest of reveal.js, disable parallax by default #595 11 years ago
Hakim El Hattab 2fc0dfa8e1 merge parallax into dev, remove default image #595 11 years ago
Michał Smoliński 2bd228534b Fix: no parallax scrolling in FF 11 years ago
Michał Smoliński 2b5c06c4ef Added parallax scrolling background 11 years ago
  1. 66
      README.md
  2. 49
      css/reveal.css
  3. 2
      css/reveal.min.css
  4. 6
      index.html
  5. 476
      js/reveal.js
  6. 4
      js/reveal.min.js
  7. 2
      plugin/markdown/markdown.js
  8. 2
      plugin/remotes/remotes.js
  9. 1
      test/examples/barebones.html

66
README.md

@ -97,6 +97,9 @@ Reveal.initialize({
// by using a data-autoslide attribute on your slides
autoSlide: 0,
// Stop auto-sliding after user input
autoSlideStoppable: true,
// Enable slide navigation via mouse wheel
mouseWheel: false,
@ -109,6 +112,16 @@ Reveal.initialize({
// Transition style for full page backgrounds
backgroundTransition: 'default' // default/linear/none
// Parallax background image
parallaxBackgroundImage: '', // e.g. "'https://s3.amazonaws.com/hakim-static/reveal-js/reveal-parallax-1.jpg'"
// Parallax background size
parallaxBackgroundSize: '', // CSS syntax, e.g. "2100px 900px"
// Number of slides away from the current that are visible
viewDistance: 3,
});
```
@ -192,6 +205,27 @@ Reveal.initialize({
});
```
### Auto-sliding
Presentations can be configure to progress through slides automatically, without any user input. To enable this you will need to tell the framework how many milliseconds it should wait between slides:
```javascript
// Slide every five seconds
Reveal.configure({
autoSlide: 5000
});
```
When this is turned on a control element will appear that enables users to pause and resume auto-sliding. Sliding is also paused automatically as soon as the user starts navigating. You can disable these controls by specifying ```autoSlideStoppable: false``` in your reveal.js config.
You can also override the slide duration for individual slides by using the ```data-autoslide``` attribute on individual sections:
```html
<section data-autoslide="10000">This will remain on screen for 10 seconds</section>
```
### Keyboard Bindings
If you're unhappy with any of the default keyboard bindings you can override them using the ```keyboard``` config option:
@ -291,6 +325,28 @@ Slides are contained within a limited portion of the screen by default to allow
Backgrounds transition using a fade animation by default. This can be changed to a linear sliding transition by passing ```backgroundTransition: 'slide'``` to the ```Reveal.initialize()``` call. Alternatively you can set ```data-background-transition``` on any section with a background to override that specific transition.
### Parallax Background
If you want to use a parallax scrolling background, set the two following config properties when initializing reveal.js (the third one is optional).
```javascript
Reveal.initialize({
// Parallax background image
parallaxBackgroundImage: '', // e.g. "https://s3.amazonaws.com/hakim-static/reveal-js/reveal-parallax-1.jpg"
// Parallax background size
parallaxBackgroundSize: '', // CSS syntax, e.g. "2100px 900px" - currently only pixels are supported (don't use % or auto)
// This slide transition gives best results:
transition: linear
});
```
Make sure that the background size is much bigger than screen size to allow for some scrolling.
### Slide Transitions
The global presentation transition is set using the ```transition``` config value. You can override the global transition for a specific slide by using the ```data-transition``` attribute:
@ -330,7 +386,7 @@ You can also add relative navigation links, similar to the built in reveal.js co
### Fragments
Fragments are used to highlight individual elements on a slide. Every element with the class ```fragment``` will be stepped through before moving on to the next slide. Here's an example: http://lab.hakim.se/reveal-js/#/16
Fragments are used to highlight individual elements on a slide. Every element with the class ```fragment``` will be stepped through before moving on to the next slide. Here's an example: http://lab.hakim.se/reveal-js/#/fragments
The default fragment style is to start out invisible and fade in. This style can be changed by appending a different class to the fragment:
@ -757,22 +813,22 @@ Some reveal.js features, like external markdown, require that presentations run
2. Install [Grunt](http://gruntjs.com/getting-started#installing-the-cli)
4. Clone the reveal.js repository
```
```sh
$ git clone git@github.com:hakimel/reveal.js.git
```
5. Navigate to the reveal.js folder
```
```sh
$ cd reveal.js
```
6. Install dependencies
```
```sh
$ npm install
```
7. Serve the presentation and monitor source files for changes
```
```sh
$ grunt serve
```

49
css/reveal.css

@ -1402,6 +1402,31 @@ body {
float: right
}
/*********************************************
* PARALLAX BACKGROUND
*********************************************/
.reveal.has-parallax-background .backgrounds {
-webkit-transition: all 0.8s ease;
-moz-transition: all 0.8s ease;
-ms-transition: all 0.8s ease;
transition: all 0.8s ease;
}
/* Global transition speed settings */
.reveal.has-parallax-background[data-transition-speed="fast"] .backgrounds {
-webkit-transition-duration: 400ms;
-moz-transition-duration: 400ms;
-ms-transition-duration: 400ms;
transition-duration: 400ms;
}
.reveal.has-parallax-background[data-transition-speed="slow"] .backgrounds {
-webkit-transition-duration: 1200ms;
-moz-transition-duration: 1200ms;
-ms-transition-duration: 1200ms;
transition-duration: 1200ms;
}
/*********************************************
* LINK PREVIEW OVERLAY
@ -1526,6 +1551,30 @@ body {
}
/*********************************************
* PLAYBACK COMPONENT
*********************************************/
.reveal .playback {
position: fixed;
left: 15px;
bottom: 15px;
z-index: 30;
cursor: pointer;
-webkit-transition: all 400ms ease;
-moz-transition: all 400ms ease;
-ms-transition: all 400ms ease;
transition: all 400ms ease;
}
.reveal.overview .playback {
opacity: 0;
visibility: hidden;
}
/*********************************************
* ROLLING LINKS
*********************************************/

2
css/reveal.min.css

File diff suppressed because one or more lines are too long

6
index.html

@ -281,7 +281,7 @@ function linkify( selector ) {
</section>
<section>
<section>
<section id="fragments">
<h2>Fragmented Views</h2>
<p>Hit the next arrow...</p>
<p class="fragment">... to step through ...</p>
@ -366,6 +366,10 @@ function linkify( selector ) {
theme: Reveal.getQueryHash().theme, // available themes are in /css/theme
transition: Reveal.getQueryHash().transition || 'default', // default/cube/page/concave/zoom/linear/fade/none
// Parallax scrolling
// parallaxBackgroundImage: 'https://s3.amazonaws.com/hakim-static/reveal-js/reveal-parallax-1.jpg',
// parallaxBackgroundSize: '2100px 900px',
// Optional libraries used to extend on reveal.js
dependencies: [
{ src: 'lib/js/classList.js', condition: function() { return !document.body.classList; } },

476
js/reveal.js

@ -68,6 +68,9 @@ var Reveal = (function(){
// by using a data-autoslide attribute on your slides
autoSlide: 0,
// Stop auto-sliding after user input
autoSlideStoppable: true,
// Enable slide navigation via mouse wheel
mouseWheel: false,
@ -80,6 +83,9 @@ var Reveal = (function(){
// Opens links in an iframe preview overlay
previewLinks: false,
// Focuses body when page changes visiblity to ensure keyboard shortcuts work
focusBodyOnPageVisiblityChange: true,
// Theme (see /css/theme)
theme: null,
@ -92,6 +98,12 @@ var Reveal = (function(){
// Transition style for full page slide backgrounds
backgroundTransition: 'default', // default/linear/none
// Parallax background image
parallaxBackgroundImage: '', // CSS syntax, e.g. "a.jpg"
// Parallax background size
parallaxBackgroundSize: '', // CSS syntax, e.g. "3000px 2000px"
// Number of slides away from the current that are visible
viewDistance: 3,
@ -102,9 +114,6 @@ var Reveal = (function(){
// Flags if reveal.js is loaded (has dispatched the 'ready' event)
loaded = false,
// The current auto-slide duration
autoSlide = 0,
// The horizontal and vertical index of the currently active slide
indexh,
indexv,
@ -124,11 +133,8 @@ var Reveal = (function(){
// Cached references to DOM elements
dom = {},
// Client support for CSS 3D transforms, see #checkCapabilities()
supports3DTransforms,
// Client support for CSS 2D transforms, see #checkCapabilities()
supports2DTransforms,
// Features supported by the browser, see #checkCapabilities()
features = {},
// Client is a mobile device, see #checkCapabilities()
isMobileDevice,
@ -136,9 +142,6 @@ var Reveal = (function(){
// Throttles mouse wheel navigation
lastMouseWheelStep = 0,
// An interval used to automatically move on to the next slide
autoSlideTimeout = 0,
// Delays updates to the URL due to a Chrome thumbnailer bug
writeURLTimeout = 0,
@ -151,6 +154,15 @@ var Reveal = (function(){
// Flags if the interaction event listeners are bound
eventsAreBound = false,
// The current auto-slide duration
autoSlide = 0,
// Auto slide properties
autoSlidePlayer,
autoSlideTimeout = 0,
autoSlideStartTime = -1,
autoSlidePaused = false,
// Holds information about the currently ongoing touch input
touch = {
startX: 0,
@ -168,7 +180,7 @@ var Reveal = (function(){
checkCapabilities();
if( !supports2DTransforms && !supports3DTransforms ) {
if( !features.transforms2d && !features.transforms3d ) {
document.body.setAttribute( 'class', 'no-transforms' );
// If the browser doesn't support core features we won't be
@ -181,6 +193,7 @@ var Reveal = (function(){
// Copy options over to our config object
extend( config, options );
extend( config, Reveal.getQueryHash() );
// Hide the address bar in mobile browsers
hideAddressBar();
@ -196,18 +209,23 @@ var Reveal = (function(){
*/
function checkCapabilities() {
supports3DTransforms = 'WebkitPerspective' in document.body.style ||
features.transforms3d = 'WebkitPerspective' in document.body.style ||
'MozPerspective' in document.body.style ||
'msPerspective' in document.body.style ||
'OPerspective' in document.body.style ||
'perspective' in document.body.style;
supports2DTransforms = 'WebkitTransform' in document.body.style ||
features.transforms2d = 'WebkitTransform' in document.body.style ||
'MozTransform' in document.body.style ||
'msTransform' in document.body.style ||
'OTransform' in document.body.style ||
'transform' in document.body.style;
features.requestAnimationFrameMethod = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame;
features.requestAnimationFrame = typeof features.requestAnimationFrameMethod === 'function';
features.canvas = !!document.createElement( 'canvas' ).getContext;
isMobileDevice = navigator.userAgent.match( /(iphone|ipod|android)/gi );
}
@ -422,7 +440,7 @@ var Reveal = (function(){
if( data.background ) {
// Auto-wrap image urls in url(...)
if( /^(http|file|\/\/)/gi.test( data.background ) || /\.(png|jpg|jpeg|gif|bmp)$/gi.test( data.background ) ) {
if( /^(http|file|\/\/)/gi.test( data.background ) || /\.(svg|png|jpg|jpeg|gif|bmp)$/gi.test( data.background ) ) {
element.style.backgroundImage = 'url('+ data.background +')';
}
else {
@ -470,6 +488,28 @@ var Reveal = (function(){
} );
// Add parallax background if specified
if( config.parallaxBackgroundImage ) {
dom.background.style.backgroundImage = 'url("' + config.parallaxBackgroundImage + '")';
dom.background.style.backgroundSize = config.parallaxBackgroundSize;
// Make sure the below properties are set on the element - these properties are
// needed for proper transitions to be set on the element via CSS. To remove
// annoying background slide-in effect when the presentation starts, apply
// these properties after short time delay
setTimeout( function() {
dom.wrapper.classList.add( 'has-parallax-background' );
}, 1 );
}
else {
dom.background.style.backgroundImage = '';
dom.wrapper.classList.remove( 'has-parallax-background' );
}
}
/**
@ -478,6 +518,8 @@ var Reveal = (function(){
*/
function configure( options ) {
var numberOfSlides = document.querySelectorAll( SLIDES_SELECTOR ).length;
dom.wrapper.classList.remove( config.transition );
// New config options may be passed when this method
@ -485,7 +527,7 @@ var Reveal = (function(){
if( typeof options === 'object' ) extend( config, options );
// Force linear transition based on browser capabilities
if( supports3DTransforms === false ) config.transition = 'linear';
if( features.transforms3d === false ) config.transition = 'linear';
dom.wrapper.classList.add( config.transition );
@ -535,6 +577,20 @@ var Reveal = (function(){
enablePreviewLinks( '[data-preview-link]' );
}
// Auto-slide playback controls
if( numberOfSlides > 1 && config.autoSlide && config.autoSlideStoppable && features.canvas && features.requestAnimationFrame ) {
autoSlidePlayer = new Playback( dom.wrapper, function() {
return Math.min( Math.max( ( Date.now() - autoSlideStartTime ) / autoSlide, 0 ), 1 );
} );
autoSlidePlayer.on( 'click', onAutoSlidePlayerClick );
autoSlidePaused = false;
}
else if( autoSlidePlayer ) {
autoSlidePlayer.destroy();
autoSlidePlayer = null;
}
// Load the theme in the config, if it's not already loaded
if( config.theme && dom.theme ) {
var themeURL = dom.theme.getAttribute( 'href' );
@ -578,10 +634,28 @@ var Reveal = (function(){
document.addEventListener( 'keydown', onDocumentKeyDown, false );
}
if ( config.progress && dom.progress ) {
if( config.progress && dom.progress ) {
dom.progress.addEventListener( 'click', onProgressClicked, false );
}
if( config.focusBodyOnPageVisiblityChange ) {
var visibilityChange;
if( 'hidden' in document ) {
visibilityChange = 'visibilitychange';
}
else if( 'msHidden' in document ) {
visibilityChange = 'msvisibilitychange';
}
else if( 'webkitHidden' in document ) {
visibilityChange = 'webkitvisibilitychange';
}
if( visibilityChange ) {
document.addEventListener( visibilityChange, onPageVisibilityChange, false );
}
}
[ 'touchstart', 'click' ].forEach( function( eventName ) {
dom.controlsLeft.forEach( function( el ) { el.addEventListener( eventName, onNavigateLeftClicked, false ); } );
dom.controlsRight.forEach( function( el ) { el.addEventListener( eventName, onNavigateRightClicked, false ); } );
@ -784,16 +858,6 @@ var Reveal = (function(){
*/
function removeAddressBar() {
// Portrait and not Chrome for iOS
if( window.orientation === 0 && !/crios/gi.test( navigator.userAgent ) ) {
document.documentElement.style.overflow = 'scroll';
document.body.style.height = '120%';
}
else {
document.documentElement.style.overflow = '';
document.body.style.height = '100%';
}
setTimeout( function() {
window.scrollTo( 0, 1 );
}, 10 );
@ -818,7 +882,7 @@ var Reveal = (function(){
*/
function enableRollingLinks() {
if( supports3DTransforms && !( 'msPerspective' in document.body.style ) ) {
if( features.transforms3d && !( 'msPerspective' in document.body.style ) ) {
var anchors = document.querySelectorAll( SLIDES_SELECTOR + ' a:not(.image)' );
for( var i = 0, len = anchors.length; i < len; i++ ) {
@ -1055,6 +1119,7 @@ var Reveal = (function(){
}
updateProgress();
updateParallax();
}
@ -1471,7 +1536,6 @@ var Reveal = (function(){
// Store references to the previous and current slides
currentSlide = currentVerticalSlides[ indexv ] || currentHorizontalSlide;
// Show fragment, if specified
if( typeof f !== 'undefined' ) {
var fragments = sortFragments( currentSlide.querySelectorAll( '.fragment' ) );
@ -1533,10 +1597,13 @@ var Reveal = (function(){
updateControls();
updateProgress();
updateBackground();
updateParallax();
// Update the URL hash
writeURL();
cueAutoSlide();
}
/**
@ -1647,18 +1714,6 @@ var Reveal = (function(){
state = state.concat( slideState.split( ' ' ) );
}
// If this slide has a data-autoslide attribute associated use this as
// autoSlide value otherwise use the global configured time
var slideAutoSlide = slides[index].getAttribute( 'data-autoslide' );
if( slideAutoSlide ) {
autoSlide = parseInt( slideAutoSlide, 10 );
}
else {
autoSlide = config.autoSlide;
}
cueAutoSlide();
}
else {
// Since there are no slides we can't be anywhere beyond the
@ -1855,6 +1910,42 @@ var Reveal = (function(){
}
/**
* Updates the position of the parallax background based
* on the current slide index.
*/
function updateParallax() {
if( config.parallaxBackgroundImage ) {
var horizontalSlides = document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ),
verticalSlides = document.querySelectorAll( VERTICAL_SLIDES_SELECTOR );
var backgroundSize = dom.background.style.backgroundSize.split( ' ' ),
backgroundWidth, backgroundHeight;
if( backgroundSize.length === 1 ) {
backgroundWidth = backgroundHeight = parseInt( backgroundSize[0], 10 );
}
else {
backgroundWidth = parseInt( backgroundSize[0], 10 );
backgroundHeight = parseInt( backgroundSize[1], 10 );
}
var slideWidth = dom.background.offsetWidth;
var horizontalSlideCount = horizontalSlides.length;
var horizontalOffset = -( backgroundWidth - slideWidth ) / ( horizontalSlideCount-1 ) * indexh;
var slideHeight = dom.background.offsetHeight;
var verticalSlideCount = verticalSlides.length;
var verticalOffset = verticalSlideCount > 0 ? -( backgroundHeight - slideHeight ) / ( verticalSlideCount-1 ) * indexv : 0;
dom.background.style.backgroundPosition = horizontalOffset + 'px ' + verticalOffset + 'px';
}
}
/**
* Determine what available routes there are for navigation.
*
@ -2149,11 +2240,35 @@ var Reveal = (function(){
*/
function cueAutoSlide() {
clearTimeout( autoSlideTimeout );
cancelAutoSlide();
if( currentSlide ) {
// If the current slide has a data-autoslide use that,
// otherwise use the config.autoSlide value
var slideAutoSlide = currentSlide.getAttribute( 'data-autoslide' );
if( slideAutoSlide ) {
autoSlide = parseInt( slideAutoSlide, 10 );
}
else {
autoSlide = config.autoSlide;
}
// Cue the next auto-slide if:
// - There is an autoSlide value
// - Auto-sliding isn't paused by the user
// - The presentation isn't paused
// - The overview isn't active
// - The presentation isn't over
if( autoSlide && !autoSlidePaused && !isPaused() && !isOverview() && ( !Reveal.isLastSlide() || config.loop === true ) ) {
autoSlideTimeout = setTimeout( navigateNext, autoSlide );
autoSlideStartTime = Date.now();
}
if( autoSlidePlayer ) {
autoSlidePlayer.setPlaying( autoSlideTimeout !== -1 );
}
// Cue the next auto-slide if enabled
if( autoSlide && !isPaused() && !isOverview() ) {
autoSlideTimeout = setTimeout( navigateNext, autoSlide );
}
}
@ -2164,6 +2279,25 @@ var Reveal = (function(){
function cancelAutoSlide() {
clearTimeout( autoSlideTimeout );
autoSlideTimeout = -1;
}
function pauseAutoSlide() {
autoSlidePaused = true;
clearTimeout( autoSlideTimeout );
if( autoSlidePlayer ) {
autoSlidePlayer.setPlaying( false );
}
}
function resumeAutoSlide() {
autoSlidePaused = false;
cueAutoSlide();
}
@ -2263,14 +2397,25 @@ var Reveal = (function(){
// ----------------------------- EVENTS -------------------------------//
// --------------------------------------------------------------------//
/**
* Called by all event handlers that are based on user
* input.
*/
function onUserInput( event ) {
if( config.autoSlideStoppable ) {
pauseAutoSlide();
}
}
/**
* Handler for the document level 'keydown' event.
*
* @param {Object} event
*/
function onDocumentKeyDown( event ) {
onUserInput( event );
// Check if there's a focused element that could be using
// the keyboard
var activeElement = document.activeElement;
@ -2357,8 +2502,13 @@ var Reveal = (function(){
event.preventDefault();
}
// ESC or O key
else if ( ( event.keyCode === 27 || event.keyCode === 79 ) && supports3DTransforms ) {
toggleOverview();
else if ( ( event.keyCode === 27 || event.keyCode === 79 ) && features.transforms3d ) {
if( dom.preview ) {
closePreview();
}
else {
toggleOverview();
}
event.preventDefault();
}
@ -2400,6 +2550,8 @@ var Reveal = (function(){
// Each touch should only trigger one action
if( !touch.captured ) {
onUserInput( event );
var currentX = event.touches[0].clientX;
var currentY = event.touches[0].clientY;
@ -2553,6 +2705,8 @@ var Reveal = (function(){
*/
function onProgressClicked( event ) {
onUserInput( event );
event.preventDefault();
var slidesTotal = toArray( document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) ).length;
@ -2565,12 +2719,12 @@ var Reveal = (function(){
/**
* Event handler for navigation control buttons.
*/
function onNavigateLeftClicked( event ) { event.preventDefault(); navigateLeft(); }
function onNavigateRightClicked( event ) { event.preventDefault(); navigateRight(); }
function onNavigateUpClicked( event ) { event.preventDefault(); navigateUp(); }
function onNavigateDownClicked( event ) { event.preventDefault(); navigateDown(); }
function onNavigatePrevClicked( event ) { event.preventDefault(); navigatePrev(); }
function onNavigateNextClicked( event ) { event.preventDefault(); navigateNext(); }
function onNavigateLeftClicked( event ) { event.preventDefault(); onUserInput(); navigateLeft(); }
function onNavigateRightClicked( event ) { event.preventDefault(); onUserInput(); navigateRight(); }
function onNavigateUpClicked( event ) { event.preventDefault(); onUserInput(); navigateUp(); }
function onNavigateDownClicked( event ) { event.preventDefault(); onUserInput(); navigateDown(); }
function onNavigatePrevClicked( event ) { event.preventDefault(); onUserInput(); navigatePrev(); }
function onNavigateNextClicked( event ) { event.preventDefault(); onUserInput(); navigateNext(); }
/**
* Handler for the window level 'hashchange' event.
@ -2590,6 +2744,24 @@ var Reveal = (function(){
}
/**
* Handle for the window level 'visibilitychange' event.
*/
function onPageVisibilityChange( event ) {
var isHidden = document.webkitHidden ||
document.msHidden ||
document.hidden;
// If, after clicking a link or similar and we're coming back,
// focus the document.body to ensure we can use keyboard shortcuts
if( isHidden === false && document.activeElement !== document.body ) {
document.activeElement.blur();
document.body.focus();
}
}
/**
* Invoked when a slide is and we're in the overview.
*/
@ -2636,6 +2808,191 @@ var Reveal = (function(){
}
/**
* Handles click on the auto-sliding controls element.
*/
function onAutoSlidePlayerClick( event ) {
// Replay
if( Reveal.isLastSlide() && config.loop === false ) {
slide( 0, 0 );
resumeAutoSlide();
}
// Resume
else if( autoSlidePaused ) {
resumeAutoSlide();
}
// Pause
else {
pauseAutoSlide();
}
}
// --------------------------------------------------------------------//
// ------------------------ PLAYBACK COMPONENT ------------------------//
// --------------------------------------------------------------------//
/**
* Constructor for the playback component, which displays
* play/pause/progress controls.
*
* @param {HTMLElement} container The component will append
* itself to this
* @param {Function} progressCheck A method which will be
* called frequently to get the current progress on a range
* of 0-1
*/
function Playback( container, progressCheck ) {
// Cosmetics
this.diameter = 50;
this.thickness = 3;
// Flags if we are currently playing
this.playing = false;
// Current progress on a 0-1 range
this.progress = 0;
// Used to loop the animation smoothly
this.progressOffset = 1;
this.container = container;
this.progressCheck = progressCheck;
this.canvas = document.createElement( 'canvas' );
this.canvas.className = 'playback';
this.canvas.width = this.diameter;
this.canvas.height = this.diameter;
this.context = this.canvas.getContext( '2d' );
this.container.appendChild( this.canvas );
this.render();
}
Playback.prototype.setPlaying = function( value ) {
var wasPlaying = this.playing;
this.playing = value;
// Start repainting if we weren't already
if( !wasPlaying && this.playing ) {
this.animate();
}
else {
this.render();
}
};
Playback.prototype.animate = function() {
var progressBefore = this.progress;
this.progress = this.progressCheck();
// When we loop, offset the progress so that it eases
// smoothly rather than immediately resetting
if( progressBefore > 0.8 && this.progress < 0.2 ) {
this.progressOffset = this.progress;
}
this.render();
if( this.playing ) {
features.requestAnimationFrameMethod.call( window, this.animate.bind( this ) );
}
};
/**
* Renders the current progress and playback state.
*/
Playback.prototype.render = function() {
var progress = this.playing ? this.progress : 0,
radius = ( this.diameter / 2 ) - this.thickness,
x = this.diameter / 2,
y = this.diameter / 2,
iconSize = 14;
// Ease towards 1
this.progressOffset += ( 1 - this.progressOffset ) * 0.1;
var endAngle = ( - Math.PI / 2 ) + ( progress * ( Math.PI * 2 ) );
var startAngle = ( - Math.PI / 2 ) + ( this.progressOffset * ( Math.PI * 2 ) );
this.context.save();
this.context.clearRect( 0, 0, this.diameter, this.diameter );
// Solid background color
this.context.beginPath();
this.context.arc( x, y, radius + 2, 0, Math.PI * 2, false );
this.context.fillStyle = 'rgba( 0, 0, 0, 0.4 )';
this.context.fill();
// Draw progress track
this.context.beginPath();
this.context.arc( x, y, radius, 0, Math.PI * 2, false );
this.context.lineWidth = this.thickness;
this.context.strokeStyle = '#666';
this.context.stroke();
if( this.playing ) {
// Draw progress on top of track
this.context.beginPath();
this.context.arc( x, y, radius, startAngle, endAngle, false );
this.context.lineWidth = this.thickness;
this.context.strokeStyle = '#fff';
this.context.stroke();
}
this.context.translate( x - ( iconSize / 2 ), y - ( iconSize / 2 ) );
// Draw play/pause icons
if( this.playing ) {
this.context.fillStyle = '#fff';
this.context.fillRect( 0, 0, iconSize / 2 - 2, iconSize );
this.context.fillRect( iconSize / 2 + 2, 0, iconSize / 2 - 2, iconSize );
}
else {
this.context.beginPath();
this.context.translate( 2, 0 );
this.context.moveTo( 0, 0 );
this.context.lineTo( iconSize - 2, iconSize / 2 );
this.context.lineTo( 0, iconSize );
this.context.fillStyle = '#fff';
this.context.fill();
}
this.context.restore();
};
Playback.prototype.on = function( type, listener ) {
this.canvas.addEventListener( type, listener, false );
};
Playback.prototype.off = function( type, listener ) {
this.canvas.removeEventListener( type, listener, false );
};
Playback.prototype.destroy = function() {
this.playing = false;
if( this.canvas.parentNode ) {
this.container.removeChild( this.canvas );
}
};
// --------------------------------------------------------------------//
// ------------------------------- API --------------------------------//
@ -2733,6 +3090,15 @@ var Reveal = (function(){
query[ a.split( '=' ).shift() ] = a.split( '=' ).pop();
} );
// Basic deserialization
for( var i in query ) {
var value = query[ i ];
if( value === 'null' ) query[ i ] = null;
else if( value === 'true' ) query[ i ] = true;
else if( value === 'false' ) query[ i ] = false;
else if( !isNaN( parseFloat( value ) ) ) query[ i ] = parseFloat( value );
}
return query;
},

4
js/reveal.min.js

File diff suppressed because one or more lines are too long

2
plugin/markdown/markdown.js

@ -171,7 +171,7 @@
// flatten the hierarchical stack, and insert <section data-markdown> tags
for( var i = 0, len = sectionStack.length; i < len; i++ ) {
// vertical
if( sectionStack[i].propertyIsEnumerable( length ) && typeof sectionStack[i].splice === 'function' ) {
if( sectionStack[i] instanceof Array ) {
markdownSections += '<section '+ options.attributes +'>';
sectionStack[i].forEach( function( child ) {

2
plugin/remotes/remotes.js

@ -34,6 +34,6 @@
;
} );
head.js('https://raw.github.com/Remotes/Remotes/master/dist/remotes.ne.min.js');
head.js('https://hakim-static.s3.amazonaws.com/reveal-js/remotes.ne.min.js');
}
})(window);

1
test/examples/barebones.html

@ -29,7 +29,6 @@
</div>
<script src="../../lib/js/head.min.js"></script>
<script src="../../js/reveal.min.js"></script>
<script>

Loading…
Cancel
Save