| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364 |
- import * as pdfjs from 'pdfjs-dist';
- // Set worker path - using a CDN for the worker to avoid complex vite configuration for now
- // or we can try to use the bundled worker if vite handles it
- pdfjs.GlobalWorkerOptions.workerSrc = `https://cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.min.mjs`;
- export const pdfRenderService = {
- async renderPageToCanvas(
- pdfData: Blob | ArrayBuffer,
- pageNumber: number,
- canvas: HTMLCanvasElement,
- targetWidth: number,
- targetHeight: number
- ): Promise<void> {
- const data = pdfData instanceof Blob ? await pdfData.arrayBuffer() : pdfData;
- const loadingTask = pdfjs.getDocument({ data });
- const pdf = await loadingTask.promise;
- if (pageNumber < 1 || pageNumber > pdf.numPages) {
- throw new Error(`Invalid page number: ${pageNumber}.`);
- }
- const page = await pdf.getPage(pageNumber);
- // Calculate scale to fit container while maintaining aspect ratio
- const unscaledViewport = page.getViewport({ scale: 1 });
- // Calculate the scale needed to fit the PDF page within the target dimensions
- const fitScale = Math.min(targetWidth / unscaledViewport.width, targetHeight / unscaledViewport.height);
- // Calculate a higher scale for rendering quality (anti-aliasing and clarity)
- const devicePixelRatio = window.devicePixelRatio || 1;
- const renderScale = fitScale * Math.max(2, devicePixelRatio);
- const viewport = page.getViewport({ scale: renderScale });
- // Set canvas to the high-resolution dimensions to maintain quality
- canvas.width = viewport.width;
- canvas.height = viewport.height;
- const context = canvas.getContext('2d');
- if (!context) return;
- // Save the context state before any transformations
- context.save();
- // Fill background
- context.fillStyle = '#f8fafc';
- context.fillRect(0, 0, canvas.width, canvas.height);
- // Calculate the position to center the PDF page in the canvas
- const offsetX = (canvas.width - viewport.width) / 2;
- const offsetY = (canvas.height - viewport.height) / 2;
- await page.render({
- canvasContext: context,
- viewport: viewport,
- transform: [1, 0, 0, 1, offsetX, offsetY]
- }).promise;
- // Restore the context state after rendering
- context.restore();
- }
- };
|