User
User

Reputation: 24749

Remove glow from HTML5 canvas drawings?

If I draw a green circle on a black background, then draw the same circle in black, a green shadow/glow is left behind. The circle is not actually erased.

How do I make it purely black again and remove the glow?

I've tried context.shadowColor = "transparent";

Here is a snippet:

context.beginPath();
context.arc(x-1, y-2, 2, 0, 2*Math.PI);
context.fillStyle = "#FF0000";
//context.strokeStyle = "#FF0000";
//context.stroke();
context.fill();
context.beginPath();
context.arc(x-1, y-2, 2, 0, 2*Math.PI);
context.fillStyle = "#000000";
//context.strokeStyle = "#000000";
//context.stroke();
context.fill();

Here is the full object:

enter image description here

Upvotes: 0

Views: 224

Answers (1)

Blindman67
Blindman67

Reputation: 54089

How to clear the canvas.

By the looks of the image you gave you are wanting to write a game or an animation of some sort.

The general way games and animations are done are by redrawing the entire game screen every frame. This greatly simplifies the design of the rendering engine. Makes it easy to draw one thing over the other by simply changing the order in which you draw them. To make something vanish just don't render it.

I am assuming you know how to load images

Clearing the screen

You have several ways to clear the screen.

// assuming ctx is the 2d Context and width and height are the canvas width and height.
ctx.clearRect(0, 0, width, height); 

Or by filling the screen with a rectangle.

var backgroundColour = "#000";
ctx.fillStyle = backgroundColour;
ctx.fillRect(0, 0, width, height);

Or use a background image

var backgroundImage = new Image();
backgroundImage.src = "backgroundImage URL";
// then wait for image to load.
// then 
ctx.drawImage(backgroundImage, 0, 0, width, height);

Drawing sprites

Now you can draw the graphics. Again there are many ways to do this. One approch is to keep a list of all the objects and draw them all in one go after the screen has cleared.

// create or load a game sprite (image)
var gameSprite = new Image();
gameSprite.src = "gameSprite URL";
// create a list of sprites.
var mySprites = [
    {x : 10, y : 10, image : gameSprite}, // sprite 1
    {x : 30, y : 60, image : gameSprite}, // sprite 2
    {x : 70, y : 40, image : gameSprite}  // sprite 3
];

// itterate the list and draw each sprite one at a time.
function renderSprites (spriteList) {
    var i,len,s;
    len = spriteList.length;
    for (i = 0; i < len; i++) {
        s = spriteList[i];
        ctx.drawImage(s.image, s.x, s.y);
    }
}

Animating it all

The last thing is you need to sync it all up with the display hardware so that it runs at the maximum frame rate possible and does not create artifacts such as shearing, or flickering. To do this you use requestAnimationFrame which is similar to setTimeout but you do not supply the timing the browser takes care of that.

You will need a main loop function that you provide to requestAnimationFrame to call when the browser is ready to draw the next frame. In this function you first clear the screen, do the game logic, draw all the sprites, and then request the next frame (though you can request the next frame at any stage within the main loop).

function mainLoop(time){   // requestAnimationFrame adds the argument (time). 
                           // This is the time in milliseconds.
    // clear the screen
    ctx.drawImage(backgroundImage,0,0,width,height);

    // do game logic here

    renderSprites(mySprites); // draw the sprites

    // now request the next frame and do it all again.
    requestAnimationFrame(mainLoop);
}

// start the animation by requesting the first frame.
requestAnimationFrame(mainLoop);

This will run at 60fps (frames per second) and can easly handle over 100 sprites (on all but the most basic device)

Upvotes: 2

Related Questions