aboutsummaryrefslogtreecommitdiffhomepage
path: root/js/reveal.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/reveal.js')
-rw-r--r--js/reveal.js225
1 files changed, 171 insertions, 54 deletions
diff --git a/js/reveal.js b/js/reveal.js
index b6210b1..fd281cb 100644
--- a/js/reveal.js
+++ b/js/reveal.js
@@ -59,6 +59,10 @@ var Reveal = (function(){
// Turns fragments on and off globally
fragments: true,
+ // Flags if the presentation is running in an embedded mode,
+ // i.e. contained within a limited portion of the screen
+ embedded: false,
+
// Number of milliseconds between automatically proceeding to the
// next slide, disabled when set to 0, this value can be overwritten
// by using a data-autoslide attribute on your slides
@@ -68,7 +72,7 @@ var Reveal = (function(){
mouseWheel: false,
// Apply a 3D roll to links on hover
- rollingLinks: true,
+ rollingLinks: false,
// Opens links in an iframe preview overlay
previewLinks: false,
@@ -83,7 +87,10 @@ var Reveal = (function(){
transitionSpeed: 'default', // default/fast/slow
// Transition style for full page slide backgrounds
- backgroundTransition: 'default', // default/linear
+ backgroundTransition: 'default', // default/linear/none
+
+ // Number of slides away from the current that are visible
+ viewDistance: 3,
// Script dependencies to load
dependencies: []
@@ -93,8 +100,8 @@ var Reveal = (function(){
autoSlide = 0,
// The horizontal and vertical index of the currently active slide
- indexh = 0,
- indexv = 0,
+ indexh,
+ indexv,
// The previous and current slide HTML elements
previousSlide,
@@ -111,19 +118,14 @@ var Reveal = (function(){
// Cached references to DOM elements
dom = {},
- // Detect support for CSS 3D transforms
- supports3DTransforms = '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,
+ // Client support for CSS 3D transforms, see #checkCapabilities()
+ supports3DTransforms,
- // Detect support for CSS 2D transforms
- supports2DTransforms = '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,
+ // Client support for CSS 2D transforms, see #checkCapabilities()
+ supports2DTransforms,
+
+ // Client is a mobile device, see #checkCapabilities()
+ isMobileDevice,
// Throttles mouse wheel navigation
lastMouseWheelStep = 0,
@@ -149,8 +151,8 @@ var Reveal = (function(){
startY: 0,
startSpan: 0,
startCount: 0,
- handled: false,
- threshold: 80
+ captured: false,
+ threshold: 40
};
/**
@@ -158,6 +160,8 @@ var Reveal = (function(){
*/
function initialize( options ) {
+ checkCapabilities();
+
if( !supports2DTransforms && !supports3DTransforms ) {
document.body.setAttribute( 'class', 'no-transforms' );
@@ -181,6 +185,28 @@ var Reveal = (function(){
}
/**
+ * Inspect the client to see what it's capable of, this
+ * should only happens once per runtime.
+ */
+ function checkCapabilities() {
+
+ supports3DTransforms = '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 ||
+ 'MozTransform' in document.body.style ||
+ 'msTransform' in document.body.style ||
+ 'OTransform' in document.body.style ||
+ 'transform' in document.body.style;
+
+ isMobileDevice = navigator.userAgent.match( /(iphone|ipod|android)/gi );
+
+ }
+
+ /**
* Finds and stores references to DOM elements which are
* required by the presentation. If a required element is
* not found, it is created.
@@ -192,6 +218,9 @@ var Reveal = (function(){
dom.wrapper = document.querySelector( '.reveal' );
dom.slides = document.querySelector( '.reveal .slides' );
+ // Prevent transitions while we're loading
+ dom.slides.classList.add( 'no-transition' );
+
// Background element
dom.background = createSingletonNode( dom.wrapper, 'div', 'backgrounds', null );
@@ -227,13 +256,18 @@ var Reveal = (function(){
}
- function createSingletonNode( container, tagname, classname, innerHTML ){
+ /**
+ * Creates an HTML element and returns a reference to it.
+ * If the element already exists the existing instance will
+ * be returned.
+ */
+ function createSingletonNode( container, tagname, classname, innerHTML ) {
var node = container.querySelector( '.' + classname );
- if( !node ){
+ if( !node ) {
node = document.createElement( tagname );
node.classList.add( classname );
- if( innerHTML !== null ){
+ if( innerHTML !== null ) {
node.innerHTML = innerHTML;
}
container.appendChild( node );
@@ -410,6 +444,9 @@ var Reveal = (function(){
// Notify listeners that the presentation is ready but use a 1ms
// timeout to ensure it's not fired synchronously after #initialize()
setTimeout( function() {
+ // Enable transitions now that we're loaded
+ dom.slides.classList.remove( 'no-transition' );
+
dispatchEvent( 'ready', {
'indexh': indexh,
'indexv': indexv,
@@ -1002,6 +1039,9 @@ var Reveal = (function(){
var wasActive = dom.wrapper.classList.contains( 'overview' );
+ // Vary the depth of the overview based on screen size
+ var depth = window.innerWidth < 400 ? 1000 : 2500;
+
dom.wrapper.classList.add( 'overview' );
dom.wrapper.classList.remove( 'exit-overview' );
@@ -1018,10 +1058,9 @@ var Reveal = (function(){
for( var i = 0, len1 = horizontalSlides.length; i < len1; i++ ) {
var hslide = horizontalSlides[i],
hoffset = config.rtl ? -105 : 105,
- htransform = 'translateZ(-2500px) translate(' + ( ( i - indexh ) * hoffset ) + '%, 0%)';
+ htransform = 'translateZ(-'+ depth +'px) translate(' + ( ( i - indexh ) * hoffset ) + '%, 0%)';
hslide.setAttribute( 'data-index-h', i );
- hslide.style.display = 'block';
hslide.style.WebkitTransform = htransform;
hslide.style.MozTransform = htransform;
hslide.style.msTransform = htransform;
@@ -1040,7 +1079,6 @@ var Reveal = (function(){
vslide.setAttribute( 'data-index-h', i );
vslide.setAttribute( 'data-index-v', j );
- vslide.style.display = 'block';
vslide.style.WebkitTransform = vtransform;
vslide.style.MozTransform = vtransform;
vslide.style.msTransform = vtransform;
@@ -1060,6 +1098,8 @@ var Reveal = (function(){
}
}
+ updateSlidesVisibility();
+
layout();
if( !wasActive ) {
@@ -1301,6 +1341,9 @@ var Reveal = (function(){
indexh = updateSlides( HORIZONTAL_SLIDES_SELECTOR, h === undefined ? indexh : h );
indexv = updateSlides( VERTICAL_SLIDES_SELECTOR, v === undefined ? indexv : v );
+ // Update the visibility of slides now that the indices have changed
+ updateSlidesVisibility();
+
layout();
// Apply the new state
@@ -1330,10 +1373,6 @@ var Reveal = (function(){
activateOverview();
}
- // Update the URL hash after a delay since updating it mid-transition
- // is likely to cause visual lag
- writeURL( 1500 );
-
// Find the current horizontal slide and any possible vertical slides
// within it
var currentHorizontalSlide = horizontalSlides[ indexh ],
@@ -1405,6 +1444,9 @@ var Reveal = (function(){
updateProgress();
updateBackground();
+ // Update the URL hash
+ writeURL();
+
}
/**
@@ -1473,16 +1515,6 @@ var Reveal = (function(){
for( var i = 0; i < slidesLength; i++ ) {
var element = slides[i];
- // Optimization; hide all slides that are three or more steps
- // away from the present slide
- if( isOverview() === false ) {
- // The distance loops so that it measures 1 between the first
- // and last slides
- var distance = Math.abs( ( index - i ) % ( slidesLength - 3 ) ) || 0;
-
- element.style.display = distance > 3 ? 'none' : 'block';
- }
-
var reverse = config.rtl && !isVerticalSlide( element );
element.classList.remove( 'past' );
@@ -1499,6 +1531,13 @@ var Reveal = (function(){
else if( i > index ) {
// Any element subsequent to index is given the 'future' class
element.classList.add( reverse ? 'past' : 'future' );
+
+ var fragments = toArray( element.querySelectorAll( '.fragment.visible' ) );
+
+ // No fragments in future slides should be visible ahead of time
+ while( fragments.length ) {
+ fragments.pop().classList.remove( 'visible' );
+ }
}
// If this element contains vertical slides
@@ -1518,7 +1557,7 @@ var Reveal = (function(){
state = state.concat( slideState.split( ' ' ) );
}
- // If this slide has a data-autoslide attribtue associated use this as
+ // 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 ) {
@@ -1528,6 +1567,8 @@ var Reveal = (function(){
autoSlide = config.autoSlide;
}
+ cueAutoSlide();
+
}
else {
// Since there are no slides we can't be anywhere beyond the
@@ -1540,6 +1581,67 @@ var Reveal = (function(){
}
/**
+ * Optimization method; hide all slides that are far away
+ * from the present slide.
+ */
+ function updateSlidesVisibility() {
+
+ // Select all slides and convert the NodeList result to
+ // an array
+ var horizontalSlides = toArray( document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) ),
+ horizontalSlidesLength = horizontalSlides.length,
+ distanceX,
+ distanceY;
+
+ if( horizontalSlidesLength ) {
+
+ // The number of steps away from the present slide that will
+ // be visible
+ var viewDistance = isOverview() ? 10 : config.viewDistance;
+
+ // Limit view distance on weaker devices
+ if( isMobileDevice ) {
+ viewDistance = isOverview() ? 6 : 1;
+ }
+
+ for( var x = 0; x < horizontalSlidesLength; x++ ) {
+ var horizontalSlide = horizontalSlides[x];
+
+ var verticalSlides = toArray( horizontalSlide.querySelectorAll( 'section' ) ),
+ verticalSlidesLength = verticalSlides.length;
+
+ // Loops so that it measures 1 between the first and last slides
+ distanceX = Math.abs( ( indexh - x ) % ( horizontalSlidesLength - viewDistance ) ) || 0;
+
+ if( verticalSlidesLength ) {
+
+ // Always show the vertical stack itself, even if its child
+ // slides are invisible
+ horizontalSlide.style.display = 'block';
+
+ var oy = getPreviousVerticalIndex( horizontalSlide );
+
+ for( var y = 0; y < verticalSlidesLength; y++ ) {
+ var verticalSlide = verticalSlides[y];
+
+ distanceY = x === indexh ? Math.abs( indexv - y ) : Math.abs( y - oy );
+
+ verticalSlide.style.display = ( distanceX + distanceY ) > viewDistance ? 'none' : 'block';
+ }
+
+ }
+ else {
+
+ horizontalSlide.style.display = distanceX > viewDistance ? 'none' : 'block';
+
+ }
+ }
+
+ }
+
+ }
+
+ /**
* Updates the progress bar to reflect the current slide.
*/
function updateProgress() {
@@ -1795,7 +1897,7 @@ var Reveal = (function(){
}
// If the slide doesn't exist, navigate to the current slide
else {
- slide( indexh, indexv );
+ slide( indexh || 0, indexv || 0 );
}
}
else {
@@ -1803,7 +1905,9 @@ var Reveal = (function(){
var h = parseInt( bits[0], 10 ) || 0,
v = parseInt( bits[1], 10 ) || 0;
- slide( h, v );
+ if( h !== indexh || v !== indexv ) {
+ slide( h, v );
+ }
}
}
@@ -1880,8 +1984,9 @@ var Reveal = (function(){
}
if( !slide && currentSlide ) {
- var visibleFragments = currentSlide.querySelectorAll( '.fragment.visible' );
- if( visibleFragments.length ) {
+ var hasFragments = currentSlide.querySelectorAll( '.fragment' ).length > 0;
+ if( hasFragments ) {
+ var visibleFragments = currentSlide.querySelectorAll( '.fragment.visible' );
f = visibleFragments.length;
}
}
@@ -2111,7 +2216,7 @@ var Reveal = (function(){
var value = config.keyboard[ key ];
- // Calback function
+ // Callback function
if( typeof value === 'function' ) {
value.apply( null, [ event ] );
}
@@ -2170,7 +2275,8 @@ var Reveal = (function(){
if( triggered ) {
event.preventDefault();
}
- else if ( event.keyCode === 27 && supports3DTransforms ) {
+ // ESC or O key
+ else if ( ( event.keyCode === 27 || event.keyCode === 79 ) && supports3DTransforms ) {
toggleOverview();
event.preventDefault();
@@ -2212,11 +2318,11 @@ var Reveal = (function(){
function onTouchMove( event ) {
// Each touch should only trigger one action
- if( !touch.handled ) {
+ if( !touch.captured ) {
var currentX = event.touches[0].clientX;
var currentY = event.touches[0].clientY;
- // If the touch started off with two points and still has
+ // If the touch started with two points and still has
// two active touches; test for the pinch gesture
if( event.touches.length === 2 && touch.startCount === 2 && config.overview ) {
@@ -2232,7 +2338,7 @@ var Reveal = (function(){
// If the span is larger than the desire amount we've got
// ourselves a pinch
if( Math.abs( touch.startSpan - currentSpan ) > touch.threshold ) {
- touch.handled = true;
+ touch.captured = true;
if( currentSpan < touch.startSpan ) {
activateOverview();
@@ -2252,23 +2358,34 @@ var Reveal = (function(){
deltaY = currentY - touch.startY;
if( deltaX > touch.threshold && Math.abs( deltaX ) > Math.abs( deltaY ) ) {
- touch.handled = true;
+ touch.captured = true;
navigateLeft();
}
else if( deltaX < -touch.threshold && Math.abs( deltaX ) > Math.abs( deltaY ) ) {
- touch.handled = true;
+ touch.captured = true;
navigateRight();
}
else if( deltaY > touch.threshold ) {
- touch.handled = true;
+ touch.captured = true;
navigateUp();
}
else if( deltaY < -touch.threshold ) {
- touch.handled = true;
+ touch.captured = true;
navigateDown();
}
- event.preventDefault();
+ // If we're embedded, only block touch events if they have
+ // triggered an action
+ if( config.embedded ) {
+ if( touch.captured || isVerticalSlide( currentSlide ) ) {
+ event.preventDefault();
+ }
+ }
+ // Not embedded? Block them all to avoid needless tossing
+ // around of the viewport in iOS
+ else {
+ event.preventDefault();
+ }
}
}
@@ -2285,7 +2402,7 @@ var Reveal = (function(){
*/
function onTouchEnd( event ) {
- touch.handled = false;
+ touch.captured = false;
}