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

时间:2015-07-06 04:56:28

标签: jquery delay html2canvas

我遇到了Html2canvas渲染的问题,因为我想拍摄一张图片的多个截图并将其发送到序列中的所选联系人,但Html2canvas正在以延迟和无顺序的方式渲染图像,这反过来又无法将图像发送到相应的选定联系人。下面是我的代码它运行成功,但延迟和无序输出产生了很多问题。

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;

}

1 个答案:

答案 0 :(得分:3)

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

此外,您正在以“不稳定”的方式使用promises,您正在等待非异步的事件。所以难怪一切都是错误的。

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()之后加载的图像。 在按顺序执行操作时,我的问题始终是onload对象的Image回调,而Html2Canvas到目前为止对我来说是正确的。

此外,您在不同浏览器上看到不同行为的原因是由于执行速度和/或图像缓存。如果浏览器可以在您使用之前加载图片一切顺利,但您不应该认为,在创建图片时始终使用onload