2012-01-16 168 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/