I want to render a PDF inside a Backbone.js/Marionette View with pdf.js, but PDFJS is not defined in pdf.worker.js. It is however defined in the Backbone View itself and also accessible via the console.
This is the code for the View:
module.exports = PDFView = Marionette.ItemView.extend({
template: require('../../../templates/pdf_frame.hbs'),
onRender: function(){
var PDF_PATH = '../../pdf/websummitpitch.pdf';
var PAGE_NUMBER = 1;
var PAGE_SCALE = 1.5;
var SVG_NS = '';
if (PDFJS) {
console.log("PDFJS is loaded in Backbone View");
} else {
console.log("PDFJS is NOT loaded in Backbone View");
}
PDFJS.workerSrc = "/js/pdf.worker.js";
console.log("workerSrc is set to ", PDFJS.workerSrc);
// Loading document and page text content
PDFJS.getDocument({url: PDF_PATH}).then(function (pdfDocument) {
console.log("get document");
pdfDocument.getPage(PAGE_NUMBER).then(function (page) {
console.log("get page");
var viewport = page.getViewport(PAGE_SCALE);
page.getTextContent().then(function (textContent) {
// building SVG and adding that to the DOM
var svg = this.buildSVG(viewport, textContent);
// render svg in <canvas id="render"> in template
document.getElementById('render').appendChild(svg);
});
});
});
},
buildSVG: function(viewport, textContent) {
// Building SVG with size of the viewport (for simplicity)
var svg = document.createElementNS(SVG_NS, 'svg:svg');
svg.setAttribute('width', viewport.width + 'px');
svg.setAttribute('height', viewport.height + 'px');
// items are transformed to have 1px font size
svg.setAttribute('font-size', 1);
// processing all items
textContent.items.forEach(function (textItem) {
// we have to take in account viewport transform, which incudes scale,
// rotation and Y-axis flip, and not forgetting to flip text.
var tx = PDFJS.Util.transform(
PDFJS.Util.transform(viewport.transform, textItem.transform),
[1, 0, 0, -1, 0, 0]);
var style = textContent.styles[textItem.fontName];
// adding text element
var text = document.createElementNS(SVG_NS, 'svg:text');
text.setAttribute('transform', 'matrix(' + tx.join(' ') + ')');
text.setAttribute('font-family', style.fontFamily);
text.textContent = textItem.str;
svg.appendChild(text);
});
return svg;
}
});
This is the console output: The blue is console input, so PDFJS is accessible via the console.
This is where the reference error occurs (in pdf.worker.js):
PDFJS.version = '1.0.233';
It is one of the very first lines, where the version number is set. However PDFJS seems to be undefined.
This is my question:
Why is it not defined? How should I fix this?
I want to render a PDF inside a Backbone.js/Marionette View with pdf.js, but PDFJS is not defined in pdf.worker.js. It is however defined in the Backbone View itself and also accessible via the console.
This is the code for the View:
module.exports = PDFView = Marionette.ItemView.extend({
template: require('../../../templates/pdf_frame.hbs'),
onRender: function(){
var PDF_PATH = '../../pdf/websummitpitch.pdf';
var PAGE_NUMBER = 1;
var PAGE_SCALE = 1.5;
var SVG_NS = 'http://www.w3/2000/svg';
if (PDFJS) {
console.log("PDFJS is loaded in Backbone View");
} else {
console.log("PDFJS is NOT loaded in Backbone View");
}
PDFJS.workerSrc = "/js/pdf.worker.js";
console.log("workerSrc is set to ", PDFJS.workerSrc);
// Loading document and page text content
PDFJS.getDocument({url: PDF_PATH}).then(function (pdfDocument) {
console.log("get document");
pdfDocument.getPage(PAGE_NUMBER).then(function (page) {
console.log("get page");
var viewport = page.getViewport(PAGE_SCALE);
page.getTextContent().then(function (textContent) {
// building SVG and adding that to the DOM
var svg = this.buildSVG(viewport, textContent);
// render svg in <canvas id="render"> in template
document.getElementById('render').appendChild(svg);
});
});
});
},
buildSVG: function(viewport, textContent) {
// Building SVG with size of the viewport (for simplicity)
var svg = document.createElementNS(SVG_NS, 'svg:svg');
svg.setAttribute('width', viewport.width + 'px');
svg.setAttribute('height', viewport.height + 'px');
// items are transformed to have 1px font size
svg.setAttribute('font-size', 1);
// processing all items
textContent.items.forEach(function (textItem) {
// we have to take in account viewport transform, which incudes scale,
// rotation and Y-axis flip, and not forgetting to flip text.
var tx = PDFJS.Util.transform(
PDFJS.Util.transform(viewport.transform, textItem.transform),
[1, 0, 0, -1, 0, 0]);
var style = textContent.styles[textItem.fontName];
// adding text element
var text = document.createElementNS(SVG_NS, 'svg:text');
text.setAttribute('transform', 'matrix(' + tx.join(' ') + ')');
text.setAttribute('font-family', style.fontFamily);
text.textContent = textItem.str;
svg.appendChild(text);
});
return svg;
}
});
This is the console output: The blue is console input, so PDFJS is accessible via the console.
This is where the reference error occurs (in pdf.worker.js):
PDFJS.version = '1.0.233';
It is one of the very first lines, where the version number is set. However PDFJS seems to be undefined.
This is my question:
Why is it not defined? How should I fix this?
Share Improve this question asked Jul 23, 2014 at 14:07 emiel187emiel187 1912 gold badges3 silver badges9 bronze badges 4-
Where do you actually load
pdf.worker.js
(can I see yourdefine
statement for the module?) – Toli Commented Jul 23, 2014 at 15:30 -
Also not sure why you are using
module.exports
. For frontend AMD modules follow this format: requirejs/docs/api.html#deffunc Remember that on frontend nothing is synchronous (as far as loading external files). – Toli Commented Jul 23, 2014 at 15:36 - Why do I use module.exports? It is pretty standard for a View in backbone/marionette. This is how the pdf.worker.js should be loaded according to the examples. PDFJS.workerSrc = "/js/pdf.worker.js"; Do I need to specify a define function? I don't fully grasp the concept and how it could help me here. Tnx:) – emiel187 Commented Jul 24, 2014 at 12:14
- are you using Require.js to load the modules? – Toli Commented Jul 24, 2014 at 22:41
1 Answer
Reset to default 1I got the pdf viewer to work. Instead of using:
PDFJS.workerSrc = "/js/pdf.worker.js";
I just disabled the worker like this:
PDFJS.disableWorker = true;
Now it magically works. Not sure why though.