淘客网站免费开源源码,随州seo优化,网站全是乱码,wordpress 缓慢beginPath
beginPath表示开始一个路径#xff0c;我们在上一章画弧的时候用到过好多次#xff0c;他的API非常简单#xff1a;
context.beginPath();
开始路径有2层意思#xff0c;一个就是本次绘制的起点是新的#xff08;不再是上次结束的点了#xff09;#xff0…beginPath
beginPath表示开始一个路径我们在上一章画弧的时候用到过好多次他的API非常简单
context.beginPath();
开始路径有2层意思一个就是本次绘制的起点是新的不再是上次结束的点了另外一个意思就是绘制的样式也是新的不再与之前的样式有关联。对于第一条上一个章节我们已经见识过了如果不开始一个新的路径那么描边弧线的时候就会有一条上次绘制结束到弧线开始时的连线当然moveTo可以避免但需要计算不方便。 现在考虑这么一个需求我们需要画3条线线的颜色分别是红绿蓝使用之前的知识你应该可以的你先试一下或许你写的代码是这样的
context.moveTo(10, 50);
context.lineTo(290, 50);
context.strokeStyle#FF0000;
context.stroke();context.moveTo(10, 75);
context.lineTo(290, 75);
context.strokeStyle#00FF00;
context.stroke();context.moveTo(10, 100);
context.lineTo(290, 100);
context.strokeStyle#0000FF;
context.stroke();
效果如下 我们发现颜色是错误的但是又不清楚哪里有问题了。难道是它的API有bug了吗?我们打断点然后单步执行看看上面三个stroke依次执行后的效果 我们可以看到当代码执行到红色以后是对的虽然把坐标系也变成红色了然后绿色执行后把绿色这条渲染对了但是又用绿色渲染了一下红色的那条线使得红色的线变成2者的叠加色了当绿色的执行完了以后把最后一条线描边成绿色但是又把前面的也渲染了一遍所以最终的颜色就是我们之前看到的。要让新的线不在绘制之前的就用beginPath来开启一个新的路径。看看我们使用后的效果
context.beginPath();
context.moveTo(10, 50);
context.lineTo(290, 50);
context.strokeStyle#FF0000;
context.stroke();context.beginPath();
context.moveTo(10, 75);
context.lineTo(290, 75);
context.strokeStyle#00FF00;
context.stroke();context.beginPath();
context.moveTo(10, 100);
context.lineTo(290, 100);
context.strokeStyle#0000FF;
context.stroke();效果如下 总结一下使用beginPath路径将不再与之前的联系绘制时也不再绘制之前的所以已绘制图案的样式不再叠加。
closePath
closePath是闭合路径注意是闭合路径而不是结束路径虽然目前的位置是在beginPath后面但是两者没什么关系它并不是endPath没有这个。
现在有需求需要描边一个45°的扇形你以你现在的技术完全可以胜任大笔一挥
context.beginPath();
context.moveTo(150, 75);
context.arc(150, 75, 80, Math.PI / 180 * 0, Math.PI / 180 * 45);
context.lineTo(150, 75);
context.stroke();
结果如下 效果不错挺满意的。现在我们观察倒数第二行代码我们使用context.lineTo(150, 75);画了一条回到圆心起点的线。在stroke的时候回到起点可以绘制出一个闭合的图形这种操作实在太多了为了简化这个步骤我们就可以使用closePath。现在直接把context.lineTo(150, 75);替换为context.closePath();你会发现效果是一样的这样就省去了自己计算起点位置的步骤了。我强烈建议在闭合路径的时候使用closePath。 需要顺便提醒一下填充fill的时候对于一个终点和起点没有闭合的路径默认会闭合了再去填充不然没得玩了如下。当然如果还有其他没有闭合的时候就比如平行的2个线段那么就真的没的完了他也“不会”绘制了。
context.beginPath();
context.moveTo(150, 75);
context.arc(150, 75, 80, Math.PI / 180 * 0, Math.PI / 180 * 45);
context.fill();
上面没有闭合直接填充结果和闭合了以后是一样的效果 点是否在路径内部
跟路径有关的一个常见问题就是需要判断点是否在一个路径的内部。canvas考虑到大家的这个需要给了大家提供了这样的API
// 坐标(x, y)是否在路径内部 如果在就返回true否则就返回false
context.isPointInPath(x, y);
这里需要注意的有三点
如果一个路径结束和开始的位置没有闭合判断的时候会按照闭合来处理如果结束点和开始点闭合后整个路径还没有闭合那么就返回false。strokeRect和fillRect不会保留绘制的矩形路径所以isPointInPath不能对他们进行判断可以使用rect代替。如果刚刚在路径所处的直线上那么需要根据线宽来决定如果路径内与线中心一侧的时候那么返回false其他的时候返回true举个例子比如线宽是1那么如果在线上说明是内部如果线宽是3那么在内部和前2个像素上是内部外面的一个像素是外部。
看了第三条你可能又会问那么就只想知道是否在线上怎么办那就可能会用到另一个API了
// 坐标(x, y)是否在描边上 如果在就返回true否则就返回false
context.isPointInStroke(x, y);
此时你可能还会问你只想知道是否在路径的内部根本不关心在不在描边上那么怎么办给你提醒一下把这两个API综合起来判断就可以了相信你一定可以做到的。此外这两个API比较简单就不再给出例子了感兴趣的同学可以自己研究下。
裁剪区域
路径学完了我们先额外插播一个小知识就是裁剪区域先看个例子我们先描边一个圆形再填充一个矩形
context.beginPath();
context.arc(150, 75, 40, Math.PI / 180 * 0, Math.PI / 180 * 360);
context.stroke();// 开始新的路径 与之前的不再有关系 如果不开始 下面的fill的时候会把上面圆也fill了
context.beginPath();
context.rect(150, 75, 40, 40);
context.fill();
结果如下 然后我们按照圆的样子裁剪矩形稍微修改一下代码
context.beginPath();
context.arc(150, 75, 40, Math.PI / 180 * 0, Math.PI / 180 * 360);
context.stroke();// 按照圆裁剪
context.clip();context.beginPath();
context.rect(150, 75, 40, 40);
context.fill(); 结果如下 这里需要注意的是裁剪也是基于路径来的所以strokeRect和fillRect是不生效的。 我们再画一个矩形
context.beginPath();
context.arc(150, 75, 40, Math.PI / 180 * 0, Math.PI / 180 * 360);
context.stroke();// 按照圆裁剪
context.clip();context.beginPath();
context.rect(150, 75, 40, 40);
context.fill();// 再画一个矩形
context.beginPath();
context.rect(190, 35, 80, 80);
context.fill();
结果 什么放错图了没错就是这个样子我们分析一下上面画了一个圆然后描边了然后按照圆裁剪那么下面画的第一个矩形会按照圆来裁剪没问题。然后画了第二个矩形那么问题来了这个矩形也被裁剪了那么怎么让第二个矩形不再裁剪呢如果后面的一直都被裁剪那么每裁剪一次就缩小一点点距离那多痛苦。
状态的保存于恢复
接下来就是我们的处理办法了如果裁剪前把当前状态保存了然后裁剪完第一个矩形后再把状态恢复了不是很好的解决了这个问题吗canvas也是这么做的
context.beginPath();
context.arc(150, 75, 40, Math.PI / 180 * 0, Math.PI / 180 * 360);
context.stroke();// 保存状态
context.save();context.clip();context.beginPath();
context.rect(150, 75, 40, 40);
context.fill();// 恢复之前保存的状态即没有裁剪时那个状态
context.restore();context.beginPath();
context.rect(190, 35, 80, 80);
context.fill();
结果 通常裁剪前一般都会保存路径的裁剪完后一般都会恢复的。除此之外保存与恢复也可以用在某些样式状态上还可以用在形变后面会讲到的类似与CSS3的transform的状态保存上。