我有一个 400x300 的 HTML 画布,我正在尝试使用圆形和 7 个三角形绘制太阳。为了绘制三角形,我按照此SO答案中的指示进行平移,旋转,平移。但是,一些三角形重叠,就好像它们具有相同的角度一样。
http://codepen.io/ralrom/pen/bgZYRO
我不知道出了什么问题,我检查了计算出的弧度,它们都落在 0 到 2*PI 之间。
var drawSun = function () {
// Circle
context.beginPath();
context.arc(75, 75, 30, 0, Math.PI * 2, true);
context.closePath();
context.fill();
context.save();
// Triangles
for (var i = 0; i < 7; i++) {
// Rotate the canvas around a point
angle = i * 360 / 7;
console.log(angle, angle * Math.PI / 180);
context.translate(75, 75);
context.rotate(angle * Math.PI / 180);
context.translate(-75, -75);
// Draw the triangle
context.beginPath();
context.fillStyle = 'rgba(0,0,0,0.5)';
context.moveTo(60, 35);
context.lineTo(75, 15);
context.lineTo(90, 35);
context.closePath();
context.fill();
context.restore();
}
}
有时这里的答案有很多点,但实际上不是那么好。使用 ctx.setTransform 可以更轻松地处理转换,因为它完全替换了现有的转换。因此,无需保存状态即可知道您在哪里。
在渲染对象时,它还可以帮助对象始终围绕其自己的旋转中心布局其坐标。您将该中心移动到需要它的地方。
无论如何,以下是您可以做到这一点的方法。该函数将处理不同的点计数,并且更有条理,没有不必要的关闭路径,保存从度到弧度的恢复和转换。
var ctx = canvas.getContext('2d');
var drawSun = function(x,y,rad,count) {
var drawRay = function(ang){
// Half width, note I get width from 2PI*r but as I need half I drop the 2
var width = (Math.PI * (rad + 5)) / count;
ctx.setTransform(1,0,0,1,x,y);
ctx.rotate(ang);
ctx.beginPath();
ctx.moveTo(-width, rad + 5);
ctx.lineTo(0, rad + 20);
ctx.lineTo(width, rad + 5);
ctx.fill();
}
ctx.fillStyle = "#F90";
ctx.setTransform(1,0,0,1,x,y); // move sun center to where it should be.
ctx.beginPath();
ctx.arc(0, 0, rad, 0, Math.PI * 2, true); // draw sun at 0,0
ctx.fill();
for (var i = 0; i < count; i++) {
drawRay((i / count) * Math.PI * 2);
// if you want to draw with first ray top center
// you need to offset by half a step
//drawRay(((i / count)-(count/2)) * Math.PI * 2);
}
// done and if you want you can reset to the default transform with
// ctx.setTransform(1,0,0,1,0,0);
}
drawSun(100,100,30,7);
<canvas id="canvas" width=200 height=200></canvas>