🚀 GrowMechanical® Document Viewer
📂 Drag & Drop PDF, Excel, Word or Image Here
Or use the file selector above
No document loaded.
GrowMechanical Document Viewer
Upload a PDF, Excel, Word or image file
to begin.
/* =========================================================
PDF.JS CONFIGURATION
========================================================= */
pdfjsLib.GlobalWorkerOptions.workerSrc =
"https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.worker.min.js";
/* =========================================================
VARIABLES
========================================================= */
const viewer =
document.getElementById("viewer");
const fileInput =
document.getElementById("fileInput");
const gridSelect =
document.getElementById("gridSelect");
const statusBox =
document.getElementById("status");
const dropZone =
document.getElementById("dropZone");
let currentFile = null;
let currentZoom = 1.4;
let currentPDF = null;
/* =========================================================
GRID
========================================================= */
function updateGrid(){
const value =
parseInt(gridSelect.value);
/*
Mobile:
Always one column.
*/
if(window.innerWidth <= 768){ viewer.style.gridTemplateColumns = "1fr"; return; } if(value === 2){ viewer.style.gridTemplateColumns = "repeat(2,minmax(0,1fr))"; } else if(value === 4){ viewer.style.gridTemplateColumns = "repeat(2,minmax(0,1fr))"; } else if(value === 6){ viewer.style.gridTemplateColumns = "repeat(3,minmax(0,1fr))"; } else if(value === 8){ viewer.style.gridTemplateColumns = "repeat(4,minmax(0,1fr))"; } } gridSelect.addEventListener( "change", updateGrid ); window.addEventListener( "resize", updateGrid ); updateGrid(); /* ========================================================= STATUS ========================================================= */ function setStatus(message){ statusBox.textContent = message; } /* ========================================================= CLEAR ========================================================= */ function clearViewer(){ viewer.innerHTML = `
GrowMechanical Document Viewer
Upload a document to begin.
`;
currentFile = null;
currentPDF = null;
setStatus(
"No document loaded."
);
}
/* =========================================================
FILE SELECT
========================================================= */
fileInput.addEventListener(
"change",
function(){
if(this.files.length){
loadFile(
this.files[0]
);
}
}
);
/* =========================================================
DRAG & DROP
========================================================= */
dropZone.addEventListener(
"dragover",
function(event){
event.preventDefault();
dropZone.classList.add(
"dragover"
);
}
);
dropZone.addEventListener(
"dragleave",
function(){
dropZone.classList.remove(
"dragover"
);
}
);
dropZone.addEventListener(
"drop",
function(event){
event.preventDefault();
dropZone.classList.remove(
"dragover"
);
const files =
event.dataTransfer.files;
if(files.length){
loadFile(files[0]);
}
}
);
/* =========================================================
LOAD FILE
========================================================= */
async function loadFile(file){
currentFile =
file;
viewer.innerHTML = "";
const extension =
file.name
.split(".")
.pop()
.toLowerCase();
setStatus(
"Loading: " +
file.name
);
try{
if(extension === "pdf"){
await renderPDF(file);
}
else if(
extension === "xlsx" ||
extension === "xls"
){
await renderExcel(file);
}
else if(
extension === "docx"
){
await renderDOCX(file);
}
else if(
[
"png",
"jpg",
"jpeg",
"webp"
].includes(extension)
){
renderImage(file);
}
else{
throw new Error(
"Unsupported file format."
);
}
}
catch(error){
console.error(error);
viewer.innerHTML = `
Unable to display file
${error.message}
`;
setStatus(
"Error loading document."
);
}
}
/* =========================================================
CREATE WATERMARK
========================================================= */
function createWatermark(){
const watermark =
document.createElement(
"div"
);
watermark.className =
"watermark";
watermark.textContent =
"www.growmechanical.com";
return watermark;
}
/* =========================================================
PDF RENDERING
========================================================= */
async function renderPDF(file){
setStatus(
"Rendering PDF..."
);
const data =
new Uint8Array(
await file.arrayBuffer()
);
currentPDF =
await pdfjsLib
.getDocument(data)
.promise;
for(
let pageNumber = 1;
pageNumber <= currentPDF.numPages;
pageNumber++
){
const page =
await currentPDF
.getPage(pageNumber);
/*
High resolution rendering.
*/
let scale =
currentZoom;
if(
window.innerWidth <= 768
){
scale =
Math.min(
currentZoom,
1.6
);
}
const viewport =
page.getViewport({
scale:scale
});
const card =
document.createElement(
"article"
);
card.className =
"page-card";
const pageNumberLabel =
document.createElement(
"div"
);
pageNumberLabel.className =
"page-number";
pageNumberLabel.textContent =
"Page " +
pageNumber;
/*
Actual PDF page with border.
*/
const pdfPage =
document.createElement(
"div"
);
pdfPage.className =
"pdf-page";
const canvas =
document.createElement(
"canvas"
);
canvas.className =
"pdf-canvas";
canvas.width =
Math.floor(
viewport.width
);
canvas.height =
Math.floor(
viewport.height
);
/*
On desktop, keep the rendered page sharp
while fittin