import * as pdfJS from './pdfjs-4.0.379.min.mjs'; import * as pdfWorker from './pdfjs-4.0.379.worker.min.mjs'; if (pdfJS != null && pdfWorker != null) { pdfJS.GlobalWorkerOptions.workerSrc = pdfWorker; } function getCanvas(item) { if (isDomSupported() && typeof item === 'string') { item = document.getElementById(item); } else if (item && item.length) { // support for array based queries item = item[0]; } if (item && item.canvas !== undefined && item.canvas) { // support for any object associated to a canvas (including a context2d) item = item.canvas; } return item; } const getPdf = (key) => { const canvas = getCanvas(key); return Object.values(pdfInstances).filter((c) => c.canvas === canvas).pop(); }; const pdfInstances = {}; class Pdf { static instances = pdfInstances; static getPdf = getPdf; constructor(item) { const canvas = getCanvas(item); //const existingPdf = getPdf(canvas); this.id = canvas.id; this.canvas = canvas; this.ctx = canvas.getContext('2d'); this.pdfDoc = null; this.pageNum = 1; this.pagesCount = 0; this.pageRendering = false; this.pageNumPending = null; this.scale = 1; this.rotation = 0; pdfInstances[this.id] = this; } } export function firstPage(dotNetHelper, elementId) { const pdf = getPdf(elementId); if (pdf == null || pdf.pageNum === 1) return; if (pdf.pageNum > 1) pdf.pageNum = 1; queueRenderPage(pdf, pdf.pageNum); setPdfViewerMetaData(dotNetHelper, pdf); } export function gotoPage(dotNetHelper, elementId, gotoPageNum) { const pdf = getPdf(elementId); if (pdf == null || gotoPageNum < 1 || gotoPageNum > pdf.pagesCount) return; pdf.pageNum = gotoPageNum; queueRenderPage(pdf, pdf.pageNum); setPdfViewerMetaData(dotNetHelper, pdf); } export function lastPage(dotNetHelper, elementId) { const pdf = getPdf(elementId); if (pdf == null || (pdf.pageNum === 1 && pdf.pageNum === pdf.pagesCount)) return; if (pdf.pageNum < pdf.pagesCount) pdf.pageNum = pdf.pagesCount; queueRenderPage(pdf, pdf.pageNum); setPdfViewerMetaData(dotNetHelper, pdf); } export function nextPage(dotNetHelper, elementId) { const pdf = getPdf(elementId); if (pdf == null || pdf.pageNum === pdf.pagesCount) return; if (pdf.pageNum < pdf.pagesCount) pdf.pageNum += 1; queueRenderPage(pdf, pdf.pageNum); setPdfViewerMetaData(dotNetHelper, pdf); } export function previousPage(dotNetHelper, elementId) { const pdf = getPdf(elementId); if (pdf == null || pdf.pageNum === 0 || pdf.pageNum === 1) return; if (pdf.pageNum > 0) pdf.pageNum -= 1; queueRenderPage(pdf, pdf.pageNum); setPdfViewerMetaData(dotNetHelper, pdf); } export async function print(dotNetHelper, elementId, url) { const pdfDoc = await pdfJS.getDocument(url).promise; const pageRange = [1, 2, 3, 4]; // TODO: update this const iframeEl = document.createElement('iframe'); iframeEl.style = 'display:none'; document.body.appendChild(iframeEl); for (const pageNumber of pageRange) { const page = await pdfDoc.getPage(pageNumber); const viewport = page.getViewport({ scale: 1.5 }); const canvas = document.createElement("canvas"); canvas.height = viewport.height; canvas.width = viewport.width; //canvas.style.height = `${viewport.height * 2}px`; //canvas.style.width = `${viewport.width * 2}px`; const ctx = canvas.getContext('2d'); const renderContext = { //intent: 'print', canvasContext: ctx, viewport: viewport }; await page.render(renderContext).promise; const iframeDoc = iframeEl.contentWindow.document; iframeDoc.body.appendChild(canvas); } setTimeout(() => { iframeEl.contentWindow.print(); iframeEl.remove(); }, 1000); } export function rotate(dotNetHelper, elementId, rotation) { const pdf = getPdf(elementId); if (pdf == null || Number.isNaN(rotation) || rotation % 90 !== 0) return; pdf.rotation = rotation; queueRenderPage(pdf, pdf.pageNum); } export function zoomInOut(dotNetHelper, elementId, scale) { const pdf = getPdf(elementId); if (pdf == null) return; if (!Number.isNaN(scale)) pdf.scale = scale; queueRenderPage(pdf, pdf.pageNum); } // resize // print // download // zoomreset /* firstPageButton.disabled = this.pageNumber <= 1; lastPageButton.disabled = this.pageNumber >= this.pagesCount; pageRotateCwButton.disabled = this.pagesCount === 0; pageRotateCcwButton.disabled = this.pagesCount === 0; */ export function initialize(dotNetHelper, elementId, scale, rotation, url) { const pdf = new Pdf(elementId); pdf.scale = scale; pdf.rotation = rotation; pdfJS.getDocument(url).promise.then(function (doc) { pdf.pdfDoc = doc; pdf.pagesCount = doc.numPages; renderPage(pdf, pdf.pageNum); dotNetHelper.invokeMethodAsync('DocumentLoaded', { pagesCount: pdf.pagesCount, pageNumber: pdf.pageNum }); }); } function isDomSupported() { return typeof window !== 'undefined' && typeof document !== 'undefined'; } /** * If another page rendering in progress, waits until the rendering is * finished. Otherwise, executes rendering immediately. */ function queueRenderPage(pdf, num) { if (pdf.pageRendering) { pdf.pageNumPending = num; } else { renderPage(pdf, num); } } /** * Get page info from document, resize canvas accordingly, and render page. * @param num Page number. */ function renderPage(pdf, num) { pdf.pageRendering = true; // Using promise to fetch the page pdf.pdfDoc.getPage(num).then((page) => { const viewport = page.getViewport({ scale: pdf.scale, rotation: pdf.rotation }); pdf.canvas.height = viewport.height; pdf.canvas.width = viewport.width; // Render PDF page into canvas context const renderContext = { canvasContext: pdf.ctx, viewport: viewport }; const renderTask = page.render(renderContext); // Wait for rendering to finish renderTask.promise.then(() => { pdf.pageRendering = false; if (pdf.pageNumPending !== null) { // New page rendering is pending renderPage(pdf, pdf.pageNumPending); pdf.pageNumPending = null; } }) .catch((error) => { // TODO: track exception }); }); } function setPdfViewerMetaData(dotNetHelper, pdf) { if (dotNetHelper == null) return; dotNetHelper.invokeMethodAsync('SetPdfViewerMetaData', { pagesCount: pdf.pagesCount, pageNumber: pdf.pageNum }); }