// ES6 Compliant Syntax
// GitHub Copilot v1.0, GPT-4.1, October 15, 2025
// File: index.js
import WebViewer from '@pdftron/webviewer';
const licenseKey = 'YOUR_WEBVIEWER_LICENSE_KEY';
// Create Thumbnail Demo
// This code demonstrates how to create a high resolution JPG or PNG thumbnail for a PDF document using the loadCanvas API.
function initializeWebViewer() {
// This code initializes the WebViewer with the basic settings
WebViewer({
path: '/lib',
licenseKey: licenseKey,
enableFilePicker: true,
loadAsPDF: true, // Ensure files are loaded as PDF documents for best thumbnail quality
}, document.getElementById('viewer')).then((instance) => {
// Enable the measurement toolbar so it appears with all the other tools, and disable Cloudy rectangular tool
const cloudyTools = [
instance.Core.Tools.ToolNames.CLOUDY_RECTANGULAR_AREA_MEASUREMENT,
instance.Core.Tools.ToolNames.CLOUDY_RECTANGULAR_AREA_MEASUREMENT2,
instance.Core.Tools.ToolNames.CLOUDY_RECTANGULAR_AREA_MEASUREMENT3,
instance.Core.Tools.ToolNames.CLOUDY_RECTANGULAR_AREA_MEASUREMENT4,
];
instance.UI.enableFeatures([instance.UI.Feature.Measurement, instance.UI.Feature.Initials]);
instance.UI.disableTools(cloudyTools);
// Set default toolbar group to Annotate
instance.UI.setToolbarGroup('toolbarGroup-Annotate');
// Set default tool on mobile devices to Pan.
if (UIElements.isMobileDevice()) {
instance.UI.setToolMode(instance.Core.Tools.ToolNames.PAN);
}
instance.Core.documentViewer.addEventListener('documentUnloaded', () => {
if (searchParams.has('file')) {
searchParams.delete('file');
history.replaceState(null, '', '?' + searchParams.toString());
}
});
instance.Core.annotationManager.enableAnnotationNumbering();
instance.UI.NotesPanel.enableAttachmentPreview();
// Add the demo-specific functionality
customizeUI(instance).then(() => {
// Create UI controls after demo is initialized
UIElements.createUIControls(instance);
});
});
}
const searchParams = new URLSearchParams(window.location.search);
const history = window.history || window.parent.history || window.top.history;
window.pageNum = 1;
window.scaleNum = 1.0;
window.thumbnailName = 'thumbnail';
window.thumbnailType = 'png';
window.thumbnailOptions = ['PNG', 'JPEG'];
const customizeUI = async (instance) => {
// Load the default document
await instance.UI.loadDocument('https://apryse.s3.us-west-1.amazonaws.com/public/files/samples/WebviewerDemoDoc.pdf');
};
// Function to handle the Create Thumbnail button click
window.onThumbnailButtonClick = (instance) => {
// Get the document
const doc = instance.Core.documentViewer.getDocument();
// Get the page number from user input
let pageNumber = parseInt(window.pageNum, 10);
// Validate page number
if (isNaN(pageNumber) || pageNumber < 1 || pageNumber > doc.getPageCount()) {
alert('Please enter a valid page number between 1 and ' + doc.getPageCount());
return; // Exit if page number is invalid
}
// Clamp the page number to valid range
pageNumber = isNaN(pageNumber) ? 1 : Math.min(Math.max(pageNumber, 1), doc.getPageCount());
// Get the scale (zoom level) from user input
const zoom = parseFloat(window.scaleNum);
if (isNaN(zoom) || zoom <= 0 || zoom > 10) {
alert('Please enter a valid zoom level between 0.1 and 10');
return; // Exit if zoom is invalid
}
// Compensate for device pixel ratio to ensure consistent output across devices
// Normalize to standard DPR of 1.0 by dividing by actual DPR
const devicePixelRatio = window.devicePixelRatio || 1;
const adjustedZoom = zoom / devicePixelRatio;
console.log(`Device Pixel Ratio: ${devicePixelRatio}`);
console.log(`Original zoom: ${zoom}, Adjusted zoom: ${adjustedZoom}`);
console.log(`This should produce thumbnails equivalent to DPR=1.0 environment`);
// Get the file name and type from user input
const name = window.thumbnailName;
const type = window.thumbnailType;
// Save to blob using the loadCanvas API
doc.loadCanvas({
pageNumber,
zoom: adjustedZoom, // Use DPI-adjusted zoom for consistent output
drawComplete: async (thumbnail) => {
// Optionally, comment out "drawAnnotations" to exclude annotations
await instance.Core.documentViewer
.getAnnotationManager()
.drawAnnotations(pageNumber, thumbnail);
// thumbnail is a HTMLCanvasElement or HTMLImageElement
thumbnail.toBlob(
(blob) => {
saveAs(blob, name + '.' + type);
},
'image/' + type,
1
);
},
});
};
// Cleanup function for when the demo is closed or page is unloaded
const cleanup = (instance) => {
if (typeof instance !== 'undefined' && instance.UI) {
if (instance.Core.documentViewer.getDocument()) {
// Insert any other cleanup code here
}
console.log('Cleaning up demo');
}
};
// Register cleanup for page unload
window.addEventListener('beforeunload', () => cleanup(instance));
window.addEventListener('unload', () => cleanup(instance));
// UI Elements Script Loader
// Loads the ui-elements.js script
function loadUIElementsScript() {
return new Promise((resolve, reject) => {
if (window.UIElements) {
console.log('UIElements already loaded');
resolve();
return;
}
const script = document.createElement('script');
script.src = '/showcase-demos/create-thumbnail/ui-elements.js';
script.onload = function () {
console.log('✅ UIElements script loaded successfully');
resolve();
};
script.onerror = function () {
console.error('Failed to load UIElements script');
reject(new Error('Failed to load ui-elements.js'));
};
document.head.appendChild(script);
});
}
// Load UIElements script first, then initialize WebViewer
loadUIElementsScript().then(() => {
initializeWebViewer();
}).catch((error) => {
console.error('Failed to load UIElements:', error);
});