I am having problems with Html2canvas render as i want to take multiple screenshots of an image and send the same to the selected contacts in a sequence but Html2canvas is rendering images in a delayed and unsequential way, which in return is not able to send the image to corresponding selected contact. Below is my code it is running successfully but the delay and unsequential output is creating a lot of problem.
function printCards(calle, eventID){
var cards = new Array();
var checkboxArray = $("input[name='contactsParty']:checked");
$('#inviteContactName').html($(checkboxArray[0]).parent().prev().children('label').text());
// iterating selected checkboxes for invitation
checkboxArray.each(function(index, value){
// getting name of next contact selected
var name = $(checkboxArray[index+1]).parents().eq(1).find('label').text();
// Getting invitation card
var invitationCard;
$.when(invitationCard = getImage(name)).promise().done(function(){
// saving the printed invitation
cards.push(invitationCard);
});
});
return cards;
}
// printing invitation card with contact name
function getImage(name){
var invitationCard = new Image();
html2canvas($("#invitationData"), {
// logging : true,
onrendered: function(canvas) {
// For image`enter code here`
var ctx=canvas.getContext("2d");
// ctx.webkitImageSmoothingEnabled = false;
// ctx.mozImageSmoothingEnabled = false;
ctx.imageSmoothingEnabled = false;
var convertedImage;
$.when(convertedImage = canvas.toDataURL('image/jpg')).promise().done(function(){
invitationCard.src = convertedImage;
$('#inviteContactName').html(name);
});
// setTimeout(function (){}, 500);
}
});
return invitationCard;
}
This shouldn't be an issue with Html2Canvas, rather the way you're loading base64 encoded images isn't using a callback.
Also, you're using promises in a "wonky" way, you're waiting on events that aren't asynchronous. So no wonder everything is in the wrong order.
canvas.toDataURL
is executed synchronously, while assigning an Image
object src
is asynchronous.
As per the MDN page about images
var img = new Image(); // Create new img element
img.onload = function() {
// image is loaded now
}
img.src = 'myImage.png'; // Set source path NOTE: this can be a base64 dataURL
Also, your getImage()
function is not returning a $.deferred()
, this means $.when()
will execute immediately.
Here's some code that should fix it, I'm creating a promise that will be resolved when the image is loaded
function getImage(name){
var promise = $.deferred();
var invitationCard = new Image();
html2canvas($("#invitationData"), {
onrendered: function(canvas) {
var ctx=canvas.getContext("2d");
ctx.imageSmoothingEnabled = false;
var convertedImage = canvas.toDataURL('image/jpg');
invitationCard.onload = function () {
// here loading is done, resolve our promise
$('#inviteContactName').html(name);
// pass the loaded image along with the promise
promise.resolve(invitationCard);
}
invitationCard.src = convertedImage;
}
});
return promise;
}
In your code calling getImage()
checkboxArray.each(function(index, value){
// getting name of next contact selected
var name = $(checkboxArray[index+1]).parents().eq(1).find('label').text();
// Getting invitation card
var invitationCard = getImage(name);
$.when(invitationCard).done(function(image){
// promise is resolved, image is loaded and can be used
cards.push(image);
});
});
I couldn't test your code specifically but I've had to manage plenty of images that had to be loaded after a series of canvas.toDataURL()
.
My problem when doing things in orderd was always the onload
callback for Image
objects, while Html2Canvas has worked correctly so far for me.
Also, the reason you see different behaviours on different browsers is due to the speed of execution and/or image caching. If the browser can load the image before you use it all goes well, but you shouldn't assume that, always use onload
when creating images.
This issue has been resolved in the upcoming release of html2canvas, as this issue has been raised earlier many times at developer's site. you just have to wait for the final release for production or you can try the beta version of it.
P.S - current release is for development purposes only and not for production. (This should be a comment but i dont have that much reputation.)
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