我想拥有它,以便当我创建一个"组件"我可以设置它的半径使其弯曲。下面是我的组件创建代码:
function component(width, height, color, x, y) {
this.width = width;
this.height = height;
this.speedX = 0;
this.speedY = 0;
this.x = x;
this.y = y;
this.color = color;
this.update = function() {
ctx = GameArena.context;
ctx.fillStyle = this.color;
ctx.fillRect(this.x, this.y, this.width, this.height);
}
}
你可以看到它指定了宽度高度,颜色和x和y位置,但是我找不到给它一个半径的方法。我的代码的另一端使用了这个组件函数:
PaintBrush = new component(30, 30, "Blue", 30, 320);
帮助将不胜感激!
答案 0 :(得分:1)
使用圆弧可以绘制一个带圆角的矩形:
arc采用参数:
arc(x, y, radius, startAngle, endAngle [,ccw]); // we won't need counter-clockwise
例如:
var pi2 = Math.PI * 2; // 360 deg.
var r = this.radius, w = this.width, h = this.height;
// ...
// draw rounded rectangle
ctx.beginPath();
ctx.arc(r, r, r, pi2*0.5, pi2*0.75); // top-left
ctx.arc(r+w-r*2, r, r, pi2*0.75, pi2); // top-right
ctx.arc(r+w-r*2, r+h-r*2, r, 0, pi2*0.25); // bottom-right
ctx.arc(r, r+h-r*2, r, pi2*0.25, pi2*0.5); // bottom-left
这只是使用半径和起点和终点角在每个角上绘制四个弧。由于我们使用单个路径,因此在每个弧之间绘制从前一个弧的末尾到新弧的开头的线 - 这就是顺序重要的原因。
只需fill()
即可关闭路径并填充形状。如果您想要stroke()
,请记住先使用closePath()
。如果您稍后通过其他对象添加了路径,请记住在添加之前使用beginPath()
。
线设置半径也会将其限制为可能的最小尺寸:
this.radius = Math.min(radius, Math.min(width, height)/2);
首先使用高度和宽度的最小值除以2。然后是半径的最小值和这个结果。这确保半径不能大于最短边的一半,这将是“不可能的”。
关于下面setTransform()
用法的说明 - 如果您没有累积转换,这应该可以正常工作。如果您这样做并且无法轻松更改,请将setTransform()
替换为ctx.translate(this.x, this.y)
,然后通过调用ctx.translate(-this.x, -this.y);
完成反转。如果它们以某种方式被转换(旋转,缩放等),我建议使用setTransforms悬停所有对象。
var GameArena = {context: c.getContext("2d")}; // dummy
var PaintBrush = new component(200, 100, "#37f", 10, 10, 16);
PaintBrush.update();
function component(width, height, color, x, y, radius) {
this.width = width;
this.height = height;
this.speedX = 0;
this.speedY = 0;
this.x = x;
this.y = y;
this.radius = Math.min(radius, Math.min(width, height)/2); // clamp radius
this.color = color;
this.update = function() {
var pi2 = Math.PI * 2; // 360 deg.
var r = this.radius, w = this.width, h = this.height;
ctx = GameArena.context;
ctx.fillStyle = this.color;
ctx.setTransform(1,0,0,1,this.x, this.y); // transform (absolute here)
// draw rounded rectangle
ctx.beginPath();
ctx.arc(r , r , r, pi2*0.5 , pi2*0.75); // top-left
ctx.arc(w-r, r , r, pi2*0.75, pi2); // top-right
ctx.arc(w-r, h-r, r, 0 , pi2*0.25); // bottom-right
ctx.arc(r , h-r, r, pi2*0.25, pi2*0.5); // bottom-left
ctx.fill();
ctx.setTransform(1,0,0,1,0,0); // reset transform
}
}
<canvas id=c></canvas>