I have to display PDF using PDFJS library on my page. The problem is that since I give the scale as a fixed number canvas in which PDF is rendered is not responsive and does not fit the bootstrap grid column width. Here is HTML code:
<div class="row">
<div class="col-md-1" style="padding-right: 15px;">
<input type="button" ng-click="openPreviousPage()"/>
</div>
<div class="col-md-8">
<canvas id="the-canvas" style="border: 1px solid black;"></canvas>
</div>
<div class="col-md-1 col-md-offset-2" style="padding-right:15px;">
<input type="button" ng-click="openNextPage()" />
</div>
</div>
and my Typescript in a controller:
openPage = (pdf: PDFDocumentProxy, pageNumber: number) => {
pdf.getPage(pageNumber).then(function getPage(page) {
var scale = 1;
var viewport = page.getViewport(scale);
var canvas = <HTMLCanvasElement>document.getElementById('the-canvas');
var context = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
var renderContext = {
canvasContext: context,
viewport: viewport
};
//...rest of actions
});
}
Would be grateful for any hint.
You can put an id
on the canvas container div
and set the scale based upon div.clientWidth
and viewport.width
.
On your HTML code:
<div class="row">
<div class="col-md-1" style="padding-right: 15px;">
<input type="button" ng-click="openPreviousPage()"/>
</div>
<div class="col-md-8" id="the-container">
<canvas id="the-canvas" style="border: 1px solid black;"></canvas>
</div>
<div class="col-md-1 col-md-offset-2" style="padding-right:15px;">
<input type="button" ng-click="openNextPage()" />
</div>
</div>
Then on the controller:
openPage = (pdf: PDFDocumentProxy, pageNumber: number) => {
pdf.getPage(pageNumber).then(function getPage(page) {
var container = document.getElementById('the-container');
var canvas = <HTMLCanvasElement>document.getElementById('the-canvas');
var context = canvas.getContext('2d');
var viewport = page.getViewport(1);
var scale = container.clientWidth / viewport.width;
viewport = page.getViewport(scale);
canvas.height = viewport.height;
canvas.width = viewport.width;
var renderContext = {
canvasContext: context,
viewport: viewport
};
//...rest of actions
});
}
Hope this helps...
For anybody working from the Acroforms example as their starting point, you may notice that viewport.width does not match what is being rendered on the screen when you inspect, which makes the above solution render the PDF larger than desired. In my case, viewport.width was 612, but was rendering to 816. I finally figured out that this is a result of the CSS_UNITS variable that lives inside pdf_viewer.js. Once I figured that out, I honed my Google search and found the conversation discussing its purpose:
"In the html/css world 1in = 96pixels, in PDF the default is 1in = 72pixels. The scale is used so when showing 100% a PDF that is 8.5in should show up on the screen as 8.5in."
To adjust for this variable, which isn't global, I just declared it again locally and then adjusted the scale formula above to include it, like this:
'use strict';
PDFJS.workerSrc = '/assets/plugins/PDFjs/web/test/pdf.worker.js';
var DEFAULT_URL = '/assets/plugins/PDFjs/web/test/form.pdf';
var DEFAULT_SCALE = 1.0;
var CSS_UNITS = 96/72;
var container = document.getElementById('pageContainer');
// Fetch the PDF document from the URL using promises.
PDFJS.getDocument(DEFAULT_URL).then(function (doc) {
// Use a promise to fetch and render the next page.
var promise = Promise.resolve();
for (var i = 1; i <= doc.numPages; i++) {
promise = promise.then(function (pageNum) {
return doc.getPage(pageNum).then(function (pdfPage) {
var viewport = pdfPage.getViewport(DEFAULT_SCALE);
var scale = container.clientWidth / (viewport.width * CSS_UNITS);
// Create the page view.
var pdfPageView = new PDFJS.PDFPageView({
container: container,
id: pageNum,
scale: scale,
defaultViewport: pdfPage.getViewport(scale),
annotationLayerFactory: new PDFJS.DefaultAnnotationLayerFactory(),
renderInteractiveForms: true,
});
// Associate the actual page with the view and draw it.
pdfPageView.setPdfPage(pdfPage);
return pdfPageView.draw();
});
}.bind(null, i));
}
});
It works well for me now. Hope I was able to save one of you some time. :)
Cheers!
Use bootstrap and put class = "img-fluid" in your canvas.
<div class="container" id="the-container">
<canvas id="the-canvas" class="img-fluid" style="border: 1px solid black;"></canvas>
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With