Image (canvas) in PDF, is generated wrong - javascript

This code allows me to generate the PDF, from an image with canvas, when I generate it in cell or reduce the revolution (width x height), the image of the table in the PDF comes out in half; how could i fix it?
PDF - A4
Correct Image
Not correct image
<script type="text/javascript">
function demoFromHTML() {
var elementHTML = document.getElementById('resultados');
html2canvas(elementHTML, {
useCORS: true,
onrendered: function(canvas) {
var pdf = new jsPDF('p', 'pt', 'A4');
var pageHeight = 1695;
var pageWidth = 1250;
for (var i = 0; i <= elementHTML.clientHeight / pageHeight; i++) {
var srcImg = canvas;
var sX = 0;
var sY = pageHeight * i;
var sWidth = pageWidth;
var sHeight = pageHeight;
var dX = 0;
var dY = 0;
var dWidth = pageWidth;
var dHeight = pageHeight;
window.onePageCanvas = document.createElement("canvas");
onePageCanvas.setAttribute('width', pageWidth);
onePageCanvas.setAttribute('height', pageHeight);
var ctx = onePageCanvas.getContext('2d');
ctx.drawImage(srcImg, sX, sY, sWidth, sHeight, dX, dY, dWidth, dHeight);
var canvasDataURL = onePageCanvas.toDataURL("image/png", 1.0);
var width = onePageCanvas.width;
var height = onePageCanvas.clientHeight;
if (i > 0)
pdf.addPage(593, 780);
pdf.setPage(i + 1);
pdf.addImage(canvasDataURL, 'JPG', 20, 40, (width * .45), (height * .45));
}
pdf.save('cotizador.pdf');
}
});
}
</script>

Related

The exported contents start at the middle of the page

I have a problem with jsPDF in wordpress website which built by elementor. The exported PDF starts from the middle of the page !
In normal content it works fine, but in product server it starts from the middle,
please check out This sample.
Is there a way to fix it?
This is the code I wrote :
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.4/jspdf.debug.js"></script>
<button class="btn" id="btn" onClick="printToPDF();">
Export to PDF
</button>
<div id="page">content</div>
<script>
function printToPDF() {
btn.innerText = "Converting...";
console.log('Converting...');
var printableArea = document.getElementById('page');
html2canvas(printableArea, {
useCORS: true,
onrendered: function(canvas) {
var pdf = new jsPDF('a', 'pt', 'a4');
var pageHeight = 1200;
var pageWidth = 1000;
for (var i = 0; i <= printableArea.clientHeight / pageHeight; i++) {
var srcImg = canvas;
var sX = 0;
var sY = pageHeight * i; // start 1 pageHeight down for every new page
var sWidth = pageWidth;
var sHeight = pageHeight;
var dX = 0;
var dY = 0;
var dWidth = pageWidth;
var dHeight = pageHeight;
window.onePageCanvas = document.createElement("canvas");
onePageCanvas.setAttribute('width', pageWidth);
onePageCanvas.setAttribute('height', pageHeight);
var ctx = onePageCanvas.getContext('2d');
ctx.drawImage(srcImg, sX, sY, sWidth, sHeight, dX, dY, dWidth, dHeight);
var canvasDataURL = onePageCanvas.toDataURL("image/png", 1.0);
var width = onePageCanvas.width;
var height = onePageCanvas.clientHeight;
if (i > 0) // if we're on anything other than the first page, add another page
pdf.addPage(612, 791); // 8.5" x 11" in pts (inches*72)
pdf.setPage(i + 1); // now we declare that we're working on that page
pdf.addImage(canvasDataURL, 'PNG', 20, 40, (width * .62), (height * .62)); // add content to the page
}
var today = new Date();
var date = today.getFullYear()+'-'+(today.getMonth()+1)+'-'+today.getDate();
pdf.save(date+'.pdf');
btn.innerText = " Export to PDF";
}
});
}
</script>

Writing to A4 pdf giving wrong size image

I am trying to write to an A4 PDF
form = document.querySelector("#theform");
html2canvas(form).then(function(canvas) {
doc = new jsPDF({
unit: 'pt',
format: 'a4',
});
for (var i = 0; i <= form.clientHeight/842; i++) {
//! This is all just html2canvas stuff
var srcImg = canvas;
var sX = 0;
var sY = 842*i;
var sWidth = 595;
var sHeight = 842;
var dX = 0;
var dY = 0;
var dWidth = 595;
var dHeight = 842;
window.onePageCanvas = document.createElement("canvas");
onePageCanvas.setAttribute('width', 595);
onePageCanvas.setAttribute('height', 842);
var ctx = onePageCanvas.getContext('2d');
ctx.drawImage(srcImg,sX,sY,sWidth,sHeight,dX,dY,dWidth,dHeight);
var canvasDataURL = onePageCanvas.toDataURL("image/png", wid = canvas.width, hgt = canvas.height);
var hratio = hgt/wid
const pdfWidth = doc.internal.pageSize.width;
const TheHeight = doc.internal.pageSize.width;
const pdfHeight = TheHeight
if (i > 0) {
doc.addPage(595, 842);
}
//! now we declare that we're working on that page
doc.setPage(i+1);
doc.addImage(canvasDataURL, 'PNG', 10, 10, pdfWidth, pdfHeight);
}
doc.autoPrint();
window.open(doc.output('bloburl'), '_blank');
}
But the it is only creating a PDF for part of the left hand side and I can't see anything wrong.. It is as though what it is writing to the PDF is twice the size it should be.

Double image background on canvas not sharing the same size

I'm trying to make a section on a website have two background images that will reveal the bottom one as the pointer moves across the screen.
I'm still new to javascript, and my code is made up of bits and pieces that I've found on google, but I can't seem to get the top image to share the same resolution and image size for whatever reason as the bottom image.
Here is the link to my codepen: https://codepen.io/Awktopus/pen/zYwKOKO
And here is my code:
HTML:
<canvas id="main-canvas" id="canvas-size" class="background-size"></canvas>
<image src="https://i.imgur.com/PbGAAIy.jpg" id="upper-image" class="hidden-bg"></img>
<image src="https://i.imgur.com/Gx14sKW.jpg" id="lower-image" class="hidden-bg"></img>
CSS:
.hidden-bg {
display: none;
}
JS:
var can = document.getElementById('main-canvas');
var ctx = can.getContext('2d');
can.width = window.innerWidth;
can.height = window.innerWidth / 2;
var upperImg = document.getElementById("upper-image");
var lowerImg = document.getElementById("lower-image");
var pat = ctx.createPattern(upperImg, "no-repeat");
var canvas = ctx.canvas ;
var hRatio = canvas.width / lowerImg.width ;
var vRatio = canvas.height / lowerImg.height ;
var ratio = Math.max ( hRatio, vRatio );
var centerShift_x = ( canvas.width - lowerImg.width*ratio ) / 2;
var centerShift_y = ( canvas.height - lowerImg.height*ratio ) / 2;
can.addEventListener('mousemove', function(e) {
var mouse = getMouse(e, can);
redraw(mouse);
}, false);
function redraw(mouse) {
can.width = can.width;
ctx.clearRect(0,0,canvas.width, canvas.height);
ctx.drawImage(lowerImg, 0,0, lowerImg.width, lowerImg.height, centerShift_x,centerShift_y,lowerImg.width*ratio, lowerImg.height*ratio);
ctx.beginPath();
ctx.rect(0,0,can.width,can.height);
ctx.arc(mouse.x, mouse.y, 250, 0, Math.PI*2, true)
ctx.clip();
ctx.fillStyle = pat;
ctx.fillRect(0, 0, lowerImg.width, lowerImg.height, centerShift_x, centerShift_y, lowerImg.width*ratio, lowerImg.height*ratio);
}
var img = new Image();
img.onload = function() {
redraw({x: -500, y:-500})
}
function getMouse(e, canvas) {
var element = canvas,
offsetX = 0,
offsetY = 0,
mx, my;
if (element.offsetParent !== undefined) {
do {
offsetX += element.offsetLeft;
offsetY += element.offsetTop;
} while ((element = element.offsetParent));
}
mx = e.pageX - offsetX;
my = e.pageY - offsetY;
return {
x: mx,
y: my
};
}
If I understood this right you will want to set the width and height and draw the upper image using drawImage(). Just use the same ratios as the lowerImage. No need to use createPattern for this.
codepen: https://codepen.io/jfirestorm44/pen/BaRLoxX
var can = document.getElementById('main-canvas');
var ctx = can.getContext('2d');
can.width = window.innerWidth;
can.height = window.innerWidth / 2;
var upperImg = document.getElementById("upper-image");
var lowerImg = document.getElementById("lower-image");
//var pat = ctx.createPattern(upperImg, "no-repeat");
var canvas = ctx.canvas ;
var hRatio = canvas.width / lowerImg.width ;
var vRatio = canvas.height / lowerImg.height ;
var ratio = Math.max ( hRatio, vRatio );
var centerShift_x = ( canvas.width - lowerImg.width*ratio ) / 2;
var centerShift_y = ( canvas.height - lowerImg.height*ratio ) / 2;
can.addEventListener('mousemove', function(e) {
var mouse = getMouse(e, can);
redraw(mouse);
}, false);
function redraw(mouse) {
can.width = can.width;
ctx.clearRect(0,0,canvas.width, canvas.height);
ctx.drawImage(lowerImg, 0,0, lowerImg.width, lowerImg.height, centerShift_x,centerShift_y,lowerImg.width*ratio, lowerImg.height*ratio);
ctx.beginPath();
ctx.rect(0,0,can.width,can.height);
ctx.arc(mouse.x, mouse.y, 250, 0, Math.PI*2, true)
ctx.clip();
ctx.drawImage(upperImg, 0,0, lowerImg.width, lowerImg.height, centerShift_x,centerShift_y,lowerImg.width*ratio, lowerImg.height*ratio);
}
var img = new Image();
img.onload = function() {
redraw({x: -500, y:-500})
}
function getMouse(e, canvas) {
var element = canvas,
offsetX = 0,
offsetY = 0,
mx, my;
if (element.offsetParent !== undefined) {
do {
offsetX += element.offsetLeft;
offsetY += element.offsetTop;
} while ((element = element.offsetParent));
}
mx = e.pageX - offsetX;
my = e.pageY - offsetY;
return {
x: mx,
y: my
};
}
.hidden-bg {
display: none;
}
<canvas id="main-canvas" id="canvas-size" class="background-size"></canvas>
<image src="https://i.imgur.com/PbGAAIy.jpg" id="upper-image" class="hidden-bg"></img>
<image src="https://i.imgur.com/Gx14sKW.jpg" id="lower-image" class="hidden-bg"></img>

Export image from canvas in printing size (300 DPI)

I am trying to make a canvas application and i get success. I just stuck in print image that is output of canvas. Size of image is too small to print enough.
Following is flow of application:
Upload image and draw to the canvas.
Do some operations like zoom, move and rotating on split canvas.
I have successfully generated single images from those splits
And I have export base64 from canvas to printing process.
Problem is here when I export data from canvas it's small image, even if I do some Imagick stuff to resize image quality of final image is not near to print on poster.
JavaScript:
function draw() {
var Activecanvas = document.getElementsByClassName("cf-photoframe-active");
var canvas = Activecanvas[0];
var ctx = canvas.getContext('2d');
var ActiveCanvasId = canvas.getAttribute("id");
var img = canvasDetail[ActiveCanvasId].selectedImage;
var imageX = canvasDetail[ActiveCanvasId].imageX;
var imageY = canvasDetail[ActiveCanvasId].imageY;
var resize = resizeDetail[ActiveCanvasId].resize;
var rotate = rotateDetail[ActiveCanvasId].rotate;
//if(resize)
$j("#resize").slider({
value: resize,
min: -300,
max: 300,
step: 1,
});
$j("#rotat").slider({
value: rotate,
min: -180,
max: 180,
step: 1,
});
if (img != '') {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.save();
var im_width = parseInt(img.width + $j("#resize").slider('value'));
var im_height = parseInt(img.height + $j("#resize").slider('value'));
var maxWidth = canvas.width; // Max width for the image
var maxHeight = canvas.height;
var iswidthMax = 0;
var imageOrgWidth = img.width;
var imageOrgHeight = img.height;
if (maxWidth < maxHeight) {
iswidthMax = 1;
} else if (maxWidth == maxHeight) {
iswidthMax = 2;
}
if (iswidthMax == 1) {
maxWidth = (maxHeight * imageOrgWidth) / imageOrgHeight;
} else if (iswidthMax == 0) {
maxHeight = (maxWidth * imageOrgHeight) / imageOrgWidth;
} else if (iswidthMax == 2) {
if (img.width > img.height) {
maxWidth = (maxHeight * imageOrgWidth) / imageOrgHeight;
} else {
maxHeight = (maxWidth * imageOrgHeight) / imageOrgWidth;
}
}
var resizeVal = $j("#resize").slider('value');
var nw = maxWidth + resizeVal;
var resizeValHeight = maxHeight * resizeVal / maxWidth;
var nh = maxHeight + resizeValHeight;
ctx.translate(imageX, imageY);
ctx.rotate(rotate * Math.PI / 180);
ctx.translate(-nw / 2, -nh / 2);
ctx.drawImage(img, 0, 0, nw, nh);
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.restore();
}
}
If you have smaller canvas elements for editing, then you will have to recombine the data from those smaller canvas elements into a canvas element which is the full size and output the data from that element.
For simplicity's sake, let's say that you have cut the image into four quadrants and drawn to four canvas elements canvas[0] - canvas[3] for editing. You would then need to recombine them into one larger canvas doing something like the following...
var imgData = [];
for (var i = 0; i < 4; i++) {
var tmpCtx = canvas[i].getContext('2d');
imgData[i] = tmpCtx.getImageData(0, 0, canvas[i].width, canvas[i].height);
}
var fullSizeCanvas = document.createElement('canvas');
fullSizeCanvas.width = img.width * 2;
fullSizeCanvas.height = img.height * 2;
var fullCtx = fullSizeCanvas.getContext('2d');
fullCtx.putImageData(imgData[0], 0, 0);
fullCtx.putImageData(imgData[1], img.width, 0);
fullCtx.putImageData(imgData[2], 0, img.height);
fullCtx.putImageData(imgData[3], img.width, img.height);
var data = fullSizeCanvas.toDataURL();

Wrap whole image on cylindrical cup in javascript html5

I want to wrap image on cylindrical cup. I am using html5 and Java script for achieve this solution. I got some idea from this link: https://stackoverflow.com/questions/31424117/.
But i am not getting solution from this link.
I want to wrap remaining image behind the cup, Like mold the remaining part and add some button for rotation.
<canvas id="canvas"></canvas>
<script>
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var productImg = new Image();
productImg.onload = function () {
var iw = productImg.width;
var ih = productImg.height;
console.log("height");
canvas.width = iw;
canvas.height = ih;
ctx.drawImage(productImg, 0, 0, productImg.width, productImg.height, 0, 0, iw, ih);
//start();
// outline
/*ctx.beginPath();
ctx.moveTo(88, 235.734375);
ctx.bezierCurveTo(88, 234.734375, 204, 298, 327, 234.734375);
ctx.stroke();*/
};
productImg.src = "https://d2z4fd79oscvvx.cloudfront.net/0018872_inspirational_teacher_mug.jpeg";
var img = new Image();
img.onload = start;
img.src = "http://blog.foreigners.cz/wp-content/uploads/2015/05/Make-new-friends.jpg";
var pointer = 0;
function start() {
var iw = img.width;
var ih = img.height;
//canvas.width = iw + 20;
//canvas.height = ih + 20;
var x1 = 125;
var y1 = 130;
var x2 = 180;
var y2 = 190;
var x3 = 405;
var y3 = 150;
// calc line equations slope & b (m,b)
var unitT = 1 / iw;
// draw vertical slices
for (var X = 0, t = 0; X < iw; X++, t += unitT) {
var xTop = (1 - t) * (1 - t) * x1 + 2 * (1 - t) * t * x2 + t * t * x3;
var yTop = (1 - t) * (1 - t) * y1 + 2 * (1 - t) * t * y2 + t * t * y3;
ctx.drawImage(img, X + pointer, 0, 1, ih, xTop, yTop, 0.85, ih - 600);
}
If i change the pointer value in above code, than remaining image
stretch.
var pointer = 100 ;
I want to wrap image on whole mug and rotate in left and right.
I've played around your plunkr for some time and came up with this:
http://plnkr.co/edit/83xAr99FjswWg0GHjDvJ?p=preview
function start() {
var iw = img.width;
var ih = img.height;
var xOffset = 125,
yOffset = 122;
var a = 122.0;
var b = 30.0;
var scaleFactor = iw / (2*a); //how many times original image is greater compared to our rendering area?
// draw vertical slices
for (var X = 0; X < iw; X+=1) {
var y = b/a * Math.sqrt(a*a - (X-a)*(X-a)); // ellipsis equation
ctx.drawImage(img, X * scaleFactor, 0, 6, ih, X + xOffset, y + yOffset, 1, ih - 605 + y/2);
}
}
I took this ellipsis equation http://www.mathopenref.com/coordgeneralellipse.html and turn it into the form where I can get Y-coordinate from related X-coordinate.
You can play with my plunkr even more to make the image more accurately cover the cup, but it is still far away from reality because this method is not considering different lightning features of the surface of the cup.
function canvas1() {
var canvas = document.getElementById("canvas1");
var ctx = canvas.getContext("2d");
var productImg = new Image();
productImg.onload = function() {
var iw = productImg.width;
var ih = productImg.height;
console.log("height");
canvas.width = iw;
canvas.height = ih;
ctx.drawImage(productImg, 0, 0, productImg.width, productImg.height,
0, 0, iw, ih);
loadUpperIMage()
};
productImg.src = "http://res.cloudinary.com/pussyhunter/image/upload/c_scale,f_auto,h_350/left_handle_cup_i7ztfs.jpg"
function loadUpperIMage() {
var img = new Image();
img.src = "https://media1.giphy.com/media/j3uyvaaslUxNe/200_s.gif"
img.onload = function() {
var iw = img.width;
var ih = img.height;
var xOffset = 102, //left padding
yOffset = 110; //top padding
//alert(ih)
var a = 75.0; //image width
var b = 10; //round ness
var scaleFactor = iw / (4 * a);
// draw vertical slices
for (var X = 0; X < iw; X += 1) {
var y = b / a * Math.sqrt(a * a - (X - a) * (X - a)); // ellipsis equation
ctx.drawImage(img, X * scaleFactor, 0, iw / 9, ih, X + xOffset, y + yOffset, 1, 174);
}
};
}
};
function canvas2() {
var canvas = document.getElementById("canvas2");
var ctx = canvas.getContext("2d");
var productImg = new Image();
productImg.onload = function() {
var iw = productImg.width;
var ih = productImg.height;
console.log("height");
canvas.width = iw;
canvas.height = ih;
ctx.drawImage(productImg, 0, 0, productImg.width, productImg.height,
0, 0, iw, ih);
loadUpperIMage()
};
productImg.src = "http://res.cloudinary.com/pussyhunter/image/upload/h_350/canter_handle_cup_xyxhdd.jpg"
function loadUpperIMage() {
var img = new Image();
img.src = "https://media1.giphy.com/media/j3uyvaaslUxNe/200_s.gif"
img.onload = function() {
var iw = img.width;
var ih = img.height;
// alert(iw)
var xOffset = 101, //left padding
yOffset = 110; //top padding
var a = 75.0; //image width
var b = 10; //round ness
var scaleFactor = iw / (4 * a);
// draw vertical slices
for (var X = 0; X < iw; X += 1) {
var y = b / a * Math.sqrt(a * a - (X - a) * (X - a)); // ellipsis equation
ctx.drawImage(img, X * scaleFactor, 0, iw / 3, ih, X + xOffset, y + yOffset, 1, 174);
}
};
}
};
function canvas3() {
var canvas = document.getElementById("canvas3");
var ctx = canvas.getContext("2d");
var productImg = new Image();
productImg.onload = function() {
var iw = productImg.width;
var ih = productImg.height;
canvas.width = iw;
canvas.height = ih;
ctx.drawImage(productImg, 0, 0, productImg.width, productImg.height,
0, 0, iw, ih);
loadUpperIMage()
};
productImg.src = "http://res.cloudinary.com/pussyhunter/image/upload/h_350/right_handle_cup_dsdhr7.jpg"
function loadUpperIMage() {
var img = new Image();
img.src = "https://media1.giphy.com/media/j3uyvaaslUxNe/200_s.gif"
img.onload = function() {
var iw = img.width;
var ih = img.height;
//alert(iw)
var xOffset = 102, //left padding
yOffset = 110; //top padding
var a = 75.0; //image width
var b = 10; //round ness
var scaleFactor = iw / (3 * a);
// draw vertical slices
for (var X = 0; X < iw; X += 1) {
var y = b / a * Math.sqrt(a * a - (X - a) * (X - a)); // ellipsis equation
ctx.drawImage(img, X * scaleFactor, 0, iw / 1.5, ih, X + xOffset, y + yOffset, 1, 174);
}
};
}
};
setTimeout(function() {
canvas1()
}, 1000);
setTimeout(function() {
canvas2()
}, 2000);
setTimeout(function() {
canvas3()
}, 3000);
function updateItems(delta)
{
var $items = $('#group').children();
var $current = $items.filter('.current');
$current = $current.length ? $current : $items.first();
var index = $current.index() + delta;
// Range check the new index
index = (index < 0) ? 0 : ((index > $items.length) ? $items.length : index);
$current.removeClass('current');
$current = $items.eq(index).addClass('current');
// Hide/show the next/prev
$("#prev").toggle(!$current.is($items.first()));
$("#next").toggle(!$current.is($items.last()));
}
$("#next").click(function () {
updateItems(1);
});
$("#prev").click(function () {
updateItems(-1);
});
// Cause initial selection
updateItems(0);
#group div{
display: none;
}
#group div.current{
display: block;
}
#next, #prev{
width: 100px;
height 40px;
cursor:pointer;
color:red;
position:fixed;
}
#next{
float: right;
}
#prev{
float: left;
margin-left:40px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
<div id="next">next</div>
<div id="prev">prev</div>
<div id="group" >
<div>
<canvas id="canvas1"></canvas>
</div>
<div>
<canvas id="canvas2"></canvas>
</div>
<div>
<canvas id="canvas3"></canvas>
</div>
</div>

Categories