浏览代码

add controlsHint option, animates vertical arrow first time we encounter a vertical slide

Hakim El Hattab 7 年之前
父节点
当前提交
617c17be3c
共有 3 个文件被更改,包括 185 次插入57 次删除
  1. 93 38
      css/reveal.css
  2. 47 13
      css/reveal.scss
  3. 45 6
      js/reveal.js

+ 93 - 38
css/reveal.css

@@ -188,6 +188,49 @@ body {
 /*********************************************
  * CONTROLS
  *********************************************/
+@-webkit-keyframes bounce-right {
+  0%, 10%, 25%, 40%, 50% {
+    -webkit-transform: translateX(0);
+            transform: translateX(0); }
+  20% {
+    -webkit-transform: translateX(10px);
+            transform: translateX(10px); }
+  30% {
+    -webkit-transform: translateX(-5px);
+            transform: translateX(-5px); } }
+@keyframes bounce-right {
+  0%, 10%, 25%, 40%, 50% {
+    -webkit-transform: translateX(0);
+            transform: translateX(0); }
+  20% {
+    -webkit-transform: translateX(10px);
+            transform: translateX(10px); }
+  30% {
+    -webkit-transform: translateX(-5px);
+            transform: translateX(-5px); } }
+
+@-webkit-keyframes bounce-down {
+  0%, 10%, 25%, 40%, 50% {
+    -webkit-transform: translateY(0);
+            transform: translateY(0); }
+  20% {
+    -webkit-transform: translateY(10px);
+            transform: translateY(10px); }
+  30% {
+    -webkit-transform: translateY(-5px);
+            transform: translateY(-5px); } }
+
+@keyframes bounce-down {
+  0%, 10%, 25%, 40%, 50% {
+    -webkit-transform: translateY(0);
+            transform: translateY(0); }
+  20% {
+    -webkit-transform: translateY(10px);
+            transform: translateY(10px); }
+  30% {
+    -webkit-transform: translateY(-5px);
+            transform: translateY(-5px); } }
+
 .reveal .controls {
   display: none;
   position: absolute;
@@ -201,8 +244,6 @@ body {
   .reveal .controls button {
     position: absolute;
     padding: 0;
-    width: 46px;
-    height: 46px;
     background-color: transparent;
     border: 0;
     outline: 0;
@@ -217,8 +258,8 @@ body {
     opacity: 0;
     -webkit-appearance: none;
     -webkit-tap-highlight-color: transparent; }
-  .reveal .controls button:before,
-  .reveal .controls button:after {
+  .reveal .controls .pagination-arrow:before,
+  .reveal .controls .pagination-arrow:after {
     content: '';
     position: absolute;
     top: 0;
@@ -231,44 +272,58 @@ body {
     -webkit-transform-origin: 3px 50%;
             transform-origin: 3px 50%;
     will-change: transform; }
-  .reveal .controls button:before {
-    -webkit-transform: translateX(7px) translateY(20px) rotate(44deg);
-            transform: translateX(7px) translateY(20px) rotate(44deg); }
-  .reveal .controls button:after {
-    -webkit-transform: translateX(7px) translateY(20px) rotate(-44deg);
-            transform: translateX(7px) translateY(20px) rotate(-44deg); }
-  .reveal .controls button:hover:before {
-    -webkit-transform: translateX(7px) translateY(20px) rotate(40deg);
-            transform: translateX(7px) translateY(20px) rotate(40deg); }
-  .reveal .controls button:hover:after {
-    -webkit-transform: translateX(7px) translateY(20px) rotate(-40deg);
-            transform: translateX(7px) translateY(20px) rotate(-40deg); }
-  .reveal .controls button:active:before {
-    -webkit-transform: translateX(7px) translateY(20px) rotate(36deg);
-            transform: translateX(7px) translateY(20px) rotate(36deg); }
-  .reveal .controls button:active:after {
-    -webkit-transform: translateX(7px) translateY(20px) rotate(-36deg);
-            transform: translateX(7px) translateY(20px) rotate(-36deg); }
+  .reveal .controls .pagination-arrow {
+    position: relative;
+    width: 46px;
+    height: 46px; }
+    .reveal .controls .pagination-arrow:before {
+      -webkit-transform: translateX(7px) translateY(20px) rotate(44deg);
+              transform: translateX(7px) translateY(20px) rotate(44deg); }
+    .reveal .controls .pagination-arrow:after {
+      -webkit-transform: translateX(7px) translateY(20px) rotate(-44deg);
+              transform: translateX(7px) translateY(20px) rotate(-44deg); }
+    .reveal .controls .pagination-arrow:hover:before {
+      -webkit-transform: translateX(7px) translateY(20px) rotate(40deg);
+              transform: translateX(7px) translateY(20px) rotate(40deg); }
+    .reveal .controls .pagination-arrow:hover:after {
+      -webkit-transform: translateX(7px) translateY(20px) rotate(-40deg);
+              transform: translateX(7px) translateY(20px) rotate(-40deg); }
+    .reveal .controls .pagination-arrow:active:before {
+      -webkit-transform: translateX(7px) translateY(20px) rotate(36deg);
+              transform: translateX(7px) translateY(20px) rotate(36deg); }
+    .reveal .controls .pagination-arrow:active:after {
+      -webkit-transform: translateX(7px) translateY(20px) rotate(-36deg);
+              transform: translateX(7px) translateY(20px) rotate(-36deg); }
   .reveal .controls .navigate-left {
     right: 82px;
-    bottom: 18px;
-    -webkit-transform: translateY(-50%);
-            transform: translateY(-50%); }
+    bottom: 18px; }
+    .reveal .controls .navigate-left .pagination-arrow {
+      -webkit-transform: translateY(-50%);
+              transform: translateY(-50%); }
   .reveal .controls .navigate-right {
     right: 0;
-    bottom: 18px;
-    -webkit-transform: translateY(-50%) rotate(180deg);
-            transform: translateY(-50%) rotate(180deg); }
+    bottom: 18px; }
+    .reveal .controls .navigate-right .pagination-arrow {
+      -webkit-transform: translateY(-50%) rotate(180deg);
+              transform: translateY(-50%) rotate(180deg); }
+    .reveal .controls .navigate-right.bounce {
+      -webkit-animation: bounce-right 2s 50 both ease-out;
+              animation: bounce-right 2s 50 both ease-out; }
   .reveal .controls .navigate-up {
     right: 18px;
-    bottom: 82px;
-    -webkit-transform: translateX(-50%) rotate(90deg);
-            transform: translateX(-50%) rotate(90deg); }
+    bottom: 82px; }
+    .reveal .controls .navigate-up .pagination-arrow {
+      -webkit-transform: translateX(-50%) rotate(90deg);
+              transform: translateX(-50%) rotate(90deg); }
   .reveal .controls .navigate-down {
     right: 18px;
-    bottom: 0;
-    -webkit-transform: translateX(-50%) rotate(-90deg);
-            transform: translateX(-50%) rotate(-90deg); }
+    bottom: 0; }
+    .reveal .controls .navigate-down .pagination-arrow {
+      -webkit-transform: translateX(-50%) rotate(-90deg);
+              transform: translateX(-50%) rotate(-90deg); }
+    .reveal .controls .navigate-down.bounce {
+      -webkit-animation: bounce-down 2s 50 both ease-out;
+              animation: bounce-down 2s 50 both ease-out; }
   .reveal .controls[data-controls-back-arrows="faded"] .navigate-left.enabled,
   .reveal .controls[data-controls-back-arrows="faded"] .navigate-up.enabled {
     opacity: 0.3; }
@@ -321,12 +376,12 @@ body {
 .reveal:not(.has-horizontal-slides) .controls .navigate-down {
   right: 0; }
 
-.reveal.has-dark-background .controls button:after,
-.reveal.has-dark-background .controls button:before {
+.reveal.has-dark-background .controls .pagination-arrow:after,
+.reveal.has-dark-background .controls .pagination-arrow:before {
   background-color: #fff; }
 
-.reveal.has-light-background .controls button:after,
-.reveal.has-light-background .controls button:before {
+.reveal.has-light-background .controls .pagination-arrow:after,
+.reveal.has-light-background .controls .pagination-arrow:before {
   background-color: #000; }
 
 /*********************************************

+ 47 - 13
css/reveal.scss

@@ -235,6 +235,18 @@ body {
  * CONTROLS
  *********************************************/
 
+@keyframes bounce-right {
+	0%, 10%, 25%, 40%, 50% {transform: translateX(0);}
+	20% {transform: translateX(10px);}
+	30% {transform: translateX(-5px);}
+}
+
+@keyframes bounce-down {
+	0%, 10%, 25%, 40%, 50% {transform: translateY(0);}
+	20% {transform: translateY(10px);}
+	30% {transform: translateY(-5px);}
+}
+
 .reveal .controls {
 	$size: 46px;
 	$length: floor($size * 0.7);
@@ -268,8 +280,6 @@ body {
 	button {
 		position: absolute;
 		padding: 0;
-		width: $size;
-		height: $size;
 		background-color: transparent;
 		border: 0;
 		outline: 0;
@@ -287,8 +297,8 @@ body {
 		-webkit-tap-highlight-color: rgba( 0, 0, 0, 0 );
 	}
 
-	button:before,
-	button:after {
+	.pagination-arrow:before,
+	.pagination-arrow:after {
 		content: '';
 		position: absolute;
 		top: 0;
@@ -303,7 +313,11 @@ body {
 		will-change: transform;
 	}
 
-	button {
+	.pagination-arrow {
+		position: relative;
+		width: $size;
+		height: $size;
+
 		@include arrowTransform( $angle );
 
 		&:hover {
@@ -318,25 +332,45 @@ body {
 	.navigate-left {
 		right: $size + $innerSpacing*2;
 		bottom: $innerSpacing;
-		transform: translateY(-50%);
+
+		.pagination-arrow {
+			transform: translateY(-50%);
+		}
 	}
 
 	.navigate-right {
 		right: 0;
 		bottom: $innerSpacing;
-		transform: translateY(-50%) rotate( 180deg );
+
+		.pagination-arrow {
+			transform: translateY(-50%) rotate( 180deg );
+		}
+
+		&.bounce {
+			animation: bounce-right 2s 50 both ease-out;
+		}
 	}
 
 	.navigate-up {
 		right: $innerSpacing;
 		bottom: $size + $innerSpacing*2;
-		transform: translateX(-50%) rotate( 90deg );
+
+		.pagination-arrow {
+			transform: translateX(-50%) rotate( 90deg );
+		}
 	}
 
 	.navigate-down {
 		right: $innerSpacing;
 		bottom: 0;
-		transform: translateX(-50%) rotate( -90deg );
+
+		.pagination-arrow {
+			transform: translateX(-50%) rotate( -90deg );
+		}
+
+		&.bounce {
+			animation: bounce-down 2s 50 both ease-out;
+		}
 	}
 
 	// Back arrow style: "faded":
@@ -432,13 +466,13 @@ body {
 	right: 0;
 }
 
-.reveal.has-dark-background .controls button:after,
-.reveal.has-dark-background .controls button:before {
+.reveal.has-dark-background .controls .pagination-arrow:after,
+.reveal.has-dark-background .controls .pagination-arrow:before {
 	background-color: #fff;
 }
 
-.reveal.has-light-background .controls button:after,
-.reveal.has-light-background .controls button:before {
+.reveal.has-light-background .controls .pagination-arrow:after,
+.reveal.has-light-background .controls .pagination-arrow:before {
 	background-color: #000;
 }
 

+ 45 - 6
js/reveal.js

@@ -52,11 +52,15 @@
 			// Display controls in the bottom right corner
 			controls: true,
 
+			// Hint at where the user can navigate, for example by animating
+			// the down arrow when we first encounter a vertical slide
+			controlsHints: true,
+
 			// Determines where controls appear, "edges" or "bottom-right"
 			controlsLayout: 'bottom-right',
 
-			// Specifies the display rules for backwards navigation arrows;
-			// "faded", "hidden" or "visible"
+			// Visibility rule for backwards navigation arrows; "faded", "hidden"
+			// or "visible"
 			controlsBackArrows: 'faded',
 
 			// Display a presentation progress bar
@@ -214,6 +218,10 @@
 
 		previousBackground,
 
+		// Remember which directions that the user has navigated towards
+		hasNavigatedRight = false,
+		hasNavigatedDown = false,
+
 		// Slides may hold a data-state attribute which we pick up and apply
 		// as a class to the body. This list contains the combined state of
 		// all current slides.
@@ -524,10 +532,10 @@
 
 		// Arrow controls
 		dom.controls = createSingletonNode( dom.wrapper, 'aside', 'controls',
-			'<button class="navigate-left" aria-label="previous slide"></button>' +
-			'<button class="navigate-right" aria-label="next slide"></button>' +
-			'<button class="navigate-up" aria-label="above slide"></button>' +
-			'<button class="navigate-down" aria-label="below slide"></button>' );
+			'<button class="navigate-left" aria-label="previous slide"><div class="pagination-arrow"></div></button>' +
+			'<button class="navigate-right" aria-label="next slide"><div class="pagination-arrow"></div></button>' +
+			'<button class="navigate-up" aria-label="above slide"><div class="pagination-arrow"></div></button>' +
+			'<button class="navigate-down" aria-label="below slide"><div class="pagination-arrow"></div></button>' );
 
 		// Slide number
 		dom.slideNumber = createSingletonNode( dom.wrapper, 'div', 'slide-number', '' );
@@ -550,6 +558,10 @@
 		dom.controlsPrev = toArray( document.querySelectorAll( '.navigate-prev' ) );
 		dom.controlsNext = toArray( document.querySelectorAll( '.navigate-next' ) );
 
+		// The right and down arrows in the standard reveal.js controls
+		dom.controlsRightArrow = dom.controls.querySelector( '.navigate-right' );
+		dom.controlsDownArrow = dom.controls.querySelector( '.navigate-down' );
+
 		dom.statusDiv = createStatusDiv();
 	}
 
@@ -2905,6 +2917,26 @@
 
 		}
 
+		if( config.controlsHints ) {
+
+			// Highlight control arrows with an animation to ensure
+			// that the viewer knows how to navigate
+			if( !hasNavigatedDown && routes.down ) {
+				dom.controlsDownArrow.classList.add( 'highlight' );
+			}
+			else {
+				dom.controlsDownArrow.classList.remove( 'highlight' );
+
+				if( !hasNavigatedRight && routes.right && indexh === 0 ) {
+					dom.controlsRightArrow.classList.add( 'highlight' );
+				}
+				else {
+					dom.controlsRightArrow.classList.remove( 'highlight' );
+				}
+			}
+
+		}
+
 	}
 
 	/**
@@ -4157,6 +4189,8 @@
 
 	function navigateRight() {
 
+		hasNavigatedRight = true;
+
 		// Reverse for RTL
 		if( config.rtl ) {
 			if( ( isOverview() || previousFragment() === false ) && availableRoutes().right ) {
@@ -4181,6 +4215,8 @@
 
 	function navigateDown() {
 
+		hasNavigatedDown = true;
+
 		// Prioritize revealing fragments
 		if( ( isOverview() || nextFragment() === false ) && availableRoutes().down ) {
 			slide( indexh, indexv + 1 );
@@ -4227,6 +4263,9 @@
 	 */
 	function navigateNext() {
 
+		hasNavigatedRight = true;
+		hasNavigatedDown = true;
+
 		// Prioritize revealing fragments
 		if( nextFragment() === false ) {
 			if( availableRoutes().down ) {