HTML5画布:如何给fillRect添加边框?

26
在HTML5中,我想要创建一个使用白色填充颜色的fillRect()和一个带有黑色边框的border。除非可以稍后再进行填充,否则不想使用strokeRect()。我正在制作一个游戏,在游戏中单击正方形会改变它们的颜色(它比这更复杂,但这是重点)。
<canvas id="canvas1" width="400" height="300" style="border:1px solid #000000;"></canvas>
    <script>
        var c=document.getElementById("canvas1");
        var ctx=c.getContext("2d");
        ctx.strokeStyle="rgba(0,0,0,1)";
        ctx.strokeRect(0,0,100,100);
    </script>
< p>画布周围的边框仅供参考。 我也可以使用CSS,但目前所有内容都在HTML中。< /p>

据我所知,有两种方法可以做到这一点,要么在画布元素周围绘制边框,要么使用strokeRect()在画布内部绘制边框。然而,我仍然不明白为什么您不能使用这些选项中的任何一个。 - Alexus
为什么你不使用fillRect后跟strokeRect呢?它正好做你要求的事情。 - Lee Goddard
3个回答

27

如果您没有库,您将无法在后期进行填充。如果您想要更改某些内容,只需重新绘制即可。 您可以使用类似下面的方法:

ctx.fillStyle = 'blue';
ctx.strokeStyle = 'red';
var fillRect = false;
ctx.rect(20, 20, 150, 100);
if (fillRect) {
  ctx.fill();
}
ctx.stroke();

如果你将fillRect更改为true,它将仅绘制边框,并且如果填充,则会填充。您可以在每个requestAnimationFrame上更新画布。

但也许你想使用像paper.js这样的库。它使得诸如点击对象之类的事情更容易,并将画布上的绘画抽象为您创建一次并稍后更新的对象,就像您所要求的那样。


2
在这段代码之前添加 ctx.beginPath(),并在其之后添加 ctx.closePath()。否则你可能会看到一些有趣但不期望的行为。 - Rustem Kakimov

14

确定您要绘制正方形的位置,包括宽度和高度。然后,先绘制一个更大的正方形,宽度和高度各增加2个单位,但中心点保持不变。这样,您就绘制了一个更大的正方形,再在其上方绘制普通的正方形,从而使正方形具有边框的视觉效果。

HTML

<canvas id="canvas1" width="400" height="300" style="border:1px solid #000000;"></canvas>

CSS

#canvas1{
  border: solid 1px black;
}

Javascript

var c=document.getElementById("canvas1");
var ctx=c.getContext("2d");

var rectXPos = 50;
var rectYPos = 50;
var rectWidth = 100;
var rectHeight = 100;

drawBorder(rectXPos, rectYPos, rectWidth, rectHeight)

ctx.fillStyle='#FFF';
ctx.fillRect(rectXPos, rectYPos, rectWidth, rectHeight);

function drawBorder(xPos, yPos, width, height, thickness = 1)
{
  ctx.fillStyle='#000';
  ctx.fillRect(xPos - (thickness), yPos - (thickness), width + (thickness * 2), height + (thickness * 2));
}

jsfiddle链接: https://jsfiddle.net/jxgw19sh/2/

-- 更新 --

drawBorder函数中添加一个额外的参数thickness,默认值为1,但是您可以在函数中提供任何其他数字作为thickness,它将使用该值而不是1。


3
调用 strokeRect 可以避免重新计算位置。 - Kaiido

7

我自己尝试了一下,效果如下:

var x = 100;
var y = 100;
var width = 50;
var height = 50;

var borderWidth = 5;   
var offset = borderWidth * 2;

c.beginPath();
c.fillStyle = 'black';
c.fillRect( x - borderWidth, y -borderWidth, width + offset, height + offset);
c.fillStyle = 'green';
c.fillRect( x, y, width, height);

请添加关于代码的一些解释。 - ppwater
3
@ppwater 我考虑过这样做,但代码看起来已经很容易理解了。无论如何,我会添加它的。 - zoshida

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