mirror of
https://github.com/hakimel/reveal.js.git
synced 2025-08-05 06:07:37 +02:00
reader mode supports scroll snapping, sticky pages with scroll triggers are always full height
This commit is contained in:
@@ -1934,6 +1934,7 @@ $notesWidthPercent: 25%;
|
||||
top: 50% !important;
|
||||
left: 50% !important;
|
||||
opacity: 1 !important;
|
||||
transform: scale(var(--slide-scale)) translate(-50%, -50%) !important;
|
||||
transform-style: flat !important;
|
||||
transform-origin: 0 0 !important;
|
||||
}
|
||||
|
2
dist/reveal.css
vendored
2
dist/reveal.css
vendored
File diff suppressed because one or more lines are too long
2
dist/reveal.esm.js
vendored
2
dist/reveal.esm.js
vendored
File diff suppressed because one or more lines are too long
2
dist/reveal.esm.js.map
vendored
2
dist/reveal.esm.js.map
vendored
File diff suppressed because one or more lines are too long
2
dist/reveal.js
vendored
2
dist/reveal.js
vendored
File diff suppressed because one or more lines are too long
2
dist/reveal.js.map
vendored
2
dist/reveal.js.map
vendored
File diff suppressed because one or more lines are too long
17
js/config.js
17
js/config.js
@@ -262,10 +262,19 @@ export default {
|
||||
// triggered animations
|
||||
view: null,
|
||||
|
||||
// When the presentation is in reader mode, this controls whether each
|
||||
// page should be as tall as the presentation viewport. Set this to false
|
||||
// for a more compact layout with multiple slides visible at a time.
|
||||
readerFullPageHeight: true,
|
||||
// Adjusts the height of each slide in reader mode
|
||||
// - full: Each slide is as tall as the viewport
|
||||
// - compact: Slides are as small as possible, allowing multiple slides
|
||||
// to be visible in parallel on tall devices
|
||||
readerLayout: 'full',
|
||||
|
||||
// Control how scroll snapping works in reader mode.
|
||||
// - false: No snapping, scrolling is continuous
|
||||
// - proximity: Snap when close to a slide
|
||||
// - mandatory: Always snap to the closest slide
|
||||
//
|
||||
// Only applies to presentations in reader mode.
|
||||
readerScrollSnap: 'proximity',
|
||||
|
||||
// The maximum number of pages a single slide can expand onto when printing
|
||||
// to PDF, unlimited by default
|
||||
|
@@ -62,9 +62,6 @@ export default class Reader {
|
||||
page.className = 'reader-page';
|
||||
pageElements.push( page );
|
||||
|
||||
slide.style.width = slideWidth + 'px';
|
||||
// slide.style.height = slideHeight + 'px';
|
||||
|
||||
// Copy the presentation-wide background to each individual
|
||||
// page when printing
|
||||
if( presentationBackground ) {
|
||||
@@ -143,21 +140,29 @@ export default class Reader {
|
||||
|
||||
}
|
||||
|
||||
generatePageMap() {
|
||||
/**
|
||||
* Updates our reader pages to match the latest configuration and
|
||||
* presentation size.
|
||||
*/
|
||||
sync() {
|
||||
|
||||
const viewportElement = this.Reveal.getViewportElement();
|
||||
const viewportHeight = viewportElement.offsetHeight;
|
||||
const config = this.Reveal.getConfig();
|
||||
|
||||
const slideSize = this.Reveal.getComputedSlideSize( window.innerWidth, window.innerHeight );
|
||||
const scale = this.Reveal.getScale();
|
||||
const fullPageHeight = this.Reveal.getConfig().readerFullPageHeight;
|
||||
const readerLayout = config.readerLayout;
|
||||
|
||||
const pageHeight = fullPageHeight === true ? viewportHeight : slideSize.height * scale;
|
||||
const viewportElement = this.Reveal.getViewportElement();
|
||||
const viewportHeight = viewportElement.offsetHeight;
|
||||
const compactHeight = slideSize.height * scale;
|
||||
const pageHeight = readerLayout === 'full' ? viewportHeight : compactHeight;
|
||||
|
||||
// The height that needs to be scrolled between scroll triggers
|
||||
const scrollTriggerHeight = viewportHeight / 2;
|
||||
|
||||
viewportElement.style.setProperty( '--page-height', pageHeight + 'px' );
|
||||
viewportElement.style.scrollSnapType = typeof config.readerScrollSnap === 'string' ?
|
||||
`y ${config.readerScrollSnap}` : '';
|
||||
|
||||
const pageElements = Array.from( this.Reveal.getRevealElement().querySelectorAll( '.reader-page' ) );
|
||||
|
||||
@@ -168,36 +173,18 @@ export default class Reader {
|
||||
slideElement: pageElement.querySelector( 'section' ),
|
||||
backgroundElement: pageElement.querySelector( '.slide-background' ),
|
||||
top: pageElement.offsetTop,
|
||||
pageHeight: pageHeight,
|
||||
scrollTriggers: []
|
||||
};
|
||||
|
||||
page.slideElement.style.width = slideSize.width + 'px';
|
||||
page.slideElement.style.height = config.center === true ? '' : slideSize.height + 'px';
|
||||
|
||||
// Each fragment 'group' is an array containing one or more
|
||||
// fragments. Multiple fragments that appear at the same time
|
||||
// are part of the same group.
|
||||
page.fragments = this.Reveal.fragments.sort( pageElement.querySelectorAll( '.fragment:not(.disabled)' ) );
|
||||
page.fragmentGroups = this.Reveal.fragments.sort( pageElement.querySelectorAll( '.fragment' ), true );
|
||||
|
||||
// The amount of empty scrollable space that has been append
|
||||
page.scrollPadding = scrollTriggerHeight * Math.max( page.fragmentGroups.length - 1, 0 );
|
||||
|
||||
// This variable is used to pad the height of our page in CSS
|
||||
page.pageElement.style.setProperty( '--page-scroll-padding', page.scrollPadding + 'px' );
|
||||
|
||||
// The total height including scrollable space
|
||||
page.totalHeight = page.pageHeight + page.scrollPadding;
|
||||
|
||||
page.bottom = page.top + page.totalHeight;
|
||||
|
||||
// If this is a sticky page, stick it to the vertical center
|
||||
if( page.scrollPadding > 0 ) {
|
||||
page.stickyElement.style.position = 'sticky';
|
||||
page.stickyElement.style.top = Math.max( ( viewportHeight - page.pageHeight ) / 2, 0 ) + 'px';
|
||||
}
|
||||
else {
|
||||
page.stickyElement.style.position = 'relative';
|
||||
}
|
||||
|
||||
// Create scroll triggers that show/hide fragments
|
||||
if( page.fragmentGroups.length ) {
|
||||
const segmentSize = 1 / ( page.fragmentGroups.length + 1 );
|
||||
@@ -211,10 +198,45 @@ export default class Reader {
|
||||
fragmentIndex: i
|
||||
}))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// Add scroll padding based on how many scroll triggers we have
|
||||
page.scrollPadding = scrollTriggerHeight * page.scrollTriggers.length;
|
||||
|
||||
// In the compact layout, only slides with scroll triggers cover the
|
||||
// full viewport height. This helps avoid empty gaps before or after
|
||||
// a sticky slide.
|
||||
if( readerLayout === 'compact' && page.scrollTriggers.length > 0 ) {
|
||||
page.pageHeight = viewportHeight;
|
||||
page.pageElement.style.setProperty( '--page-height', viewportHeight + 'px' );
|
||||
}
|
||||
else {
|
||||
page.pageHeight = pageHeight;
|
||||
page.pageElement.style.removeProperty( '--page-height' );
|
||||
}
|
||||
|
||||
page.pageElement.style.scrollSnapAlign = page.pageHeight < viewportHeight ? 'center' : 'start';
|
||||
|
||||
// This variable is used to pad the height of our page in CSS
|
||||
page.pageElement.style.setProperty( '--page-scroll-padding', page.scrollPadding + 'px' );
|
||||
|
||||
// The total height including scrollable space
|
||||
page.totalHeight = page.pageHeight + page.scrollPadding;
|
||||
|
||||
page.bottom = page.top + page.totalHeight;
|
||||
|
||||
// If this is a sticky page, stick it to the vertical center
|
||||
if( page.scrollTriggers.length > 0 ) {
|
||||
page.stickyElement.style.position = 'sticky';
|
||||
page.stickyElement.style.top = Math.max( ( viewportHeight - page.pageHeight ) / 2, 0 ) + 'px';
|
||||
|
||||
// Make this page freeze at the vertical center of the viewport
|
||||
page.top -= ( viewportHeight - page.pageHeight ) / 2;
|
||||
}
|
||||
else {
|
||||
page.stickyElement.style.position = 'relative';
|
||||
}
|
||||
|
||||
return page;
|
||||
} );
|
||||
@@ -223,15 +245,7 @@ export default class Reader {
|
||||
|
||||
layout() {
|
||||
|
||||
this.generatePageMap();
|
||||
|
||||
const scale = this.Reveal.getScale();
|
||||
|
||||
this.pages.forEach( ( page ) => {
|
||||
page.slideElement.style.transform = `scale(${scale}) translate(-50%, -50%)`;
|
||||
} );
|
||||
|
||||
|
||||
this.sync();
|
||||
this.onScroll();
|
||||
|
||||
}
|
||||
|
@@ -2744,7 +2744,7 @@ export default function( revealElement, options ) {
|
||||
isFocused: focus.isFocused.bind( focus ),
|
||||
|
||||
isReaderMode: reader.isActive.bind( reader ),
|
||||
isPrintMode: print.isActive.bind( print ),
|
||||
isPrinting: print.isActive.bind( print ),
|
||||
|
||||
// Checks if reveal.js has been loaded and is ready for use
|
||||
isReady: () => ready,
|
||||
|
Reference in New Issue
Block a user