Html2Canvas delay when rendering images, not in sequence

I am having problems rendering Html2canvas, because I want to take several screenshots and send them to the selected contacts in sequence, but Html2canvas renders images with a delay and inconsequentially, which in turn is not able to send the image to the corresponding selected contact. Below, my code works successfully, but the delay and non-obvious output create a lot of problems.

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; } 
+5
source share
2 answers

This problem was resolved in the upcoming version of html2canvas, as this problem was repeatedly raised on the developer's site. you just need to wait for the final release for production, or you can try the beta.

PS - the current release is intended only for development purposes, and not for production. (This should be a comment, but I do not have such a reputation.)

+2
source

This should not be a problem with Html2Canvas, rather the way you load base64 encoded images does not use a callback.

In addition, you use promises in the winning mode, you expect events that are not asynchronous. Therefore, it is not surprising that everything is in the wrong order.

canvas.toDataURL runs synchronously, and the purpose of the Image src object is asynchronous .

According to the MDN image page

 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 

In addition, your getImage() function does not return $.deferred() , which means that $.when() will execute immediately .

Here is the code that should fix it, I create a promise that will be resolved when the image is uploaded

 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; } 

When calling getImage() code

 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 verify your code, but I had to manage the many images that needed to be loaded after the canvas.toDataURL() series. My problem when doing things in orderd was always the onload callback for Image objects, and the Html2Canvas worked correctly so far for me.

In addition, the reason you see different types of behavior in different browsers is due to the speed of execution and / or caching of images. If the browser can download the image before using it, everything will be fine, but you should not assume that you always use onload when creating images .

+3
source

All Articles