mirror of
https://github.com/hakimel/reveal.js.git
synced 2025-08-11 00:55:01 +02:00
reader mode; deeplink support, presentation scaling, scroll trigger fixes
This commit is contained in:
@@ -1885,6 +1885,7 @@ $notesWidthPercent: 25%;
|
|||||||
width: auto !important;
|
width: auto !important;
|
||||||
height: auto !important;
|
height: auto !important;
|
||||||
overflow: visible !important;
|
overflow: visible !important;
|
||||||
|
touch-action: manipulation;
|
||||||
}
|
}
|
||||||
.reveal .slides {
|
.reveal .slides {
|
||||||
position: static;
|
position: static;
|
||||||
|
@@ -174,24 +174,23 @@ export default class Fragments {
|
|||||||
*
|
*
|
||||||
* @return {{shown: array, hidden: array}}
|
* @return {{shown: array, hidden: array}}
|
||||||
*/
|
*/
|
||||||
update( index, fragments ) {
|
update( index, fragments, slide = this.Reveal.getCurrentSlide() ) {
|
||||||
|
|
||||||
let changedFragments = {
|
let changedFragments = {
|
||||||
shown: [],
|
shown: [],
|
||||||
hidden: []
|
hidden: []
|
||||||
};
|
};
|
||||||
|
|
||||||
let currentSlide = this.Reveal.getCurrentSlide();
|
if( slide && this.Reveal.getConfig().fragments ) {
|
||||||
if( currentSlide && this.Reveal.getConfig().fragments ) {
|
|
||||||
|
|
||||||
fragments = fragments || this.sort( currentSlide.querySelectorAll( '.fragment' ) );
|
fragments = fragments || this.sort( slide.querySelectorAll( '.fragment' ) );
|
||||||
|
|
||||||
if( fragments.length ) {
|
if( fragments.length ) {
|
||||||
|
|
||||||
let maxIndex = 0;
|
let maxIndex = 0;
|
||||||
|
|
||||||
if( typeof index !== 'number' ) {
|
if( typeof index !== 'number' ) {
|
||||||
let currentFragment = this.sort( currentSlide.querySelectorAll( '.fragment.visible' ) ).pop();
|
let currentFragment = this.sort( slide.querySelectorAll( '.fragment.visible' ) ).pop();
|
||||||
if( currentFragment ) {
|
if( currentFragment ) {
|
||||||
index = parseInt( currentFragment.getAttribute( 'data-fragment-index' ) || 0, 10 );
|
index = parseInt( currentFragment.getAttribute( 'data-fragment-index' ) || 0, 10 );
|
||||||
}
|
}
|
||||||
@@ -252,7 +251,7 @@ export default class Fragments {
|
|||||||
// the current fragment index.
|
// the current fragment index.
|
||||||
index = typeof index === 'number' ? index : -1;
|
index = typeof index === 'number' ? index : -1;
|
||||||
index = Math.max( Math.min( index, maxIndex ), -1 );
|
index = Math.max( Math.min( index, maxIndex ), -1 );
|
||||||
currentSlide.setAttribute( 'data-fragment', index );
|
slide.setAttribute( 'data-fragment', index );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -11,6 +11,9 @@ export default class Reader {
|
|||||||
|
|
||||||
this.Reveal = Reveal;
|
this.Reveal = Reveal;
|
||||||
|
|
||||||
|
this.activated = false;
|
||||||
|
this.activatedCallbacks = [];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async activate() {
|
async activate() {
|
||||||
@@ -90,6 +93,10 @@ export default class Reader {
|
|||||||
|
|
||||||
this.Reveal.layout();
|
this.Reveal.layout();
|
||||||
|
|
||||||
|
this.activated = true;
|
||||||
|
this.activatedCallbacks.forEach( callback => callback() );
|
||||||
|
this.activatedCallbacks = [];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -107,6 +114,9 @@ export default class Reader {
|
|||||||
|
|
||||||
generatePageMap() {
|
generatePageMap() {
|
||||||
|
|
||||||
|
const viewportElement = this.Reveal.getViewportElement();
|
||||||
|
const viewportHeight = viewportElement.offsetHeight;
|
||||||
|
|
||||||
const slideSize = this.Reveal.getComputedSlideSize( window.innerWidth, window.innerHeight );
|
const slideSize = this.Reveal.getComputedSlideSize( window.innerWidth, window.innerHeight );
|
||||||
const scale = this.Reveal.getScale();
|
const scale = this.Reveal.getScale();
|
||||||
|
|
||||||
@@ -116,6 +126,9 @@ export default class Reader {
|
|||||||
this.pageElements = Array.from( this.Reveal.getRevealElement().querySelectorAll( '.reader-page' ) );
|
this.pageElements = Array.from( this.Reveal.getRevealElement().querySelectorAll( '.reader-page' ) );
|
||||||
|
|
||||||
this.pageMap = this.pageElements.map( pageElement => {
|
this.pageMap = this.pageElements.map( pageElement => {
|
||||||
|
// pageElement.style.width = ( viewportElement.offsetWidth / scale ) + 'px';
|
||||||
|
// pageElement.style.height = ( viewportElement.offsetHeight / scale ) + 'px';
|
||||||
|
|
||||||
const page = {
|
const page = {
|
||||||
pageElement: pageElement,
|
pageElement: pageElement,
|
||||||
slideElement: pageElement.querySelector( 'section' ),
|
slideElement: pageElement.querySelector( 'section' ),
|
||||||
@@ -140,7 +153,7 @@ export default class Reader {
|
|||||||
page.bottom = page.top + page.totalHeight;
|
page.bottom = page.top + page.totalHeight;
|
||||||
|
|
||||||
// Pad the page height to reserve scrollable height
|
// Pad the page height to reserve scrollable height
|
||||||
page.pageElement.style.marginBottom = page.scrollHeight + 'px';
|
page.pageElement.style.marginBottom = page.scrollHeight / scale + 'px';
|
||||||
|
|
||||||
// Create scroll triggers that show/hide fragments
|
// Create scroll triggers that show/hide fragments
|
||||||
if( page.fragmentGroups.length ) {
|
if( page.fragmentGroups.length ) {
|
||||||
@@ -155,6 +168,9 @@ export default class Reader {
|
|||||||
fragmentIndex: i
|
fragmentIndex: i
|
||||||
}))
|
}))
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Make this page freeze at the vertical center of the viewport
|
||||||
|
page.top -= ( viewportHeight - page.pageHeight ) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
return page;
|
return page;
|
||||||
@@ -162,13 +178,24 @@ export default class Reader {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
update() {
|
layout() {
|
||||||
|
|
||||||
this.generatePageMap();
|
this.generatePageMap();
|
||||||
this.onScroll();
|
this.onScroll();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scrollToSlide( slideElement ) {
|
||||||
|
|
||||||
|
if( !this.activated ) {
|
||||||
|
this.activatedCallbacks.push( () => this.scrollToSlide( slideElement ) );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
slideElement.parentNode.scrollIntoView();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
onScroll() {
|
onScroll() {
|
||||||
|
|
||||||
const viewportElement = this.Reveal.getViewportElement();
|
const viewportElement = this.Reveal.getViewportElement();
|
||||||
@@ -196,7 +223,13 @@ export default class Reader {
|
|||||||
|
|
||||||
page.scrollTriggers.forEach( trigger => {
|
page.scrollTriggers.forEach( trigger => {
|
||||||
if( scrollProgress >= trigger.range[0] && scrollProgress < trigger.range[1] ) {
|
if( scrollProgress >= trigger.range[0] && scrollProgress < trigger.range[1] ) {
|
||||||
this.Reveal.fragments.update( trigger.fragmentIndex, page.fragments );
|
if( !trigger.active ) {
|
||||||
|
trigger.active = true;
|
||||||
|
this.Reveal.fragments.update( trigger.fragmentIndex, page.fragments, page.slideElement );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
trigger.active = false;
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
33
js/reveal.js
33
js/reveal.js
@@ -234,9 +234,13 @@ export default function( revealElement, options ) {
|
|||||||
// to be read or printed linearly
|
// to be read or printed linearly
|
||||||
if( isPrintMode || isReaderMode ) {
|
if( isPrintMode || isReaderMode ) {
|
||||||
|
|
||||||
removeEventListeners();
|
if( isPrintMode ) {
|
||||||
|
removeEventListeners();
|
||||||
window.addEventListener( 'resize', onWindowResize, false );
|
}
|
||||||
|
else {
|
||||||
|
keyboard.unbind();
|
||||||
|
touch.unbind();
|
||||||
|
}
|
||||||
|
|
||||||
// Avoid content flickering during layout
|
// Avoid content flickering during layout
|
||||||
revealElement.style.visibility = 'hidden';
|
revealElement.style.visibility = 'hidden';
|
||||||
@@ -896,7 +900,9 @@ export default function( revealElement, options ) {
|
|||||||
document.documentElement.style.setProperty( '--vh', ( window.innerHeight * 0.01 ) + 'px' );
|
document.documentElement.style.setProperty( '--vh', ( window.innerHeight * 0.01 ) + 'px' );
|
||||||
}
|
}
|
||||||
|
|
||||||
const size = getComputedSlideSize();
|
const size = reader.isActive() ?
|
||||||
|
getComputedSlideSize( dom.viewport.offsetWidth, dom.viewport.offsetHeight ) :
|
||||||
|
getComputedSlideSize();;
|
||||||
|
|
||||||
const oldScale = scale;
|
const oldScale = scale;
|
||||||
|
|
||||||
@@ -924,10 +930,10 @@ export default function( revealElement, options ) {
|
|||||||
}
|
}
|
||||||
else if( reader.isActive() ) {
|
else if( reader.isActive() ) {
|
||||||
dom.slides.style.zoom = '';
|
dom.slides.style.zoom = '';
|
||||||
dom.slides.style.left = 'auto';
|
dom.slides.style.left = '';
|
||||||
dom.slides.style.top = 'auto';
|
dom.slides.style.top = '';
|
||||||
dom.slides.style.bottom = 'auto';
|
dom.slides.style.bottom = '';
|
||||||
dom.slides.style.right = 'auto';
|
dom.slides.style.right = '';
|
||||||
dom.slides.style.height = 'auto';
|
dom.slides.style.height = 'auto';
|
||||||
transformSlides( { layout: 'scale('+ scale +')' } );
|
transformSlides( { layout: 'scale('+ scale +')' } );
|
||||||
}
|
}
|
||||||
@@ -981,9 +987,10 @@ export default function( revealElement, options ) {
|
|||||||
|
|
||||||
dom.viewport.style.setProperty( '--slide-scale', scale );
|
dom.viewport.style.setProperty( '--slide-scale', scale );
|
||||||
|
|
||||||
|
reader.layout();
|
||||||
|
|
||||||
progress.update();
|
progress.update();
|
||||||
backgrounds.updateParallax();
|
backgrounds.updateParallax();
|
||||||
reader.update();
|
|
||||||
|
|
||||||
if( overview.isActive() ) {
|
if( overview.isActive() ) {
|
||||||
overview.update();
|
overview.update();
|
||||||
@@ -1309,6 +1316,14 @@ export default function( revealElement, options ) {
|
|||||||
// Query all horizontal slides in the deck
|
// Query all horizontal slides in the deck
|
||||||
const horizontalSlides = dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR );
|
const horizontalSlides = dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR );
|
||||||
|
|
||||||
|
// If we're in reader mode we scroll the target slide into view
|
||||||
|
// instead of running our standard slide transition
|
||||||
|
if( reader.isActive() ) {
|
||||||
|
const scrollToSlide = dom.wrapper.querySelectorAll( SLIDES_SELECTOR )[ h ];
|
||||||
|
if( scrollToSlide ) reader.scrollToSlide( scrollToSlide );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Abort if there are no slides
|
// Abort if there are no slides
|
||||||
if( horizontalSlides.length === 0 ) return;
|
if( horizontalSlides.length === 0 ) return;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user