/** * Creates a visual progress bar for the presentation. */ export default class Progress { constructor(Reveal) { this.Reveal = Reveal; this.onProgressClicked = this.onProgressClicked.bind(this); } render() { this.element = document.createElement("div"); this.element.className = "progress"; this.Reveal.getRevealElement().appendChild(this.element); this.bar = document.createElement("span"); this.element.appendChild(this.bar); } /** * Called when the reveal.js config is updated. */ configure(config, oldConfig) { this.element.style.display = config.progress ? "block" : "none"; } bind() { if (this.Reveal.getConfig().progress && this.element) { this.element.addEventListener("click", this.onProgressClicked, false); } } unbind() { if (this.Reveal.getConfig().progress && this.element) { this.element.removeEventListener("click", this.onProgressClicked, false); } } /** * Updates the progress bar to reflect the current slide. */ update() { // Update progress if enabled if (this.Reveal.getConfig().progress && this.bar) { let scale = this.Reveal.getProgress(); // Don't fill the progress bar if there's only one slide if (this.Reveal.getTotalSlides() < 2) { scale = 0; } this.bar.style.transform = "scaleX(" + scale + ")"; } } getMaxWidth() { return this.Reveal.getRevealElement().offsetWidth; } /** * Clicking on the progress bar results in a navigation to the * closest approximate horizontal slide using this equation: * * ( clickX / presentationWidth ) * numberOfSlides * * @param {object} event */ onProgressClicked(event) { this.Reveal.onUserInput(event); event.preventDefault(); let slides = this.Reveal.getSlides(); let slidesTotal = slides.length; let slideIndex = Math.floor( (event.clientX / this.getMaxWidth()) * slidesTotal ); if (this.Reveal.getConfig().rtl) { slideIndex = slidesTotal - slideIndex; } let targetIndices = this.Reveal.getIndices(slides[slideIndex]); this.Reveal.slide(targetIndices.h, targetIndices.v); } destroy() { this.element.remove(); } }