2017-02-15 105 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>