fix(web): lecteur PDF — pages blanches après rendu et base minimale stable
Le canvas PDF restait vide après rendu (blank-detected): la détection d'encre reposait sur un seuil de blanc trop sensible et un fond de canvas non maîtrisé. Le rendu passe à un fond sentinel explicite avec classification rendered-ok/blank-detected et un seuil de pixels visibles. Le lecteur est par ailleurs ramené à une base minimale stable: layout plein viewport (app-main-reader), suppression des modes de lecture et des préférences par livre, helpers de pagination/viewport extraits dans readerLayout.ts. Shell, lecteurs CBZ/EPUB et styles alignés sur cette base. Refs #31 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
54
apps/web/src/reader/readerLayout.ts
Normal file
54
apps/web/src/reader/readerLayout.ts
Normal file
@ -0,0 +1,54 @@
|
||||
export type ReaderSize = {
|
||||
width: number;
|
||||
height: number;
|
||||
};
|
||||
|
||||
export function clampReaderPage(page: number, pageCount: number) {
|
||||
const safePageCount = Math.max(1, Math.floor(pageCount));
|
||||
return Math.max(1, Math.min(Math.floor(page), safePageCount));
|
||||
}
|
||||
|
||||
export function previousReaderPage(page: number, pageCount: number) {
|
||||
return clampReaderPage(page - 1, pageCount);
|
||||
}
|
||||
|
||||
export function nextReaderPage(page: number, pageCount: number) {
|
||||
return clampReaderPage(page + 1, pageCount);
|
||||
}
|
||||
|
||||
export function readerPositionLabel(page: number, pageCount: number) {
|
||||
return `Page ${clampReaderPage(page, pageCount)} / ${Math.max(1, Math.floor(pageCount))}`;
|
||||
}
|
||||
|
||||
export function containPageSize(viewport: ReaderSize, page: ReaderSize): ReaderSize {
|
||||
if (viewport.width <= 0 || viewport.height <= 0 || page.width <= 0 || page.height <= 0) {
|
||||
return { width: 0, height: 0 };
|
||||
}
|
||||
const scale = Math.min(viewport.width / page.width, viewport.height / page.height);
|
||||
return {
|
||||
width: Math.max(1, Math.floor(page.width * scale)),
|
||||
height: Math.max(1, Math.floor(page.height * scale))
|
||||
};
|
||||
}
|
||||
|
||||
export function orientedContainPageSize(viewport: ReaderSize, page: ReaderSize): ReaderSize {
|
||||
if (viewport.width <= 0 || viewport.height <= 0 || page.width <= 0 || page.height <= 0) {
|
||||
return { width: 0, height: 0 };
|
||||
}
|
||||
const fitByHeight = page.height >= page.width;
|
||||
const primaryScale = fitByHeight ? viewport.height / page.height : viewport.width / page.width;
|
||||
const crossScale = fitByHeight ? viewport.width / page.width : viewport.height / page.height;
|
||||
const scale = Math.min(primaryScale, crossScale);
|
||||
return {
|
||||
width: Math.max(1, Math.floor(page.width * scale)),
|
||||
height: Math.max(1, Math.floor(page.height * scale))
|
||||
};
|
||||
}
|
||||
|
||||
export function readableViewportSize(size: ReaderSize): ReaderSize | null {
|
||||
if (size.width < 32 || size.height < 32) return null;
|
||||
return {
|
||||
width: Math.floor(size.width),
|
||||
height: Math.floor(size.height)
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user