分析的代码来自神神的蜗牛:https://blog.youkuaiyun.com/zhouzme/article/details/78894149
关键方法clearRect
Scratch.prototype.scratch = function(e) {
var position = this.getPosition(e);
var x = position.x - this.zone.left;
var y = position.y - this.zone.top + window.pageYOffset;
// 这部分是原作者的写法,清除类似一个喷漆枪的感觉,以一个圆心为中心随机清除点
// var i = 0;
// var len = this.options.nPoints;
// for(i; i<len; i++) {
// var points = this.clearPoint(x, y);
// this.ctx.clearRect(points.x, points.y, this.options.pointSize.x, this.options.pointSize.y);
// }
// parv2提供的方法,用clip更高效、简洁
var r = this.options.radius;
this.ctx.save();
this.ctx.beginPath();
this.ctx.arc(x + r, y + r, r, 0, 2 * Math.PI);
this.ctx.clip();
this.ctx.clearRect(x, y , 2 * r, 2 * r);
this.ctx.restore();
// 获取当前已清除区域所占比例
this.percent = this.getPercent();
};
options是配置, 传入的参数, nPoint是清除区域的杂点数量,radius清除区域的半径
beginPath() 方法开始一条路径,或重置当前的路径
clip()方法你可以理解为ps里面的选区,先在以点击坐标为圆心选择一个半径r的圆形选区,清除一块长2r,宽2r的方块时候,也不会影响到圆外的区域
关于save和restore
restore
将画布状态重置到save
保存时的样子。画布状态分为画布的坐标(transform
),画布绘制区域(clip
),画布中设置的组合方式(globalCompositeOperatio
)。当我们在使用transform,clip和globalCompositeOperatio
时会改变画布的状态,而这种改变会影响到接下来的画布绘制操作,所以在进行这种操作前需要使用save
来对画布进行一次保存,在进行改变状态后的下一步操作中使用restore
来重置画布状态
作者:闲余幽梦
链接:https://www.jianshu.com/p/dd0487ff4293
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
另一种解释:
save和restore是用于绘制环境的保存与还原,如果你不写这一对方法,你前面进行的操作就不会被还原,而是在原来的绘制环境(简单理解就是原图形)上进行新的操作,这样你第二次画的内容都是在原图上画的。clip与你第一次restore的顺序没有关系,你可以把每一帧的绘画放在一个save和restore之间,最重要的是你需要在clip前调用beginpath方法,如果不调用beginpath你每次的剪切圆不会消失而是一直保持在画面上