-1

I'm trying to draw two images on the same canvas, but the second image being loaded is "erasing" the first. The images are the same size and they complete each other.

HTML:

<canvas id="canvas style="width: 400px"/>
<img id="img1" src="myImage1" />
<img id="img2" src="myImage2" />

JS:

var canvas = document.getElementByID("canvas");
var ctx = canvas.getContext('2d');

var img1 = document.getElementByID("img1");
var img2 = document.getElementByID("img2");

img1.onload = function(){
 canvas.width = img1.naturalWidth;
 canvas.height = img1.naturalHeight;

 ctx.drawImage(img1, 0, 0);
}

img2.onload = function(){
 canvas.width = img2.naturalWidth;
 canvas.height = img2.naturalHeight;

 ctx.drawImage(img2, 0, 0);
}
  • 2
    You are drawing one on top of another. How can you see both? – Konrad Jun 23 '23 at 12:40
  • the part that one has painted the other doesn't so they complete each other – Janio Junior Jun 23 '23 at 12:46
  • 1
    That makes no sense. If you have two images, both drawn at coordinate `0,0` then _at least_ a `1x1` pixel will be covered up from the first draw with the second draw. In short: if they 'complete' each other you should align them as such using thir `naturalWidth` and `naturalHeight`. Secondly, your `.width =` and `.height =` _also_ resets the canvas and clears it. So if you reset the width and height every time, it will result in an empty buffer. In short: you should try get a better grasp of the canvas fundamentals for this one... – somethinghere Jun 23 '23 at 12:54
  • _"the part that one has painted the other doesn't"_ - and just to be clear, by "not painted" you mean complete alpha transparency, yes ...? – CBroe Jun 23 '23 at 12:57
  • Aside from the valid points made here, is the common misunderstanding that the canvas keeps track of all the shapes that are drawn. Think of it like a real live canvas. Whenever you paint over something else, you can not just 'unpaint' your second layer to see the first one again. – Wimanicesir Jun 23 '23 at 12:57
  • please provide the images – Helder Sepulveda Jun 23 '23 at 13:34
  • Does this answer your question? [Preventing Canvas Clear when Resizing Window](https://stackoverflow.com/questions/5517783/preventing-canvas-clear-when-resizing-window) – Konrad Jun 23 '23 at 13:39

2 Answers2

2

Changing the size of the canvas clears the context.

If you're sure the images align, all you have to do is make sure you only initialize once using the dimensions of whichever image loads first:

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext('2d');

var img1 = document.getElementById("img1");
var img2 = document.getElementById("img2");

var didInit = false;
function init(img) {
  canvas.width = img.naturalWidth;
  canvas.height = img.naturalHeight;
  didInit = true;
}

img1.onload = function(){
 if (!didInit) init(img1);
 ctx.drawImage(img1, 0, 0);
}

img2.onload = function(){
 if (!didInit) init(img2);
 ctx.drawImage(img2, 0, 0);
}
canvas {
  display: block;
  border: 1px solid lime;
}

img {
  visibility: hidden;
}
<canvas id="canvas"></canvas>

<img id="img1" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAYAAACtWK6eAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAImSURBVHgB7daxDcNADARBvqH+W343IG3MYKYEAgvemZk7bHKGNX4DfBIIBIFAEAgEgUAQCASBQBAIBIFAEAgEgUAQCASBQBAIBIFAEAgEgUAQCASBQBAIBIFAEAgEgUAQCASBQBAIBIFAEAgEgUAQCASBQBAIBIFAEAgEgUAQCASBQBAIBIFAEAgEgUAQCASBQBAIBIFAEAgEgUAQCASBQBAIBIFAEAgEgUAQCASBQBAIBIFAEAgEgUAQCASBQBAIBIFAEAgEgUAQCASBQBAIBIFAEAgEgUAQCASBQBAIBIFAEAgEgUAQCASBQBAIBIFAEAgEgUAQCASBQBAIBIFAEAgEgUAQCASBQBAIBIFAEAgEgUAQCASBQBAIhGdg5gyvHGafO2xxTSwIAtnFR19GIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBALhGba5wxb3D2JQBpHWtsxvAAAAAElFTkSuQmCC" alt="black" />

<img id="img2" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAYAAACtWK6eAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAIrSURBVHgB7daxDcMwDABBOvD+KyuB6/hrFnegFpDwEK9hlfMMS5zPAK8EAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAuEemDnDP+c6LmeV6xm2sGJBEMgufvNlBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQ7t85wxbeYpkv/gALi57sGR8AAAAASUVORK5CYII=" alt="red" />

Alternatively, you could wait for all images to be loaded, find the largest width and height dimension, set the canvas size and only then draw all the images to it.

const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");


const loadedImages = [];
const drawImagesToPage = () => {
  let maxW = 0;
  let maxH = 0;
  
  for (const img of loadedImages) {
    maxW = Math.max(maxW, img.naturalWidth);
    maxH = Math.max(maxH, img.naturalHeight);
  }
  
  canvas.width = maxW;
  canvas.height = maxH;
  
  for (const img of loadedImages) {
    ctx.drawImage(img, 0, 0);
  }
}

document
  .querySelectorAll("img")
  .forEach((img, idx, all) => {
    loadedImages.push(img);
    
    if (loadedImages.length === all.length) {
      drawImagesToPage();
    }
  });
canvas {
  display: block;
  border: 1px solid lime;
}

img {
  visibility: hidden;
}
<canvas id="canvas"></canvas>

<img id="img1" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAYAAACtWK6eAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAImSURBVHgB7daxDcNADARBvqH+W343IG3MYKYEAgvemZk7bHKGNX4DfBIIBIFAEAgEgUAQCASBQBAIBIFAEAgEgUAQCASBQBAIBIFAEAgEgUAQCASBQBAIBIFAEAgEgUAQCASBQBAIBIFAEAgEgUAQCASBQBAIBIFAEAgEgUAQCASBQBAIBIFAEAgEgUAQCASBQBAIBIFAEAgEgUAQCASBQBAIBIFAEAgEgUAQCASBQBAIBIFAEAgEgUAQCASBQBAIBIFAEAgEgUAQCASBQBAIBIFAEAgEgUAQCASBQBAIBIFAEAgEgUAQCASBQBAIBIFAEAgEgUAQCASBQBAIBIFAEAgEgUAQCASBQBAIBIFAEAgEgUAQCASBQBAIhGdg5gyvHGafO2xxTSwIAtnFR19GIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBALhGba5wxb3D2JQBpHWtsxvAAAAAElFTkSuQmCC" alt="black" />

<img id="img2" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAYAAACtWK6eAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAIrSURBVHgB7daxDcMwDABBOvD+KyuB6/hrFnegFpDwEK9hlfMMS5zPAK8EAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAuEemDnDP+c6LmeV6xm2sGJBEMgufvNlBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQBAJBIBAEAkEgEAQCQSAQ7t85wxbeYpkv/gALi57sGR8AAAAASUVORK5CYII=" alt="red" />
user3297291
  • 22,592
  • 4
  • 29
  • 45
0

You can't change height or width because canvas will be cleared

Better wait for both images to load and then set dimensions

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");

var img1 = document.getElementById("img1");
var img2 = document.getElementById("img2");

ctx.fillStyle = "red";
ctx.fillRect(0, 0, 300, 300);

Promise.all([
  new Promise((r) => {
    img1.onload = function() {
      r(img1);
    };
  }),
  new Promise((r) => {
    img2.onload = function() {
      r(img2);
    };
  })
]).then(([img1, img2]) => {
  const width = Math.max(img1.naturalWidth, img2.naturalWidth);
  const height = Math.max(img1.naturalHeight, img2.naturalHeight);
  
  canvas.width = width;
  canvas.height = height;
  ctx.drawImage(img1, 0, 0);
  ctx.drawImage(img2, 0, 0);
});
<!DOCTYPE html>
<html>

<head>
  <title>Parcel Sandbox</title>
  <meta charset="UTF-8" />
</head>

<body>
  <canvas id="canvas"></canvas>
  <img id="img1" src="https://i.imgur.com/hXp1nj4.png" />
  <img id="img2" src="https://i.imgur.com/2XpTBZa.png" />
</body>

</html>
Konrad
  • 21,590
  • 4
  • 28
  • 64