HTML5 Canvas-Oreilly.Canvas.Pocket.Reference (4)

 

关于stroke和fill方法有两点值得特别注意。首先,两种方法的操

作都是基于当前路径的所有子路径上。如果我们像下面的代码

那样添加一条新的线段:
c.moveTo(300,100); // Begin a new subpath at (300,100)
c.lineTo(300,200); // Draw a vertical line to (300,200)
那么当我们想要画出两条相连的矩形边框和一条单独的垂直线

,我们得调用stroke方法。第二个指的注意的就是,stroke和fill两

种方法都不能修改当前的路径:当你之前调用了fill方法,过会

再调用stroke方法时,路径并不会发生任何变化。当一条路径完成的时候,需要调用beginPath方法开始绘制下一条路径。如果你不这么做,就会使得后面新建的子路径添加到了当前的路径上,这样你就会一遍一遍的绘制以前的路径。
例子1-1展示了正多边形的的画法,程序给我们展示了moveTo,lineTo的用法以及如何使用closePath方法定义一条新子路径、利用fill和stroke绘制这些路径。就这样,得到了1-3的图形。
Example 1-1. Regular polygons with moveTo(), lineTo(), and
closePath()
// Define a regular polygon with n sides, centered at (x,y)
// with radius r. The vertices are equally spaced along the
// circumference of a circle. Put the first vertex straight
// up or at the specified angle. Rotate clockwise, unless
// the last argument is true.
function polygon(c,n,x,y,r,angle,counterclockwise) {
angle = angle || 0;
counterclockwise = counterclockwise || false;
// Compute vertex position and begin a subpath there
c.moveTo(x + r*Math.sin(angle),
y - r*Math.cos(angle));
var delta = 2*Math.PI/n; // Angle between vertices
for(var i = 1; i < n; i++) { // For remaining vertices
// Compute angle of this vertex
angle += counterclockwise?-delta:delta;
// Compute position of vertex and add a line to it
c.lineTo(x + r*Math.sin(angle),
y - r*Math.cos(angle));
}
c.closePath(); // Connect last vertex back to the first
}
// Start a new path and add polygon subpaths
c.beginPath();
polygon(c, 3, 50, 70, 50); // Triangle
polygon(c, 4, 150, 60, 50, Math.PI/4); // Square
polygon(c, 5, 255, 55, 50); // Pentagon
polygon(c, 6, 365, 53, 50, Math.PI/6); // Hexagon
// Add a small counterclockwise square inside the hexagon
polygon(c, 4, 365, 53, 20, Math.PI/4, true);
// Set properties that control how the graphics will look
c.fillStyle = "#ccc"; // Light-gray interiors
c.strokeStyle = "#008"; // outlined with dark-blue lines
c.lineWidth = 5; // five pixels wide.
// Now draw all the polygons (each in its own subpath)
c.fill(); // Fill the shapes
c.stroke(); // And stroke their outlines

                                                                Figure 1-3. Regular polygons

 

注意到例子在一个六边形里面花了一个内嵌的正方形。方形和六边形其实是独立的子路径,但是两者却重叠了。当这种事情发生的时候(或者自身的线条相互交叉时),canvas画布需要知道两个路径,谁在内部,谁在外围。canvas画布采用了一种叫做“非零弯曲规则”去判别。这种情况下,因为六边形的绘图方向和方形相异,所以方形的内部并不会被填充。相异指的就是:六边形的顶点是顺时针相连,而方形的顶点却是逆时针相连接的。如果方形也是逆时针绘制的话,那么程序就会调用fill填充方形的内部。

 


                                                                                                                非零弯曲规则
为了判断一点P是否在路径的内部,利用非零弯曲规则,从P点任意画一条射线,无限延伸(或者终点取在路径的外边的一些散点)。现在定义一个计数器,初始值为0,列举出路径穿过射线的各种情况,每当路径顺时针穿过射线的时候,计数器加一。每当路径逆时针穿过射线的时候,计数器减一。当所有的情况均考虑后后,计数非0的话,点P在路径的内部,否则,点P在路径的外部。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值