简体   繁体   中英

How to put overlapping images on html5 canvas?

I want to make a cool visualization where I would overlap lots of semi-transparent images on my canvas. For this, I decided to use context.putImageData() because these images are stored as arrays. The problem is that this method disregards the actual background of the canvas with the already drawn images and computes the transparency with respect to the white background.

Here is a snippet showing the current behavior:

<!DOCTYPE html>
<html>

<body>
<canvas id='cvs' width='100' height='100'></canvas>
</body>
<script>
const size = 50
const context = document.getElementById('cvs').getContext('2d');

const redSquare = context.createImageData(size, size);

for (let i=0; i<size*size*4; i=i+4) {
    redSquare.data[i] = 255;
    redSquare.data[i + 3] = 255; // 1.0 opacity rbga(1, 0, 0, 1)
}

context.putImageData(redSquare, 10, 10);

const trasparentBlackSquare = context.createImageData(size, size);

for (let i=0; i<size*size*4; i=i+4) {
    trasparentBlackSquare.data[i + 3] = 100; // 0.4 opacity rbga(0, 0, 0, 0.4)
}

context.putImageData(trasparentBlackSquare, 30, 30);

</script>

</html>

And the result looks like this: 当前行为 .

However, I would want it to look this way: 预期行为

I generated this image with two distinct overlapping canvases which is not suitable for my problem.

Please let me know if there are any workarounds to this problem.

If you write an image into a 'workspace' canvas you can go through the image data for that, changing the opacity, just as you have done for the black square. Then write it back to workspace canvas. You can then write it to your main canvas using drawImage.

Here's what I tried on my server, obviously you have to put in a suitable img src to avoid CORS problems. And also make the img and workspace elements visibility:hidden - I've left them visible to show what is going on.

<!DOCTYPE html>
<html>

<body>
img
<img id="img" src="https://rgspaces.org.uk/wp-content/uploads/may-morning-in-lockdown-100x100.jpg"/>
cvs
<canvas id='cvs' width='100' height='100'></canvas>
workspace
<canvas id='workspace' width='100' height='100' style="visibility:visible;"></canvas>
</body>
<script>
window.onload=init;
function init() {
  const size = 50
  const cvs = document.getElementById('cvs')
  const context = cvs.getContext('2d');
  const workspace= document.getElementById('workspace')
  const workspacectx=workspace.getContext('2d');
  const img=document.getElementById('img');

  context.fillStyle = 'rgb(255,0,0,1)';
  context.fillRect(10, 10, size, size);

  workspacectx.drawImage(img,20,20,size,size);

  imgdata=workspacectx.getImageData(20, 20, size, size);
  for (var i=0;i<size*size*4;i+=4) {
    imgdata.data[i+3]=150;//if it already has an opacity 0 you would leave it
  }
  workspacectx.putImageData(imgdata,20,20);
  context.drawImage(workspace,20,20);
}
</script>

</html>

What you are looking for is composing canvas images. This might help: https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Compositing/Example

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM