Files
mylesen/public/js/papar_dokumen.js

138 lines
5.2 KiB
JavaScript

/**
* papar_dokumen.js
* Handles document list -> preview rendering (PDF + images) on canvas
* Requires: jQuery, pdfjsLib (global), Bootstrap
*
* Note: Ensure pdfjsLib global is available (use non-module CDN).
*/
(function ($, window, document, undefined) {
'use strict';
$(function () {
const $canvas = $('#pdf-canvas');
const canvas = $canvas.length ? $canvas[0] : null;
const ctx = canvas ? canvas.getContext('2d') : null;
const $container = $('#preview-container');
let currentUrl = null;
let zoom = 1.0;
if (!canvas || !ctx) {
console.warn('Canvas not found for dokumen preview.');
return;
}
// init event bindings
$(document).on('click', '.dokumen-item', function () {
const url = $(this).data('url');
if (!url) return;
currentUrl = url;
loadFile(url);
});
$('#btn-zoom-in').on('click', function (e) {
e.preventDefault();
zoom = Math.min(3, zoom + 0.2);
if (currentUrl) loadFile(currentUrl);
});
$('#btn-zoom-out').on('click', function (e) {
e.preventDefault();
zoom = Math.max(0.2, zoom - 0.2);
if (currentUrl) loadFile(currentUrl);
});
function loadFile(url) {
const ext = (url.split('.').pop() || '').toLowerCase();
if (['pdf'].includes(ext)) {
renderPDF(url);
} else if (['jpg','jpeg','png','gif','webp'].includes(ext)) {
renderImage(url);
} else {
toast('Format tidak disokong untuk preview', 'error');
}
}
// Render first page of PDF
function renderPDF(url) {
// ensure pdfjsLib exists
if (typeof pdfjsLib === 'undefined') {
console.error('pdfjsLib not found. Include PDF.js (non-module) before papar_dokumen.js');
return;
}
// disable workers to avoid CORS/worker issues, or set workerSrc if available
if (pdfjsLib.GlobalWorkerOptions && !pdfjsLib.GlobalWorkerOptions.workerSrc) {
// try use CDN worker (same version assumed)
pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.16.105/pdf.worker.min.js';
}
pdfjsLib.getDocument(url).promise.then(function (pdf) {
return pdf.getPage(1).then(function (page) {
const containerWidth = $container.width();
const viewport = page.getViewport({ scale: 1 });
const scale = (containerWidth / viewport.width) * zoom;
const scaledViewport = page.getViewport({ scale: scale });
const outputScale = window.devicePixelRatio || 1;
canvas.width = Math.floor(scaledViewport.width * outputScale);
canvas.height = Math.floor(scaledViewport.height * outputScale);
canvas.style.width = Math.floor(scaledViewport.width) + "px";
canvas.style.height = Math.floor(scaledViewport.height) + "px";
const renderContext = {
canvasContext: ctx,
viewport: scaledViewport,
transform: [outputScale, 0, 0, outputScale, 0, 0],
};
ctx.clearRect(0, 0, canvas.width, canvas.height);
page.render(renderContext);
});
}).catch(function (err) {
console.error('Error rendering PDF', err);
toast('Gagal memaparkan PDF.');
});
}
// Render image to canvas, fit to container and support zoom
function renderImage(url) {
const img = new Image();
img.crossOrigin = 'anonymous';
img.onload = function () {
const containerW = $container.width();
const containerH = $container.height();
const fitScale = Math.min(containerW / img.width, containerH / img.height);
const finalW = Math.max(1, Math.floor(img.width * fitScale * zoom));
const finalH = Math.max(1, Math.floor(img.height * fitScale * zoom));
canvas.width = finalW;
canvas.height = finalH;
canvas.style.width = finalW + 'px';
canvas.style.height = finalH + 'px';
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(img, 0, 0, finalW, finalH);
};
img.onerror = function () {
console.error('Error loading image', url);
toast('Imej gagal dimuatkan.');
};
img.src = url;
}
function toast(msg, lvl = 'info') {
if ($('#globalToast').length) {
$('#globalToast .toast-body').text(msg);
new bootstrap.Toast($('#globalToast')[0]).show();
} else {
console[lvl === 'error' ? 'error' : 'log'](msg);
}
}
});
})(jQuery, window, document);