From 691099c6a25861405f067d3b1f7c669c4642a535 Mon Sep 17 00:00:00 2001
From: Hakim El Hattab <hakim.elhattab@gmail.com>
Date: Sat, 10 Nov 2012 09:41:26 -0500
Subject: [PATCH] rough support for vertical centering #70

---
 css/reveal.css | 73 ++++++++++++++++++++++++++++++++++----------------
 js/reveal.js   | 50 ++++++++++++++++++++++++++++++++--
 2 files changed, 98 insertions(+), 25 deletions(-)

diff --git a/css/reveal.css b/css/reveal.css
index 412e8ec..c654505 100644
--- a/css/reveal.css
+++ b/css/reveal.css
@@ -48,7 +48,6 @@ html,
 body {
 	width: 100%;
 	height: 100%;
-	min-height: 600px;
 	overflow: hidden;
 }
 
@@ -164,11 +163,6 @@ body {
  * DEFAULT ELEMENT STYLES
  *********************************************/
 
-.reveal .slides section {
-	line-height: 1.2em;
-	font-weight: normal;
-}
-
 .reveal img {
 	/* preserve aspect ratio and scale image so it's bound within the section */
 	max-width: 100%;
@@ -495,14 +489,20 @@ body {
  * SLIDES
  *********************************************/
 
+.reveal {
+	width: 100%;
+	height: 100%;
+	min-height: 600px;
+	position: relative;
+}
+
 .reveal .slides {
 	position: absolute;
 	max-width: 900px;
+	min-height: 600px;
 	width: 80%;
-	height: 60%;
 	left: 50%;
 	top: 50%;
-	margin-top: -320px;
 	padding: 20px 0px;
 	overflow: visible;
 	z-index: 1;
@@ -520,41 +520,60 @@ body {
 	    -ms-perspective: 600px;
 	        perspective: 600px;
 
-	-webkit-perspective-origin: 0% 25%;
-	   -moz-perspective-origin: 0% 25%;
-	    -ms-perspective-origin: 0% 25%;
-	        perspective-origin: 0% 25%;
+	-webkit-perspective-origin: 0% 0%;
+	   -moz-perspective-origin: 0% 0%;
+	    -ms-perspective-origin: 0% 0%;
+	        perspective-origin: 0% 0%;
 }
 
 .reveal .slides>section,
 .reveal .slides>section>section {
-	display: none;
+	visibility: hidden;
 	position: absolute;
 	width: 100%;
-	min-height: 600px;
 
 	z-index: 10;
+	line-height: 1.2em;
+	font-weight: normal;
 
 	-webkit-transform-style: preserve-3d;
 	   -moz-transform-style: preserve-3d;
 	    -ms-transform-style: preserve-3d;
 	        transform-style: preserve-3d;
 
-	-webkit-transition: all 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
-	   -moz-transition: all 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
-	    -ms-transition: all 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
-	     -o-transition: all 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
-	        transition: all 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
-}
-
-.reveal .slides>section.present {
-	display: block;
+	-webkit-transition: -webkit-transform 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985),
+	                    visibility 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985),
+	                    opacity 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+	   -moz-transition: -moz-transform 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985),
+	                    visibility 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985),
+	                    opacity 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+	    -ms-transition: -ms-transform 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985),
+	                    visibility 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985),
+	                    opacity 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+	     -o-transition: -o-transform 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985),
+	                    visibility 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985),
+	                    opacity 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+	        transition: transform 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985),
+	                    visibility 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985),
+	                    opacity 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+}
+
+.reveal .slides>section.present,
+.reveal .slides>section>section.present {
+	visibility: visible;
 	z-index: 11;
 	opacity: 1;
 }
 
 .reveal .slides>section {
 	margin-left: -50%;
+	margin-top: -50%;
+}
+
+.reveal.center,
+.reveal.center .slides {
+	padding: 0;
+	min-height: auto;
 }
 
 
@@ -1113,6 +1132,14 @@ body {
 	        transform: none;
 }
 
+.no-transition {
+	-webkit-transition: none;
+	   -moz-transition: none;
+	    -ms-transition: none;
+	     -o-transition: none;
+	        transition: none;
+}
+
 
 /*********************************************
  * BACKGROUND STATES
diff --git a/js/reveal.js b/js/reveal.js
index d92ee76..a1683ec 100644
--- a/js/reveal.js
+++ b/js/reveal.js
@@ -29,6 +29,8 @@ var Reveal = (function(){
 			// Enable the slide overview mode
 			overview: true,
 
+			center: false,
+
 			// Loop the presentation
 			loop: false,
 
@@ -264,6 +266,10 @@ var Reveal = (function(){
 		// Updates the presentation to match the current configuration values
 		configure();
 
+		// Force an initial layout, will thereafter be invoked as the window
+		// is resized
+		layout();
+
 		// Read the initial hash
 		readURL();
 
@@ -301,6 +307,10 @@ var Reveal = (function(){
 			dom.wrapper.classList.add( config.transition );
 		}
 
+		if( config.center ) {
+			dom.wrapper.classList.add( 'center' );
+		}
+
 		if( config.mouseWheel ) {
 			document.addEventListener( 'DOMMouseScroll', onDocumentMouseScroll, false ); // FF
 			document.addEventListener( 'mousewheel', onDocumentMouseScroll, false );
@@ -332,6 +342,7 @@ var Reveal = (function(){
 		document.addEventListener( 'touchmove', onDocumentTouchMove, false );
 		document.addEventListener( 'touchend', onDocumentTouchEnd, false );
 		window.addEventListener( 'hashchange', onWindowHashChange, false );
+		window.addEventListener( 'resize', onWindowResize, false );
 
 		if( config.keyboard ) {
 			document.addEventListener( 'keydown', onDocumentKeyDown, false );
@@ -358,6 +369,7 @@ var Reveal = (function(){
 		document.removeEventListener( 'touchmove', onDocumentTouchMove, false );
 		document.removeEventListener( 'touchend', onDocumentTouchEnd, false );
 		window.removeEventListener( 'hashchange', onWindowHashChange, false );
+		window.removeEventListener( 'resize', onWindowResize, false );
 
 		if ( config.progress && dom.progress ) {
 			dom.progress.removeEventListener( 'click', preventAndForward( onProgressClick ), false );
@@ -448,6 +460,33 @@ var Reveal = (function(){
 		}
 	}
 
+	/**
+	 * Applies JavaScript-controlled layout rules to the
+	 * presentation.
+	 */
+	function layout() {
+		if( config.center ) {
+
+			// Select all slides, vertical and horizontal
+			var slides = Array.prototype.slice.call( document.querySelectorAll( '.reveal .slides section' ) );
+
+			// Determine the minimum top offset for slides
+			var minTop = -dom.wrapper.offsetHeight / 2;
+
+			for( var i = 0, len = slides.length; i < len; i++ ) {
+				var slide = slides[ i ];
+
+				if( slide.classList.contains( 'stack' ) ) {
+					slide.style.marginTop = 0;
+				}
+				else {
+					slide.style.marginTop = Math.max( - ( slide.offsetHeight / 2 ) - 20, minTop ) + 'px';
+				}
+			}
+
+		}
+	}
+
 	/**
 	 * Displays the overview of slides (quick nav) by
 	 * scaling down and arranging all slide elements.
@@ -643,6 +682,8 @@ var Reveal = (function(){
 		indexh = updateSlides( HORIZONTAL_SLIDES_SELECTOR, h === undefined ? indexh : h );
 		indexv = updateSlides( VERTICAL_SLIDES_SELECTOR, v === undefined ? indexv : v );
 
+		layout();
+
 		// Apply the new state
 		stateLoop: for( var i = 0, len = state.length; i < len; i++ ) {
 			// Check if this state existed on the previous slide. If it
@@ -1284,13 +1325,18 @@ var Reveal = (function(){
 
 	/**
 	 * Handler for the window level 'hashchange' event.
-	 *
-	 * @param {Object} event
 	 */
 	function onWindowHashChange( event ) {
 		readURL();
 	}
 
+	/**
+	 * Handler for the window level 'resize' event.
+	 */
+	function onWindowResize( event ) {
+		layout();
+	}
+
 	/**
 	 * Invoked when a slide is and we're in the overview.
 	 */
-- 
2.26.2