2.2 绘制复杂图形
前面了解了基本图形的绘制方法,下面我们来看看复杂图形该如何绘制。
2.2.1 画曲线
贝塞尔曲线,又称贝兹曲线或贝济埃曲线,是应用于二维图形应用程序的数学曲线。在这里我们不研究贝塞尔曲线的原理,主要介绍在Canvas中如何绘制它。
1 . 二次贝塞尔曲线
二次贝塞尔曲线有一个控制点。在Canvas中用quadraticCurveTo(cpx,cpy,x,y)函数来绘制二次贝塞尔曲线,cpx、cpy表示控制点的坐标;x、y表示终点坐标。
它的绘制如代码清单2-11所示。
代码清单 2-11
<script type="text/javascript">
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.beginPath();
ctx.moveTo(100,100);
ctx.quadraticCurveTo(20,50,200,20);
ctx.stroke();
</script>
绘制效果如图2-11所示。
图2-12所示是它的原理图。
2 . 三次贝塞尔曲线
三次贝塞尔曲线与二次贝塞尔曲线的区别在于,三次贝塞尔曲线有两个控制点,如代码清单2-12所示。
代码清单 2-12
<script type="text/javascript">
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.moveTo(68, 130);
var cX1 = 20;
var cY1 = 10;
var cX2 = 268;
var cY2 = 10;
var endX = 268;
var endY = 170;
ctx.bezierCurveTo(cX1, cY1, cX2,cY2, endX, endY);
ctx.stroke();
</script>
绘制效果如图2-13所示。
图2-14所示是它的原理图。
2.2.2 利用clip在指定区域绘图
clip函数使用当前路径作为连续绘制操作的剪切区域。我们可以把它看作一扇窗户,无论在画板上绘制了多大的图形,最后看到的图形都只能由clip这扇窗户来决定。
为了更容易理解,我们看代码清单2-13。
代码清单 2-13
<script type="text/javascript">
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.arc(100,100,40,0,360*Math.PI/180,true);
ctx.clip();
ctx.beginPath();
//设定颜色
ctx.fillStyle="lightblue";
//绘制矩形
ctx.fillRect(0,0,300,150);
</script>
在这里,我们首先用arc画了一个圆,然后加入clip函数,最后又画了一个矩形,最后的效果如图2-15所示。
可以看到,虽然我们画了一个矩形,但是最后出现的图形里并没有矩形。这是因为首先绘制的是一个圆,然后clip函数将当前的这个圆作为绘制操作的区域,所以之后画出的图形只能显示在这个区域内。也就是说,即使一间房子再大,可是它的窗户很小,最后我们透过这扇窗户能够看到的空间也就只有窗户这么大。所以代码清单中画出的大矩形只能显示出图2-15所示的效果了。
2.2.3 绘制自定义图形
所谓自定义图形,是指将上面讲到的各种方法结合起来,实现一些特殊的图形。比如代码清单2-14。
代码清单 2-14
<script type="text/javascript">
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.beginPath();
ctx.moveTo(100, 150);
ctx.bezierCurveTo(50, 100, 100, 0, 150, 50);
ctx.bezierCurveTo(200, 0, 250, 100, 200, 150);
ctx.bezierCurveTo(250, 200, 200, 300, 150, 250);
ctx.bezierCurveTo( 100, 300, 50, 200,100, 150);
ctx.closePath();
ctx.moveTo(100, 150);
ctx.lineTo(150, 50);
ctx.lineTo(200, 150);
ctx.lineTo(150, 250);
ctx.lineTo(100, 150);
ctx.lineWidth = 5;
ctx.strokeStyle = "#ff0000";
ctx.stroke();
</script>
上面代码绘制的自定义图形如图2-16所示。