diff options
author | pacien | 2018-07-20 22:18:36 +0200 |
---|---|---|
committer | pacien | 2018-07-20 22:18:36 +0200 |
commit | ca443d6e6c46aefeef600a84bece426908dbd951 (patch) | |
tree | 1d2b65454e47d650499d71d59cb20052a0a62847 | |
parent | 5ec493bf9aaba1b827aa4fccf7430721917fdd47 (diff) | |
download | beamer-viewer-ca443d6e6c46aefeef600a84bece426908dbd951.tar.gz |
Fix canvas flicker
-rw-r--r-- | pointless/viewer/screen.js | 96 | ||||
-rw-r--r-- | pointless/viewer/viewer.css | 4 |
2 files changed, 50 insertions, 50 deletions
diff --git a/pointless/viewer/screen.js b/pointless/viewer/screen.js index 42ea781..9ba4574 100644 --- a/pointless/viewer/screen.js +++ b/pointless/viewer/screen.js | |||
@@ -11,79 +11,83 @@ class Screen { | |||
11 | constructor(window, secondary=false, withTimer=false) { | 11 | constructor(window, secondary=false, withTimer=false) { |
12 | this.window = window; | 12 | this.window = window; |
13 | this.secondary = secondary; | 13 | this.secondary = secondary; |
14 | this.canvas = window.document.getElementById("screen"); | ||
15 | this.context = this.canvas.getContext("2d"); | ||
16 | this.page = null; | ||
17 | 14 | ||
18 | var self = this; | 15 | this.canvasId = "screen"; |
19 | this.window.addEventListener("resize", function() { | 16 | this.page = null; |
20 | self._refreshPage(); | ||
21 | }); | ||
22 | 17 | ||
23 | this.timer = withTimer ? new Timer(window) : null; | 18 | this.timer = withTimer ? new Timer(window) : null; |
24 | this.pageTurnCount = 0; | 19 | this.pageTurnCount = 0; |
20 | |||
21 | this._registerListeners(); | ||
25 | } | 22 | } |
26 | 23 | ||
27 | setPage(page) { | 24 | setPage(page) { |
28 | if (this.pageTurnCount === 1 && this.timer != null) | 25 | if (this.pageTurnCount++ === 1 && this.timer != null) |
29 | this.timer.start(); | 26 | this.timer.start(); |
30 | 27 | ||
31 | this.page = page; | 28 | this.page = page; |
32 | this._changePage(); | 29 | this._repaint(); |
33 | this.pageTurnCount++; | 30 | } |
31 | |||
32 | _registerListeners() { | ||
33 | const self = this; | ||
34 | this.window.addEventListener("resize", function() { | ||
35 | self._repaint(); | ||
36 | }); | ||
34 | } | 37 | } |
35 | 38 | ||
36 | _resizeScreen(ratio) { | 39 | _getScreenSize(ratio) { |
37 | var windowRatio = this.window.innerWidth / this.window.innerHeight; | 40 | const windowRatio = this.window.innerWidth / this.window.innerHeight; |
38 | var scaleFactor = ratio / windowRatio; | 41 | const horizontalScaleFactor = ratio / windowRatio; |
39 | this.canvas.width = this.window.innerWidth * Math.min(scaleFactor, 1); | 42 | return { |
40 | this.canvas.height = this.window.innerHeight / Math.max(scaleFactor, 1); | 43 | width: this.window.innerWidth * Math.min(horizontalScaleFactor, 1), |
44 | height: this.window.innerHeight / Math.max(horizontalScaleFactor, 1) | ||
45 | }; | ||
41 | } | 46 | } |
42 | 47 | ||
43 | _setOffset() { | 48 | _getSlideSizeRatio() { |
44 | var xOffset = this.secondary ? -this.canvas.width : 0; | 49 | const viewport = this.page.getViewport(1); |
45 | this.context.transform(1, 0, 0, 1, xOffset, 0); | 50 | return (viewport.width / 2) / viewport.height; |
46 | } | 51 | } |
47 | 52 | ||
48 | _makeWorkCanvas(width, height) { | 53 | _newCanvas(width, height, xOffset, yOffset) { |
49 | var canvas = document.createElement("canvas"); | 54 | const canvas = document.createElement("canvas"); |
50 | canvas.width = width; | 55 | canvas.width = width; |
51 | canvas.height = height; | 56 | canvas.height = height; |
52 | return canvas; | 57 | |
58 | const context = canvas.getContext("2d"); | ||
59 | context.transform(1, 0, 0, 1, xOffset, yOffset); | ||
60 | |||
61 | return { canvas: canvas, context: context }; | ||
53 | } | 62 | } |
54 | 63 | ||
55 | _transferCanvas(source) { | 64 | _showCanvas(canvas) { |
56 | this.context.drawImage(source, 0, 0); | 65 | const oldCanvas = this.window.document.getElementById(this.canvasId); |
66 | canvas.id = oldCanvas.id; | ||
67 | canvas.classList = oldCanvas.classList; | ||
68 | oldCanvas.replaceWith(canvas); | ||
57 | } | 69 | } |
58 | 70 | ||
59 | _paintPage() { | 71 | _render(canvas, context, scaleFactor) { |
60 | var renderRatio = this.canvas.height / this.page.getViewport(1).height; | 72 | const renderContext = { |
61 | var renderViewport = this.page.getViewport(renderRatio); | 73 | canvasContext: context, |
62 | var workCanvas = this._makeWorkCanvas(renderViewport.width, renderViewport.height); | 74 | viewport: this.page.getViewport(scaleFactor) |
63 | var workContext = workCanvas.getContext("2d"); | 75 | }; |
64 | var renderContext = { canvasContext: workContext, viewport: renderViewport }; | ||
65 | 76 | ||
66 | var self = this; | 77 | const self = this; |
67 | this.page.render(renderContext).then(function() { | 78 | this.page.render(renderContext).then(function() { |
68 | self._transferCanvas(workCanvas); | 79 | self._showCanvas(canvas); |
69 | }); | 80 | }); |
70 | } | 81 | } |
71 | 82 | ||
72 | _changePage() { | 83 | _repaint() { |
73 | this.canvas.style.opacity = 0; | ||
74 | var self = this; | ||
75 | setTimeout(function() { | ||
76 | self._refreshPage(); | ||
77 | self.canvas.style.opacity = 1; | ||
78 | }, 300); | ||
79 | } | ||
80 | |||
81 | _refreshPage() { | ||
82 | if (this.page == null) return; | 84 | if (this.page == null) return; |
83 | var viewport = this.page.getViewport(1); | 85 | |
84 | var ratio = (viewport.width / 2) / viewport.height; | 86 | const screenRatio = this._getSlideSizeRatio(); |
85 | this._resizeScreen(ratio); | 87 | const { width, height } = this._getScreenSize(screenRatio); |
86 | this._setOffset(); | 88 | const scaleFactor = height / this.page.getViewport(1).height; |
87 | this._paintPage(); | 89 | const xOffset = this.secondary ? -width : 0; |
90 | const { canvas, context } = this._newCanvas(width, height, xOffset, 0); | ||
91 | this._render(canvas, context, scaleFactor); | ||
88 | } | 92 | } |
89 | } | 93 | } |
diff --git a/pointless/viewer/viewer.css b/pointless/viewer/viewer.css index 6d2112e..09ef4e1 100644 --- a/pointless/viewer/viewer.css +++ b/pointless/viewer/viewer.css | |||
@@ -98,7 +98,3 @@ header span { | |||
98 | .notification:empty { | 98 | .notification:empty { |
99 | display: none; | 99 | display: none; |
100 | } | 100 | } |
101 | |||
102 | #screen { | ||
103 | transition: opacity 300ms; | ||
104 | } | ||