1
0
mirror of https://github.com/hakimel/reveal.js.git synced 2025-07-31 03:40:28 +02:00

reader mode progress bar can be dragged to scroll

This commit is contained in:
Hakim El Hattab
2023-10-10 11:16:31 +02:00
parent f80ee3b917
commit 234799114a
7 changed files with 80 additions and 22 deletions

View File

@@ -2021,7 +2021,6 @@ $notesWidthPercent: 25%;
transform: translateY(-50%);
border-radius: 8px;
z-index: 10;
overflow: hidden;
}
.reader-progress-playhead {
@@ -2031,7 +2030,7 @@ $notesWidthPercent: 25%;
top: 0;
left: 0;
border-radius: 8px;
background-color: rgba( 255, 255, 255, 0.7);
background-color: #fff;
transition: all 0.1s ease;
z-index: 2;
}
@@ -2040,19 +2039,35 @@ $notesWidthPercent: 25%;
position: absolute;
width: 100%;
transition: all 0.2s ease;
background-color: rgba( 0, 0, 0, 0.4 );
background-color: rgba( 255, 255, 255, 0.2 );
border-radius: 8px;
}
.reader-progress-slide:last-child {
border-bottom-left-radius: 8px;
border-bottom-right-radius: 8px;
}
.reader-progress-slide.active {
background-color: #000;
border-radius: 8px;
background-color: #fff;
}
.reader-progress-trigger {
position: absolute;
width: 100%;
transition: all 0.2s ease;
}
.reader-progress-slide.active.has-triggers {
background-color: rgba( 255, 255, 255, 0.4 );
z-index: 10;
}
.reader-progress-slide.active .reader-progress-trigger:after {
content: '';
position: absolute;
width: 4px;
height: 4px;
border-radius: 6px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: #000;
}
}

2
dist/reveal.css vendored

File diff suppressed because one or more lines are too long

2
dist/reveal.esm.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

2
dist/reveal.js vendored

File diff suppressed because one or more lines are too long

2
dist/reveal.js.map vendored

File diff suppressed because one or more lines are too long

View File

@@ -131,6 +131,35 @@ export default class Reader {
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 );
}
/**
@@ -210,7 +239,7 @@ export default class Reader {
const pageHeight = readerLayout === 'full' ? viewportHeight : compactHeight;
// The height that needs to be scrolled between scroll triggers
const scrollTriggerHeight = viewportHeight / 2;
const scrollTriggerHeight = viewportHeight;
this.viewportElement.style.setProperty( '--page-height', pageHeight + 'px' );
this.viewportElement.style.scrollSnapType = typeof config.readerScrollSnap === 'string' ?
@@ -303,7 +332,7 @@ export default class Reader {
this.progressBarInner.querySelectorAll( '.reader-progress-slide' ).forEach( slide => slide.remove() );
const spacing = 2;
const spacing = 4;
const viewportHeight = this.viewportElement.offsetHeight;
const scrollHeight = this.viewportElement.scrollHeight;
@@ -318,10 +347,21 @@ export default class Reader {
page.progressBarSlide = document.createElement( 'div' );
page.progressBarSlide.className = 'reader-progress-slide';
page.progressBarSlide.classList.toggle( 'has-triggers', page.scrollTriggers.length > 0 );
page.progressBarSlide.style.top = page.top / scrollHeight * this.progressBarHeight + 'px';
page.progressBarSlide.style.height = page.totalHeight / scrollHeight * this.progressBarHeight - spacing + 'px';
this.progressBarInner.appendChild( page.progressBarSlide );
page.scrollTriggers.forEach( trigger => {
const triggerElement = document.createElement( 'div' );
triggerElement.className = 'reader-progress-trigger';
triggerElement.style.top = trigger.range[0] * page.totalHeight / scrollHeight * this.progressBarHeight + 'px';
triggerElement.style.height = ( trigger.range[1] - trigger.range[0] ) * page.totalHeight / scrollHeight * this.progressBarHeight - spacing + 'px';
page.progressBarSlide.appendChild( triggerElement );
} );
} );
}
@@ -341,9 +381,6 @@ export default class Reader {
this.pages.forEach( ( page ) => {
page.progressBarSlide.classList.toggle( 'active', !!page.active );
page.scrollTriggers.forEach( trigger => {
// page.progressBarSlide.classList.toggle( 'active', !!trigger.active );
} );
} );
}
@@ -367,7 +404,13 @@ export default class Reader {
// Find the page closest to the center of the viewport, this
// is the page we want to focus and activate
const activePage = this.pages.reduce( ( closestPage, page ) => {
const distance = Math.abs( ( page.top + page.pageHeight / 2 ) - scrollTop - viewportHeight / 2 );
// For tall pages with multiple scroll triggers we need to
// check the distnace from both the top of the page and the
// bottom
const distance = Math.min(
Math.abs( ( page.top + page.pageHeight / 2 ) - scrollTop - viewportHeight / 2 ),
Math.abs( ( page.top + ( page.totalHeight - page.pageHeight / 2 ) ) - scrollTop - viewportHeight / 2 )
);
return distance < closestPage.distance ? { page, distance } : closestPage;
}, { page: this.pages[0], distance: Infinity } ).page;