155 lines
5.6 KiB
JavaScript
155 lines
5.6 KiB
JavaScript
window.pdfViewer = {
|
|
_pdfCache: new Map(),
|
|
_resizeObserver: null,
|
|
_currentContainerId: null,
|
|
_currentPdfUrls: null,
|
|
_renderTimeout: null,
|
|
_lastRenderedUrls: null, // Track what was last rendered
|
|
|
|
renderPdfs: async function (containerId, pdfUrls) {
|
|
// Wait for container to be available
|
|
let container = null;
|
|
for (let i = 0; i < 50; i++) {
|
|
container = document.getElementById(containerId);
|
|
if (container) break;
|
|
await new Promise(resolve => setTimeout(resolve, 100));
|
|
}
|
|
|
|
if (!container) {
|
|
console.error('Container not found after waiting:', containerId);
|
|
return;
|
|
}
|
|
|
|
// Check if URLs changed - if same, skip render (use cache)
|
|
const urlsKey = JSON.stringify(pdfUrls);
|
|
if (this._lastRenderedUrls === urlsKey && this._currentContainerId === containerId) {
|
|
console.log('[PDF] Same URLs, skipping render (cached)');
|
|
return;
|
|
}
|
|
|
|
console.log('[PDF] New URLs detected, rendering:', pdfUrls);
|
|
|
|
// Store for resize handling
|
|
this._currentContainerId = containerId;
|
|
this._currentPdfUrls = pdfUrls;
|
|
this._lastRenderedUrls = urlsKey;
|
|
|
|
// Setup resize observer
|
|
this._setupResizeObserver(container);
|
|
|
|
// Render
|
|
await this._doRender(container, pdfUrls);
|
|
},
|
|
|
|
_setupResizeObserver: function(container) {
|
|
// Clean up previous observer
|
|
if (this._resizeObserver) {
|
|
this._resizeObserver.disconnect();
|
|
}
|
|
|
|
let lastWidth = container.clientWidth;
|
|
|
|
this._resizeObserver = new ResizeObserver((entries) => {
|
|
const newWidth = entries[0].contentRect.width;
|
|
// Only re-render if width changed significantly (more than 5px)
|
|
if (Math.abs(newWidth - lastWidth) > 5) {
|
|
lastWidth = newWidth;
|
|
// Debounce the re-render
|
|
if (this._renderTimeout) {
|
|
clearTimeout(this._renderTimeout);
|
|
}
|
|
this._renderTimeout = setTimeout(() => {
|
|
this._doRender(container, this._currentPdfUrls);
|
|
}, 150);
|
|
}
|
|
});
|
|
|
|
this._resizeObserver.observe(container);
|
|
},
|
|
|
|
_doRender: async function(container, pdfUrls) {
|
|
container.innerHTML = '';
|
|
|
|
if (typeof pdfjsLib === 'undefined') {
|
|
console.error('PDF.js not loaded');
|
|
container.innerHTML = '<p style="color:red;">PDF.js nincs betöltve</p>';
|
|
return;
|
|
}
|
|
|
|
const pixelRatio = window.devicePixelRatio || 1;
|
|
const scrollbarWidth = 17;
|
|
const containerWidth = container.clientWidth - scrollbarWidth;
|
|
|
|
if (containerWidth <= 0) {
|
|
console.log('Container width is 0, skipping render');
|
|
return;
|
|
}
|
|
|
|
console.log('[PDF] Rendering at width:', containerWidth, 'URLs:', pdfUrls);
|
|
|
|
for (const url of pdfUrls) {
|
|
try {
|
|
// Use cached PDF document if available (PDF.js document cache)
|
|
let pdf = this._pdfCache.get(url);
|
|
if (!pdf) {
|
|
console.log('[PDF] Loading new PDF:', url);
|
|
const loadingTask = pdfjsLib.getDocument(url);
|
|
pdf = await loadingTask.promise;
|
|
this._pdfCache.set(url, pdf);
|
|
} else {
|
|
console.log('[PDF] Using cached PDF:', url);
|
|
}
|
|
|
|
for (let pageNum = 1; pageNum <= pdf.numPages; pageNum++) {
|
|
const page = await pdf.getPage(pageNum);
|
|
|
|
const viewport = page.getViewport({ scale: 1 });
|
|
const scale = containerWidth / viewport.width;
|
|
const displayHeight = viewport.height * scale;
|
|
const scaledViewport = page.getViewport({ scale: scale * pixelRatio });
|
|
|
|
const canvas = document.createElement('canvas');
|
|
canvas.width = scaledViewport.width;
|
|
canvas.height = scaledViewport.height;
|
|
canvas.style.width = containerWidth + 'px';
|
|
canvas.style.height = displayHeight + 'px';
|
|
canvas.style.marginBottom = '8px';
|
|
canvas.style.display = 'block';
|
|
container.appendChild(canvas);
|
|
|
|
const context = canvas.getContext('2d');
|
|
await page.render({
|
|
canvasContext: context,
|
|
viewport: scaledViewport
|
|
}).promise;
|
|
}
|
|
} catch (error) {
|
|
console.error('[PDF] Error rendering:', url, error);
|
|
const errorDiv = document.createElement('div');
|
|
errorDiv.textContent = 'Hiba a PDF betöltésekor: ' + url + ' - ' + error.message;
|
|
errorDiv.style.color = 'red';
|
|
errorDiv.style.marginBottom = '8px';
|
|
container.appendChild(errorDiv);
|
|
}
|
|
}
|
|
},
|
|
|
|
dispose: function() {
|
|
if (this._resizeObserver) {
|
|
this._resizeObserver.disconnect();
|
|
this._resizeObserver = null;
|
|
}
|
|
if (this._renderTimeout) {
|
|
clearTimeout(this._renderTimeout);
|
|
}
|
|
// Keep PDF cache for performance, only clear on full dispose
|
|
this._pdfCache.clear();
|
|
this._lastRenderedUrls = null;
|
|
},
|
|
|
|
// Clear only the render cache (not PDF documents)
|
|
clearRenderCache: function() {
|
|
this._lastRenderedUrls = null;
|
|
}
|
|
};
|