first commit
This commit is contained in:
137
public/js/papar_dokumen.js
Normal file
137
public/js/papar_dokumen.js
Normal file
@@ -0,0 +1,137 @@
|
||||
/**
|
||||
* 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);
|
||||
Reference in New Issue
Block a user