围绕中心点旋转三角形而不重叠



我有一个 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>

最新更新