-
Notifications
You must be signed in to change notification settings - Fork 1
/
pdf-utility.ts
87 lines (70 loc) · 2.87 KB
/
pdf-utility.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import { PDFDocumentProxy, PDFRenderTask } from './pdf'; // Definitions only
/** Size of PDF page */
export interface PdfPageSize {
width: number;
height: number;
}
/** URI of the PDF JS library */
// @ts-ignore: This property does exist, regardless of what TS thinks
const pdfApiUri = `${import.meta.url}/../../pdfjs-dist/build/pdf.min.js`;
/** URI of the PDF JS web worker */
// @ts-ignore: This property does exist, regardless of what TS thinks
const pdfWorkerUri = `${import.meta.url}/../../pdfjs-dist/build/pdf.worker.min.js`;
/** Flag indicating that PDF library is currently being loaded, wait for it to . */
let pdfApiLoading = false;
/** Flag indicating that PDF library has been downloaded. */
let pdfApiReady: any;
/** Add a legacy side-effect script to the <head> of the page.
* This is needed for the PDF.js API as it adds a global variable to the window.
* @param uri The URI of the script.
* @returns A promise that resolves once the script has loaded and rejects on error. */
function loadScript(uri: string) {
return new Promise((resolve, reject) => {
const script = document.createElement('script') as HTMLScriptElement;
script.type = 'text/javascript';
script.onload = resolve;
script.onerror = reject;
document.getElementsByTagName('head')[0].appendChild(script);
script.src = uri;
});
}
/** Get the PDF.js API */
export async function pdfApi(): Promise<any> {
if (pdfApiReady)
return pdfApiReady;
if ((window as any).pdfjsLib)
return pdfApiReady = (window as any).pdfjsLib; // Loaded externally
while (pdfApiLoading)
await new Promise(requestAnimationFrame);
if (pdfApiReady)
return pdfApiReady;
try {
pdfApiLoading = true;
console.log('📃 PDF API loading...');
console.time('📃 PDF API loaded.');
// Add a <script> tag pointing to the API
await loadScript(pdfApiUri);
// Wait for the script to populate the global variable
while (!(window as any).pdfjsLib)
await new Promise(requestAnimationFrame);
pdfApiReady = (window as any).pdfjsLib;
// The workerSrc property needs to be specified.
pdfApiReady.GlobalWorkerOptions.workerSrc = pdfWorkerUri;
console.timeEnd('📃 PDF API loaded.');
}
finally { pdfApiLoading = false; }
return pdfApiReady;
}
/** Get the size of the first page.
* @param pdf The PDF document proxy.
* @param zoom The current zoom level.
* @returns The width and height in pixels. */
export async function firstPageSize(pdf: PDFDocumentProxy, zoom: number): Promise<PdfPageSize> {
// Get the size of the first page and estimate rest from that
const firstPage = await pdf.getPage(1);
const viewport = firstPage.getViewport({ scale: zoom });
return {
width: viewport.width,
height: viewport.height
};
}