From 12bc1c4123fa1227715d2c7dc8254bb8bd449fd8 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sun, 2 Aug 2026 03:28:57 +0900 Subject: fix(slides): fix flickering --- services/nuldoc/public/slides/slide.js | 63 +++++++++++++--------- .../2023-01-18/phpstudy-tokyo-148/index.html | 2 +- .../2023-02-15/phpstudy-tokyo-149/index.html | 2 +- .../2023-03-15/phpstudy-tokyo-150/index.html | 2 +- .../slides/2023-03-24/phperkaigi-2023/index.html | 2 +- .../2023-03-25/phperkaigi-2023-tokens/index.html | 2 +- .../2023-04-12/phpstudy-tokyo-151/index.html | 2 +- .../2023-06-21/phpstudy-tokyo-153/index.html | 2 +- .../2023-06-23/phpconfuk-2023-eve/index.html | 2 +- .../2023-07-26/phpstudy-tokyo-154/index.html | 2 +- .../2023-08-24/phpstudy-tokyo-155/index.html | 2 +- .../2023-10-25/phpstudy-tokyo-157/index.html | 2 +- .../2024-01-24/phpstudy-tokyo-160/index.html | 2 +- .../slides/2024-03-08/phperkaigi-2024/index.html | 2 +- .../slides/slides/2024-03-15/ya8-2024/index.html | 2 +- .../2024-04-13/phpcon-odawara-2024/index.html | 2 +- .../2024-04-25/phpstudy-tokyo-163/index.html | 2 +- .../2024-07-18/phpstudy-tokyo-166/index.html | 2 +- .../2024-10-30/phpstudy-tokyo-169/index.html | 2 +- .../slides/slides/2024-11-30/cohackpp/index.html | 2 +- .../2025-02-22/phpcon-nagoya-2025/index.html | 2 +- .../slides/2025-03-23/phperkaigi-2025/index.html | 2 +- .../2025-04-12/phpcon-odawara-2025/index.html | 2 +- .../slides/2025-07-26/techramen-25-conf/index.html | 2 +- .../2025-10-29/phpstudy-tokyo-180/index.html | 2 +- .../slides/2025-11-24/phpconkagawa-2025/index.html | 2 +- .../phperkaigi-2026-book-revue/index.html | 2 +- .../slides/2026-03-22/phperkaigi-2026/index.html | 2 +- .../2026-04-11/phpcon-odawara-2026/index.html | 2 +- .../slides/2026-05-25/phperkaigi-mini-1/index.html | 2 +- .../slides/2026-07-27/phperkaigi-mini-3/index.html | 2 +- services/nuldoc/static/slides/slide.js | 63 +++++++++++++--------- 32 files changed, 106 insertions(+), 80 deletions(-) diff --git a/services/nuldoc/public/slides/slide.js b/services/nuldoc/public/slides/slide.js index 8d6ba52d..a90fda7a 100644 --- a/services/nuldoc/public/slides/slide.js +++ b/services/nuldoc/public/slides/slide.js @@ -8,13 +8,22 @@ async function init() { const url = canvas.dataset.slideLink; let pageNum = 1; - let pageNumPending = null; - let pageRendering = false; let doc = null; + let renderTask = null; + let renderToken = 0; + + const backCanvas = document.createElement("canvas"); + const backCtx = backCanvas.getContext("2d"); const renderPage = async (num) => { - pageRendering = true; + const token = ++renderToken; + if (renderTask !== null) { + renderTask.cancel(); + renderTask = null; + } + const page = await doc.getPage(num); + if (token !== renderToken) return; const baseViewport = page.getViewport({ scale: 1.0 }); const containerWidth = canvas.parentElement.clientWidth; @@ -22,65 +31,69 @@ async function init() { const viewport = page.getViewport({ scale }); const outputScale = globalThis.devicePixelRatio || 1; - canvas.height = Math.floor(viewport.height * outputScale); - canvas.width = Math.floor(viewport.width * outputScale); - canvas.style.width = Math.floor(viewport.width) + "px"; - canvas.style.height = Math.floor(viewport.height) + "px"; + const cssWidth = Math.floor(viewport.width); + const cssHeight = Math.floor(viewport.height); + backCanvas.width = Math.floor(viewport.width * outputScale); + backCanvas.height = Math.floor(viewport.height * outputScale); const transform = outputScale !== 1 ? [outputScale, 0, 0, outputScale, 0, 0] : null; // TODO: error handling - await page.render({ - canvasContext: ctx, + const task = page.render({ + canvasContext: backCtx, viewport, transform, }); - - pageRendering = false; - if (pageNumPending !== null) { - renderPage(pageNumPending); - pageNumPending = null; + renderTask = task; + try { + await task.promise; + } catch (e) { + if (e?.name === "RenderingCancelledException") return; + throw e; + } finally { + if (renderTask === task) renderTask = null; } - }; + if (token !== renderToken) return; - const queueRenderPage = (num) => { - if (pageRendering) { - pageNumPending = num; - } else { - renderPage(num); + if (canvas.width !== backCanvas.width || canvas.height !== backCanvas.height) { + canvas.width = backCanvas.width; + canvas.height = backCanvas.height; + canvas.style.width = cssWidth + "px"; + canvas.style.height = cssHeight + "px"; } + ctx.drawImage(backCanvas, 0, 0); }; const prev = document.getElementById("prev"); prev.addEventListener("click", () => { if (pageNum <= 1) return; pageNum--; - queueRenderPage(pageNum); + renderPage(pageNum); }); const next = document.getElementById("next"); next.addEventListener("click", () => { if (pageNum >= doc.numPages) return; pageNum++; - queueRenderPage(pageNum); + renderPage(pageNum); }); document.addEventListener("keydown", (e) => { if (e.key === "ArrowLeft" || e.key === "h") { if (pageNum <= 1) return; pageNum--; - queueRenderPage(pageNum); + renderPage(pageNum); } else if (e.key === "ArrowRight" || e.key === "l") { if (pageNum >= doc.numPages) return; pageNum++; - queueRenderPage(pageNum); + renderPage(pageNum); } }); // TODO: error handling doc = await getDocument(url).promise; - queueRenderPage(pageNum); + renderPage(pageNum); } document.addEventListener("DOMContentLoaded", init); diff --git a/services/nuldoc/public/slides/slides/2023-01-18/phpstudy-tokyo-148/index.html b/services/nuldoc/public/slides/slides/2023-01-18/phpstudy-tokyo-148/index.html index 4eaaa701..c4a4fe24 100644 --- a/services/nuldoc/public/slides/slides/2023-01-18/phpstudy-tokyo-148/index.html +++ b/services/nuldoc/public/slides/slides/2023-01-18/phpstudy-tokyo-148/index.html @@ -79,7 +79,7 @@ - diff --git a/services/nuldoc/public/slides/slides/2023-02-15/phpstudy-tokyo-149/index.html b/services/nuldoc/public/slides/slides/2023-02-15/phpstudy-tokyo-149/index.html index 33533e49..ec3139e9 100644 --- a/services/nuldoc/public/slides/slides/2023-02-15/phpstudy-tokyo-149/index.html +++ b/services/nuldoc/public/slides/slides/2023-02-15/phpstudy-tokyo-149/index.html @@ -79,7 +79,7 @@ - diff --git a/services/nuldoc/public/slides/slides/2023-03-15/phpstudy-tokyo-150/index.html b/services/nuldoc/public/slides/slides/2023-03-15/phpstudy-tokyo-150/index.html index b7853141..270822e3 100644 --- a/services/nuldoc/public/slides/slides/2023-03-15/phpstudy-tokyo-150/index.html +++ b/services/nuldoc/public/slides/slides/2023-03-15/phpstudy-tokyo-150/index.html @@ -82,7 +82,7 @@ - diff --git a/services/nuldoc/public/slides/slides/2023-03-24/phperkaigi-2023/index.html b/services/nuldoc/public/slides/slides/2023-03-24/phperkaigi-2023/index.html index 56440e71..bccf3555 100644 --- a/services/nuldoc/public/slides/slides/2023-03-24/phperkaigi-2023/index.html +++ b/services/nuldoc/public/slides/slides/2023-03-24/phperkaigi-2023/index.html @@ -82,7 +82,7 @@ - diff --git a/services/nuldoc/public/slides/slides/2023-03-25/phperkaigi-2023-tokens/index.html b/services/nuldoc/public/slides/slides/2023-03-25/phperkaigi-2023-tokens/index.html index 14d858b3..8d4d4bfa 100644 --- a/services/nuldoc/public/slides/slides/2023-03-25/phperkaigi-2023-tokens/index.html +++ b/services/nuldoc/public/slides/slides/2023-03-25/phperkaigi-2023-tokens/index.html @@ -82,7 +82,7 @@ - diff --git a/services/nuldoc/public/slides/slides/2023-04-12/phpstudy-tokyo-151/index.html b/services/nuldoc/public/slides/slides/2023-04-12/phpstudy-tokyo-151/index.html index 4d8db688..8a74c9b7 100644 --- a/services/nuldoc/public/slides/slides/2023-04-12/phpstudy-tokyo-151/index.html +++ b/services/nuldoc/public/slides/slides/2023-04-12/phpstudy-tokyo-151/index.html @@ -79,7 +79,7 @@ - diff --git a/services/nuldoc/public/slides/slides/2023-06-21/phpstudy-tokyo-153/index.html b/services/nuldoc/public/slides/slides/2023-06-21/phpstudy-tokyo-153/index.html index 442b0b79..eaa5f350 100644 --- a/services/nuldoc/public/slides/slides/2023-06-21/phpstudy-tokyo-153/index.html +++ b/services/nuldoc/public/slides/slides/2023-06-21/phpstudy-tokyo-153/index.html @@ -79,7 +79,7 @@ - diff --git a/services/nuldoc/public/slides/slides/2023-06-23/phpconfuk-2023-eve/index.html b/services/nuldoc/public/slides/slides/2023-06-23/phpconfuk-2023-eve/index.html index bdfa3799..e0734b16 100644 --- a/services/nuldoc/public/slides/slides/2023-06-23/phpconfuk-2023-eve/index.html +++ b/services/nuldoc/public/slides/slides/2023-06-23/phpconfuk-2023-eve/index.html @@ -79,7 +79,7 @@ - diff --git a/services/nuldoc/public/slides/slides/2023-07-26/phpstudy-tokyo-154/index.html b/services/nuldoc/public/slides/slides/2023-07-26/phpstudy-tokyo-154/index.html index 64afbe41..e1b2707c 100644 --- a/services/nuldoc/public/slides/slides/2023-07-26/phpstudy-tokyo-154/index.html +++ b/services/nuldoc/public/slides/slides/2023-07-26/phpstudy-tokyo-154/index.html @@ -79,7 +79,7 @@ - diff --git a/services/nuldoc/public/slides/slides/2023-08-24/phpstudy-tokyo-155/index.html b/services/nuldoc/public/slides/slides/2023-08-24/phpstudy-tokyo-155/index.html index 8c2da1d0..5a0af08b 100644 --- a/services/nuldoc/public/slides/slides/2023-08-24/phpstudy-tokyo-155/index.html +++ b/services/nuldoc/public/slides/slides/2023-08-24/phpstudy-tokyo-155/index.html @@ -79,7 +79,7 @@ - diff --git a/services/nuldoc/public/slides/slides/2023-10-25/phpstudy-tokyo-157/index.html b/services/nuldoc/public/slides/slides/2023-10-25/phpstudy-tokyo-157/index.html index d083f1f1..8461d7eb 100644 --- a/services/nuldoc/public/slides/slides/2023-10-25/phpstudy-tokyo-157/index.html +++ b/services/nuldoc/public/slides/slides/2023-10-25/phpstudy-tokyo-157/index.html @@ -79,7 +79,7 @@ - diff --git a/services/nuldoc/public/slides/slides/2024-01-24/phpstudy-tokyo-160/index.html b/services/nuldoc/public/slides/slides/2024-01-24/phpstudy-tokyo-160/index.html index 93bc1add..9c174c05 100644 --- a/services/nuldoc/public/slides/slides/2024-01-24/phpstudy-tokyo-160/index.html +++ b/services/nuldoc/public/slides/slides/2024-01-24/phpstudy-tokyo-160/index.html @@ -79,7 +79,7 @@ - diff --git a/services/nuldoc/public/slides/slides/2024-03-08/phperkaigi-2024/index.html b/services/nuldoc/public/slides/slides/2024-03-08/phperkaigi-2024/index.html index 2bc099b3..f8261c3f 100644 --- a/services/nuldoc/public/slides/slides/2024-03-08/phperkaigi-2024/index.html +++ b/services/nuldoc/public/slides/slides/2024-03-08/phperkaigi-2024/index.html @@ -85,7 +85,7 @@ - diff --git a/services/nuldoc/public/slides/slides/2024-03-15/ya8-2024/index.html b/services/nuldoc/public/slides/slides/2024-03-15/ya8-2024/index.html index acd52ed7..779dca54 100644 --- a/services/nuldoc/public/slides/slides/2024-03-15/ya8-2024/index.html +++ b/services/nuldoc/public/slides/slides/2024-03-15/ya8-2024/index.html @@ -82,7 +82,7 @@ - diff --git a/services/nuldoc/public/slides/slides/2024-04-13/phpcon-odawara-2024/index.html b/services/nuldoc/public/slides/slides/2024-04-13/phpcon-odawara-2024/index.html index 2281679f..919e39a0 100644 --- a/services/nuldoc/public/slides/slides/2024-04-13/phpcon-odawara-2024/index.html +++ b/services/nuldoc/public/slides/slides/2024-04-13/phpcon-odawara-2024/index.html @@ -82,7 +82,7 @@ - diff --git a/services/nuldoc/public/slides/slides/2024-04-25/phpstudy-tokyo-163/index.html b/services/nuldoc/public/slides/slides/2024-04-25/phpstudy-tokyo-163/index.html index a323f430..90a568bf 100644 --- a/services/nuldoc/public/slides/slides/2024-04-25/phpstudy-tokyo-163/index.html +++ b/services/nuldoc/public/slides/slides/2024-04-25/phpstudy-tokyo-163/index.html @@ -79,7 +79,7 @@ - diff --git a/services/nuldoc/public/slides/slides/2024-07-18/phpstudy-tokyo-166/index.html b/services/nuldoc/public/slides/slides/2024-07-18/phpstudy-tokyo-166/index.html index c73eacc9..f55f5259 100644 --- a/services/nuldoc/public/slides/slides/2024-07-18/phpstudy-tokyo-166/index.html +++ b/services/nuldoc/public/slides/slides/2024-07-18/phpstudy-tokyo-166/index.html @@ -79,7 +79,7 @@ - diff --git a/services/nuldoc/public/slides/slides/2024-10-30/phpstudy-tokyo-169/index.html b/services/nuldoc/public/slides/slides/2024-10-30/phpstudy-tokyo-169/index.html index 5eaac717..8034f473 100644 --- a/services/nuldoc/public/slides/slides/2024-10-30/phpstudy-tokyo-169/index.html +++ b/services/nuldoc/public/slides/slides/2024-10-30/phpstudy-tokyo-169/index.html @@ -79,7 +79,7 @@ - diff --git a/services/nuldoc/public/slides/slides/2024-11-30/cohackpp/index.html b/services/nuldoc/public/slides/slides/2024-11-30/cohackpp/index.html index 8378583c..4852055c 100644 --- a/services/nuldoc/public/slides/slides/2024-11-30/cohackpp/index.html +++ b/services/nuldoc/public/slides/slides/2024-11-30/cohackpp/index.html @@ -79,7 +79,7 @@ - diff --git a/services/nuldoc/public/slides/slides/2025-02-22/phpcon-nagoya-2025/index.html b/services/nuldoc/public/slides/slides/2025-02-22/phpcon-nagoya-2025/index.html index 169c8845..8596053c 100644 --- a/services/nuldoc/public/slides/slides/2025-02-22/phpcon-nagoya-2025/index.html +++ b/services/nuldoc/public/slides/slides/2025-02-22/phpcon-nagoya-2025/index.html @@ -82,7 +82,7 @@ - diff --git a/services/nuldoc/public/slides/slides/2025-03-23/phperkaigi-2025/index.html b/services/nuldoc/public/slides/slides/2025-03-23/phperkaigi-2025/index.html index f7dc1936..1aeb2f0f 100644 --- a/services/nuldoc/public/slides/slides/2025-03-23/phperkaigi-2025/index.html +++ b/services/nuldoc/public/slides/slides/2025-03-23/phperkaigi-2025/index.html @@ -82,7 +82,7 @@ - diff --git a/services/nuldoc/public/slides/slides/2025-04-12/phpcon-odawara-2025/index.html b/services/nuldoc/public/slides/slides/2025-04-12/phpcon-odawara-2025/index.html index 4239cd54..860f2451 100644 --- a/services/nuldoc/public/slides/slides/2025-04-12/phpcon-odawara-2025/index.html +++ b/services/nuldoc/public/slides/slides/2025-04-12/phpcon-odawara-2025/index.html @@ -82,7 +82,7 @@ - diff --git a/services/nuldoc/public/slides/slides/2025-07-26/techramen-25-conf/index.html b/services/nuldoc/public/slides/slides/2025-07-26/techramen-25-conf/index.html index 3e2f1858..b3bbbcb3 100644 --- a/services/nuldoc/public/slides/slides/2025-07-26/techramen-25-conf/index.html +++ b/services/nuldoc/public/slides/slides/2025-07-26/techramen-25-conf/index.html @@ -82,7 +82,7 @@ - diff --git a/services/nuldoc/public/slides/slides/2025-10-29/phpstudy-tokyo-180/index.html b/services/nuldoc/public/slides/slides/2025-10-29/phpstudy-tokyo-180/index.html index fc2d859e..4d30109d 100644 --- a/services/nuldoc/public/slides/slides/2025-10-29/phpstudy-tokyo-180/index.html +++ b/services/nuldoc/public/slides/slides/2025-10-29/phpstudy-tokyo-180/index.html @@ -79,7 +79,7 @@ - diff --git a/services/nuldoc/public/slides/slides/2025-11-24/phpconkagawa-2025/index.html b/services/nuldoc/public/slides/slides/2025-11-24/phpconkagawa-2025/index.html index 68026392..1e2996fd 100644 --- a/services/nuldoc/public/slides/slides/2025-11-24/phpconkagawa-2025/index.html +++ b/services/nuldoc/public/slides/slides/2025-11-24/phpconkagawa-2025/index.html @@ -82,7 +82,7 @@ - diff --git a/services/nuldoc/public/slides/slides/2026-03-21/phperkaigi-2026-book-revue/index.html b/services/nuldoc/public/slides/slides/2026-03-21/phperkaigi-2026-book-revue/index.html index 0aacbadf..90334d1c 100644 --- a/services/nuldoc/public/slides/slides/2026-03-21/phperkaigi-2026-book-revue/index.html +++ b/services/nuldoc/public/slides/slides/2026-03-21/phperkaigi-2026-book-revue/index.html @@ -85,7 +85,7 @@ - diff --git a/services/nuldoc/public/slides/slides/2026-03-22/phperkaigi-2026/index.html b/services/nuldoc/public/slides/slides/2026-03-22/phperkaigi-2026/index.html index 8f54d0d6..d0bdbb21 100644 --- a/services/nuldoc/public/slides/slides/2026-03-22/phperkaigi-2026/index.html +++ b/services/nuldoc/public/slides/slides/2026-03-22/phperkaigi-2026/index.html @@ -82,7 +82,7 @@ - diff --git a/services/nuldoc/public/slides/slides/2026-04-11/phpcon-odawara-2026/index.html b/services/nuldoc/public/slides/slides/2026-04-11/phpcon-odawara-2026/index.html index 875e3b56..ccb95bd7 100644 --- a/services/nuldoc/public/slides/slides/2026-04-11/phpcon-odawara-2026/index.html +++ b/services/nuldoc/public/slides/slides/2026-04-11/phpcon-odawara-2026/index.html @@ -85,7 +85,7 @@ - diff --git a/services/nuldoc/public/slides/slides/2026-05-25/phperkaigi-mini-1/index.html b/services/nuldoc/public/slides/slides/2026-05-25/phperkaigi-mini-1/index.html index 84a6195e..01b4d377 100644 --- a/services/nuldoc/public/slides/slides/2026-05-25/phperkaigi-mini-1/index.html +++ b/services/nuldoc/public/slides/slides/2026-05-25/phperkaigi-mini-1/index.html @@ -88,7 +88,7 @@ - diff --git a/services/nuldoc/public/slides/slides/2026-07-27/phperkaigi-mini-3/index.html b/services/nuldoc/public/slides/slides/2026-07-27/phperkaigi-mini-3/index.html index 98a31baf..ecabd1a1 100644 --- a/services/nuldoc/public/slides/slides/2026-07-27/phperkaigi-mini-3/index.html +++ b/services/nuldoc/public/slides/slides/2026-07-27/phperkaigi-mini-3/index.html @@ -88,7 +88,7 @@ - diff --git a/services/nuldoc/static/slides/slide.js b/services/nuldoc/static/slides/slide.js index 8d6ba52d..a90fda7a 100644 --- a/services/nuldoc/static/slides/slide.js +++ b/services/nuldoc/static/slides/slide.js @@ -8,13 +8,22 @@ async function init() { const url = canvas.dataset.slideLink; let pageNum = 1; - let pageNumPending = null; - let pageRendering = false; let doc = null; + let renderTask = null; + let renderToken = 0; + + const backCanvas = document.createElement("canvas"); + const backCtx = backCanvas.getContext("2d"); const renderPage = async (num) => { - pageRendering = true; + const token = ++renderToken; + if (renderTask !== null) { + renderTask.cancel(); + renderTask = null; + } + const page = await doc.getPage(num); + if (token !== renderToken) return; const baseViewport = page.getViewport({ scale: 1.0 }); const containerWidth = canvas.parentElement.clientWidth; @@ -22,65 +31,69 @@ async function init() { const viewport = page.getViewport({ scale }); const outputScale = globalThis.devicePixelRatio || 1; - canvas.height = Math.floor(viewport.height * outputScale); - canvas.width = Math.floor(viewport.width * outputScale); - canvas.style.width = Math.floor(viewport.width) + "px"; - canvas.style.height = Math.floor(viewport.height) + "px"; + const cssWidth = Math.floor(viewport.width); + const cssHeight = Math.floor(viewport.height); + backCanvas.width = Math.floor(viewport.width * outputScale); + backCanvas.height = Math.floor(viewport.height * outputScale); const transform = outputScale !== 1 ? [outputScale, 0, 0, outputScale, 0, 0] : null; // TODO: error handling - await page.render({ - canvasContext: ctx, + const task = page.render({ + canvasContext: backCtx, viewport, transform, }); - - pageRendering = false; - if (pageNumPending !== null) { - renderPage(pageNumPending); - pageNumPending = null; + renderTask = task; + try { + await task.promise; + } catch (e) { + if (e?.name === "RenderingCancelledException") return; + throw e; + } finally { + if (renderTask === task) renderTask = null; } - }; + if (token !== renderToken) return; - const queueRenderPage = (num) => { - if (pageRendering) { - pageNumPending = num; - } else { - renderPage(num); + if (canvas.width !== backCanvas.width || canvas.height !== backCanvas.height) { + canvas.width = backCanvas.width; + canvas.height = backCanvas.height; + canvas.style.width = cssWidth + "px"; + canvas.style.height = cssHeight + "px"; } + ctx.drawImage(backCanvas, 0, 0); }; const prev = document.getElementById("prev"); prev.addEventListener("click", () => { if (pageNum <= 1) return; pageNum--; - queueRenderPage(pageNum); + renderPage(pageNum); }); const next = document.getElementById("next"); next.addEventListener("click", () => { if (pageNum >= doc.numPages) return; pageNum++; - queueRenderPage(pageNum); + renderPage(pageNum); }); document.addEventListener("keydown", (e) => { if (e.key === "ArrowLeft" || e.key === "h") { if (pageNum <= 1) return; pageNum--; - queueRenderPage(pageNum); + renderPage(pageNum); } else if (e.key === "ArrowRight" || e.key === "l") { if (pageNum >= doc.numPages) return; pageNum++; - queueRenderPage(pageNum); + renderPage(pageNum); } }); // TODO: error handling doc = await getDocument(url).promise; - queueRenderPage(pageNum); + renderPage(pageNum); } document.addEventListener("DOMContentLoaded", init); -- cgit v1.3.1