在一个画布上绘制多个图像

时间:2011-12-06 18:33:28

标签: javascript image html5

我有一个数组,其中包含有关如何绘制image的所有信息。我想绘制2 images,当我这样做时,它只绘制最后一张图像。我该怎么办?

for(i = 0; i < tiles.length; i++)
{
    var sourceX = tiles[i][5];
    var sourceY = tiles[i][6];
    var sourceWidth = tiles[i][9];
    var sourceHeight = tiles[i][10];
    var destWidth = sourceWidth;
    var destHeight = sourceHeight;
    var destX = tiles[i][7];
    var destY = tiles[i][8];

    var imageObj = new Image();
    imageObj.onload = function()
    {
        context.drawImage(imageObj, sourceX, sourceY, sourceWidth, sourceHeight, destX, destY, destWidth, destHeight);
    };
    imageObj.src = tiles[i][4];
}

6 个答案:

答案 0 :(得分:9)

我无法解释更具体的原因,但这是我想出的解决方案。它对我有用。

&#13;
&#13;
C = input("Choose your charecter to insert. ")
P = int(input("Choose your character's position. "))
S = input("Choose your string. ")

if P > len(S):
    print(S)
else:
    st = S[:P] + C + S[P:]

    print(st)
    print(C, P, S)
&#13;
const getContext = () => document.getElementById('my-canvas').getContext('2d');

// It's better to use async image loading.
const loadImage = url => {
  return new Promise((resolve, reject) => {
    const img = new Image();
    img.onload = () => resolve(img);
    img.onerror = () => reject(new Error(`load ${url} fail`));
    img.src = url;
  });
};

// Here, I created a function to draw image.
const depict = options => {
  const ctx = getContext();
  // And this is the key to this solution
  // Always remember to make a copy of original object, then it just works :)
  const myOptions = Object.assign({}, options);
  return loadImage(myOptions.uri).then(img => {
    ctx.drawImage(img, myOptions.x, myOptions.y, myOptions.sw, myOptions.sh);
  });
};

const imgs = [
  { uri: 'http://placehold.it/50x50/f00/000?text=R', x: 15, y:  15, sw: 50, sh: 50 },
  { uri: 'http://placehold.it/50x50/ff0/000?text=Y', x: 15, y:  80, sw: 50, sh: 50 },
  { uri: 'http://placehold.it/50x50/0f0/000?text=G', x: 15, y: 145, sw: 50, sh: 50 }
];

imgs.forEach(depict);
&#13;
#my-canvas { background: #7F7F7F; }
&#13;
&#13;
&#13;

答案 1 :(得分:4)

我不是肯定的,但是imageObj可能不是你在imageObj.onload函数中所期望的imageObj。而不是做

 context.drawImage(imageObj, sourceX, sourceY,

看看你做什么时发生了什么

 context.drawImage(this, sourceX, sourceY,

答案 2 :(得分:1)

如果您要加载多张图片,建议您先预先加载所有图片。有关更多信息,请参见此处:

http://www.html5canvastutorials.com/tutorials/html5-canvas-image-loader/

答案 3 :(得分:1)

我有类似的问题, 我喜欢

的解决方案

https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Basic_animations

只需调用window.requestAnimationFrame(draw);从你的绘图功能,它将运行一个无限循环,并在它们准备好后立即绘制图像

答案 4 :(得分:0)

这是一个解决方案,也是推荐的替代方案;两者都使用<function>.bind(<this>[,<arg1>][,<arg2>])

bind包装预期的函数,并使用其他指定的参数(args)对其执行调用。 bind的第一个参数将是函数的this实例。将其设置为undefined将传递原始this实例。

匿名函数。

  var settings;

  for(i = 0; i < tiles.length; i++)
  {
      settings = {};
      settings.sourceX = tiles[i][5];
      settings.sourceY = tiles[i][6];
      settings.sourceWidth = tiles[i][9];
      settings.sourceHeight = tiles[i][10];
      settings.destWidth = sourceWidth;
      settings.destHeight = sourceHeight;
      settings.destX = tiles[i][7];
      settings.destY = tiles[i][8];

      settings.imageObj = new Image();
      settings.imageObj.onload = function(args)
      {
         context.drawImage(args.image, args.sourceX, args.sourceY, args.sourceWidth, args.sourceHeight, args.destX, args.destY, args.destWidth, args.destHeight);
      }.bind(undefined, settings);
      settings.imageObj.src = tiles[i][4];
  }

我更喜欢不使用 匿名函数进行常见事件处理;相反,我会声明一个对象来存储处理程序。

这样你就可以在运行时替换处理程序。以下列方式。

声明对象以存储事件处理函数

  var Handlers = { 
      "drawImageHandler" : function drawImageHandler(args)
      {
          context.drawImage(args.image, args.sourceX, args.sourceY, args.sourceWidth, args.sourceHeight, args.destX, args.destY, args.destWidth, args.destHeight);
      }
  };

  function DebugInit() 
  {
      var func = Handlers.drawImageHandler;
      Handlers.drawImageHandler = function(func, args) {
         console.log("%o", args);
         func(args);
      }.bind(undefined, func);
  }


  var settings = {};
  DebugInit(); // when called, encapsulates Handlers.drawImageHandler;

  for(i = 0; i < tiles.length; i++)
  {
      settings = {};
      settings.sourceX = tiles[i][5];
      settings.sourceY = tiles[i][6];
      settings.sourceWidth = tiles[i][9];
      settings.sourceHeight = tiles[i][10];
      settings.destWidth = sourceWidth;
      settings.destHeight = sourceHeight;
      settings.destX = tiles[i][7];
      settings.destY = tiles[i][8];
      settings.imageObj = new Image();
      settings.imageObj.onload = Handlers.drawImageHandler.bind(undefined, settings);      
      settings.imageObj.src = tiles[i][4];
  }

jsFiddle Example Fiddle

答案 5 :(得分:0)

private void forceRTLIfSupported()
{
  if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1){
    getWindow().getDecorView().setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
  }
}

我的js游戏,我希望它有助于欢呼!