1

我使用 Juan Mendes 逻辑(http://js-bits.blogspot.in/2010/07/canvas-rounded-corner-rectangles.html)创建一个圆角矩形。但是我想增加它的厚度。所以我尝试添加

ctx.lineWidth

即使我得到了厚度,添加线宽后圆角也消失了。

JSFiddle - http://jsfiddle.net/cZ2gH/

另外,如何在矩形内绘制图像边框也被四舍五入?

4

2 回答 2

1

这就是裁剪窗口的用途。思路是:创建路径,调用ctx.clip(),所有后续的绘制操作都不会影响路径之外的任何东西。

我不确定粗线的问题是什么。在玩了一会儿之后,我决定采用以下方法:1)将裁剪的图像绘制为圆形;2)绘制相同的圆形矩形,上面有粗线。

(我尝试过的其他事情,例如绘制一个填充的圆形矩形并将图像剪切到内部较小的圆形矩形也不起作用。)

Jsfiddle在这里

另外:这在 CSS3 中很简单。除非您需要使用画布获得的控制级别,否则您可能想尝试以声明方式进行操作(此处为 CSS fiddle )。

于 2013-11-02T16:31:51.360 回答
1

复合法

如果需要画布,您可以简单地使用复合模式(或者我会推荐 CSS3 和border-radius其他答案)。

现场演示在这里

var rect = [20, 20, 300, 300],
    cr = 25;            // corner radius

现在创建一个圆角矩形路径:

var pi = Math.PI,       // cache it here to make code more readable
    x1 = rect[0],       // cache points
    y1 = rect[1],
    x2 = rect[2] + x1,
    y2 = rect[3] + y1;

// create a rounded rectangle path
ctx.beginPath();

ctx.arc(x1 + cr, y1 + cr, cr, pi, 1.5 * pi);  // upper left corner
ctx.arc(x2 - cr, y1 + cr, cr, 1.5 * pi, 0);   // upper right corner
ctx.arc(x2 - cr, y2 - cr, cr, 0, 0.5 * pi);   // lower right corner
ctx.arc(x1 + cr, y2 - cr, cr, 0.5 * pi, pi);  // lower left corner

ctx.closePath();

现在我们有了圆角矩形的路径。接下来我们需要做的是在其中制作纯色,以便我们可以将其用于合成模式 - 我们在这里只使用默认填充颜色:

ctx.fill();

现在我们可以设置复合模式来表示下一个绘制的东西应该绘制在我们拥有的东西(实心像素)之上:

ctx.globalCompositeOperation = 'source-atop';

// draw in image
ctx.drawImage(img, x1, y1, x2 - x1, y2 - y1);

然后我们重置合成模式,以便我们可以正常绘制(这比使用保存/恢复更快且成本更低):

ctx.globalCompositeMode = 'source-over';  /// default composite mode

// draw a thick border    
ctx.lineWidth = 20;
ctx.stroke();

复合模式与剪辑的缺点和优点。

另一种方法是clip()在路径上使用,但请注意剪裁将迫使您使用save()/restore()因为目前没有干净的方法来重置剪裁(将来可能会修复)。保存/恢复是一项代价高昂的操作,因为它将所有设置存储到堆栈中,并且在恢复时需要将所有设置弹回。

如果您在没有先删除剪辑的情况下描边路径,则描边将被切成两半。

对于合成,缺点是如果您已经将其他内容绘制到新图像后面的背景中。要解决此问题,您需要使用屏幕外画布来执行此操作,然后将结果绘制到主画布中。

于 2013-11-02T19:31:40.113 回答