来源:http://blog.csdn.net/liuyan19891230/article/details/51253183
Canvas提供了4个绘制曲线的方法:
arc(x,y,stratAngle,endAngle,true/false);//默认为false
arcTo(x1,y1,x2,y2,r);
x1,y2坐标一,x2,y2坐标2,r是圆弧半径
quadraticCurveTo(dx,dy,x,y);
dx,dy控制点,x,y是结束点
bezierCurveTo(dx1,dy1,dx2,dy2,x,y);
dx1,dy1是控制点一,dx2,dy2是控制点二,x,y是结束点
1、arc(x,y,startAngle,endAngle,true/false)的用法。
<body>
<canvas id = "palette" width="300px" height="300px">
您的浏览器不支持canvas标签,请升级浏览器或更换其它浏览器
</canvas>
</body>
</html>
<script>
var palette = document.querySelector("#palette").getContext("2d");
palette.arc(100,100,100,0,Math.PI/2,false);
palette.fillStyle = "#229138";
palette.fill();
palette.strokeStyle = "#FF0000";
palette.lineWidth = 5;
palette.stroke();
</script>
对于arc中的startAngle和endAngle,注意是使用弧度表示,值的范围是0~2兀,弧度与角度之间的计算公式为:弧度 = 角度*兀/360。兀在JS中为Math.PI.
![这里写图片描述](https://img-blog.csdn.net/20160426190448227)
如果我们将arc(110,110,100,0,Math.PI/2,false)中的false改为true,得到的图形如下:
![这里写图片描述](https://img-blog.csdn.net/20160426190507672)
由此,我们可以得到一个非常重要的结论:
true/false表示得不是角度旋转的方向,角度的计算始终是顺时针方向来计算的,仅仅代表的是绘制弧度的方向是顺时针绘制还是逆时针绘制。
canvas中默认的0°方向是沿着X轴的正方向:
![这里写图片描述](https://img-blog.csdn.net/20160426190540501)
2、arcTo(x1,y1,x2,y2,r)的用法。
为了更好的看出效果,给canvas背景添加辅助线,每一格为50px*50px。
<body>
<canvas id = "palette" width="500px" height="500px">
您的浏览器不支持Canvas标签,请升级或更换浏览器
</canvas>
</body>
</html>
<script>
var palette = document.querySelector("#palette").getContext("2d")
palette.moveTo(0,0)
palette.lineTo(0,300)
palette.moveTo(50.5,0)
palette.lineTo(50.5,300)
palette.moveTo(100.5,0)
palette.lineTo(100.5,300)
palette.moveTo(150.5,0)
palette.lineTo(150.5,300)
palette.moveTo(200.5,0)
palette.lineTo(200.5,300)
palette.moveTo(250.5,0)
palette.lineTo(250.5,300)
palette.moveTo(300.5,0)
palette.lineTo(300.5,300)
palette.moveTo(0,0)
palette.lineTo(300,0)
palette.moveTo(0,50.5)
palette.lineTo(300,50.5)
palette.moveTo(0,100.5)
palette.lineTo(300,100.5)
palette.moveTo(0,150.5)
palette.lineTo(300,150.5)
palette.moveTo(0,200.5)
palette.lineTo(300,200.5)
palette.moveTo(0,250.5)
palette.lineTo(300,250.5)
palette.moveTo(0,300.5)
palette.lineTo(300,300.5)
palette.stroke()
palette.beginPath()
palette.moveTo(0,300.5)
palette.arcTo(50,100,200,50,100)
palette.strokeStyle = "#FF0000"
palette.lineWidth = 5
palette.stroke()
</script>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
![这里写图片描述](https://img-blog.csdn.net/20160426190618902)
可以看到arcTo画出的是起点到第一个坐标点,第一个坐标点到第二个坐标点的两条直线的一个圆弧,圆弧与这条切线相切。
为了进一步确定,并研究半径对曲线的影响,我们改变一下上面的代码
注:后面的代码中都使用这个格子,代码相同部分不再粘贴出来。
<script>
palette.beginPath()
palette.moveTo(50,250)
palette.arcTo(50,100,300,100,100)
palette.strokeStyle = "#FF0000"
palette.lineWidth = 5
palette.stroke()
</script>
![这里写图片描述](https://img-blog.csdn.net/20160426190823889)
通过观察,感觉是以(150,200)为圆心,半径为100画的圆弧,而(50,250)到(50,200)即起点到紫色的点部分仅仅是直线,这个紫色的点是canvas通过计算得到的点,如果这一段无法是弧线,那么就会直接是一段直线。
为了验证猜想,我们再改变一下上面的代码。
<script>
palette.beginPath()
palette.moveTo(50,300)
palette.arcTo(50,100,300,100,100)
palette.strokeStyle = "#FF0000"
palette.lineWidth = 5
palette.stroke()
</script>
![这里写图片描述](https://img-blog.csdn.net/20160426190943768)
可以看出,(50,300)到(50,200)这段完全是直线,而尽管我们将结束点移至(300,100)的位置,但是弧线并未延长。如果补全这个圆的话,几乎应该是下图的蓝色圆,过了(150,100)切点之后,就要向下延伸了。
因此,第二个结论,我认为是:圆弧的结束点,就是圆与第二条直线的切点。
![这里写图片描述](https://img-blog.csdn.net/20160426191024408)
当然,我们也可以尝试改变半径的大小,如我们将半径改为200。
![这里写图片描述](https://img-blog.csdn.net/20160426191233925)
另外一个需要注意的是,起点不能与第一个点重合,否则是不能画图圆弧的。
<script>
palette.beginPath()
palette.moveTo(50,100)
palette.arcTo(50,100,300,100,100)
palette.strokeStyle = "#FF0000"
palette.lineWidth = 5
palette.stroke()
</script>
图上并未出现圆弧。
![这里写图片描述](https://img-blog.csdn.net/20160426191313725)
3、quadraticCurveTo(dx,dy,x,y)的用法。
<script>
palette.beginPath()
palette.moveTo(50,200)
palette.quadraticCurveTo(100,100,250,250)
palette.strokeStyle = "#FF0000"
palette.lineWidth = 5
palette.stroke()
</script>
![这里写图片描述](https://img-blog.csdn.net/20160426191345585)
因为quadraticCurveTo(dx,dy,x,y)只有一个控制点,最多只能画出图示的曲线,而不能画出S形曲线,引入bezierCurveTo(dx1,dy1,dx2,dy2,x,y)
4、bezierCurveTo(dx1,dy1,dx2,dy2,x,y)的用法。
<script>
palette.beginPath()
palette.moveTo(50,150)
palette.bezierCurveTo(100,50,200,200,250,100)
palette.strokeStyle = "#FF0000"
palette.lineWidth = 5
palette.stroke()
</script>
一共涉及到四个点,起点:moveTo(x,y);终点,还有两个控制点。当两个控制点在起点和终点的两侧时,会得到S曲线,而当两个控制点在连线的一侧时,会得到曲线,效果类似quadraticCurveTo.当然,如果所有的点都在一条直线上,会得到一条直线,但是我想应该不会有人这么无聊吧。
![这里写图片描述](https://img-blog.csdn.net/20160426191435457)
试试看两个控制点在一侧的情况
<script>
palette.beginPath()
palette.moveTo(50,150)
palette.bezierCurveTo(100,50,200,80,250,100)
palette.strokeStyle = "#FF0000"
palette.lineWidth = 5
palette.stroke()
</script>
![这里写图片描述](https://img-blog.csdn.net/20160426191504712)