Canvas广告粒子需同步缓冲区尺寸、映射鼠标坐标、设置pointer-events: none防遮挡、适配高DPI并控制粒子数量,否则易模糊、错位或卡顿。

直接加 就行,但广告位通常窄、有容器限制、还要兼容老浏览器——不重设缓冲区尺寸、不处理坐标映射、不控制层级,粒子要么糊成一片,要么盖住按钮,要么在手机上完全不动。
canvas.width 和 canvas.height 必须手动同步容器尺寸
广告位很少全屏,比如一个 300x250 的 banner 容器,只靠 CSS 设置 width: 300px; height: 250px 不够。Canvas 的绘图缓冲区仍用默认 300x150,粒子运动范围被压缩,鼠标交互坐标全错。
正确做法是读取父容器尺寸并赋值给 Canvas 的原生属性:
const canvas = document.getElementById("ad-particles");
const container = canvas.parentElement;
const rect = container.getBoundingClientRect();
canvas.width = rect.width;
canvas.height = rect.height;
别忘了在 window.resize 时也重新执行——但广告 iframe 内可能监听不到主窗口事件,更稳妥的是用 ResizeObserver 监听容器本身:
- 如果广告跑在 iframe 里,
ResizeObserver是唯一可靠方式 - 不支持的旧浏览器(IE)需降级为定时轮询
offsetWidth/Height - 避免直接用
window.innerWidth,那会拉伸到整个视口
鼠标交互失效?先查坐标是否映射到 canvas 内部
广告常需要 hover 时粒子排斥、点击跳转,但 mousemove 拿到的 clientX/clientY 是页面坐标,不是 canvas 坐标。
必须减去 canvas 左上角相对于视口的偏移:
canvas.addEventListener("mousemove", (e) => {
const rect = canvas.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
// 后续用 x/y 做力场计算
});
常见坑:
- 容器用了
transform或position: relative,getBoundingClientRect()依然准确,不用额外补偿 - canvas 设了
border或padding,rect已包含,无需再减 - 高 DPI 屏幕(如 Retina)下没调用
ctx.scale(devicePixelRatio, devicePixelRatio),粒子会发虚,但坐标映射逻辑不变
z-index 层叠问题:粒子不能挡住广告按钮和文案
广告区域通常有 CTA 按钮、标题文案、甚至视频控件。粒子 canvas 默认是普通文档流元素,容易盖住内容。
关键 CSS 配置:
#ad-particles {
position: absolute;
top: 0;
left: 0;
z-index: 1; /* 确保低于按钮(z-index: 10)但高于背景(z-index: 0) */
pointer-events: none; /* 让鼠标穿透到下层按钮 */
}
注意点:
-
pointer-events: none是核心,否则 hover/click 全被 canvas 拦截 - 如果广告容器本身用了
overflow: hidden,确保 canvas 没被裁切——可加will-change: transform触发独立渲染层 - 不要用
z-index: -1,部分浏览器下会脱离 stacking context,导致层级失控
性能卡顿?优先砍粒子数量和连线逻辑
广告 JS 执行环境受限(尤其微信内嵌 WebView),300x250 区域里超过 60 个粒子就可能掉帧。
实测有效的优化项:
- 粒子数控制在
30–50,用Math.random() * 0.7 + 0.3控制透明度,视觉密度不减但 GPU 压力下降 - 禁用连线(
distance 那套)——广告位太小,连线几乎全屏覆盖,且计算开销大 - 动画循环用
requestAnimationFrame,但每帧只更新Math.min(5, particles.length)个粒子位置,其余保持静止或缓动 - 避免在
draw()里反复调用ctx.beginPath()和ctx.arc(),改用ctx.fillRect()绘制方形粒子,快 3 倍以上
真正难的不是让粒子动起来,而是让它在广告约束条件下不抢焦点、不拖慢页面、不糊、不溢出容器——这些细节没对齐,再酷的效果也会变成负体验。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











