Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drawing multiple images on one canvas

I have an array that contains all the information about how the image should be drawn. I want to draw 2 images and when I do it, it's only drawing the last image. What can I do?

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];
}
like image 319
user1068455 Avatar asked Dec 06 '11 18:12

user1068455


2 Answers

I couldn't explain more specific reasons, but here is the solution I figured out. It works for me.

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);
#my-canvas { background: #7F7F7F; }
<canvas id="my-canvas" width="80" height="210"></canvas>
like image 114
Ryan Huang Avatar answered Sep 17 '22 18:09

Ryan Huang


I'm not positive, but that imageObj may not be the imageObj you'd expect in the imageObj.onload function. Instead of doing

 context.drawImage(imageObj, sourceX, sourceY,

See what happens when you do

 context.drawImage(this, sourceX, sourceY,
like image 20
Jeffrey Sweeney Avatar answered Sep 19 '22 18:09

Jeffrey Sweeney