应用场景
我们的项目中有个功能是,canvas上的某个图片选中后可以再这个图片上用鼠标拖拽绘制画笔线条。
当然绘制的边界要控制在图片大小范围内的,那么鼠标是可以随意动的,怎么能控制只在图片上的时候才绘制呢?
Canvas 2D API 有直接提供的方法:CanvasRenderingContext2D
.isPointInPath()
用于判断在当前路径中是否包含检测点的方法。
isPointInPath介绍
语法:
boolean ctx.isPointInPath(x, y); boolean ctx.isPointInPath(x, y, fillRule); boolean ctx.isPointInPath(path, x, y); boolean ctx.isPointInPath(path, x, y, fillRule);
参数:
x | 检测点的X坐标 | |
y | 检测点的Y坐标 | |
fillRule | 用来决定点在路径内还是在路径外的算法。 |
|
返回值:
一个Boolean值,当检测点包含在当前或指定的路径内,返回 true;否则返回 false。
非零环绕原则
规则是从点引出任意一条射线,与路径交点结果计算,如果计数不为0,那么此点就在路径范围里面,在调用fill()方法时,浏览器就会对其进行填充。如果最终值是0,那么此区域就不在路径范围内,浏览器就不会对其进行填充。
首先,我们得给图形确定一条路径,只要“一笔画”并且“不走重复路线”就可以了。如图,标出的是其中的一种路径方向。我们先假定路径的正方向(逆时针)为1,那么反方向(顺时针)就是其相反数-1。(整个定义可以反过来的,正方向为顺时针,反方向为逆时针)
接下来,我们就来判断了。
点P1中引出的任意一条射线L1,与一条正方向路径相交,那么我们就给计数器+1,结果为+1,所以点P1在外面。
点P2中引出的任意一条射线L2,与两条子路径的正方向相交,计数器+2,结果为+2,所以点P2在外面。
点P3中引出的任意一条射线L3,与两条子路径相交,但是其中有一条的反方向,计数器+1-1,结果为0,所以点P3在里面。
点P4中引出的任意一条射线L4,与一条子路径相交,路径为反方向,计数器-1,结果为-1,所以点P4在外面。
只要结果不为0,判断的点就在区域的外面。结果为0,点在区域里面(绿色区域)
奇偶环绕原则
奇偶环绕原则理解为:
平面内的任何一点P,引出一条射线,注意不要经过多边形的顶点,如果射线与多边形的交点的个数为奇数,则点P在多边形的内部;如果交点的个数为偶数,则点P在多边形的外部。
我们用这个方法判断的结果是:
P1,P4与路径交点为1,所以是在里面
P2,P3与路径交点为2,所以实在外面
isPointInStroke检测某点是否在路径的描边线上
isPointInStroke()
。boolean ctx.isPointInStroke(x, y);