d m
d m

Reputation: 591

Clearing a strokeRect() on HTML5 Canvas

I can draw a square with a border on my canvas perfectly fine. However, when I attempt to clear this square-with-border shape using the clearRect() function, some strokes do not get cleared.

HTML

<div>
    <canvas width="300" height="250">
    </canvas>
</div>

JS

var $context = $('canvas')[0].getContext('2d');

// Create 4 filled squares
$context.fillStyle = 'pink';
$context.fillRect(120, 0, 30, 30);
$context.fillRect(120, 30, 30, 30);
$context.fillRect(150, 0, 30, 30);
$context.fillRect(150, 30, 30, 30);

// Create borders around them
$context.strokeRect(120, 0, 30, 30);
$context.strokeRect(120, 30, 30, 30);
$context.strokeRect(150, 0, 30, 30);
$context.strokeRect(150, 30, 30, 30);

// Now erase the squares (individually)
$context.clearRect(120, 0, 30, 30);
$context.clearRect(120, 30, 30, 30);
$context.clearRect(150, 0, 30, 30);
$context.clearRect(150, 30, 30, 30);

See the jsFiddle here.

After looking more carefully, it seems the clearRect() function doesn’t actually clear the stroke from my strokeRect() call. So I was thinking, maybe what I need to do is simply stroke the border with a strokeStyle of ‘white’. However, when I do this (new fiddle here), it seems like this paints a white stroke but only with an alpha value of 128! My globalAlpha is set to 1…shouldn’t this be completely opaque?

What am I not understanding here? Does the clearRect() not clear calls to strokeRect()? And if not, should the solution be stroking over the existing strokeRect() but with a color of white?

Note that I cannot simply just clear the canvas but must clear one square at a time.

Thanks in advance!

Upvotes: 5

Views: 16653

Answers (3)

Erick Oziel
Erick Oziel

Reputation: 1222

clearReact wasn't working for me because I forgot to use beginPath before drawing lines. Use: context.beginPath();

So this will do:

var $context = $('canvas')[0].getContext('2d');

$context.fillStyle = 'pink';
$context.fillRect(120, 0, 30, 30);
$context.fillRect(120, 30, 30, 30);
$context.fillRect(150, 0, 30, 30);
$context.fillRect(150, 30, 30, 30);

// add this:
$context.beginPath();

$context.strokeRect(120, 0, 30, 30);
$context.strokeRect(120, 30, 30, 30);
$context.strokeRect(150, 0, 30, 30);
$context.strokeRect(150, 30, 30, 30);

$('.erase').on('click', function() {
    // Now erase everything
    $context.clearRect(0,0,$('canvas')[0].width, $('canvas')[0].height);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
    <canvas width="300" height="250"></canvas>
</div>
<button class="erase">Attempt to Clear</button>

Upvotes: 4

Navya
Navya

Reputation: 53

You can also do this:

$context.clearRect(0, 0, canvas.width, canvas.height);

This will clear the canvas context completely.

Upvotes: 1

Michal
Michal

Reputation: 2532

Things are working correctly. Borders via strokeRect add height and width to the shape equal to the lineWidth. clearRect isn't a fancy function, it just works like an eraser - removing "paint" only from the area you specify.

In your example, the lineWidth is the default of 1. Your code draws rectangles of 30x30, and then applies a border via stroke of width 1. The resulting shape is 32x32 - resulting from 1 + 30 + 1.

To clear this whole thing, you have to tweak your math a bit:

$context.clearRect(119, -1, 32, 32);
$context.clearRect(119, 29, 32, 32);
$context.clearRect(149, -1, 32, 32);
$context.clearRect(149, 29, 32, 32);

This moves over one x and one y coordinate, as well as increases the size of the clear to cover the border as well as the shape itself.

jsfiddle: http://jsfiddle.net/fg6fmjhb/2/

Upvotes: 11

Related Questions