@inizioevoke/astro-core 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +31 -0
- package/src/components/Modal/Modal.astro +36 -0
- package/src/components/Modal/Modal.css +145 -0
- package/src/components/Modal/Modal.ts +109 -0
- package/src/components/Modal/ModalOverlay.astro +1 -0
- package/src/components/Modal/ModalTrigger.astro +29 -0
- package/src/components/PdfViewer/PdfViewer.astro +103 -0
- package/src/components/PdfViewer/PdfViewer.css +198 -0
- package/src/components/PdfViewer/PdfViewer.ts +183 -0
- package/src/components/PdfViewer/pdf.min.mjs +28 -0
- package/src/components/PdfViewer/pdf.mjs +26465 -0
- package/src/components/PdfViewer/pdf.mjs.map +1 -0
- package/src/components/PdfViewer/pdf.worker.min.mjs +28 -0
- package/src/components/PdfViewer/pdf.worker.mjs +63057 -0
- package/src/components/PdfViewer/pdf.worker.mjs.map +1 -0
- package/src/components/ScrollContainer/ScrollContainer.astro +55 -0
- package/src/components/ScrollContainer/ScrollContainer.css +64 -0
- package/src/components/ScrollContainer/ScrollContainer.ts +143 -0
- package/src/components/Tabs/TabItem.astro +24 -0
- package/src/components/Tabs/Tabs.astro +94 -0
- package/src/components/Tabs/Tabs.css +70 -0
- package/src/components/Tabs/Tabs.ts +22 -0
- package/src/components/Zoom/Zoom.astro +64 -0
- package/src/components/Zoom/ZoomContent.astro +0 -0
- package/src/components/Zoom/ZoomModal.astro +0 -0
- package/src/components/index.ts +8 -0
- package/src/integrations/index.ts +2 -0
- package/src/integrations/prune-build.ts +71 -0
- package/src/integrations/relative-links.ts +178 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import * as pdfjs from './pdf.mjs';
|
|
2
|
+
import type { PDFDocumentProxy } from 'pdfjs-dist';
|
|
3
|
+
import * as ScrollContainer from '../ScrollContainer/ScrollContainer';
|
|
4
|
+
|
|
5
|
+
pdfjs.GlobalWorkerOptions.workerSrc = './pdf.worker.min.mjs';
|
|
6
|
+
|
|
7
|
+
interface PdfViewerSettings {
|
|
8
|
+
workerDir?: string;
|
|
9
|
+
workerSrc?: string;
|
|
10
|
+
}
|
|
11
|
+
export function init(settings: PdfViewerSettings = {}) {
|
|
12
|
+
if (!settings.workerDir) {
|
|
13
|
+
settings.workerDir = './';
|
|
14
|
+
}
|
|
15
|
+
if (!settings.workerSrc) {
|
|
16
|
+
settings.workerSrc = `${settings.workerDir}${settings.workerDir.endsWith('/') ? '' : '/'}pdf.worker.min.mjs`
|
|
17
|
+
}
|
|
18
|
+
pdfjs.GlobalWorkerOptions.workerSrc = settings.workerSrc;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export async function createViewer(selector: string) {
|
|
22
|
+
const pdfViewer = document.querySelector<HTMLElement>(selector);
|
|
23
|
+
if (pdfViewer) {
|
|
24
|
+
const ddlPage = pdfViewer.querySelector('select') as HTMLSelectElement;
|
|
25
|
+
const toolbar = pdfViewer.querySelector('.evo-pdf-viewer-toolbar') as HTMLElement;
|
|
26
|
+
const toolbarHeight = parseFloat(getComputedStyle(toolbar).height);
|
|
27
|
+
const pageSelect = toolbar.querySelector('.evo-pdf-viewer-nav-page select') as HTMLSelectElement;
|
|
28
|
+
const scrollContainer = ScrollContainer.getScrollContainer(pdfViewer.querySelector('.evo-scroll-container') as HTMLElement) as ScrollContainer.IScrollContainer;
|
|
29
|
+
|
|
30
|
+
const zoom = (z: number) => {
|
|
31
|
+
const style = getComputedStyle(pdfViewer);
|
|
32
|
+
const current = Math.floor(parseFloat(style.getPropertyValue('--evo-pdf-viewer-scale')) * 10);
|
|
33
|
+
const scale = z === 0 ? 10 : current + z;
|
|
34
|
+
if (scale >= 1) {
|
|
35
|
+
const scroll = ScrollContainer.getScroll(scrollContainer);
|
|
36
|
+
pdfViewer.style.setProperty('--evo-pdf-viewer-scale', (scale/10).toString());
|
|
37
|
+
ScrollContainer.scroll(scrollContainer, { left: scroll.left * scale / current, top: scroll.top * scale / current });
|
|
38
|
+
ScrollContainer.refresh(scrollContainer);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const gotoPage = (page: number | string) => {
|
|
43
|
+
if (typeof page == 'string') {
|
|
44
|
+
page = parseInt(page, 10);
|
|
45
|
+
}
|
|
46
|
+
requestAnimationFrame(() => {
|
|
47
|
+
const container = pdfViewer.querySelector('.evo-scroll-content') as HTMLElement;
|
|
48
|
+
const canvas = container.querySelector<HTMLElement>(`canvas[data-page="${page}"]`);
|
|
49
|
+
if (canvas) {
|
|
50
|
+
container.scroll({ top: canvas.getBoundingClientRect().top + container.scrollTop - toolbarHeight }); // , behavior: 'smooth' });
|
|
51
|
+
pageSelect.selectedIndex = page - 1;
|
|
52
|
+
}
|
|
53
|
+
})
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
pageSelect.addEventListener('change', (e) => {
|
|
57
|
+
const page = pageSelect.options[pageSelect.selectedIndex].value;
|
|
58
|
+
gotoPage(page);
|
|
59
|
+
}, { passive: true });
|
|
60
|
+
|
|
61
|
+
pdfViewer.querySelector<HTMLButtonElement>('button.evo-pdf-viewer-toolbar-zoom-out')?.addEventListener('click', () => {
|
|
62
|
+
zoom(-1);
|
|
63
|
+
}, { passive: true });
|
|
64
|
+
|
|
65
|
+
pdfViewer.querySelector<HTMLButtonElement>('button.evo-pdf-viewer-toolbar-zoom-in')?.addEventListener('click', () => {
|
|
66
|
+
zoom(1);
|
|
67
|
+
}, { passive: true });
|
|
68
|
+
|
|
69
|
+
pdfViewer.querySelector<HTMLButtonElement>('button.evo-pdf-viewer-toolbar-zoom-reset')?.addEventListener('click', () => {
|
|
70
|
+
zoom(0);
|
|
71
|
+
}, { passive: true });
|
|
72
|
+
|
|
73
|
+
const pdf: PDFDocumentProxy = await pdfjs.getDocument(pdfViewer.getAttribute('data-pdf') as string).promise;
|
|
74
|
+
|
|
75
|
+
const bookmarks: Record<string, number> = JSON.parse(atob(pdfViewer.getAttribute('data-bookmarks') as string));
|
|
76
|
+
if (Object.keys(bookmarks).length > 0) {
|
|
77
|
+
const toolbarBookmarks = toolbar.querySelector('.evo-pdf-viewer-toolbar-bookmarks') as HTMLElement;
|
|
78
|
+
const bookmarksSelect = toolbarBookmarks.querySelector('select') as HTMLSelectElement;
|
|
79
|
+
Object.entries(bookmarks).forEach(([ key, value ]) => {
|
|
80
|
+
const option = document.createElement('option') as HTMLOptionElement;
|
|
81
|
+
option.value = value.toString();
|
|
82
|
+
option.innerText = key;
|
|
83
|
+
bookmarksSelect.options.add(option);
|
|
84
|
+
});
|
|
85
|
+
bookmarksSelect.addEventListener('change', () => {
|
|
86
|
+
gotoPage(bookmarksSelect.options[bookmarksSelect.selectedIndex].value);
|
|
87
|
+
bookmarksSelect.selectedIndex = 0;
|
|
88
|
+
});
|
|
89
|
+
toolbarBookmarks.classList.remove('hidden');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const outputScale = window.devicePixelRatio || 1;
|
|
93
|
+
const pages = new Array(pdf.numPages).fill(1).map((v, i) => { return i + 1; });
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
pdfViewer.querySelector<HTMLButtonElement>('button.evo-pdf-viewer-toolbar-prev')?.addEventListener('click', () => {
|
|
97
|
+
const page = parseInt(pageSelect.options[pageSelect.selectedIndex].value, 10) - 1;
|
|
98
|
+
if (page > 0) {
|
|
99
|
+
gotoPage(page);
|
|
100
|
+
}
|
|
101
|
+
}, { passive: true });
|
|
102
|
+
|
|
103
|
+
pdfViewer.querySelector<HTMLButtonElement>('button.evo-pdf-viewer-toolbar-next')?.addEventListener('click', () => {
|
|
104
|
+
const page = parseInt(pageSelect.options[pageSelect.selectedIndex].value, 10) + 1;
|
|
105
|
+
if (page <= pages.length) {
|
|
106
|
+
gotoPage(page);
|
|
107
|
+
}
|
|
108
|
+
}, { passive: true });
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
const pdfContainer = pdfViewer.querySelector('.evo-scroll-content') as HTMLElement;
|
|
112
|
+
pdfViewer.querySelector<HTMLElement>('.evo-pdf-viewer-nav-page-count')!.innerText = pages.length.toString();
|
|
113
|
+
for (const pageNum of pages) {
|
|
114
|
+
const option = document.createElement('option');
|
|
115
|
+
option.value = pageNum.toString();
|
|
116
|
+
option.innerText = `${pageNum}`;
|
|
117
|
+
ddlPage.options.add(option);
|
|
118
|
+
|
|
119
|
+
const pdfPage = await pdf.getPage(pageNum);
|
|
120
|
+
const pdfPageWidth = pdfPage.getViewport({ scale: 1}).width;
|
|
121
|
+
const containerStyle = getComputedStyle(pdfContainer);
|
|
122
|
+
const trackWidth = parseInt(containerStyle.getPropertyValue('--evo-scroll-container-track-width'));
|
|
123
|
+
const viewport = pdfPage.getViewport({ scale: parseFloat(containerStyle.width) / pdfPageWidth });
|
|
124
|
+
|
|
125
|
+
const canvas = document.createElement('canvas');
|
|
126
|
+
canvas.setAttribute('data-page', pageNum.toString());
|
|
127
|
+
const width = Math.floor(viewport.width * outputScale);
|
|
128
|
+
const height = Math.floor(viewport.height * outputScale);
|
|
129
|
+
canvas.width = width;
|
|
130
|
+
canvas.height = height;
|
|
131
|
+
canvas.style.aspectRatio = `${width}/${height}`;
|
|
132
|
+
canvas.style.width = `calc(${Math.floor(viewport.width) - (trackWidth * 2)}px * var(--evo-pdf-viewer-scale)`;
|
|
133
|
+
// canvas.style.height = `${Math.floor(viewport.height)}px`;
|
|
134
|
+
pdfContainer.append(canvas);
|
|
135
|
+
|
|
136
|
+
pdfPage.render({
|
|
137
|
+
canvas,
|
|
138
|
+
// canvasContext: canvas.getContext('2d') as CanvasRenderingContext2D,
|
|
139
|
+
transform: outputScale !== 1 ? [outputScale, 0, 0, outputScale, 0, 0] : undefined,
|
|
140
|
+
viewport
|
|
141
|
+
});
|
|
142
|
+
ScrollContainer.refresh(scrollContainer);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Function to check and update current page
|
|
146
|
+
const updateCurrentPage = () => {
|
|
147
|
+
const canvases = pdfContainer.querySelectorAll<HTMLCanvasElement>('canvas');
|
|
148
|
+
let visiblePage: HTMLCanvasElement | undefined;
|
|
149
|
+
let maxVisibility = 0;
|
|
150
|
+
|
|
151
|
+
canvases.forEach((canvas) => {
|
|
152
|
+
const rect = canvas.getBoundingClientRect();
|
|
153
|
+
const containerRect = scrollContainer.container.getBoundingClientRect();
|
|
154
|
+
|
|
155
|
+
// Calculate intersection height
|
|
156
|
+
const intersectTop = Math.max(rect.top, containerRect.top);
|
|
157
|
+
const intersectBottom = Math.min(rect.bottom, containerRect.bottom);
|
|
158
|
+
const intersectionHeight = Math.max(0, intersectBottom - intersectTop);
|
|
159
|
+
|
|
160
|
+
// Calculate visibility ratio
|
|
161
|
+
const visibility = intersectionHeight / (rect.height || 1);
|
|
162
|
+
|
|
163
|
+
if (visibility > maxVisibility) {
|
|
164
|
+
maxVisibility = visibility;
|
|
165
|
+
visiblePage = canvas;
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
if (visiblePage && maxVisibility >= 0.1) {
|
|
170
|
+
const pageNum = visiblePage.getAttribute('data-page');
|
|
171
|
+
if (pageNum) {
|
|
172
|
+
pageSelect.selectedIndex = parseInt(pageNum, 10) - 1;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
// Update on scroll
|
|
178
|
+
scrollContainer.content.addEventListener('scroll', updateCurrentPage, { passive: true });
|
|
179
|
+
|
|
180
|
+
// Initial update
|
|
181
|
+
updateCurrentPage();
|
|
182
|
+
}
|
|
183
|
+
}
|