fix: reduce split-page hairline artifacts in canvas rendering

This commit is contained in:
Jürgen Mummert
2026-04-14 15:23:39 +02:00
parent a6c9aef952
commit 583fa81eb8
+18 -42
View File
@@ -5,6 +5,7 @@ const FLIPBOOK_MODULE_URL = '/bundles/flipbook/assets/vendor/flipbook.esm.min.js
const TURN_SOUND_URL = '/bundles/flipbook/assets/audio/turn.mp3';
const INIT_MARKER = 'pdfFlipbookInitialized';
const BOOTSTRAP_MARKER = '__mummertPdfFlipbookBootstrapBound';
const MIN_OUTPUT_SCALE = 2;
let dependenciesPromise;
let moduleCounter = 0;
@@ -567,7 +568,7 @@ class PdfFlipbookModule {
const scale = this.pageWidth / renderWidth;
const viewport = page.getViewport({ scale });
const devicePixelRatio = window.devicePixelRatio || 1;
const outputScale = Math.max(1, devicePixelRatio);
const outputScale = Math.max(MIN_OUTPUT_SCALE, devicePixelRatio);
const existingCanvas = pageElement.querySelector('canvas');
if (existingCanvas) {
@@ -590,51 +591,26 @@ class PdfFlipbookModule {
canvas.style.width = `${canvasCssWidth}px`;
canvas.style.height = `${Math.floor(viewport.height)}px`;
if (descriptor.segment === 'full') {
const renderTask = page.render({
canvasContext: context,
viewport,
transform: outputScale === 1 ? null : [outputScale, 0, 0, outputScale, 0, 0],
intent: 'display',
});
const baseTransform = outputScale === 1 ? null : [outputScale, 0, 0, outputScale, 0, 0];
let transform = baseTransform;
await renderTask.promise;
} else {
const spreadCanvas = document.createElement('canvas');
const spreadContext = spreadCanvas.getContext('2d', { alpha: false });
if (descriptor.segment !== 'full' && baseTransform) {
const segmentOffsetX = descriptor.segment === 'left'
? 0
: -Math.floor((viewport.width * outputScale) / 2);
if (!spreadContext) {
throw new Error('Could not create split canvas context.');
}
spreadCanvas.width = Math.floor(viewport.width * outputScale);
spreadCanvas.height = Math.floor(viewport.height * outputScale);
const spreadRenderTask = page.render({
canvasContext: spreadContext,
viewport,
transform: outputScale === 1 ? null : [outputScale, 0, 0, outputScale, 0, 0],
intent: 'display',
});
await spreadRenderTask.promise;
const halfWidth = Math.floor(spreadCanvas.width / 2);
const sourceX = descriptor.segment === 'left' ? 0 : spreadCanvas.width - halfWidth;
context.drawImage(
spreadCanvas,
sourceX,
0,
halfWidth,
spreadCanvas.height,
0,
0,
canvas.width,
canvas.height,
);
transform = [outputScale, 0, 0, outputScale, segmentOffsetX, 0];
}
const renderTask = page.render({
canvasContext: context,
viewport,
transform,
intent: 'display',
});
await renderTask.promise;
const loader = pageElement.querySelector('.mod-pdf-flipbook__page-loader');
if (loader) {