/* * Beamer Viewer, a web-based PDF presentation viewer * Copyright 2018-2024 Pacien TRAN-GIRARD * SPDX-License-Identifier: EUPL-1.2 */ "use strict"; class Screen { constructor(window, secondary=false, withTimer=false) { this.window = window; this.secondary = secondary; this.canvasId = "screen"; this.page = null; this.timer = withTimer ? new Timer(window) : null; this.pageTurnCount = 0; this._registerListeners(); this._hideWelcomeScreen(); } setPage(page) { if (this.pageTurnCount++ === 1 && this.timer != null) this.timer.start(); this.page = page; this._repaint(); } _registerListeners() { this.window.addEventListener("resize", () => this._repaint()); } _hideWelcomeScreen() { const welcomeScreen = this.window.document.getElementById("welcomeScreen"); welcomeScreen.style.display = "none"; } _getScreenSize(ratio) { const windowRatio = this.window.innerWidth / this.window.innerHeight; const horizontalScaleFactor = ratio / windowRatio; return { width: this.window.innerWidth * Math.min(horizontalScaleFactor, 1), height: this.window.innerHeight / Math.max(horizontalScaleFactor, 1) }; } _getScreenOffsets(secondary, width, height) { if (!secondary) return { xOffset: 0, yOffset: 0 }; const viewport = this.page.getViewport(1); if (viewport.width > viewport.height) return { xOffset: -width, yOffset: 0 }; else return { xOffset: 0, yOffset: -height }; } _getSlideSizeRatio() { const viewport = this.page.getViewport(1); if (viewport.width > viewport.height) return (viewport.width / 2) / viewport.height; else return viewport.width / (viewport.height / 2); } _getScaleFactor(width, height) { const viewport = this.page.getViewport(1); if (viewport.width > viewport.height) return height / viewport.height; else return width / viewport.width; } _newCanvas(width, height, xOffset, yOffset) { const canvas = document.createElement("canvas"); canvas.width = width; canvas.height = height; const context = canvas.getContext("2d"); context.transform(1, 0, 0, 1, xOffset, yOffset); return { canvas: canvas, context: context }; } _showCanvas(canvas) { const oldCanvas = this.window.document.getElementById(this.canvasId); canvas.id = oldCanvas.id; canvas.classList = oldCanvas.classList; oldCanvas.replaceWith(canvas); } _render(canvas, context, scaleFactor) { const renderContext = { canvasContext: context, viewport: this.page.getViewport(scaleFactor) }; this.page .render(renderContext) .then(() => this._showCanvas(canvas)); } _repaint() { if (this.page == null) return; const screenRatio = this._getSlideSizeRatio(); const { width, height } = this._getScreenSize(screenRatio); const scaleFactor = this._getScaleFactor(width, height); const { xOffset, yOffset } = this._getScreenOffsets(this.secondary, width, height); const { canvas, context } = this._newCanvas(width, height, xOffset, yOffset); this._render(canvas, context, scaleFactor); } }