I have been following this tutorial to embed a PDF on my website using PDF.js. But I only want to embed a certain part, ie. a section in the middle of the PDF page. Is there a smart way to do this? Can I somehow crop the PDF displayed?
I use this code to render the pdf
const scale = 1,
canvas = document.querySelector('#pdf-render'),
ctx = canvas.getContext('2d');
const renderPage = num => {
pageIsRendering = true;
//get the page
pdfDoc.getPage(num).then(page => {
//set scale
const viewport = page.getViewport({scale});
canvas.height = viewport.height;
canvas.width = viewport.width;
const renderCtx = {
canvasContext: ctx,
viewport
};
page.render(renderCtx).promise.then(() => {
pageIsRendering = false;
if(pageNumIsPending !== null){
renderPage(pageNumIsPending);
pageNumIsPending = null;
}
});
Related
I want show second upload file content in canvas,but it always show first one.
This is my html:
<input type="file" id="myfile" name="myfile" value="upload">
<div>
<button id="prev">prev</button>
<button id="next">next</button>
<span>Page: <span id="page_num"></span> / <span id="page_count"></span></span>
</div>
<canvas id="the-canvas"></canvas>
canvas first img will be right, but others are wrong.
This is my js:
var pdfjsLib = window['pdfjs-dist/build/pdf'];
pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://mozilla.github.io/pdf.js/build/pdf.worker.js';
var pdfDoc = null,
pageNum = 1,
pageRendering = false,
pageNumPending = null,
scale = 1.5,
canvas = document.getElementById('the-canvas'),
ctx = canvas.getContext('2d');
$("#myfile").on("change", function (e) {
var file = e.target.files[0];
var fileReader = new FileReader();
fileReader.onload = function () {
var pdfData = new Uint8Array(this.result);
// Using DocumentInitParameters object to load binary data.
var loadingTask = pdfjsLib.getDocument({data: pdfData});
function renderPage(num) {
pageRendering = true;
// Using promise to fetch the page
pdfDoc.getPage(num).then(function(page) {
var viewport = page.getViewport({scale: scale});
canvas.height = viewport.height;
canvas.width = viewport.width;
// Render PDF page into canvas context
var renderContext = {
canvasContext: ctx,
viewport: viewport
};
var renderTask = page.render(renderContext);
// Wait for rendering to finish
renderTask.promise.then(function() {
pageRendering = false;
if (pageNumPending !== null) {
// New page rendering is pending
renderPage(pageNumPending);
pageNumPending = null;
}
});
});
document.getElementById('page_num').textContent = num;
}
function queueRenderPage(num) {
if (pageRendering) {
pageNumPending = num;
} else {
renderPage(num);
}
}
function onPrevPage() {
if (pageNum <= 1) {
return;
}
pageNum--;
queueRenderPage(pageNum);
}
document.getElementById('prev').addEventListener('click', onPrevPage);
function onNextPage() {
if (pageNum >= pdfDoc.numPages) {
return;
}
pageNum++;
queueRenderPage(pageNum);
}
document.getElementById('next').addEventListener('click', onNextPage);
pdfjsLib.getDocument({data: pdfData}).promise.then(function(pdfDoc_) {
pdfDoc = pdfDoc_;
document.getElementById('page_count').textContent = pdfDoc.numPages;
// Initial/first page rendering
renderPage(pageNum);
});
};
fileReader.readAsArrayBuffer(file);
});
pdf.js upload second file but show first content, how to show second content,thanks a lot
pdf.js upload second file but show first content, how to show second content,thanks a lot
pdf.js upload second file but show first content, how to show second content,thanks a lot
I'm using Mozilla PDF.js library and the demo works properly but the rendered PDF doesn't show forms / Acroforms.
Please help me out, how could I switch-on the forms and let the users to fulfill them.
I use a canvas at HTML:
<body>
<canvas id="pdf-render"></canvas>
<script src="https://mozilla.github.io/pdf.js/build/pdf.js"></script>
<script src="js/main.js"></script>
</body>
And my main.js:
const url = 'pdf.pdf';
let pdfDoc = null,
pageNum = 1,
pageIsRendering = false,
pageNumIsPending = null;
const scale = 1,
canvas = document.querySelector('#pdf-render'),
ctx = canvas.getContext('2d');
// Render the page
const renderPage = num => {
pageIsRendering = true;
// Get page
pdfDoc.getPage(num).then(page => {
// Set scale
const viewport = page.getViewport({ scale });
canvas.height = viewport.height;
canvas.width = viewport.width;
const renderCtx = {
canvasContext: ctx,
viewport
};
page.render(renderCtx).promise.then(() => {
pageIsRendering = false;
if (pageNumIsPending !== null) {
renderPage(pageNumIsPending);
pageNumIsPending = null;
}
});
});
};
// Check for pages rendering
const queueRenderPage = num => {
if (pageIsRendering) {
pageNumIsPending = num;
} else {
renderPage(num);
}
};
// Get Document
pdfjsLib
.getDocument(url)
.promise.then(pdfDoc_ => {
pdfDoc = pdfDoc_;
renderPage(pageNum);
})
.catch(err => {
// Display error
});
The PDF looks nice and appear but my main usage would be the forms. I'm sure it can be done, but I'm quite newbie at PDF.js lib.
I'm want to take image and insert it to cursor and on mouse scroll the cursor will shrink or grow.
I try to do it by convert image to base64 and then to cursor, i just test it without scroll and it always make black square cursor.
img64 = new Image();
img64.src = './assets/tools/pencil.png';
var cnva64 = document.createElement('canvas');
cnva64.height = img64.naturalHeight;
cnva64.width = img64.naturalWidth;
var ctx64 = cnva64.getContext('2d');
ctx64.drawImage(img64, 0, 0, cnva64.width, cnva64.height);
var base64String = cnva64.toDataURL();
Board.canvas.style.cursor = `url(${base64String}), auto`;
Edit
if i'm doing it like this it's work but it isn't take the size of it
img = new Image();
img.src = './assets/tools/cursor/pencil.png';
img.style.width = "58px";
img.style.height = "38px";
Board.canvas.style.cursor = `url(${img64.src}), auto`;
I manged to do what i wanted but then i notified by chrome
Remove cursors greater than 32x32 device-independent pixels intersecting native UI
window.addEventListener('load', () =>{
Board = new CanvasBoard()
Board.canvas.addEventListener('wheel', function(e) {
let linesize = document.getElementById("LineSizePicker");
let add = (e.deltaY/100)*-1
if(parseInt(linesize.value)+add<=88 && parseInt(linesize.value)+add>0){
linesize.value = parseInt(linesize.value)+add;
Board.ChangeLineSize(linesize.value);
}
});
})
class CanvasBoard{
constructor(){
this.canvas = document.querySelector("#canvas");
this.context = this.canvas.getContext("2d");
this.Mode = "Pencil";
let img = document.getElementById(`${this.Mode}IMG`)
let CursorBae64 = this.ToBase64(img,28)
this.canvas.style.cursor = `url(${CursorBae64}), auto`
}
ToBase64(img64,Size){
img64.Height = Size;
img64.width = Size;
let Canvas64 = document.createElement('canvas');
Canvas64.height = img64.Height;
Canvas64.width = img64.width;
let ctx64 = Canvas64.getContext('2d');
ctx64.drawImage(img64, 0, 0, Canvas64.width, Canvas64.height);
let Base64 = Canvas64.toDataURL();
return B64
}
ChangeLineSize(Size){
let img64 = document.getElementById(`${this.Mode}IMG`)
img64.src = document.getElementById(`Old${this.Mode}IMG`).src
if(Size>10 && Size<40){
let base64 = this.ToBase64(img64,Size);
img64.src = base64;
this.canvas.style.cursor = `url(${img64.src}) 0 -${Size}, auto`
}
this.lineThickness = Size
}
}
I am getting a base64 encoded pdf as multiple response and I have to decode it to create one pdf.
Here is my code for reference.
var pdf_base1 = "data:application/pdf;base64,JVBERi0xLjQKJfbk/N8KMSAwIG9iago8PAovVHlwZSAvQ2F0YWxvZwovUGFnZXMgMiAwIFIKL0Fjcm9Gb3JtIDMgMCBSCi9NZXRhZGF0YSA0IDAgUgo+PgplbmRvYmoKNSAwIG9iago8PAovUHJvZHVZXIgKFJBRCBQREYg..." //shortend
var pdf_base2 = "data:application/pdf;base64,JVBERi0xLjQKJfbk/N8KMSAwIG9iago8PAovVHlwZSAvQ2F0YWxvZwovUGFnZXMgMiAwIFIKL0Fjcm9Gb3JtIDMgMCBSCi9NZXRhZGF0YSA0IDAgUgo+PgplbmRvYmoKNSAwIG9iago8PAovUHJvZHVZXIgKFJBRCBQREYg..." //shortend
var pdfDoc,pageNum= 1,pageNumPending = null,pageRendering = false,
pdf= [];
pdf.push(pdf_base1,pdf_base2);
pdf.map(each=>{
this.callPdfLib(each);
})
callPdfLib=(data)=>{
var self = this;
// var files = self.state.files;
var pageCount = this.pageCount;
var arrrBuffer = self.base64ToArrayBuffer(data);
pdfjsLib.getDocument({data:arrrBuffer}).promise.then(function(page) {
pdfDoc = page;
pageCount.textContent = page.numPages;
self.renderPage(pageNum);
});
}
renderPage=(num)=>{
var canvas = this.canvas;
pageRendering = true;
pdfDoc.getPage(num).then(function(page) {
var scale = 1.5;
var viewport = page.getViewport({scale: scale});
var context = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
var renderContext = {
canvasContext: context,
viewport: viewport
};
var renderTask = page.render(renderContext);
renderTask.promise.then(function() {
pageRendering = false;
if (pageNumPending !== null) {
this.renderPage(pageNumPending);
pageNumPending = null;
}
});
})
}
Both variables are base64 encode pdfs.
By doing this, I am getting an error.
Unhandled Rejection (Error): Cannot use the same canvas during multiple render() operations. Use different canvas or ensure previous operations were cancelled or completed.
you have to create a canvas for each page and append it to the body of your container element, also as it is an async operation you can use async/await so that it previews the first page then the second, and so on.
You can use this link for reference
https://gist.github.com/fcingolani/3300351
I use mozilla pdf.js. I have a code:
<canvas id="the-canvas"/>
function displayDocument(){
PDFJS.getDocument(numberOdDocument[attachment]).then(function (pdfDoc_) {
pdfDoc = pdfDoc_;
renderPage(pageNum);
});
}
function renderPage(num) {
pdfDoc.getPage(num).then(function(page) {
var viewport = page.getViewport(scale, rotate);
canvas.height = '900';
canvas.width = '500';
var renderContext = {
canvasContext: ctx,
viewport: viewport
};
var renderTask = page.render(renderContext);
renderTask.promise.then(function () {
pageRendering = false;
if (pageNumPending !== null) {
renderPage(pageNumPending);
pageNumPending = null;
}
});
});
}
Now i see only one page in canvas tag, but I want add scrollbar to my canvvas, and I want change page with scroll. How can I do that?
Allow scroll
First, create a parent div to encapsulate the canvas element :
<div>
<canvas id="the-canvas"/>
</div>
Then, set a fixed size with a vertical scroll
<div style="width:650px;height:600px;overflow-y:scroll;">...</div>
Finally, you can set the scale you want using the variable "scale" but keep these original lines :
function renderPage(num) {
pdfDoc.getPage(num).then(function(page) {
var viewport = page.getViewport(scale);
canvas.height = viewport.height;
canvas.width = viewport.width;
...
Render all pages
Keep in mind, that render a lot of pages will take a bit of time but here is how to do it.
Idea : you need to render each page in a separate canvas element.
First, create dynamically the canvas element with a specific id during render :
<div id="pdf-viewer"></div>
...
function renderPage(num) {
pdfDoc.getPage(num).then(function(page) {
var canvasId = 'pdf-viewer-' + num;
$('#pdf-viewer').append($('<canvas/>', {'id': canvasId}));
var canvas = document.getElementById(canvasId);
...
Finally, call renderPage() for each page
function renderAllPages() {
for (var i = 1; i <= pdfDoc.numPages; i++) {
renderPage(i);
}
}