Html2Canvas延迟渲染图像而不是顺序

Html2Canvas delay in rendering images and not in a sequence

我在使用 Html2canvas 渲染时遇到问题,因为我想截取一个图像的多个屏幕截图并将其按顺序发送给选定的联系人,但是 Html2canvas 以延迟和不连续的方式渲染图像,这在 return 无法将图像发送给相应的选定联系人。下面是我的代码,它 运行 成功,但延迟和不连续的输出造成了很多问题。

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;

}

此问题已在即将发布的 html2canvas 版本中得到解决,因为此问题之前已在开发者网站上多次提出。你只需要等待最终版本的生产,或者你可以尝试它的测试版。

P.S - 当前版本仅用于开发目的,不用于生产。 (这应该是评论,但我没有那么多声誉。)

这不应该是 Html2Canvas 的问题,而是您加载 base64 编码图像的方式没有使用回调。

此外,您正在以 "wonky" 的方式使用承诺,您正在等待非异步事件。所以难怪一切都是错误的顺序。

canvas.toDataURL是同步执行的,而分配一个Image对象src是异步的.

根据 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

此外,您的 getImage() 函数 没有返回 $.deferred(),这意味着 $.when() 立即执行.

这里有一些应该修复它的代码,我正在创建一个将在加载图像时解决的承诺

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

在您的代码中调用 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);
            });
        });

我无法专门测试您的代码,但我不得不管理大量图像,这些图像必须在一系列 canvas.toDataURL() 之后加载。 我按 orderd 做事时的问题始终是 Image 对象的 onload 回调,而 Html2Canvas 到目前为止对我来说工作正常。

此外,您在不同浏览器上看到不同行为的原因是执行速度 and/or 图像缓存。如果浏览器可以在您使用之前加载图像,那么一切顺利,但您不应该假设,在创建图像时总是使用 onload