头闻号

义乌市少本电子商务商行

综合性公司

首页 > 新闻中心 > 科技常识:详解HTML5 Canvas绘制不规则图形时的非零环绕原则
科技常识:详解HTML5 Canvas绘制不规则图形时的非零环绕原则
发布时间:2024-09-22 06:52:12        浏览次数:4        返回列表

今天小编跟大家讲解下有关详解HTML5 Canvas绘制不规则图形时的非零环绕原则 ,相信小伙伴们对这个话题应该有所关注吧,小编也收集到了有关详解HTML5 Canvas绘制不规则图形时的非零环绕原则 的相关资料,希望小伙伴们看了有所帮助。

路径方向与非零环绕原则平时我们画的图形都是规规矩矩的 那么如果我们用线条画了个抽象派作品 就像下面这图一样 童鞋们知道怎么用fill()染色呢

这里就要用到数学上的一个方法——非零环绕原则 来判断哪块区域是里面 哪块区域是外面。接下来 我们具体来看下什么是非零环绕原则。

首先 我们得给图形确定一条路径 只要“一笔画”并且“不走重复路线”就可以了。如图 标出的是其中的一种路径方向。我们先假定路径的正方向为1(其实为-1啥的也都可以 正负方向互为相反数 不是0就行) 那么反方向就是其相反数-1。然后 我们在子路径切割的几块区域内的任意一点各取一条方向任意的射线 这里我只取了三个区域的射线为例 来判断这三块区域是“里面”还是“外面”。接下来 我们就来判断了。S1中引出的射线L1 与S1的子路径的正方向相交 那么我们就给计数器+1 结果为+1 在外面。S2中引出的射线L2 与两条子路径的正方向相交 计数器+2 结果为+2 在外面。S3中引出的射线L3 与两条子路径相交 但是其中有一条的反方向 计数器+1-1 结果为0 在里面。没错 只要结果不为0 该射线所在的区域就在外面。

绘制圆环记得arc方法吗 它的最后一个参数就是判断是路径方向的 如果是路径相反的两个同心圆在一起 图上色会有什么神奇的效果呢

下面我们通过代码来实现它。

Javascript Code复制内容到剪贴板 <!DOCTYPEhtml> <htmllang="zh"> <head> <metacharset="UTF-8"> <title>圆环</title> <style> body{background:url("./images/bg3.jpg")repeat;} #canvas{border:1pxsolid#aaaaaa;display:block;margin:50pxauto;} </style> </head> <body> <divid="canvas-warp"> <canvasid="canvas"> 你的浏览器居然不支持Canvas !赶快换一个吧!! </canvas> </div> <script> window.onload=function(){ varcanvas=document.getElementById("canvas"); canvas.width=800; canvas.height=600; varcontext=canvas.getContext("2d"); context.fillStyle="#FFF"; context.fillRect(0,0,800,600); context.shadowColor="#545454"; context.shadowOffsetX=5; context.shadowOffsetY=5; context.shadowBlur=2; context.arc(400,300,200,0,Math.PI*2,false); context.arc(400,300,230,0,Math.PI*2,true); context.fillStyle="#00AAAA"; context.fill(); }; </script> </body> </html>

运行结果:

镂空剪纸效果接下来 我们利用非零环绕原则和阴影来绘制一个镂空的剪纸效果。

Javascript Code复制内容到剪贴板 <!DOCTYPEhtml> <htmllang="zh"> <head> <metacharset="UTF-8"> <title>镂空剪纸效果</title> <style> body{background:url("./images/bg3.jpg")repeat;} #canvas{border:1pxsolid#aaaaaa;display:block;margin:50pxauto;} </style> </head> <body> <divid="canvas-warp"> <canvasid="canvas"> 你的浏览器居然不支持Canvas !赶快换一个吧!! </canvas> </div> <script> window.onload=function(){ varcanvas=document.getElementById("canvas"); canvas.width=800; canvas.height=600; varcontext=canvas.getContext("2d"); context.fillStyle="#FFF"; context.fillRect(0,0,800,600); context.beginPath(); context.rect(200,100,400,400); drawPathRect(context,250,150,300,150); drawPathTriangle(context,345,350,420,450,270,450); context.arc(500,400,50,0,Math.PI*2,true); context.closePath(); context.fillStyle="#058"; context.shadowColor="gray"; context.shadowOffsetX=10; context.shadowOffsetY=10; context.shadowBlur=10; context.fill(); }; //逆时针绘制矩形 functiondrawPathRect(cxt,x,y,w,h){ cxt.moveTo(x,y); cxt.lineTo(x,y+h); cxt.lineTo(x+w,y+h); cxt.lineTo(x+w,y); cxt.lineTo(x,y); } //逆时针绘制三角形 functiondrawPathTriangle(cxt,x1,y1,x2,y2,x3,y3){ cxt.moveTo(x1,y1); cxt.lineTo(x3,y3); cxt.lineTo(x2,y2); cxt.lineTo(x1,y1); } </script> </body> </html>

运行结果:

这里手动绘制矩形的原因是我们想要得到逆时针路径的矩形 而且API提供的rect()方法绘制是顺时针矩形。另外 需要注意的是 这个剪纸是一个图形 一个路径。不能在绘制镂空三角形和绘制镂空矩形的方法里使用beginPath()和closePath() 不然它们就会是新的路径、新的图形 而不是剪纸的子路径、子图形 就无法使用非零环绕原则。

来源:爱蒂网