Skip to content

Commit

Permalink
finishing touches on reader mode progress bar
Browse files Browse the repository at this point in the history
  • Loading branch information
hakimel committed Oct 10, 2023
1 parent 2347991 commit a6abd04
Show file tree
Hide file tree
Showing 8 changed files with 130 additions and 58 deletions.
19 changes: 19 additions & 0 deletions css/reveal.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2011,6 +2011,13 @@ $notesWidthPercent: 25%;
position: sticky;
top: 50%;
z-index: 20;
opacity: 0;
transition: all 0.3s ease;

&.visible,
&:hover {
opacity: 1;
}

.reader-progress-inner {
position: absolute;
Expand All @@ -2021,6 +2028,18 @@ $notesWidthPercent: 25%;
transform: translateY(-50%);
border-radius: 8px;
z-index: 10;

// Hit area
&:after {
content: '';
position: absolute;
width: 200%;
height: 100%;
top: 0;
left: -50%;
background: rgba( 0, 0, 0, 0 );
z-index: -1;
}
}

.reader-progress-playhead {
Expand Down
2 changes: 1 addition & 1 deletion dist/reveal.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/reveal.esm.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/reveal.esm.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/reveal.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/reveal.js.map

Large diffs are not rendered by default.

8 changes: 7 additions & 1 deletion js/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -276,9 +276,15 @@ export default {
// Only applies to presentations in reader mode.
readerScrollSnap: 'proximity',

// Enables and configure the reader mode scroll bar.
// - 'auto': Show the scrollbar while scrolling, hide while idle
// - true: Always show the scrollbar
// - false: Never show the scrollbar
readerScrollBar: 'auto',

// Responsively activate the reader mode when we reach the specified
// width (in pixels)
readerActivationWidth: 800,
readerActivationWidth: null,

// The maximum number of pages a single slide can expand onto when printing
// to PDF, unlimited by default
Expand Down
151 changes: 99 additions & 52 deletions js/controllers/reader.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { HORIZONTAL_SLIDES_SELECTOR, SLIDES_SELECTOR } from '../utils/constants.js'
import { queryAll, createStyleSheet } from '../utils/util.js'

const HIDE_SCROLLBAR_TIMEOUT = 500;

/**
* The reader mode lets you read a reveal.js presentation
* as a linear scrollable page.
Expand Down Expand Up @@ -116,52 +118,6 @@ export default class Reader {

}

createProgressBar() {

this.progressBar = document.createElement( 'div' );
this.progressBar.className = 'reader-progress';

this.progressBarInner = document.createElement( 'div' );
this.progressBarInner.className = 'reader-progress-inner';
this.progressBar.appendChild( this.progressBarInner );

this.progressBarPlayhead = document.createElement( 'div' );
this.progressBarPlayhead.className = 'reader-progress-playhead';
this.progressBarInner.appendChild( this.progressBarPlayhead );

this.viewportElement.insertBefore( this.progressBar, this.viewportElement.firstChild );

const handleMouseDown = ( event ) => {

event.preventDefault();

document.addEventListener( 'mousemove', handleDocumentMouseMove );
document.addEventListener( 'mouseup', handleDocumentMouseUp );

handleDocumentMouseMove( event );

};

const handleDocumentMouseMove = ( event ) => {

let progress = Math.max( Math.min( ( event.clientY - this.progressBarInner.getBoundingClientRect().top ) / this.progressBarHeight, 1 ), 0 );
progress = Math.max( Math.min( progress, 1 ), 0 );

this.viewportElement.scrollTop = progress * ( this.viewportElement.scrollHeight - this.viewportElement.offsetHeight );

};

const handleDocumentMouseUp = ( event ) => {

document.removeEventListener( 'mousemove', handleDocumentMouseMove );
document.removeEventListener( 'mouseup', handleDocumentMouseUp );

};

this.progressBarInner.addEventListener( 'mousedown', handleMouseDown );

}

/**
* Deactivates the reader mode and restores the standard slide-based
* presentation.
Expand All @@ -177,7 +133,7 @@ export default class Reader {
this.viewportElement.removeEventListener( 'scroll', this.onScroll );
this.viewportElement.classList.remove( 'reveal-reader' );

this.progressBar.remove();
this.removeProgressBar();

this.Reveal.getSlidesElement().innerHTML = this.slideHTMLBeforeActivation;
this.Reveal.sync();
Expand Down Expand Up @@ -324,7 +280,76 @@ export default class Reader {
return page;
} );

this.createProgressBarSlides();
if( config.readerScrollBar ) {
this.createProgressBar();
this.createProgressBarSlides();
}
else {
this.removeProgressBar();
}

}

createProgressBar() {

if( this.progressBar ) return;

this.progressBar = document.createElement( 'div' );
this.progressBar.className = 'reader-progress';

this.progressBarInner = document.createElement( 'div' );
this.progressBarInner.className = 'reader-progress-inner';
this.progressBar.appendChild( this.progressBarInner );

this.progressBarPlayhead = document.createElement( 'div' );
this.progressBarPlayhead.className = 'reader-progress-playhead';
this.progressBarInner.appendChild( this.progressBarPlayhead );

this.viewportElement.insertBefore( this.progressBar, this.viewportElement.firstChild );

const handleMouseDown = ( event ) => {

event.preventDefault();

this.draggingProgressBar = true;

document.addEventListener( 'mousemove', handleDocumentMouseMove );
document.addEventListener( 'mouseup', handleDocumentMouseUp );

handleDocumentMouseMove( event );

};

const handleDocumentMouseMove = ( event ) => {

let progress = ( event.clientY - this.progressBarInner.getBoundingClientRect().top ) / this.progressBarHeight;

progress = Math.max( Math.min( progress, 1 ), 0 );

this.viewportElement.scrollTop = progress * ( this.viewportElement.scrollHeight - this.viewportElement.offsetHeight );

};

const handleDocumentMouseUp = ( event ) => {

this.draggingProgressBar = false;
this.showProgressBar();

document.removeEventListener( 'mousemove', handleDocumentMouseMove );
document.removeEventListener( 'mouseup', handleDocumentMouseUp );

};

this.progressBarInner.addEventListener( 'mousedown', handleMouseDown );

}

removeProgressBar() {

if( this.progressBar ) {
this.progressBar.remove();
this.progressBar = null;
}

}

Expand Down Expand Up @@ -377,11 +402,33 @@ export default class Reader {

moveProgressBarTo( progress ) {

this.progressBarPlayhead.style.transform = `translateY(${progress * this.progressBarScrollableHeight}px)`;
if( this.progressBar ) {

this.pages.forEach( ( page ) => {
page.progressBarSlide.classList.toggle( 'active', !!page.active );
} );
this.progressBarPlayhead.style.transform = `translateY(${progress * this.progressBarScrollableHeight}px)`;

this.pages.forEach( ( page ) => {
page.progressBarSlide.classList.toggle( 'active', !!page.active );
} );

this.showProgressBar();

}

}

showProgressBar() {

this.progressBar.classList.add( 'visible' );

clearTimeout( this.hideProgressBarTimeout );

if( this.Reveal.getConfig().readerScrollBar === 'auto' && !this.draggingProgressBar ) {

this.hideProgressBarTimeout = setTimeout( () => {
this.progressBar.classList.remove( 'visible' );
}, HIDE_SCROLLBAR_TIMEOUT );

}

}

Expand Down

0 comments on commit a6abd04

Please sign in to comment.