mirror of
https://github.com/hakimel/reveal.js.git
synced 2025-08-01 12:20:33 +02:00
reader mode -> scroll view, auto-enable below 435px width
This commit is contained in:
@@ -1868,13 +1868,13 @@ $notesWidthPercent: 25%;
|
||||
|
||||
|
||||
/*********************************************
|
||||
* READER MODE
|
||||
* SCROLL VIEW
|
||||
*********************************************/
|
||||
.reveal-viewport.loading-scroll-mode {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.reveal-viewport.reveal-reader {
|
||||
.reveal-viewport.reveal-scroll {
|
||||
& {
|
||||
margin: 0 auto !important;
|
||||
overflow: auto;
|
||||
@@ -1882,14 +1882,14 @@ $notesWidthPercent: 25%;
|
||||
overflow-y: auto;
|
||||
z-index: 1;
|
||||
|
||||
--r-reader-progress-width: 7px;
|
||||
--r-reader-progress-trigger-size: 5px;
|
||||
--r-scrollbar-width: 7px;
|
||||
--r-scrollbar-trigger-size: 5px;
|
||||
--r-controls-spacing: 8px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 500px) {
|
||||
--r-reader-progress-width: 3px;
|
||||
--r-reader-progress-trigger-size: 3px;
|
||||
--r-scrollbar-width: 3px;
|
||||
--r-scrollbar-trigger-size: 3px;
|
||||
}
|
||||
|
||||
.controls,
|
||||
@@ -1923,7 +1923,7 @@ $notesWidthPercent: 25%;
|
||||
perspective-origin: 50% 50%;
|
||||
}
|
||||
|
||||
.reader-page {
|
||||
.scroll-page {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: calc(var(--page-height) + var(--page-scroll-padding));
|
||||
@@ -1931,13 +1931,13 @@ $notesWidthPercent: 25%;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.reader-page-sticky {
|
||||
.scroll-page-sticky {
|
||||
position: sticky;
|
||||
height: var(--page-height);
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
.reader-page-content {
|
||||
.scroll-page-content {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
@@ -1946,7 +1946,7 @@ $notesWidthPercent: 25%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.reader-page section {
|
||||
.scroll-page section {
|
||||
visibility: visible !important;
|
||||
display: block !important;
|
||||
position: absolute !important;
|
||||
@@ -1975,14 +1975,14 @@ $notesWidthPercent: 25%;
|
||||
}
|
||||
|
||||
// Chromium
|
||||
.reveal-viewport.reveal-reader[data-reader-scroll-bar="true"]::-webkit-scrollbar,
|
||||
.reveal-viewport.reveal-reader[data-reader-scroll-bar="auto"]::-webkit-scrollbar {
|
||||
.reveal-viewport.reveal-scroll[data-scrollbar="true"]::-webkit-scrollbar,
|
||||
.reveal-viewport.reveal-scroll[data-scrollbar="auto"]::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
// Firefox
|
||||
.reveal-viewport.reveal-reader[data-reader-scroll-bar="true"],
|
||||
.reveal-viewport.reveal-reader[data-reader-scroll-bar="auto"] {
|
||||
.reveal-viewport.reveal-scroll[data-scrollbar="true"],
|
||||
.reveal-viewport.reveal-scroll[data-scrollbar="auto"] {
|
||||
scrollbar-width: none;
|
||||
}
|
||||
|
||||
@@ -1997,7 +1997,7 @@ $notesWidthPercent: 25%;
|
||||
--r-overlay-element-fg-color: 240, 240, 240;
|
||||
}
|
||||
|
||||
.reveal-viewport.reveal-reader .reader-progress {
|
||||
.reveal-viewport.reveal-scroll .scrollbar {
|
||||
position: sticky;
|
||||
top: 50%;
|
||||
z-index: 20;
|
||||
@@ -2009,40 +2009,40 @@ $notesWidthPercent: 25%;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.reader-progress-inner {
|
||||
.scrollbar-inner {
|
||||
position: absolute;
|
||||
width: var(--r-reader-progress-width);
|
||||
width: var(--r-scrollbar-width);
|
||||
height: calc(var(--viewport-height) - var(--r-controls-spacing) * 2);
|
||||
right: var(--r-controls-spacing);
|
||||
top: 0;
|
||||
transform: translateY(-50%);
|
||||
border-radius: var(--r-reader-progress-width);
|
||||
border-radius: var(--r-scrollbar-width);
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.reader-progress-playhead {
|
||||
.scrollbar-playhead {
|
||||
position: absolute;
|
||||
width: var(--r-reader-progress-width);
|
||||
height: var(--r-reader-progress-width);
|
||||
width: var(--r-scrollbar-width);
|
||||
height: var(--r-scrollbar-width);
|
||||
top: 0;
|
||||
left: 0;
|
||||
border-radius: var(--r-reader-progress-width);
|
||||
border-radius: var(--r-scrollbar-width);
|
||||
background-color: rgba(var(--r-overlay-element-bg-color), 1);
|
||||
z-index: 11;
|
||||
transition: background-color 0.2s ease;
|
||||
}
|
||||
|
||||
.reader-progress-slide {
|
||||
.scrollbar-slide {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
background-color: rgba(var(--r-overlay-element-bg-color), 0.2);
|
||||
box-shadow: 0 0 0px 1px rgba(var(--r-overlay-element-fg-color), 0.1);
|
||||
border-radius: var(--r-reader-progress-width);
|
||||
border-radius: var(--r-scrollbar-width);
|
||||
transition: background-color 0.2s ease;
|
||||
}
|
||||
|
||||
// Hit area
|
||||
.reader-progress-slide:after {
|
||||
.scrollbar-slide:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 200%;
|
||||
@@ -2053,27 +2053,27 @@ $notesWidthPercent: 25%;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.reader-progress-slide:hover,
|
||||
.reader-progress-slide.active {
|
||||
.scrollbar-slide:hover,
|
||||
.scrollbar-slide.active {
|
||||
background-color: rgba(var(--r-overlay-element-bg-color), 0.4);
|
||||
}
|
||||
|
||||
.reader-progress-trigger {
|
||||
.scrollbar-trigger {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
transition: background-color 0.2s ease;
|
||||
}
|
||||
|
||||
.reader-progress-slide.active.has-triggers {
|
||||
.scrollbar-slide.active.has-triggers {
|
||||
background-color: rgba(var(--r-overlay-element-bg-color), 0.4);
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.reader-progress-slide.active .reader-progress-trigger:after {
|
||||
.scrollbar-slide.active .scrollbar-trigger:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: var(--r-reader-progress-trigger-size);
|
||||
height: var(--r-reader-progress-trigger-size);
|
||||
width: var(--r-scrollbar-trigger-size);
|
||||
height: var(--r-scrollbar-trigger-size);
|
||||
border-radius: 20px;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
@@ -2083,13 +2083,13 @@ $notesWidthPercent: 25%;
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
.reader-progress-slide.active .reader-progress-trigger.active:after,
|
||||
.reader-progress-slide.active .reader-progress-trigger.active ~ .reader-progress-trigger:after {
|
||||
.scrollbar-slide.active .scrollbar-trigger.active:after,
|
||||
.scrollbar-slide.active .scrollbar-trigger.active ~ .scrollbar-trigger:after {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.reader-progress-slide.active .reader-progress-trigger ~ .reader-progress-trigger.active:after {
|
||||
transform: translate(calc( var(--r-reader-progress-width) * -2), 0);
|
||||
.scrollbar-slide.active .scrollbar-trigger ~ .scrollbar-trigger.active:after {
|
||||
transform: translate(calc( var(--r-scrollbar-width) * -2), 0);
|
||||
background-color: rgba(var(--r-overlay-element-bg-color), 1);
|
||||
}
|
||||
}
|
||||
|
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
@@ -4,7 +4,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>reveal.js - Reader Mode</title>
|
||||
<title>reveal.js - Scroll View</title>
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
<div class="slides">
|
||||
|
||||
<section><h1>Reader Mode</h1></section>
|
||||
<section><h1>Scroll View</h1></section>
|
||||
<section data-background="indigo">
|
||||
<h2>Scroll triggers</h2>
|
||||
<ul>
|
||||
@@ -111,7 +111,7 @@
|
||||
<script src="../plugin/highlight/highlight.js"></script>
|
||||
<script>
|
||||
Reveal.initialize({
|
||||
view: 'reader',
|
||||
view: 'scroll',
|
||||
hash: true,
|
||||
|
||||
plugins: [ RevealMarkdown, RevealHighlight, RevealNotes ]
|
22
js/config.js
22
js/config.js
@@ -258,33 +258,33 @@ export default {
|
||||
|
||||
// Can be used to initialize reveal.js in one of the following views:
|
||||
// - print: Render the presentation so that it can be printed to PDF
|
||||
// - reader: Show the presentation as a tall scrollable page with scroll
|
||||
// - scroll: Show the presentation as a tall scrollable page with scroll
|
||||
// triggered animations
|
||||
view: null,
|
||||
|
||||
// Adjusts the height of each slide in reader mode
|
||||
// Adjusts the height of each slide in the scroll view.
|
||||
// - 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',
|
||||
scrollLayout: 'full',
|
||||
|
||||
// Control how scroll snapping works in reader mode.
|
||||
// Control how scroll snapping works in the scroll view.
|
||||
// - 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: 'mandatory',
|
||||
// Only applies to presentations in scroll view.
|
||||
scrollSnap: 'mandatory',
|
||||
|
||||
// Enables and configure the reader mode scroll bar.
|
||||
// Enables and configure the scroll view progress bar.
|
||||
// - 'auto': Show the scrollbar while scrolling, hide while idle
|
||||
// - true: Always show the scrollbar
|
||||
// - false: Never show the scrollbar
|
||||
readerScrollbar: 'auto',
|
||||
scrollProgress: 'auto',
|
||||
|
||||
// Responsively activate the reader mode when we reach the specified
|
||||
// width (in pixels)
|
||||
readerActivationWidth: null,
|
||||
// Automatically activate the scroll view when we the viewport falls
|
||||
// below the given width.
|
||||
scrollActivationWidth: 435,
|
||||
|
||||
// The maximum number of pages a single slide can expand onto when printing
|
||||
// to PDF, unlimited by default
|
||||
|
@@ -40,8 +40,8 @@ export default class Notes {
|
||||
|
||||
if( this.Reveal.getConfig().showNotes &&
|
||||
this.element && this.Reveal.getCurrentSlide() &&
|
||||
!this.Reveal.isReaderMode() &&
|
||||
!this.Reveal.isPrinting()
|
||||
!this.Reveal.isScrollView() &&
|
||||
!this.Reveal.isPrintView()
|
||||
) {
|
||||
this.element.innerHTML = this.getSlideNotes() || '<span class="notes-placeholder">No notes on this slide.</span>';
|
||||
}
|
||||
@@ -58,8 +58,8 @@ export default class Notes {
|
||||
|
||||
if( this.Reveal.getConfig().showNotes &&
|
||||
this.hasNotes() &&
|
||||
!this.Reveal.isReaderMode() &&
|
||||
!this.Reveal.isPrinting()
|
||||
!this.Reveal.isScrollView() &&
|
||||
!this.Reveal.isPrintView()
|
||||
) {
|
||||
this.Reveal.getRevealElement().classList.add( 'show-notes' );
|
||||
}
|
||||
|
@@ -24,7 +24,7 @@ export default class Overview {
|
||||
activate() {
|
||||
|
||||
// Only proceed if enabled in config
|
||||
if( this.Reveal.getConfig().overview && !this.Reveal.isReaderMode() && !this.isActive() ) {
|
||||
if( this.Reveal.getConfig().overview && !this.Reveal.isScrollView() && !this.isActive() ) {
|
||||
|
||||
this.active = true;
|
||||
|
||||
|
@@ -4,7 +4,7 @@ import { queryAll, createStyleSheet } from '../utils/util.js'
|
||||
/**
|
||||
* Setups up our presentation for printing/exporting to PDF.
|
||||
*/
|
||||
export default class Print {
|
||||
export default class PrintView {
|
||||
|
||||
constructor( Reveal ) {
|
||||
|
@@ -7,10 +7,10 @@ const MIN_PROGRESS_SEGMENT_HEIGHT = 6;
|
||||
const MIN_PLAYHEAD_HEIGHT = 8;
|
||||
|
||||
/**
|
||||
* The reader mode lets you read a reveal.js presentation
|
||||
* The scroll view lets you read a reveal.js presentation
|
||||
* as a linear scrollable page.
|
||||
*/
|
||||
export default class Reader {
|
||||
export default class ScrollView {
|
||||
|
||||
constructor( Reveal ) {
|
||||
|
||||
@@ -24,7 +24,7 @@ export default class Reader {
|
||||
}
|
||||
|
||||
/**
|
||||
* Activates the reader mode. This rearranges the presentation DOM
|
||||
* Activates the scroll view. This rearranges the presentation DOM
|
||||
* by—among other things—wrapping each slide in a page element.
|
||||
*/
|
||||
activate() {
|
||||
@@ -36,12 +36,12 @@ export default class Reader {
|
||||
this.active = true;
|
||||
|
||||
// Store the full presentation HTML so that we can restore it
|
||||
// when/if the reader mode is deactivated
|
||||
// when/if the scroll view is deactivated
|
||||
this.slideHTMLBeforeActivation = this.Reveal.getSlidesElement().innerHTML;
|
||||
|
||||
const horizontalSlides = queryAll( this.Reveal.getRevealElement(), HORIZONTAL_SLIDES_SELECTOR );
|
||||
|
||||
this.viewportElement.classList.add( 'loading-scroll-mode', 'reveal-reader' );
|
||||
this.viewportElement.classList.add( 'loading-scroll-mode', 'reveal-scroll' );
|
||||
|
||||
let presentationBackground;
|
||||
|
||||
@@ -65,15 +65,15 @@ export default class Reader {
|
||||
// group it under the same page element as the previous slide
|
||||
if( previousSlide && this.Reveal.shouldAutoAnimateBetween( previousSlide, slide ) ) {
|
||||
contentContainer = document.createElement( 'div' );
|
||||
contentContainer.className = 'reader-page-content reader-auto-animate-page';
|
||||
contentContainer.className = 'scroll-page-content scroll-auto-animate-page';
|
||||
contentContainer.style.display = 'none';
|
||||
previousSlide.closest( '.reader-page-content' ).parentNode.appendChild( contentContainer );
|
||||
previousSlide.closest( '.scroll-page-content' ).parentNode.appendChild( contentContainer );
|
||||
}
|
||||
else {
|
||||
// Wrap the slide in a page element and hide its overflow
|
||||
// so that no page ever flows onto another
|
||||
const page = document.createElement( 'div' );
|
||||
page.className = 'reader-page';
|
||||
page.className = 'scroll-page';
|
||||
pageElements.push( page );
|
||||
|
||||
// Copy the presentation-wide background to each page
|
||||
@@ -82,11 +82,11 @@ export default class Reader {
|
||||
}
|
||||
|
||||
const stickyContainer = document.createElement( 'div' );
|
||||
stickyContainer.className = 'reader-page-sticky';
|
||||
stickyContainer.className = 'scroll-page-sticky';
|
||||
page.appendChild( stickyContainer );
|
||||
|
||||
contentContainer = document.createElement( 'div' );
|
||||
contentContainer.className = 'reader-page-content';
|
||||
contentContainer.className = 'scroll-page-content';
|
||||
stickyContainer.appendChild( contentContainer );
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ export default class Reader {
|
||||
}
|
||||
|
||||
/**
|
||||
* Deactivates the reader mode and restores the standard slide-based
|
||||
* Deactivates the scroll view and restores the standard slide-based
|
||||
* presentation.
|
||||
*/
|
||||
deactivate() {
|
||||
@@ -156,7 +156,7 @@ export default class Reader {
|
||||
this.active = false;
|
||||
|
||||
this.viewportElement.removeEventListener( 'scroll', this.onScroll );
|
||||
this.viewportElement.classList.remove( 'reveal-reader' );
|
||||
this.viewportElement.classList.remove( 'reveal-scroll' );
|
||||
|
||||
this.removeProgressBar();
|
||||
|
||||
@@ -180,7 +180,7 @@ export default class Reader {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the reader mode is currently active.
|
||||
* Checks if the scroll view is currently active.
|
||||
*/
|
||||
isActive() {
|
||||
|
||||
@@ -194,14 +194,14 @@ export default class Reader {
|
||||
createProgressBar() {
|
||||
|
||||
this.progressBar = document.createElement( 'div' );
|
||||
this.progressBar.className = 'reader-progress';
|
||||
this.progressBar.className = 'scrollbar';
|
||||
|
||||
this.progressBarInner = document.createElement( 'div' );
|
||||
this.progressBarInner.className = 'reader-progress-inner';
|
||||
this.progressBarInner.className = 'scrollbar-inner';
|
||||
this.progressBar.appendChild( this.progressBarInner );
|
||||
|
||||
this.progressBarPlayhead = document.createElement( 'div' );
|
||||
this.progressBarPlayhead.className = 'reader-progress-playhead';
|
||||
this.progressBarPlayhead.className = 'scrollbar-playhead';
|
||||
this.progressBarInner.appendChild( this.progressBarPlayhead );
|
||||
|
||||
this.viewportElement.insertBefore( this.progressBar, this.viewportElement.firstChild );
|
||||
@@ -261,7 +261,7 @@ export default class Reader {
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates our reader pages to match the latest configuration and
|
||||
* Updates our pages to match the latest configuration and
|
||||
* presentation size.
|
||||
*/
|
||||
syncPages() {
|
||||
@@ -270,7 +270,7 @@ export default class Reader {
|
||||
|
||||
const slideSize = this.Reveal.getComputedSlideSize( window.innerWidth, window.innerHeight );
|
||||
const scale = this.Reveal.getScale();
|
||||
const useCompactLayout = config.readerLayout === 'compact';
|
||||
const useCompactLayout = config.scrollLayout === 'compact';
|
||||
|
||||
const viewportHeight = this.viewportElement.offsetHeight;
|
||||
const compactHeight = slideSize.height * scale;
|
||||
@@ -280,22 +280,21 @@ export default class Reader {
|
||||
const scrollTriggerHeight = useCompactLayout ? compactHeight : viewportHeight;
|
||||
|
||||
this.viewportElement.style.setProperty( '--page-height', pageHeight + 'px' );
|
||||
this.viewportElement.style.scrollSnapType = typeof config.readerScrollSnap === 'string' ?
|
||||
`y ${config.readerScrollSnap}` : '';
|
||||
this.viewportElement.style.scrollSnapType = typeof config.scrollSnap === 'string' ? `y ${config.scrollSnap}` : '';
|
||||
|
||||
// This will hold all scroll triggers used to show/hide slides
|
||||
this.slideTriggers = [];
|
||||
|
||||
const pageElements = Array.from( this.Reveal.getRevealElement().querySelectorAll( '.reader-page' ) );
|
||||
const pageElements = Array.from( this.Reveal.getRevealElement().querySelectorAll( '.scroll-page' ) );
|
||||
|
||||
this.pages = pageElements.map( pageElement => {
|
||||
const page = this.createPage({
|
||||
pageElement,
|
||||
slideElement: pageElement.querySelector( 'section' ),
|
||||
stickyElement: pageElement.querySelector( '.reader-page-sticky' ),
|
||||
contentElement: pageElement.querySelector( '.reader-page-content' ),
|
||||
stickyElement: pageElement.querySelector( '.scroll-page-sticky' ),
|
||||
contentElement: pageElement.querySelector( '.scroll-page-content' ),
|
||||
backgroundElement: pageElement.querySelector( '.slide-background' ),
|
||||
autoAnimateElements: pageElement.querySelectorAll( '.reader-auto-animate-page' ),
|
||||
autoAnimateElements: pageElement.querySelectorAll( '.scroll-auto-animate-page' ),
|
||||
autoAnimatePages: []
|
||||
});
|
||||
|
||||
@@ -324,7 +323,7 @@ export default class Reader {
|
||||
}, page.autoAnimatePages.length );
|
||||
|
||||
// Clean up from previous renders
|
||||
page.pageElement.querySelectorAll( '.reader-snap-point' ).forEach( el => el.remove() );
|
||||
page.pageElement.querySelectorAll( '.scroll-snap-point' ).forEach( el => el.remove() );
|
||||
|
||||
// Create snap points for all scroll triggers
|
||||
// - Can't be absolute in FF
|
||||
@@ -333,7 +332,7 @@ export default class Reader {
|
||||
// inner triggers won't work
|
||||
for( let i = 0; i < totalScrollTriggerCount + 1; i++ ) {
|
||||
const triggerStick = document.createElement( 'div' );
|
||||
triggerStick.className = 'reader-snap-point';
|
||||
triggerStick.className = 'scroll-snap-point';
|
||||
triggerStick.style.height = scrollTriggerHeight + 'px';
|
||||
triggerStick.style.scrollSnapAlign = useCompactLayout ? 'center' : 'start';
|
||||
page.pageElement.appendChild( triggerStick );
|
||||
@@ -390,9 +389,9 @@ export default class Reader {
|
||||
}))
|
||||
*/
|
||||
|
||||
this.viewportElement.setAttribute( 'data-reader-scroll-bar', config.readerScrollbar );
|
||||
this.viewportElement.setAttribute( 'data-scrollbar', config.scrollProgress );
|
||||
|
||||
if( config.readerScrollbar && this.totalScrollTriggerCount > 1 ) {
|
||||
if( config.scrollProgress && this.totalScrollTriggerCount > 1 ) {
|
||||
// Create the progress bar if it doesn't already exist
|
||||
if( !this.progressBar ) this.createProgressBar();
|
||||
|
||||
@@ -534,7 +533,7 @@ export default class Reader {
|
||||
*/
|
||||
syncProgressBar() {
|
||||
|
||||
this.progressBarInner.querySelectorAll( '.reader-progress-slide' ).forEach( slide => slide.remove() );
|
||||
this.progressBarInner.querySelectorAll( '.scrollbar-slide' ).forEach( slide => slide.remove() );
|
||||
|
||||
const scrollHeight = this.viewportElement.scrollHeight;
|
||||
const viewportHeight = this.viewportElement.offsetHeight;
|
||||
@@ -558,7 +557,7 @@ export default class Reader {
|
||||
|
||||
// Visual representation of a slide
|
||||
page.progressBarSlide = document.createElement( 'div' );
|
||||
page.progressBarSlide.className = 'reader-progress-slide';
|
||||
page.progressBarSlide.className = 'scrollbar-slide';
|
||||
page.progressBarSlide.style.top = slideTrigger.range[0] * this.progressBarHeight + 'px';
|
||||
page.progressBarSlide.style.height = ( slideTrigger.range[1] - slideTrigger.range[0] ) * this.progressBarHeight - spacing + 'px';
|
||||
page.progressBarSlide.classList.toggle( 'has-triggers', page.scrollTriggers.length > 0 );
|
||||
@@ -568,7 +567,7 @@ export default class Reader {
|
||||
page.scrollTriggerElements = page.scrollTriggers.map( ( trigger, i ) => {
|
||||
|
||||
const triggerElement = document.createElement( 'div' );
|
||||
triggerElement.className = 'reader-progress-trigger';
|
||||
triggerElement.className = 'scrollbar-trigger';
|
||||
triggerElement.style.top = ( trigger.range[0] - slideTrigger.range[0] ) * this.progressBarHeight + 'px';
|
||||
triggerElement.style.height = ( trigger.range[1] - trigger.range[0] ) * this.progressBarHeight - spacing + 'px';
|
||||
page.progressBarSlide.appendChild( triggerElement );
|
||||
@@ -688,10 +687,12 @@ export default class Reader {
|
||||
|
||||
clearTimeout( this.hideProgressBarTimeout );
|
||||
|
||||
if( this.Reveal.getConfig().readerScrollbar === 'auto' && !this.draggingProgressBar ) {
|
||||
if( this.Reveal.getConfig().scrollProgress === 'auto' && !this.draggingProgressBar ) {
|
||||
|
||||
this.hideProgressBarTimeout = setTimeout( () => {
|
||||
this.progressBar.classList.remove( 'visible' );
|
||||
if( this.progressBar ) {
|
||||
this.progressBar.classList.remove( 'visible' );
|
||||
}
|
||||
}, HIDE_SCROLLBAR_TIMEOUT );
|
||||
|
||||
}
|
||||
@@ -705,7 +706,7 @@ export default class Reader {
|
||||
*/
|
||||
scrollToSlide( slideElement ) {
|
||||
|
||||
// If the reader mode isn't active yet, queue this action
|
||||
// If the scroll view isn't active yet, queue this action
|
||||
if( !this.active ) {
|
||||
this.activatedCallbacks.push( () => this.scrollToSlide( slideElement ) );
|
||||
}
|
||||
@@ -730,8 +731,8 @@ export default class Reader {
|
||||
clearTimeout( this.storeScrollPositionTimeout );
|
||||
|
||||
this.storeScrollPositionTimeout = setTimeout( () => {
|
||||
sessionStorage.setItem( 'reveal-reader-scroll', this.viewportElement.scrollTop );
|
||||
sessionStorage.setItem( 'reveal-reader-scroll-origin', location.origin + location.pathname );
|
||||
sessionStorage.setItem( 'reveal-scroll-top', this.viewportElement.scrollTop );
|
||||
sessionStorage.setItem( 'reveal-scroll-origin', location.origin + location.pathname );
|
||||
|
||||
this.storeScrollPositionTimeout = null;
|
||||
}, 50 );
|
||||
@@ -743,8 +744,8 @@ export default class Reader {
|
||||
*/
|
||||
restoreScrollPosition() {
|
||||
|
||||
const scrollPosition = sessionStorage.getItem( 'reveal-reader-scroll' );
|
||||
const scrollOrigin = sessionStorage.getItem( 'reveal-reader-scroll-origin' );
|
||||
const scrollPosition = sessionStorage.getItem( 'reveal-scroll-top' );
|
||||
const scrollOrigin = sessionStorage.getItem( 'reveal-scroll-origin' );
|
||||
|
||||
if( scrollPosition && scrollOrigin === location.origin + location.pathname ) {
|
||||
this.viewportElement.scrollTop = parseInt( scrollPosition, 10 );
|
||||
@@ -769,15 +770,18 @@ export default class Reader {
|
||||
contentElement.style.display = 'block';
|
||||
|
||||
slideElement.classList.add( 'present' );
|
||||
backgroundElement.classList.add( 'present' );
|
||||
|
||||
this.Reveal.setCurrentReaderPage( slideElement, indexh, indexv );
|
||||
if( backgroundElement ) {
|
||||
backgroundElement.classList.add( 'present' );
|
||||
}
|
||||
|
||||
this.Reveal.setCurrentScrollPage( slideElement, indexh, indexv );
|
||||
this.Reveal.backgrounds.bubbleSlideContrastClassToElement( slideElement, this.viewportElement );
|
||||
|
||||
// If this page is part of an auto-animation there will be one
|
||||
// content element per auto-animated page. We need to show the
|
||||
// current page and hide all others.
|
||||
Array.from( contentElement.parentNode.querySelectorAll( '.reader-page-content' ) ).forEach( sibling => {
|
||||
Array.from( contentElement.parentNode.querySelectorAll( '.scroll-page-content' ) ).forEach( sibling => {
|
||||
if( sibling !== contentElement ) {
|
||||
sibling.style.display = 'none';
|
||||
}
|
||||
@@ -857,7 +861,7 @@ export default class Reader {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of all pages in the reader moder. This includes
|
||||
* Get a list of all pages in the scroll view. This includes
|
||||
* both top-level slides and auto-animate steps.
|
||||
*
|
||||
* @returns {Array}
|
@@ -25,7 +25,7 @@ export default class SlideContent {
|
||||
*/
|
||||
shouldPreload( element ) {
|
||||
|
||||
if( this.Reveal.isReaderMode() ) {
|
||||
if( this.Reveal.isScrollView() ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -23,7 +23,7 @@ export default class SlideNumber {
|
||||
configure( config, oldConfig ) {
|
||||
|
||||
let slideNumberDisplay = 'none';
|
||||
if( config.slideNumber && !this.Reveal.isPrinting() ) {
|
||||
if( config.slideNumber && !this.Reveal.isPrintView() ) {
|
||||
if( config.showSlideNumber === 'all' ) {
|
||||
slideNumberDisplay = 'block';
|
||||
}
|
||||
|
79
js/reveal.js
79
js/reveal.js
@@ -3,6 +3,8 @@ import SlideNumber from './controllers/slidenumber.js'
|
||||
import JumpToSlide from './controllers/jumptoslide.js'
|
||||
import Backgrounds from './controllers/backgrounds.js'
|
||||
import AutoAnimate from './controllers/autoanimate.js'
|
||||
import ScrollView from './controllers/scrollview.js'
|
||||
import PrintView from './controllers/printview.js'
|
||||
import Fragments from './controllers/fragments.js'
|
||||
import Overview from './controllers/overview.js'
|
||||
import Keyboard from './controllers/keyboard.js'
|
||||
@@ -11,8 +13,6 @@ import Controls from './controllers/controls.js'
|
||||
import Progress from './controllers/progress.js'
|
||||
import Pointer from './controllers/pointer.js'
|
||||
import Plugins from './controllers/plugins.js'
|
||||
import Reader from './controllers/reader.js'
|
||||
import Print from './controllers/print.js'
|
||||
import Touch from './controllers/touch.js'
|
||||
import Focus from './controllers/focus.js'
|
||||
import Notes from './controllers/notes.js'
|
||||
@@ -106,6 +106,8 @@ export default function( revealElement, options ) {
|
||||
jumpToSlide = new JumpToSlide( Reveal ),
|
||||
autoAnimate = new AutoAnimate( Reveal ),
|
||||
backgrounds = new Backgrounds( Reveal ),
|
||||
scrollView = new ScrollView( Reveal ),
|
||||
printView = new PrintView( Reveal ),
|
||||
fragments = new Fragments( Reveal ),
|
||||
overview = new Overview( Reveal ),
|
||||
keyboard = new Keyboard( Reveal ),
|
||||
@@ -114,8 +116,6 @@ export default function( revealElement, options ) {
|
||||
progress = new Progress( Reveal ),
|
||||
pointer = new Pointer( Reveal ),
|
||||
plugins = new Plugins( Reveal ),
|
||||
reader = new Reader( Reveal ),
|
||||
print = new Print( Reveal ),
|
||||
focus = new Focus( Reveal ),
|
||||
touch = new Touch( Reveal ),
|
||||
notes = new Notes( Reveal );
|
||||
@@ -211,7 +211,7 @@ export default function( revealElement, options ) {
|
||||
// Create slide backgrounds
|
||||
backgrounds.update( true );
|
||||
|
||||
// Activate the print/reader mode if configured
|
||||
// Activate the print/scroll view if configured
|
||||
activateInitialView();
|
||||
|
||||
// Read the initial hash
|
||||
@@ -244,9 +244,9 @@ export default function( revealElement, options ) {
|
||||
function activateInitialView() {
|
||||
|
||||
const activatePrintView = config.view === 'print';
|
||||
const activateReaderView = config.view === 'reader';
|
||||
const activateScrollView = config.view === 'scroll' || config.view === 'reader';
|
||||
|
||||
if( activatePrintView || activateReaderView ) {
|
||||
if( activatePrintView || activateScrollView ) {
|
||||
|
||||
if( activatePrintView ) {
|
||||
removeEventListeners();
|
||||
@@ -262,14 +262,14 @@ export default function( revealElement, options ) {
|
||||
// The document needs to have loaded for the PDF layout
|
||||
// measurements to be accurate
|
||||
if( document.readyState === 'complete' ) {
|
||||
print.activate();
|
||||
printView.activate();
|
||||
}
|
||||
else {
|
||||
window.addEventListener( 'load', () => print.activate() );
|
||||
window.addEventListener( 'load', () => printView.activate() );
|
||||
}
|
||||
}
|
||||
else {
|
||||
reader.activate();
|
||||
scrollView.activate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -417,7 +417,7 @@ export default function( revealElement, options ) {
|
||||
function setupScrollPrevention() {
|
||||
|
||||
setInterval( () => {
|
||||
if( !reader.isActive() && dom.wrapper.scrollTop !== 0 || dom.wrapper.scrollLeft !== 0 ) {
|
||||
if( !scrollView.isActive() && dom.wrapper.scrollTop !== 0 || dom.wrapper.scrollLeft !== 0 ) {
|
||||
dom.wrapper.scrollTop = 0;
|
||||
dom.wrapper.scrollLeft = 0;
|
||||
}
|
||||
@@ -924,7 +924,7 @@ export default function( revealElement, options ) {
|
||||
*/
|
||||
function layout() {
|
||||
|
||||
if( dom.wrapper && !print.isActive() ) {
|
||||
if( dom.wrapper && !printView.isActive() ) {
|
||||
|
||||
const viewportWidth = dom.viewport.offsetWidth;
|
||||
const viewportHeight = dom.viewport.offsetHeight;
|
||||
@@ -941,7 +941,7 @@ export default function( revealElement, options ) {
|
||||
document.documentElement.style.setProperty( '--vh', ( window.innerHeight * 0.01 ) + 'px' );
|
||||
}
|
||||
|
||||
const size = reader.isActive() ?
|
||||
const size = scrollView.isActive() ?
|
||||
getComputedSlideSize( viewportWidth, viewportHeight ) :
|
||||
getComputedSlideSize();
|
||||
|
||||
@@ -961,8 +961,8 @@ export default function( revealElement, options ) {
|
||||
scale = Math.min( scale, config.maxScale );
|
||||
|
||||
// Don't apply any scaling styles if scale is 1 or we're
|
||||
// in reader mode
|
||||
if( scale === 1 || reader.isActive() ) {
|
||||
// in the scroll view
|
||||
if( scale === 1 || scrollView.isActive() ) {
|
||||
dom.slides.style.zoom = '';
|
||||
dom.slides.style.left = '';
|
||||
dom.slides.style.top = '';
|
||||
@@ -1017,15 +1017,15 @@ export default function( revealElement, options ) {
|
||||
});
|
||||
}
|
||||
|
||||
// Responsively turn on the reader mode if there is an activation
|
||||
// Responsively turn on the scroll mode if there is an activation
|
||||
// width configured. Ignore if we're configured to always be in
|
||||
// reader mode.
|
||||
if( typeof config.readerActivationWidth === 'number' && config.view !== 'reader' ) {
|
||||
if( size.presentationWidth < config.readerActivationWidth ) {
|
||||
if( !reader.isActive() ) reader.activate();
|
||||
// scroll mode.
|
||||
if( typeof config.scrollActivationWidth === 'number' && config.view !== 'scroll' ) {
|
||||
if( size.presentationWidth <= config.scrollActivationWidth ) {
|
||||
if( !scrollView.isActive() ) scrollView.activate();
|
||||
}
|
||||
else {
|
||||
if( reader.isActive() ) reader.deactivate();
|
||||
if( scrollView.isActive() ) scrollView.deactivate();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1034,7 +1034,7 @@ export default function( revealElement, options ) {
|
||||
dom.viewport.style.setProperty( '--viewport-width', viewportWidth + 'px' );
|
||||
dom.viewport.style.setProperty( '--viewport-height', viewportHeight + 'px' );
|
||||
|
||||
reader.layout();
|
||||
scrollView.layout();
|
||||
|
||||
progress.update();
|
||||
backgrounds.updateParallax();
|
||||
@@ -1375,11 +1375,11 @@ export default function( revealElement, options ) {
|
||||
// Query all horizontal slides in the deck
|
||||
const horizontalSlides = dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR );
|
||||
|
||||
// If we're in reader mode we scroll the target slide into view
|
||||
// If we're in scroll mode, we scroll the target slide into view
|
||||
// instead of running our standard slide transition
|
||||
if( reader.isActive() ) {
|
||||
const scrollToSlide = reader.getSlideByIndices( h, v );
|
||||
if( scrollToSlide ) reader.scrollToSlide( scrollToSlide );
|
||||
if( scrollView.isActive() ) {
|
||||
const scrollToSlide = scrollView.getSlideByIndices( h, v );
|
||||
if( scrollToSlide ) scrollView.scrollToSlide( scrollToSlide );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1565,13 +1565,14 @@ export default function( revealElement, options ) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called anytime current page in reader mode changes. The current
|
||||
* page is the page that occupies the most space in the viewport.
|
||||
* Called anytime a new slide should be activated while in the scroll
|
||||
* view. The active slide is the page that occupies the most space in
|
||||
* the scrollable viewport.
|
||||
*
|
||||
* @param {number} pageIndex
|
||||
* @param {HTMLElement} slideElement
|
||||
*/
|
||||
function setCurrentReaderPage( slideElement, h, v ) {
|
||||
function setCurrentScrollPage( slideElement, h, v ) {
|
||||
|
||||
let indexhBefore = indexh || 0;
|
||||
|
||||
@@ -1754,7 +1755,7 @@ export default function( revealElement, options ) {
|
||||
let slides = Util.queryAll( dom.wrapper, selector ),
|
||||
slidesLength = slides.length;
|
||||
|
||||
let printMode = reader.isActive() || print.isActive();
|
||||
let printMode = scrollView.isActive() || printView.isActive();
|
||||
let loopedForwards = false;
|
||||
let loopedBackwards = false;
|
||||
|
||||
@@ -1914,7 +1915,7 @@ export default function( revealElement, options ) {
|
||||
}
|
||||
|
||||
// All slides need to be visible when exporting to PDF
|
||||
if( print.isActive() ) {
|
||||
if( printView.isActive() ) {
|
||||
viewDistance = Number.MAX_VALUE;
|
||||
}
|
||||
|
||||
@@ -2145,8 +2146,8 @@ export default function( revealElement, options ) {
|
||||
|
||||
// If a slide is specified, return the indices of that slide
|
||||
if( slide ) {
|
||||
// In reader mode the original h/x index is stored on the slide
|
||||
if( reader.isActive() ) {
|
||||
// In scroll mode the original h/x index is stored on the slide
|
||||
if( scrollView.isActive() ) {
|
||||
h = parseInt( slide.getAttribute( 'data-index-h' ), 10 );
|
||||
|
||||
if( slide.getAttribute( 'data-index-v' ) ) {
|
||||
@@ -2842,8 +2843,8 @@ export default function( revealElement, options ) {
|
||||
// Toggles the overview mode on/off
|
||||
toggleOverview: overview.toggle.bind( overview ),
|
||||
|
||||
// Toggles the reader mode on/off
|
||||
toggleReaderMode: reader.toggle.bind( reader ),
|
||||
// Toggles the scroll view on/off
|
||||
toggleScrollView: scrollView.toggle.bind( scrollView ),
|
||||
|
||||
// Toggles the "black screen" mode on/off
|
||||
togglePause,
|
||||
@@ -2868,8 +2869,8 @@ export default function( revealElement, options ) {
|
||||
isOverview: overview.isActive.bind( overview ),
|
||||
isFocused: focus.isFocused.bind( focus ),
|
||||
|
||||
isReaderMode: reader.isActive.bind( reader ),
|
||||
isPrinting: print.isActive.bind( print ),
|
||||
isScrollView: scrollView.isActive.bind( scrollView ),
|
||||
isPrintView: printView.isActive.bind( printView ),
|
||||
|
||||
// Checks if reveal.js has been loaded and is ready for use
|
||||
isReady: () => ready,
|
||||
@@ -2955,7 +2956,7 @@ export default function( revealElement, options ) {
|
||||
registerKeyboardShortcut: keyboard.registerKeyboardShortcut.bind( keyboard ),
|
||||
|
||||
getComputedSlideSize,
|
||||
setCurrentReaderPage,
|
||||
setCurrentScrollPage,
|
||||
|
||||
// Returns the current scale of the presentation content
|
||||
getScale: () => scale,
|
||||
@@ -2993,7 +2994,7 @@ export default function( revealElement, options ) {
|
||||
|
||||
// Controllers
|
||||
focus,
|
||||
reader,
|
||||
scroll: scrollView,
|
||||
progress,
|
||||
controls,
|
||||
location,
|
||||
|
@@ -4,7 +4,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>reveal.js - Test Reader Mode</title>
|
||||
<title>reveal.js - Test Scroll View</title>
|
||||
|
||||
<link rel="stylesheet" href="../dist/reveal.css">
|
||||
<link rel="stylesheet" href="../node_modules/qunit/qunit/qunit.css">
|
||||
@@ -57,18 +57,18 @@
|
||||
return Reveal.getViewportElement().offsetHeight;
|
||||
}
|
||||
|
||||
Reveal.initialize({ view: 'reader' }).then( async () => {
|
||||
Reveal.initialize({ view: 'scroll' }).then( async () => {
|
||||
|
||||
QUnit.module( 'Reader Mode' );
|
||||
QUnit.module( 'Scroll View' );
|
||||
|
||||
QUnit.test( 'Activates', assert => {
|
||||
assert.ok( getScrollHeight() > getViewportHeight(), 'Is overflowing' );
|
||||
});
|
||||
|
||||
QUnit.test( 'Can be toggled via API', assert => {
|
||||
Reveal.toggleReaderMode( false );
|
||||
Reveal.toggleScrollView( false );
|
||||
assert.ok( getScrollHeight() <= getViewportHeight(), 'Is not overflowing' );
|
||||
Reveal.toggleReaderMode( true );
|
||||
Reveal.toggleScrollView( true );
|
||||
assert.ok( getScrollHeight() > getViewportHeight(), 'Is overflowing' );
|
||||
});
|
||||
|
Reference in New Issue
Block a user