简体   繁体   中英

Draw multiple images to canvas and then remove one of them

After getting a Canvas element and its context

var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');

Let's say I drew 3 images on it.

context.drawImage(image,x,y,100,100);
context.drawImage(image,x+20,y+20,100,100);
context.drawImage(image,x+40,y+40,100,100); //image 3

How do I remove image 3 from the canvas keeping the other two? Won't clearRect remove anything in the drawing area?! If not, why?

Thanks a lot.

It does not a contain any separate element like we see in html when multiple element flow over another with different z-index. Its just like a state. So it is like an array of pixel data (they call it ImageData). You can capture a state.

Just a sample code:

<!DOCTYPE html>

<p>Image to use:</p>
<img id="scream" width="220" height="277" src="img_the_scream.jpg" alt="The Scream">

<table>
    <tr>
        <td>
            <p>Canvas:</p>
            <canvas id="myCanvas" width="240" height="297" style="border:1px solid #d3d3d3;">
                Your browser does not support the HTML5 canvas tag.
            </canvas>
        </td>
        <td>
            <p>Extra Canvas:</p>
            <canvas id="myCanvas2" width="240" height="297" style="border:1px solid #d3d3d3;">
                Your browser does not support the HTML5 canvas tag.
            </canvas>
        </td>
</table>

<script>
    window.onload = function() {
        var c = document.getElementById("myCanvas");
        var ctx = c.getContext("2d");
        var img = document.getElementById("scream");
        ctx.drawImage(img, 10, 10);
        ctx.drawImage(img, 110, 40);

        var c2 = document.getElementById("myCanvas2"); // will copy the sate here
        c2.getContext("2d").putImageData(ctx.getImageData(0, 0, 240, 297), 0, 0);

        ctx.drawImage(img, 30, 60);

    }
</script>

<p><strong>Note:</strong> The canvas tag is not supported in Internet Explorer 8 and earlier versions.</p>

I just modified the sample code of w3schools tryIt ( http://www.w3schools.com/tags/tryit.asp?filename=tryhtml5_canvas_drawimage ).

You can use ctx.save() to keep a restorable state while making changes using drawImage() . And to restore to that very last saves state, you can use ctx.restore() .

How do I remove image 3 from the canvas keeping the other two?

You need to clear the canvas for example using clearRect() , then redraw only those you want to keep. There are just unbound pixels on the canvas which you need to manually track.

One suggestion on how to do this is encapsulate the information about an image into a simple object:

var oImg1 = {
  image: img1,   // image object
  visible: true, // state
  x: 10,         // handy
  y: 10          // dandy
},
//... etc. for the other images (could use an array if there are many)

Then

if (oImg1.visible) ctx.drawImage(oImg1.image, oImg1.x, oImg1.y);

When you need to remove an image set visible to false , clear and redraw using conditions.

You can either simply clear and redraw the images you require, if you're doing this via a loop.

Or, you can simply draw over the image you no longer require.

Eg

<img id="img1" src="GITS01.jpg" style="display:none;">
<img id="img2" src="Matrix01.jpg" style="display:none;">
<img id="img3" src="silent-hills2.jpg" style="display:none;">
<canvas id="canvas"></canvas>
<script>
var ctx = document.getElementById('canvas').getContext('2d');
ctx.canvas.width = window.innerWidth * 0.8;
ctx.canvas.height = window.innerHeight * 0.8;

var img1 = document.getElementById('img1');
var img2 = document.getElementById('img2');
var img3 = document.getElementById('img3');

// Let's clear the canvas first.
ctx.fillStyle = '#101010';
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);

// Draw 3 images, top left, top right and bottom right quadrants.
ctx.drawImage(img1, 0, 0, ctx.canvas.width / 2, ctx.canvas.height / 2);
ctx.drawImage(img2, ctx.canvas.width / 2, 0, ctx.canvas.width / 2, ctx.canvas.height / 2);
ctx.drawImage(img3, 0, ctx.canvas.height / 2, ctx.canvas.width / 2, ctx.canvas.height / 2);

// Now, let's remove that second image in the top right quadrant,
// by simply drawing over it with a blank rectangle.
ctx.fillRect(ctx.canvas.width / 2, 0, ctx.canvas.width / 2, ctx.canvas.height / 2);
</script>

Depending on what else you need to draw, or if there's overlapping elements, then you will need to simply clear the canvas and redraw what you require. This is because the canvas draws in immediate mode. You either need to draw over what you just drew precisely, or you have to clear and start again, removing the draw operations for the things you don't need.

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