详述Canvas(四)/绘制曲线

来源: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>
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

对于arc中的startAngle和endAngle,注意是使用弧度表示,值的范围是0~2兀,弧度与角度之间的计算公式为:弧度 = 角度*兀/360。兀在JS中为Math.PI. 
这里写图片描述

如果我们将arc(110,110,100,0,Math.PI/2,false)中的false改为true,得到的图形如下: 
这里写图片描述

由此,我们可以得到一个非常重要的结论: 
true/false表示得不是角度旋转的方向,角度的计算始终是顺时针方向来计算的,仅仅代表的是绘制弧度的方向是顺时针绘制还是逆时针绘制。 
canvas中默认的0°方向是沿着X轴的正方向: 
这里写图片描述

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

这里写图片描述

可以看到arcTo画出的是起点到第一个坐标点,第一个坐标点到第二个坐标点的两条直线的一个圆弧,圆弧与这条切线相切。 
为了进一步确定,并研究半径对曲线的影响,我们改变一下上面的代码 
注:后面的代码中都使用这个格子,代码相同部分不再粘贴出来。

<script>
    palette.beginPath();
    palette.moveTo(50,250);
    palette.arcTo(50,100,300,100,100);
    palette.strokeStyle = "#FF0000";
    palette.lineWidth = 5;
    palette.stroke();
</script>
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

这里写图片描述

通过观察,感觉是以(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>
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

这里写图片描述

可以看出,(50,300)到(50,200)这段完全是直线,而尽管我们将结束点移至(300,100)的位置,但是弧线并未延长。如果补全这个圆的话,几乎应该是下图的蓝色圆,过了(150,100)切点之后,就要向下延伸了。 
因此,第二个结论,我认为是:圆弧的结束点,就是圆与第二条直线的切点。

这里写图片描述

当然,我们也可以尝试改变半径的大小,如我们将半径改为200。

这里写图片描述

另外一个需要注意的是,起点不能与第一个点重合,否则是不能画图圆弧的。

<script>
    palette.beginPath();
    palette.moveTo(50,100);
    palette.arcTo(50,100,300,100,100);
    palette.strokeStyle = "#FF0000";
    palette.lineWidth = 5;
    palette.stroke();
</script>
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

图上并未出现圆弧。 
这里写图片描述

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>
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

这里写图片描述

因为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>
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

一共涉及到四个点,起点:moveTo(x,y);终点,还有两个控制点。当两个控制点在起点和终点的两侧时,会得到S曲线,而当两个控制点在连线的一侧时,会得到曲线,效果类似quadraticCurveTo.当然,如果所有的点都在一条直线上,会得到一条直线,但是我想应该不会有人这么无聊吧。 
这里写图片描述

试试看两个控制点在一侧的情况

<script>
    palette.beginPath();
    palette.moveTo(50,150);
    palette.bezierCurveTo(100,50,200,80,250,100);
    palette.strokeStyle = "#FF0000";
    palette.lineWidth = 5;
    palette.stroke();
</script>
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值