电话
400 9058 355
Canvas马赛克原理是通过getImageData获取像素数据,将每个块(如8×8)替换为左上角像素颜色;需同源、图片加载完成;块尺寸影响性能与效果,建议从8起步并做坐标对齐;动态更新应仅重绘变化区域并用requestAnimationFrame节流;移动端需换算触摸坐标,iOS需注意内存限制。
马赛克不是靠 CSS 滤镜,HTML5 里真正可控的实现方式是操作 canvas 的像素数据。核心就是:把一块区域内的所有像素,替换成该区域左上角(或平均)像素的颜色。
关键限制在于:getImageData 只能在同源 canvas 上调用,跨域图片会触发安全错误;且必须等图片完全加载(img.onload)后再绘图,否则读到的是空数据。
ctx.drawImage(img, 0, 0)
把图片画进离屏 canvasctx.getImageData(x, y, width, height) 获取目标区域原始像素ctx.putImageData() 写回块尺寸不是越大越好。16×16 看起来“糊”,但处理快;4×4 更细腻,但循环量翻 16 倍。实际建议从 blockSize = 8 起手调试。
注意:块尺寸必须能整除目标区域宽高,否则边缘会被截断。更稳妥的做法是用 Math.floor 对坐标做对齐:
const x0 = Math.floor(x / blockSize) * blockSize; const y0 = Math.floor(y / blockSize) * blockSize;
这样无论鼠标点在哪,都能自动吸附到最近的马赛克格子起点。
如果想让马赛克随鼠标移动实时更新(比如打码工具),别在 mousemove 里直接重绘整张图——太卡。只重绘变化区域即可:
lastRect = {x, y, w, h}
newRect,用 unionRect 合并两个区域作为重绘范围getImageData → 处理 → putImageData
requestAnimationFrame 节流,避免帧率暴跌漏掉这一步,小图都可能掉到 10fps 以下。
在 iPhone 或安卓浏览器里,touchstart 的 clientX/clientY 是视口坐标,不是 canvas 像素坐标。必须换算:
const rect = canvas.getBoundingClientRect(); const x = (e.touches[0].clientX - rect.left) * (canvas.width / rect.width); const y = (e.touches[0].clientY - rect.top) * (canvas.height / rect.height);
不处理这个,手指点的位置和马赛克出现的位置会严重错位,尤其页面有缩放或滚动时。另外 iOS Safari 对 getImageData 的内存限制更严,块尺寸超过 32 容易直接崩溃。
邮箱:8955556@qq.com
Q Q:8955556
本文详解如何将Go官方present工具(用于生成HTML5...
PySNMP在不同版本中对SNMP错误状态(errorSta...
time.Sleep仅阻塞当前goroutine,其他gor...
PHPfopen()创建含特殊符号的文件名失败主因是操作系统...
WooCommerce中通过代码为分组产品动态聚合子商品的属...
io.ReadFull返回io.ErrUnexpectedE...
本文详解Yii2中控制器向视图传递ActiveRecord数...
本文详解为何通过wp_set_object_terms()为...
Pytest中使用@mock.patch类装饰器会导致补丁泄...
带缓冲的channel是并发安全的FIFO队列;make(c...