html5 canvas 橡皮擦
2015年02月12日 11:07
0 点赞
0 评论
更新于 2025-11-21 16:17
许久未和大家分享关于 HTML5 技术的文章了,之前我专注于研究 jQuery 插件。这次在博客园偶然看到一篇文章,觉得十分有趣,便分享给大家。对技术研究感兴趣的朋友可以深入钻研,我认为这个橡皮擦功能非常实用。
关键代码
// 通过修改 globalCompositeOperation 来达到擦除的效果
function tapClip() {
var hastouch = "ontouchstart" in window ? true : false,
tapstart = hastouch ? "touchstart" : "mousedown",
tapmove = hastouch ? "touchmove" : "mousemove",
tapend = hastouch ? "touchend" : "mouseup";
canvas.addEventListener(tapstart, function (e) {
clearTimeout(timeout);
e.preventDefault();
var x1 = hastouch ? e.targetTouches[0].pageX : e.clientX - canvas.offsetLeft;
var y1 = hastouch ? e.targetTouches[0].pageY : e.clientY - canvas.offsetTop;
ctx.lineCap = "round"; // 设置线条两端为圆弧
ctx.lineJoin = "round"; // 设置线条转折为圆弧
ctx.lineWidth = a * 2;
ctx.globalCompositeOperation = "destination-out";
ctx.save();
ctx.beginPath();
ctx.arc(x1, y1, 1, 0, 2 * Math.PI);
ctx.fill();
ctx.restore();
canvas.addEventListener(tapmove, tapmoveHandler);
canvas.addEventListener(tapend, function () {
canvas.removeEventListener(tapmove, tapmoveHandler);
timeout = setTimeout(function () {
var imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
var dd = 0;
for (var x = 0; x < imgData.width; x += 30) {
for (var y = 0; y < imgData.height; y += 30) {
var i = (y * imgData.width + x) * 4 + 3;
if (imgData.data[i] > 0) {
dd++;
}
}
}
if (dd / (imgData.width * imgData.height / 900) < 0.4) {
canvas.className = "noOp";
}
}, 100);
});
function tapmoveHandler(e) {
e.preventDefault();
var x2 = hastouch ? e.targetTouches[0].pageX : e.clientX - canvas.offsetLeft;
var y2 = hastouch ? e.targetTouches[0].pageY : e.clientY - canvas.offsetTop;
ctx.save();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.stroke();
ctx.restore();
x1 = x2;
y1 = y2;
}
});
}
代码解释
- 事件判断:首先通过判断
ontouchstart是否存在于window对象中,来确定设备是否支持触摸事件。根据判断结果,为触摸和鼠标操作分别设置不同的事件类型(tapstart、tapmove、tapend)。 - 起始事件处理:当触发起始事件(
tapstart)时,会清除之前设置的定时器,阻止默认事件行为。记录起始点的坐标(x1和y1),并设置线条的样式(两端为圆弧、转折为圆弧、线条宽度),同时将globalCompositeOperation设置为destination-out,该属性用于实现擦除效果。 - 绘制初始点:保存当前绘图状态,开始新的路径,绘制一个半径为 1 的圆形并填充,然后恢复绘图状态。
- 移动和结束事件处理:添加移动事件(
tapmove)和结束事件(tapend)的监听器。在移动事件处理函数中,记录当前点的坐标(x2和y2),从起始点绘制线条到当前点,更新起始点坐标。在结束事件处理函数中,移除移动事件监听器,并设置一个定时器,在 100 毫秒后检查画布上的像素数据,根据剩余不透明像素的比例来决定是否添加noOp类名。
这段代码利用 HTML5 Canvas 的特性,结合事件处理和绘图操作,实现了一个简单的橡皮擦功能。