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;
}
});
}

代码解释

  1. 事件判断:首先通过判断 ontouchstart 是否存在于 window 对象中,来确定设备是否支持触摸事件。根据判断结果,为触摸和鼠标操作分别设置不同的事件类型(tapstarttapmovetapend)。
  2. 起始事件处理:当触发起始事件(tapstart)时,会清除之前设置的定时器,阻止默认事件行为。记录起始点的坐标(x1y1),并设置线条的样式(两端为圆弧、转折为圆弧、线条宽度),同时将 globalCompositeOperation 设置为 destination-out,该属性用于实现擦除效果。
  3. 绘制初始点:保存当前绘图状态,开始新的路径,绘制一个半径为 1 的圆形并填充,然后恢复绘图状态。
  4. 移动和结束事件处理:添加移动事件(tapmove)和结束事件(tapend)的监听器。在移动事件处理函数中,记录当前点的坐标(x2y2),从起始点绘制线条到当前点,更新起始点坐标。在结束事件处理函数中,移除移动事件监听器,并设置一个定时器,在 100 毫秒后检查画布上的像素数据,根据剩余不透明像素的比例来决定是否添加 noOp 类名。

这段代码利用 HTML5 Canvas 的特性,结合事件处理和绘图操作,实现了一个简单的橡皮擦功能。

作者信息

boke

boke

共发布了 3994 篇文章