New to custom Widget development so please point me in a different direction if this doesn’t make sense. So I have this idea of modifying the image annotator widget to use PDFs instead of images. In theory I should be able to do this using the Modzilla pdf.js library which should let me load a pdf into a HTML canvas element. However I have been stuck getting the pdf.js library imported and working in my widget, before I continue hacking away at it wondering if folks have already done this and can help me out here.
Here’s my widget javascript code:
var pdfData = atob(
'JVBERi0xLjcKCjEgMCBvYmogICUgZW50cnkgcG9pbnQKPDwKICAvVHlwZSAvQ2F0YWxvZwog' +
'IC9QYWdlcyAyIDAgUgo+PgplbmRvYmoKCjIgMCBvYmoKPDwKICAvVHlwZSAvUGFnZXMKICAv' +
'TWVkaWFCb3ggWyAwIDAgMjAwIDIwMCBdCiAgL0NvdW50IDEKICAvS2lkcyBbIDMgMCBSIF0K' +
'Pj4KZW5kb2JqCgozIDAgb2JqCjw8CiAgL1R5cGUgL1BhZ2UKICAvUGFyZW50IDIgMCBSCiAg' +
'L1Jlc291cmNlcyA8PAogICAgL0ZvbnQgPDwKICAgICAgL0YxIDQgMCBSIAogICAgPj4KICA+' +
'PgogIC9Db250ZW50cyA1IDAgUgo+PgplbmRvYmoKCjQgMCBvYmoKPDwKICAvVHlwZSAvRm9u' +
'dAogIC9TdWJ0eXBlIC9UeXBlMQogIC9CYXNlRm9udCAvVGltZXMtUm9tYW4KPj4KZW5kb2Jq' +
'Cgo1IDAgb2JqICAlIHBhZ2UgY29udGVudAo8PAogIC9MZW5ndGggNDQKPj4Kc3RyZWFtCkJU' +
'CjcwIDUwIFRECi9GMSAxMiBUZgooSGVsbG8sIHdvcmxkISkgVGoKRVQKZW5kc3RyZWFtCmVu' +
'ZG9iagoKeHJlZgowIDYKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDEwIDAwMDAwIG4g' +
'CjAwMDAwMDAwNzkgMDAwMDAgbiAKMDAwMDAwMDE3MyAwMDAwMCBuIAowMDAwMDAwMzAxIDAw' +
'MDAwIG4gCjAwMDAwMDAzODAgMDAwMDAgbiAKdHJhaWxlcgo8PAogIC9TaXplIDYKICAvUm9v' +
'dCAxIDAgUgo+PgpzdGFydHhyZWYKNDkyCiUlRU9G');
loadScripts();
async function loadScripts() {
console.log(`Loading script...`);
const response = await fetch('https://mozilla.github.io/pdf.js/build/pdf.js');
const responseBody = await response.text();
const scriptElm = document.createElement("script");
const inlineCode = document.createTextNode(responseBody);
scriptElm.appendChild(inlineCode);
document.body.appendChild(scriptElm);
console.log(`Script successfully loaded`);
const workerResponse = await fetch('//mozilla.github.io/pdf.js/build/pdf.worker.js');
pdfjsLib.GlobalWorkerOptions.workerSrc = await workerResponse.text();
console.log(pdfjsLib)
var loadingTask = pdfjsLib.getDocument({ data: pdfData, });
loadingTask.promise.then(function(pdf) {
console.log('PDF loaded');
// Fetch the first page
var pageNumber = 1;
pdf.getPage(pageNumber).then(function(page) {
console.log('Page loaded');
var scale = 1.5;
var viewport = page.getViewport({scale: scale});
// Prepare canvas using PDF page dimensions
var canvas = document.getElementById('the-canvas');
var context = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
// Render PDF page into canvas context
var renderContext = {
canvasContext: context,
viewport: viewport
};
var renderTask = page.render(renderContext);
renderTask.promise.then(function () {
console.log('Page rendered');
});
});
}, function (reason) {
// PDF loading error
console.error(reason);
});
}
FWIW I am getting the following when I run the code: Error: Setting up fake worker failed: "Cannot load script at: /**
Just digging into this one right now. A few things stand out:
loadScripts() sometimes fails because the underlying library has nested dependencies it is trying to download. This often is the case with large Js libraries (with lots of their own dependencies)
When running this code within a HTML file, It also fails to load. This is generally my first check to debug behavior I think is tied to something specific to CWs.
<html>
<head>
<script type="text/javascript">
var pdfData = atob(
'JVBERi0xLjcKCjEgMCBvYmogICUgZW50cnkgcG9pbnQKPDwKICAvVHlwZSAvQ2F0YWxvZwog' +
'IC9QYWdlcyAyIDAgUgo+PgplbmRvYmoKCjIgMCBvYmoKPDwKICAvVHlwZSAvUGFnZXMKICAv' +
'TWVkaWFCb3ggWyAwIDAgMjAwIDIwMCBdCiAgL0NvdW50IDEKICAvS2lkcyBbIDMgMCBSIF0K' +
'Pj4KZW5kb2JqCgozIDAgb2JqCjw8CiAgL1R5cGUgL1BhZ2UKICAvUGFyZW50IDIgMCBSCiAg' +
'L1Jlc291cmNlcyA8PAogICAgL0ZvbnQgPDwKICAgICAgL0YxIDQgMCBSIAogICAgPj4KICA+' +
'PgogIC9Db250ZW50cyA1IDAgUgo+PgplbmRvYmoKCjQgMCBvYmoKPDwKICAvVHlwZSAvRm9u' +
'dAogIC9TdWJ0eXBlIC9UeXBlMQogIC9CYXNlRm9udCAvVGltZXMtUm9tYW4KPj4KZW5kb2Jq' +
'Cgo1IDAgb2JqICAlIHBhZ2UgY29udGVudAo8PAogIC9MZW5ndGggNDQKPj4Kc3RyZWFtCkJU' +
'CjcwIDUwIFRECi9GMSAxMiBUZgooSGVsbG8sIHdvcmxkISkgVGoKRVQKZW5kc3RyZWFtCmVu' +
'ZG9iagoKeHJlZgowIDYKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDEwIDAwMDAwIG4g' +
'CjAwMDAwMDAwNzkgMDAwMDAgbiAKMDAwMDAwMDE3MyAwMDAwMCBuIAowMDAwMDAwMzAxIDAw' +
'MDAwIG4gCjAwMDAwMDAzODAgMDAwMDAgbiAKdHJhaWxlcgo8PAogIC9TaXplIDYKICAvUm9v' +
'dCAxIDAgUgo+PgpzdGFydHhyZWYKNDkyCiUlRU9G');
loadScripts();
async function loadScripts() {
console.log(`Loading script...`);
const response = await fetch('https://mozilla.github.io/pdf.js/build/pdf.js');
const responseBody = await response.text();
const scriptElm = document.createElement("script");
const inlineCode = document.createTextNode(responseBody);
scriptElm.appendChild(inlineCode);
document.body.appendChild(scriptElm);
console.log(`Script successfully loaded`);
const workerResponse = await fetch('http://mozilla.github.io/pdf.js/build/pdf.worker.js');
pdfjsLib.GlobalWorkerOptions.workerSrc = await workerResponse.text();
console.log(pdfjsLib)
var loadingTask = pdfjsLib.getDocument({ data: pdfData, });
loadingTask.promise.then(function(pdf) {
console.log('PDF loaded');
// Fetch the first page
var pageNumber = 1;
pdf.getPage(pageNumber).then(function(page) {
console.log('Page loaded');
var scale = 1.5;
var viewport = page.getViewport({scale: scale});
// Prepare canvas using PDF page dimensions
var canvas = document.getElementById('the-canvas');
var context = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
// Render PDF page into canvas context
var renderContext = {
canvasContext: context,
viewport: viewport
};
var renderTask = page.render(renderContext);
renderTask.promise.then(function () {
console.log('Page rendered');
});
});
}, function (reason) {
// PDF loading error
console.error(reason);
});
}
</script>
</head>
</html>
I haven’t played much with anything outside of png, jpg, and base64 encoding for images, so I cant provide too much additional insight on this one.
Okay, I’ll check them out. I was able to make this custom widget through the Co-pilot. It displays Base64 of images. So I was hoping to do the same for PDF. customWidget-Base64 Image view (copy).json (1.5 KB)
Hello, to date, has anyone found a solution to this problem? I have APIs that return Base64 data that I would like to display in a PDF… So far, I only have a widget that allows me to convert Base64 to PNG but not to PDF. Thank you for your feedback.
If the scripts are provided you have to define a pdfJSWoker which is necessary for the pdf lib then you have to load the base64 of the pdf via widget parameter or via request. So you can easily use the pdf lib samples (Examples).
Keep in mind that you have to define a function to handle more than one pdf pages.