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.
Related
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>
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>
I am using a north,south, west, est coordinate system and I want to draw on my map an image in the right place and with a specific size.
I tried first to draw just one point, and it appeared on the right position (so the coordinate stuff seems work), but if I try to draw the image it doesn't appear on the map.I know that I can not directly give to the icon an height and a width, so I first created a canvas to use after. This is my code:
if ( this.nord && this.sud && this.est && this.ovest && this.opacityPercentage) {
var extent = ol.proj.transformExtent([this.nord, this.ovest, this.sud, this.est], 'EPSG:4326', 'EPSG:3857');
var height = ol.extent.getHeight(extent);
var width = ol.extent.getWidth(extent);
var center = ol.extent.getCenter(extent);
var sourceImage = new Image();
var canvas = document.createElement('canvas');
sourceImage.src = 'https://www.mikenunn.net/data/oak-tree-icon-png-17.png';
canvas.width = width;
canvas.height = height;
canvas.getContext("2d").drawImage(sourceImage, 0, 0, width, height);
var resizedImageURL = canvas.toDataURL();
var treePoint = new ol.geom.Point(center);
var featureTree = new ol.Feature(treePoint);
featureTree.setStyle(new ol.style.Style({
image: new ol.style.Icon({
src: resizedImageURL,
opacity: this.opacityPercentage,
})
}));
this.features.push(featureTree);
this.mapView.fit(treePoint, {minResolution: 0.05});
} else {
this.controller.fireEvent('mapstaterequest');
}
In case, there is another way I could use to achieve my purpose?
If you cannot preload sourceImage (e.g. you don't know the url until you need it) you need to process it in an onload function similar to xhr
var sourceImage = new Image();
sourceImage.onload = function() {
var canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
canvas.getContext("2d").drawImage(sourceImage, 0, 0, width, height);
var resizedImageURL = canvas.toDataURL();
var treePoint = new ol.geom.Point(center);
var featureTree = new ol.Feature(treePoint);
featureTree.setStyle(new ol.style.Style({
image: new ol.style.Icon({
src: resizedImageURL,
opacity: this.opacityPercentage,
})
}));
this.features.push(featureTree);
this.mapView.fit(treePoint, {minResolution: 0.05});
}
sourceImage.src = 'https://www.mikenunn.net/data/oak-tree-icon-png-17.png';
I solved in this way:
if ( this.nord && this.sud && this.est && this.ovest && this.image && this.opacity) {
var extent = ol.proj.transformExtent([this.ovest, this.sud, this.est, this.nord], 'EPSG:4326', 'EPSG:3857');
var center = ol.extent.getCenter(extent);
var size = ol.extent.getSize(extent)
var view = map.getView();
var resolutionAtEquator = view.getResolution();
var width = ol.extent.getWidth(extent);
var height = ol.extent.getHeight(extent);
var radius = width/2;
var rotation = 0;
var circle = circle || new ol.geom.Circle(center, radius);
var circleFeature = new ol.Feature(circle);
circleFeature.set('rotation', rotation);
var geom = ol.geom.Polygon.fromExtent(extent);
circleFeature.setGeometry(geom);
this.features.push(circleFeature);
this.mapView.fit(geom, {minResolution: 0.05});
} else {
this.controller.fireEvent('mapstaterequest');
}
and I edited the style function like that:
styleFunction = function(feature, resolution) {
var rayDrawValue = img.width/2;
var resAdjust = rayDrawValue * resolution;
var rotation = feature.get('rotation');
if (rotation !== undefined) {
var extent = feature.getGeometry().getExtent();
var coordinates = feature.getGeometry().getCoordinates()[0];
var getBottomLeft = ol.extent.getBottomLeft(extent);
var getBottomRight = ol.extent.getBottomRight(extent);
var getTopLeft = ol.extent.getTopLeft(extent);
var getTopRight = ol.extent.getTopRight(extent);
var center = ol.extent.getCenter(extent);
var dx = center[0] - getBottomLeft[0];
var dy = 0;
var scaleX = Math.sqrt(dx * dx + dy * dy)/resAdjust;
var dx = 0;
var dy = getTopRight[1] - center[1];
var scaleY = Math.sqrt(dx * dx + dy * dy)/resAdjust;
var treeStyle2 = getStyle(img, scaleX, scaleY);
treeStyle2.setGeometry(new ol.geom.Point(center));
treeStyle2.getImage().setRotation(rotation);
return debug ? styles.concat([treeStyle2]) : treeStyle2;
} else if (feature.getGeometry().getCenter) {
treeStyle.setGeometry(new ol.geom.Point(feature.getGeometry().getCenter()));
treeStyle.getImage().setRotation(feature.getGeometry().get('rotation'));
treeStyle.getImage().setScale(feature.getGeometry().getRadius()/resAdjust);
return treeStyle;
} else {
return styles;
}
};
i am stuck in passing data from php to kineticjs throught json below is the code
$arrParams = array('images' =>$images, 'captions' => $content);
init({"container":"slider","data":<?php echo json_encode($arrParams); ?>});
i want to pass the above Json array in my below given coded kineticjs code
var data;
var canvasWidth;
var canvasHeight;
var stage;
var layer = new Kinetic.Layer();
var imageNodes = [];
var imageObjects = [];
var imageBox = [];
var captionBox = [];
var textNodes = [];
var totalObjects = 0;
var objectLoaded = 0;
var currentSlide = false;
var defaultPosition = [];
var rightCardPosition = [];
var leftCardPosition = [];
function init(config) {
canvasWidth = config.width | 600;
canvasHeight = config.height | 300;
defaultPosition["x"] = canvasWidth / 4;
defaultPosition["y"] = canvasHeight + 5;
leftCardPosition["start"] = [];
leftCardPosition["end"] = [];
leftCardPosition["start"]["x"] = (canvasWidth / 3) - 180;
leftCardPosition["start"]["y"] = canvasHeight - 260;
leftCardPosition["end"]["x"] = (canvasWidth + 100);
leftCardPosition["end"]["y"] = -250;
rightCardPosition["start"] = [];
rightCardPosition["end"] = [];
rightCardPosition["start"]["x"] = (canvasWidth / 3) + 160;
rightCardPosition["start"]["y"] = canvasHeight - 300;
rightCardPosition["end"]["x"] = (canvasWidth + 100);
rightCardPosition["end"]["y"] = -250;
stage = new Kinetic.Stage({
container: config.container,
width: canvasWidth,
height: canvasHeight
});
totalObjects = data.images.length;
for (var i = 0; i < data.images.length; i++) {
totalObjects += data.captions[i].length;
}
for (var i = 0; i < data.images.length; i++) {
loadImage(data.images[i]);
loadCaption(data.captions[i]);
}
}
I am getting error like in the line
totalObjects = data.images.length;
data is undefine... which means images is not pass from the json array
You're encoding the JSON with PHP, now you just need to parse it with JavaScript and store it in your data variable.
data = JSON.parse(config.data);
Put this at the start of your init function and it should work for you.
What I am trying to do is load images dynamically and then draw them on the screen. However, when I call console.log(images), it is empty.
Here is the code:
if (canvas.getContext)
{
var ctx = canvas.getContext("2d");
var images = new Array();
for (i = 0; i < mattes_array.length; i++)
{
var imgsrc = mattes_array[i]["imgsrc"];
var total_size = mattes_array[i]["total_size"];
var cpu = mattes_array[i]["cpu"];
var cid = mattes_array[i]["cid"];
var imageObj = new Image();
imageObj.onload = function() {
images[i] = imageObj;
console.log(images[i]);
};
imageObj.id = "matte_" + cid;
imageObj.src = imgsrc;
}
console.log(images); //this is empty
for (i = 0; i < mattes_array.length; i++)
{
var imgsrc = mattes_array[i]["imgsrc"];
var total_size = mattes_array[i]["total_size"];
var cpu = mattes_array[i]["cpu"];
var cid = mattes_array[i]["cid"];
var pattern = ctx.createPattern(images[i], 'repeat');
ctx.strokeStyle = pattern;
ctx.lineWidth = width - opening_width - (total_size * 2);
ctx.strokeRect(0, 0, width, height);
}
}
I have also tried doing it in one loop, but it seems to only draw the last image:
if (canvas.getContext)
{
var ctx = canvas.getContext("2d");
var images = new Array();
for (i = 0; i < mattes_array.length; i++)
{
var imgsrc = mattes_array[i]["imgsrc"];
var total_size = mattes_array[i]["total_size"];
var cpu = mattes_array[i]["cpu"];
var cid = mattes_array[i]["cid"];
var imageObj = new Image();
imageObj.onload = function() {
var pattern = ctx.createPattern(imageObj, 'repeat');
ctx.strokeStyle = pattern;
ctx.lineWidth = width - opening_width - (total_size * 2);
ctx.strokeRect(0, 0, width, height);
};
imageObj.id = "matte_" + cid;
imageObj.src = imgsrc;
}
}
Here is an image of what I am trying to do:
Images load asynchronously. You're trying to draw them before they are loaded. Give this a try:
if (canvas.getContext)
{
var ctx = canvas.getContext("2d");
var images = new Array();
var loaded = 0;
for (i = 0; i < mattes_array.length; i++)
{
var imgsrc = mattes_array[i]["imgsrc"];
var total_size = mattes_array[i]["total_size"];
var cpu = mattes_array[i]["cpu"];
var cid = mattes_array[i]["cid"];
var imageObj = new Image();
imageObj.onload = function() {
images[i] = imageObj;
console.log(images[i]);
if ( ++loaded === mattes_array.length ) onloaded();
};
imageObj.id = "matte_" + cid;
imageObj.src = imgsrc;
}
function onloaded() {
console.log(images); //this is won't be empty anymore
for (i = 0; i < mattes_array.length; i++)
{
var imgsrc = mattes_array[i]["imgsrc"];
var total_size = mattes_array[i]["total_size"];
var cpu = mattes_array[i]["cpu"];
var cid = mattes_array[i]["cid"];
var pattern = ctx.createPattern(images[i], 'repeat');
ctx.strokeStyle = pattern;
ctx.lineWidth = width - opening_width - (total_size * 2);
ctx.strokeRect(0, 0, width, height);
}
}
}