在HTML5画布上清除strokeRect()

5
我可以在我的画布上画一个带边框的正方形,但是当我尝试使用clearRect()函数清除这个带边框的形状时,有些笔画没有被清除。
<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);

请查看这里的jsFiddle 链接

仔细观察后,似乎 clearRect() 函数并没有真正清除我对 strokeRect() 的描边效果。所以我想,也许我需要做的是只用 ‘white’strokeStyle 描绘边框。然而,当我这样做时(新的 fiddle 链接),它似乎只画了一个 alpha 值为 128 的白色描边!我的 globalAlpha 已经设为 1 了……这不应该是完全不透明的吗?

我在这里理解错了什么?clearRect() 是否不能清除对 strokeRect() 的调用?如果不能,那么解决方案是否应该是使用白色重新描绘现有的 strokeRect()

请注意,我不能简单地清除画布,必须逐个清除每个正方形。

提前致谢!


1
clearRect() 运行良好。当描绘时,斜线具有宽度。在外部和内部两侧都是如此。您只需要扩展 clearRect。还要注意 stroke 具有一些透明度。 - Spencer Wieczorek
@SpencerWieczorek - 不确定如何“扩展”clearRect()函数。我尝试在调用clearRect()之前将lineWidth设置为2而不是默认值1,但这并没有什么作用。您具体会如何设置清除矩形的外侧和内侧? - d m
clearRect() 在每个方向上多覆盖一个像素。例如,除了清除 30x30 区域外,还要清除 32x32 区域。 - Spencer Wieczorek
当@SpencerWieczorek说“extend”时,他的意思是clearRect(120-2, 0-2, 30+4, 30+4)。顺便说一句,HTML画布工作流通常会清除画布并重新绘制所有所需的形状,而不是尝试擦除现有的绘图。正如你已经发现的那样,画布使擦除变得非常复杂。关键是“记住”形状的定义,以便它们可以被重新绘制--通常在JavaScript对象中。干杯! - markE
明白了...感谢您的快速回复! - d m
3个回答

11

事情正在正常运作。通过strokeRect添加的边框高度和宽度等于lineWidthclearRect不是一个花哨的函数,它的工作原理就像橡皮擦-只从您指定的区域删除“绘画”。

在您的示例中,lineWidth是默认值1。您的代码绘制30x30的矩形,然后通过宽度为1的描边应用边框。生成的形状为32x32-结果为1+30+1。

要清除整个内容,您需要对数学进行微调:

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

这会在x和y坐标上各移动一个单位,并且增加透明区域的大小以覆盖边框和形状本身。

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


3

clearReact 对我无效是因为在画线前我忘记使用 beginPath。 正确用法为: context.beginPath();

这样就可以了:

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>


1

你也可以这样做:

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

这将完全清除画布上下文。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接