2017-02-15 64 views
0

我有一个400x300的HTML画布,我试图用圆和7个三角形绘制太阳。要绘制三角形,我按照this SO Answer上的指示做翻译,旋转,翻译。然而,一些三角形重叠,就好像它们具有相同的角度。围绕中心点旋转三角形而不重叠

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(); 
    } 
} 

回答

2

有时候这里的答案有很多点,但实际上并不是那么好。使用ctx.setTransform可以更轻松地处理转换,因为它完全取代了现有的转换。因此,没有必要保存状态来知道你在哪里。

它也有助于渲染对象始终围绕自己的旋转中心布局它们的坐标。您将该中心移到您需要的地方。

反正下面是你如何做到这一点。该函数将处理不同的点数,并且组织更简单一些,没有不必要的关闭路径,保存恢复并从Deg转换为弧度。

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>