【问题标题】:Html2Canvas delay in rendering images and not in a sequenceHtml2Canvas 延迟渲染图像而不是序列
【发布时间】:2015-09-23 03:18:15
【问题描述】:

我在使用 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;

}

【问题讨论】:

  • @Niklas 请看看这个话题......
  • 可以在 Question 中包含html 吗? , 创建 stacksn-ps , jsfiddle jsfiddle.net 来演示?尝试在 img invitationCard load 事件中将 invitationCard 作为已解析的 jQuery.Deferred 返回?
  • yup 尝试了 evrithing .....使用了 jQuery.Deferred 但仍然延迟 n 无序执行...
  • "yup 尝试了 evrithing.....用了 jQuery.Deferred 但仍然延迟 n 非顺序执行..." 可以创建 stacksn-ps, jsfiddle jsfiddle.net 来演示?
  • @guest271314 使用此代码的模块非常复杂...所以我无法创建小提琴或 stacksn-p .....此代码在Firefox 但在 chrome 中它是不连续的。

标签: jquery delay html2canvas


【解决方案1】:

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

此外,您正在以一种“古怪”的方式使用 Promise,您正在等待非异步事件。所以难怪一切都在错误的顺序。

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

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

【讨论】:

  • getImage(name) 函数正在返回生成的图像,但根据您的回答,返回的是延迟对象而不是图像,因此我无法将生成的图像获取到我的卡片数组中。我真的很感谢你的回答,但这不是我的要求,因为我将生成的图像存储在一个数组中以供进一步使用,而且也是按照选中复选框的顺序。
  • @Abhishek 如果这是您需要的,您可以将加载的图像与承诺一起传递,检查代码,我已经更新了 resolvedone 部分
  • 很抱歉通知您....代码不符合我以各种可能的方式测试的要求....它正在生成重复的图像。
  • @Abhishek 您是否在卡片数组中获得了两个图像?还是打印两次?从您发布的代码来看,它不应该发生,也许它可能是此处未显示的其他代码。
  • 场景是必须显示提供给 getImage() 的图像名称。应用您的代码后,提供的名称会多次显示。这不应该发生,一张图片上的一个名字。
【解决方案2】:

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

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

【讨论】:

  • 这看起来不像 Html2Canvas 中的问题,你有它的来源吗?
猜你喜欢
  • 1970-01-01
  • 2019-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-28
  • 2016-01-10
  • 2019-01-10
相关资源
最近更新 更多