将CSS3的边框半径应用到HTML5 Canvas中

7

我将尝试在画布中复现CSS3的边框半径。

绘制圆角矩形很容易,但在CSS中,每个边框的值可以很高。

例如:
HTML

<div class="normal_radius"></div>
<div class="high_radius"></div>
<div class="high2_radius"></div>

CSS

div { height:50px;width:50px;position:absolute;top:10px; }
.normal_radius {
    border: 1px solid black;
    border-radius: 5px 5px 10px 15px;
    left: 10px;
}
.high_radius {
    border: 1px solid red;
    border-radius: 5000px 500px 100px 150px;
    left: 80px;
}
.high2_radius {
    border: 1px solid blue;
    border-radius: 2500px 250px 50px 75px;
    left: 160px;
}

这里有一个jsfiddle

黑色的普通边框半径值,我可以重现。 红色的高边框半径值,我不知道如何重现。 而蓝色的高边框半径值除以2,与红色相同。

我的问题很简单,如何在画布中重现红色和蓝色的效果?

最好的问候。


我认为您需要使用路径方法自己绘制曲线。请访问https://developer.mozilla.org/en-US/docs/Canvas_tutorial/Drawing_shapes并向下滚动至“moveTo”和“Bezier and quadratic curves”。 - Mic
只是一个问题:当border-radius: 100% 10% 0 0;可以达到同样的效果时,为什么在CSS中要使用那些巨大的border-radius值呢?http://jsfiddle.net/fAJ9t/66/ - Ana
你好,感谢您的回答,但我知道如何绘制圆角矩形,我想要的是如果用户输入高值,则绘制圆角矩形的算法/公式。 - kran
2个回答

6
下面的函数非常接近。虽然如果您使用的值大于宽度和高度,您将会遇到问题。 Live Demo">演示
function canvasRadius(x, y, w, h, tl, tr, br, bl){
  var r = x + w,
      b = y + h;

  ctx.beginPath();
  ctx.moveTo(x+tl, y);
  ctx.lineTo(r-(tr), y);
  ctx.quadraticCurveTo(r, y, r, y+tr);
  ctx.lineTo(r, b-br);
  ctx.quadraticCurveTo(r, b, r-br, b);
  ctx.lineTo(x+bl, b);
  ctx.quadraticCurveTo(x, b, x, b-bl);
  ctx.lineTo(x, y+tl);
  ctx.quadraticCurveTo(x, y, x+tl, y);
  ctx.stroke();

}

canvasRadius(10,10,50,50,5,5,10,15);
ctx.strokeStyle = "red";
canvasRadius(80,10,50,50,47,3,0,0);
ctx.strokeStyle = "blue";
canvasRadius(160,10,50,50,47,3,0,0);

嗨,在W3C网站上,我发现了以下内容:http://www.w3.org/TR/css3-background/#corner-overlap但是我不理解。 - kran

1

这里是解决方案:

CanvasRenderingContext2D.prototype.roundRect=function(x,y,width,height,tl,tr,br,bl) {
  var x1,x2,x3,x4,y1,y2,y3,y4,radii,ratio=0,CURVE2KAPPA=0.5522847498307934;
  ratio=Math.min(Math.min(width/(tl+tr),width/(br+bl)),Math.min(height/(tl+bl),height/(tr+br)));
  if ((ratio>0)&&(ratio<1)) {
    tl*=ratio;
    tr*=ratio;
    bl*=ratio;
    br*=ratio;
  }
  xw=x+width;
  yh=y+height;
  x1=x+tl;
  x2=xw-tr;
  x3=xw-br;
  x4=x+bl;
  y1=y+tr;
  y2=yh-br;
  y3=yh-bl;
  y4=y+tl;
  this.beginPath();
  this.moveTo(x1,y);
  this.lineTo(x2,y);
  radii=CURVE2KAPPA*tr;
  this.bezierCurveTo(x2+radii,y,xw,y1-radii,xw,y1);
  this.lineTo(xw,y2);
  radii=CURVE2KAPPA*br;
  this.bezierCurveTo(xw,y2+radii,x3+radii,yh,x3,yh);
  this.lineTo(x4,yh);
  radii=CURVE2KAPPA*bl;
  this.bezierCurveTo(x4-radii,yh,x,y3+radii,x,y3);
  this.lineTo(x,y4);
  radii=CURVE2KAPPA*tl;
  this.bezierCurveTo(x,y4-radii,x1-radii,y,x1,y);
  this.stroke();
}

ctx.roundRect(0,0,50,50,5,5,10,15);
ctx.strokeStyle="red";
ctx.roundRect(0,0,50,50,5000,500,100,150);
ctx.strokeStyle="blue";
ctx.roundRect(0,0,50,50,2500,250,50,75);

现场演示

玩得开心。


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