2012-01-16 140 views
5

畫箭揚程曲線,我試圖提取低於3個箭頭。我可以正確繪製頂部,但無法正確繪製其他2個箭頭。我使用HTML5 Canvas繪製這些箭頭。在HTML5畫布

enter image description here

的問題時我包含arcTo電話。由於某些原因,我無法獲得正確的曲線。也許我應該使用貝塞爾曲線? 任何人都可以告訴我用什麼HTML5/Javascript函數來生成上面的箭頭?

你能否提供瞭如何實現上述箭頭頭的例子嗎?

繼承人的的jsfiddle顯示怎麼回事錯誤:http://jsfiddle.net/hJX8X/

<canvas id="testCanvas" width="400px" height="400px"> 

</canvas> 
<script type="text/javascript"> 
<!-- 
    var canvas = document.getElementById("testCanvas"); 
    var dc  = canvas.getContext("2d"); 

    // Points which are correct (when I draw straight lines its a perfect arrow 
    var width = 400; 
    var height = 100; 
    var arrowW = 0.35 * width; 
    var arrowH = 0.75 * height; 
    var p1  = {x: 0,    y: (height-arrowH)/2}; 
    var p2  = {x: (width-arrowW), y: (height-arrowH)/2}; 
    var p3  = {x: (width-arrowW), y: 0}; 
    var p4  = {x: width,   y: height/2}; 
    var p5  = {x: (width-arrowW), y: height}; 
    var p6  = {x: (width-arrowW), y: height-((height-arrowH)/2)}; 
    var p7  = {x: 0,    y: height-((height-arrowH)/2)}; 

    dc.clearRect(0, 0, canvas.width, canvas.height); 
    dc.fillStyle = "#FF0000"; 

    dc.beginPath(); 

    dc.moveTo(p1.x, p1.y); 
    dc.lineTo(p2.x, p2.y); 
    dc.lineTo(p3.x, p3.y);  
    dc.moveTo(p3.x, p3.y); 
    dc.arcTo(p3.x, p3.y, p4.x, p4.y, 50); 
    dc.moveTo(p4.x, p4.y); 
    dc.arcTo(p4.x, p4.y, p5.x, p5.y, 50); 
    dc.moveTo(p5.x, p5.y); 
    dc.lineTo(p6.x, p6.y); 
    dc.lineTo(p7.x, p7.y); 

    dc.closePath(); 
    dc.fill(); 

    /* Draw arrow without curves 
    dc.moveTo(p1.x, p1.y); 
    dc.lineTo(p2.x, p2.y); 
    dc.lineTo(p3.x, p3.y);  
    dc.lineTo(p4.x, p4.y); 
    dc.lineTo(p5.x, p5.y); 
    dc.lineTo(p6.x, p6.y); 
    dc.lineTo(p7.x, p7.y); 
    */ 
--> 
</script> 
+0

可以提供@rkmax我已經發布了的jsfiddle預期的結果 – rkmax 2012-01-16 04:05:20

+0

的例子(圖)現在證明我的努力,箭頭太蹲下 – 2012-01-16 04:12:53

回答

9

因此,我們已經得到了這條道路,使一個箭頭。我註釋它:

dc.moveTo(p1.x, p1.y); 
dc.lineTo(p2.x, p2.y); // end of main block 
dc.lineTo(p3.x, p3.y); // topmost point  
dc.lineTo(p4.x, p4.y); // endpoint 
dc.lineTo(p5.x, p5.y); // bottommost point 
dc.lineTo(p6.x, p6.y); // end at bottom point 
dc.lineTo(p7.x, p7.y); 

我們真的想保持它儘可能相似,除了我們想要得到的端點(反面)中不僅僅是一個直線的方式不同。我們絕對不希望使用除第一個任意moveTo命令。這真的讓事情變得混亂,讓他們很難理解。我也避免使用arcTo,除非你真的需要弧的一部分(就像在一個餅圖中),因爲與其他路徑命令相比,它相當混亂。

所以我們使用二次曲線這是像濟耶,但只能有一個控制點,使它們非常簡單。他們通過指定一個控制點,如this (on the left)來工作。

所以我們採取完全相同的箭頭代碼,然後插入兩個二次貝濟耶做一個瘦小的箭頭。我們希望控制點是八九不離十「內部」的箭頭的質量,使二次方程式向內彎曲:

dc.moveTo(p1.x, p1.y); 
dc.lineTo(p2.x, p2.y); // end of main block 
dc.lineTo(p3.x, p3.y); // topmost point 
// control point is based on p3 (topmost point) 
dc.quadraticCurveTo(p3.x + 20, p3.y + 30, p4.x, p4.y); // endpoint 
// control point is based on p5 (bottommost point) 
dc.quadraticCurveTo(p5.x + 20, p5.y - 30, p5.x, p5.y); // bottommost point 
dc.lineTo(p6.x, p6.y); // end at bottom point 
dc.lineTo(p7.x, p7.y); 

還是個胖子,我們把控制點在同一高度的最上面和最下面的點,和周圍的一樣X作爲終點:

dc.beginPath(); 
// Draw arrow without curves 
dc.moveTo(p1.x, p1.y); 
dc.lineTo(p2.x, p2.y); // end of main block 
dc.lineTo(p3.x, p3.y); // topmost point 
// control point is based on p3 (topmost point) 
dc.quadraticCurveTo(p3.x + 120, p3.y, p4.x, p4.y); // endpoint 
// control point is based on p5 (bottommost point) 
dc.quadraticCurveTo(p5.x + 120, p5.y, p5.x, p5.y); // bottommost point 
dc.lineTo(p6.x, p6.y); // end at bottom point 
dc.lineTo(p7.x, p7.y); 
這裏

活生生的例子:http://jsfiddle.net/Yp7DM/