refac
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
import DOMPurify from 'dompurify';
|
||||
import { getContext, onDestroy, onMount, tick } from 'svelte';
|
||||
import type { Readable } from 'svelte/store';
|
||||
import { clampDocumentTargetPage } from '$lib/utils/documentPreview';
|
||||
|
||||
import Spinner from './Spinner.svelte';
|
||||
|
||||
@@ -13,6 +14,7 @@
|
||||
|
||||
export let data: ArrayBuffer | null = null;
|
||||
export let className = '';
|
||||
export let targetPage: number | null = null;
|
||||
|
||||
let outerContainer: HTMLDivElement;
|
||||
let containerEl: HTMLDivElement;
|
||||
@@ -84,6 +86,16 @@
|
||||
updateFitScale();
|
||||
};
|
||||
|
||||
const scrollToTargetPage = async () => {
|
||||
if (!containerEl) return;
|
||||
const pages = containerEl.querySelectorAll('section.docx');
|
||||
const page = clampDocumentTargetPage(targetPage, pages.length);
|
||||
if (!page) return;
|
||||
|
||||
await tick();
|
||||
(pages[page - 1] as HTMLElement | undefined)?.scrollIntoView({ block: 'start' });
|
||||
};
|
||||
|
||||
const renderDocx = async (arrayBuffer: ArrayBuffer | null) => {
|
||||
const currentRender = ++renderId;
|
||||
clearPreview();
|
||||
@@ -112,6 +124,7 @@
|
||||
});
|
||||
await tick();
|
||||
updateFitScale();
|
||||
await scrollToTargetPage();
|
||||
} catch (e) {
|
||||
console.error('Error rendering DOCX preview:', e);
|
||||
|
||||
@@ -130,6 +143,10 @@
|
||||
|
||||
$: if (mounted) renderDocx(data);
|
||||
|
||||
$: if (!loading && targetPage && !fallbackHtml) {
|
||||
void scrollToTargetPage();
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
mounted = true;
|
||||
void tick().then(() => {
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
<script lang="ts">
|
||||
import { onMount, onDestroy } from 'svelte';
|
||||
import { onMount, onDestroy, tick } from 'svelte';
|
||||
import pdfWorkerUrl from 'pdfjs-dist/build/pdf.worker.mjs?url';
|
||||
import panzoom, { type PanZoom } from 'panzoom';
|
||||
import { clampDocumentTargetPage } from '$lib/utils/documentPreview';
|
||||
import Spinner from './Spinner.svelte';
|
||||
|
||||
export let url: string | null = null;
|
||||
export let data: ArrayBuffer | Uint8Array | null = null;
|
||||
export let className = 'w-full h-[70vh]';
|
||||
export let targetPage: number | null = null;
|
||||
|
||||
type PdfDocument = import('pdfjs-dist').PDFDocumentProxy;
|
||||
type PdfTextLayer = InstanceType<typeof import('pdfjs-dist').TextLayer>;
|
||||
@@ -98,6 +100,17 @@
|
||||
}
|
||||
};
|
||||
|
||||
const scrollToTargetPage = async () => {
|
||||
if (!outerContainer || !sceneElement || !pdfDoc) return;
|
||||
const page = clampDocumentTargetPage(targetPage, pdfDoc.numPages);
|
||||
if (!page) return;
|
||||
|
||||
await tick();
|
||||
const pageWrapper = sceneElement.querySelectorAll('.pdf-page-wrapper')[page - 1] as
|
||||
HTMLElement | undefined;
|
||||
pageWrapper?.scrollIntoView({ block: 'start' });
|
||||
};
|
||||
|
||||
// Re-render existing canvases at a new zoom level (preserves panzoom transform)
|
||||
const rerenderPages = async (forZoom: number) => {
|
||||
if (!pdfDoc || !sceneElement) return;
|
||||
@@ -223,6 +236,7 @@
|
||||
|
||||
lastRenderedZoom = 1;
|
||||
initPanzoom();
|
||||
await scrollToTargetPage();
|
||||
};
|
||||
|
||||
const loadPdf = async () => {
|
||||
@@ -258,6 +272,10 @@
|
||||
loadPdf();
|
||||
});
|
||||
|
||||
$: if (!loading && pdfDoc && targetPage) {
|
||||
void scrollToTargetPage();
|
||||
}
|
||||
|
||||
onDestroy(() => {
|
||||
if (rerenderTimer) clearTimeout(rerenderTimer);
|
||||
pzInstance?.dispose();
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
<script lang="ts">
|
||||
import { onDestroy, onMount, tick } from 'svelte';
|
||||
import panzoom, { type PanZoom } from 'panzoom';
|
||||
import { clampDocumentTargetPage } from '$lib/utils/documentPreview';
|
||||
|
||||
export let slides: string[] = [];
|
||||
export let currentSlide = 0;
|
||||
export let className = '';
|
||||
export let targetPage: number | null = null;
|
||||
|
||||
let rootEl: HTMLDivElement;
|
||||
let stageEl: HTMLElement;
|
||||
@@ -22,6 +24,8 @@
|
||||
let wheelDelta = 0;
|
||||
let lastWheelNavigationAt = 0;
|
||||
let lastScrolledSlide = -1;
|
||||
let appliedTargetPage: number | null = null;
|
||||
let appliedTargetSlides: string[] | null = null;
|
||||
let thumbnailButtons: Array<HTMLButtonElement | undefined> = [];
|
||||
const slideShortcutKeys = ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'];
|
||||
const wheelNavigationThreshold = 80;
|
||||
@@ -158,7 +162,7 @@
|
||||
const transform = pzInstance?.getTransform();
|
||||
if (transform && Math.abs(transform.scale - 1) >= 0.01) {
|
||||
e.preventDefault();
|
||||
pzInstance?.moveBy(-e.deltaX, -e.deltaY);
|
||||
pzInstance?.moveBy(-e.deltaX, -e.deltaY, false);
|
||||
zoomLevel = pzInstance?.getTransform().scale ?? 1;
|
||||
return;
|
||||
}
|
||||
@@ -203,6 +207,18 @@
|
||||
void tick().then(scrollSelectedThumbnailIntoView);
|
||||
}
|
||||
|
||||
$: if (
|
||||
mounted &&
|
||||
targetPage &&
|
||||
slides.length > 0 &&
|
||||
(targetPage !== appliedTargetPage || slides !== appliedTargetSlides)
|
||||
) {
|
||||
appliedTargetPage = targetPage;
|
||||
appliedTargetSlides = slides;
|
||||
const page = clampDocumentTargetPage(targetPage, slides.length);
|
||||
if (page) selectSlide(page - 1);
|
||||
}
|
||||
|
||||
onDestroy(() => {
|
||||
pzInstance?.dispose();
|
||||
resizeObserver?.disconnect();
|
||||
|
||||
Reference in New Issue
Block a user