saz*_*azr 5 javascript html5 bezier canvas
我试图绘制下面的3个箭头.我可以正确地绘制顶部,但我无法正确绘制其他2个箭头.我正在使用HTML5 Canvas绘制这些箭头.

我的arcTo调用出现问题.由于某种原因,我无法得到正确的曲线.也许我应该使用Bezier曲线?有人能告诉我我使用什么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>
Run Code Online (Sandbox Code Playgroud)
所以我们有了这条带箭头的道路.我注释了它:
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);
Run Code Online (Sandbox Code Playgroud)
我们真的希望保持尽可能相似,除非我们想要以不同于直线的方式到达端点(和返回).我们绝对不想使用moveTo除第一个之外的任何命令.这真的让事情变得混乱,让人难以理解.我也避免使用arcTo,除非你真的需要弧的一部分(比如在饼图中),因为它与其他路径命令相比相当混乱.
所以我们将使用像beziers一样的二次曲线,但只有一个控制点,这使得它们非常简单.它们通过指定这样的控制点(左侧)来工作.
所以我们采用相同的箭头代码并插入两个二次贝塞尔曲线来制作一个瘦箭头.我们希望控制点在箭头的质量"内部"排序,以使正方形向内弯曲:
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);
Run Code Online (Sandbox Code Playgroud)
或者是一个胖的,我们将控制点放在与最高点和最低点相同的高度,并且与端点在同一个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);
Run Code Online (Sandbox Code Playgroud)
这里的实例:http://jsfiddle.net/Yp7DM/
| 归档时间: |
|
| 查看次数: |
7214 次 |
| 最近记录: |