diff --git a/css/reveal.css b/css/reveal.css
index 051f0794..9967c2ae 100644
--- a/css/reveal.css
+++ b/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; }
/*********************************************
diff --git a/css/reveal.scss b/css/reveal.scss
index 8785d4af..6209486b 100644
--- a/css/reveal.scss
+++ b/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;
}
diff --git a/js/reveal.js b/js/reveal.js
index 42c38223..d39e2886 100644
--- a/js/reveal.js
+++ b/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',
- '' +
- '' +
- '' +
- '' );
+ '' +
+ '' +
+ '' +
+ '' );
// 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 ) {