【问题标题】:html5 drawing multiple canvas imageshtml5 绘制多个画布图像
【发布时间】:2014-04-29 03:14:25
【问题描述】:

我在 html 中遇到了画布问题。我想绘制多个画布图像。 我创建了一个循环来创建多个画布,然后我想在每个画布中绘制一个图像。

for (var i = 1; i <= playerStuff.MovingCards.length; i++){
    $("#playersField").append("<canvas id='movingCardsField"+i+"' height='"+movingCardSizeY+"'\n\
                             width='"+movingCardSizeX+"'\n\
                             data='"+playerStuff.MovingCards[i-1].movePoints+"'></canvas>");
    var imgObj = new Image();
    var drawField = document.getElementById('movingCardsField'+i).getContext("2d"); 
    imgObj.onload = function(){
            drawField.drawImage(imgObj, 0,0);
    };
    imgObj.src = "./img/moveCards/"+playerStuff.MovingCards[i-1].name;
}

结果是只有最后一个画布有绘制的图像。我在这里错过了什么?

【问题讨论】:

    标签: html image canvas


    【解决方案1】:

    请不要为此使用 JQuery。一般来说,我不是 JQuery 的朋友,但这是我个人的看法,但在这里你真的不应该使用它,使用 DOM 会更快。

    var playersField=document.getElementById("playersField");
    var canvasElements=new Array ();
    var canvasElement, drawField,imgObj;
    var drawFields=new Array ();
    
    for (var i = 0; i <= playerStuff.MovingCards.length; i++)
      {
      canvasElement=document.createElement ("canvas");
      canvasElement.height=movingCardSizeY;
      canvasElement.width=movingCardSizeX;
      canvasElement.data=playerStuff.MovingCards[i-1].movePoints;
      playersField.appendChild(canvasElement);
    
      drawField=canvasElement.getContext("2d");
      drawFields.push (drawField);
      imgObj = new Image();
      imgObj.src = "./img/moveCards/"+playerStuff.MovingCards[i-1].name;
      imgObj.index=i;
    
      imgObj.onload = function (){
            drawFields[this.index].drawImage(this, 0,0);
      };
    

    【讨论】:

    • 你必须从索引 0 开始重新排列你的移动卡片。为什么很多人从索引 1 而不是索引 0 开始。我已经看到很多次了。有什么好处,让第一个数组字段为空?
    • 这行得通。谢谢你。但是我现在遇到了一个奇怪的问题。我收到此错误:未捕获的类型错误:无法读取未定义的属性“名称”。但一切正常。即使我在控制台上打印 player.stuff.movi​​ngcards[0].name 它也在工作。
    • 请显示它引发此错误的行和一些上下文
    • 查看后我认为问题出在 MovingCards [i-1],我从您的脚本中复制的。它必须是 MovingCards[i].. 因为 i 从 0 到 ... 并且 i=0 和 MovingCards [0-1] =-1 的第一个值不存在
    【解决方案2】:

    那是因为 onload 是异步的,当 for 的所有迭代都结束时,onload 可能还没有被调用。然后 drawField 变量是最后一个元素。快速解决这个问题(但不是最干净的解决方案)

    变量的范围与 c++ 或其他语言不同。

    for (var i = 1; i <= playerStuff.MovingCards.length; i++){
        (function(element) {
            $("#playersField").append("<canvas id='movingCardsField"+i+"' height='"+movingCardSizeY+"'\n\
                             width='"+movingCardSizeX+"'\n\
                             data='"+element.movePoints+"'></canvas>");
            var imgObj = new Image();
            var drawField = document.getElementById('movingCardsField'+i).getContext("2d"); 
            imgObj.onload = function(){
                drawField.drawImage(imgObj, 0,0);
            };
          imgObj.src = "./img/moveCards/"+element.name;
    })(playerStuff.MovingCards[i - 1]);
    

    }

    这可能会起作用,或多或少,我没有检查两次代码

    顺便说一句,效率也不是很高

    这应该更好

    var domElement = $("#playersField");
    var canvasStart = "<canvas id='movingCardsField";
    var canvasEnd = "' height='"+movingCardSizeY + "'width='" + movingCardSizeX + "' data='" + element.movePoints + "'></canvas>";
    
    function createCanvas(element) {
        var canvas = canvasStart + (i + 1) + canvasEnd;
        domElement.append(canvas);
    
        var imgObj = new Image();
        var drawField = document.getElementById('movingCardsField' + (i + 1)).getContext("2d"); 
        imgObj.onload = function() {
            drawField.drawImage(imgObj, 0,0);
        };
        imgObj.src = "./img/moveCards/" + element.name;
    }
    
    for (var i = 0; i < playerStuff.MovingCards.length; i++) {
        createCanvas(playerStuff.MovingCards[i]);
    }
    

    【讨论】:

    • 谢谢。这也奏效了。但我不确定我是否理解了一切。所以问题是,当循环结束时,onload 函数还没有完成?所以你的解决方案是,你在每个循环中调用函数并且没有变量被覆盖?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-22
    • 2012-08-15
    • 2020-04-14
    • 2015-11-01
    • 1970-01-01
    • 2011-08-07
    相关资源
    最近更新 更多