Init
This commit is contained in:
commit
0ad405c26e
78 changed files with 9127 additions and 0 deletions
71
src/lib/components/PdfBackground.svelte
Normal file
71
src/lib/components/PdfBackground.svelte
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
<script lang="ts">
|
||||
import { loadSource, renderPage } from '$lib/pdf/render';
|
||||
import { vault } from '$lib/storage/vault.svelte';
|
||||
import type { Origin } from '$lib/model/types';
|
||||
|
||||
interface Props {
|
||||
origin: Origin;
|
||||
width: number;
|
||||
height: number;
|
||||
/** Current zoom (screen px per PDF point). */
|
||||
scale: number;
|
||||
}
|
||||
|
||||
let { origin, width, height, scale }: Props = $props();
|
||||
let canvas: HTMLCanvasElement;
|
||||
let failed = $state(false);
|
||||
|
||||
// Render at a stepped resolution so zooming doesn't re-render constantly.
|
||||
const STEPS = [0.25, 0.5, 1, 1.5, 2, 3, 4];
|
||||
const MAX_PIXELS = 12_000_000;
|
||||
const resolution = $derived.by(() => {
|
||||
const want = scale * (window.devicePixelRatio || 1);
|
||||
const step = STEPS.find((s) => s >= want) ?? STEPS[STEPS.length - 1];
|
||||
const cap = Math.sqrt(MAX_PIXELS / (width * height));
|
||||
return Math.min(step, cap);
|
||||
});
|
||||
|
||||
$effect(() => {
|
||||
const res = resolution;
|
||||
const { sourceId, pageIndex } = origin;
|
||||
let job: ReturnType<typeof renderPage> | null = null;
|
||||
let cancelled = false;
|
||||
const timer = setTimeout(async () => {
|
||||
try {
|
||||
const doc = await loadSource(sourceId, () => vault.getSource(sourceId));
|
||||
if (cancelled) return;
|
||||
job = renderPage(doc, pageIndex, canvas, res);
|
||||
failed = false;
|
||||
} catch {
|
||||
failed = true;
|
||||
}
|
||||
}, 120);
|
||||
return () => {
|
||||
cancelled = true;
|
||||
clearTimeout(timer);
|
||||
job?.cancel();
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
||||
<canvas bind:this={canvas} class="bg" class:failed></canvas>
|
||||
{#if failed}
|
||||
<div class="missing">Source PDF “{origin.name}” is not available</div>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
.bg {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.missing {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
||||
Loading…
Add table
Add a link
Reference in a new issue