
本文详解如何通过监听 resize 事件动态更新 Canvas 的宽高属性,并同步重置绘图逻辑状态(如雨滴列数、位置数组),确保全屏背景动画在窗口缩放时始终保持铺满且渲染正确。
本文详解如何通过监听 `resize` 事件动态更新 canvas 的宽高属性,并同步重置绘图逻辑状态(如雨滴列数、位置数组),确保全屏背景动画在窗口缩放时始终保持铺满且渲染正确。
要实现 Canvas 随浏览器窗口实时自适应,关键在于区分 CSS 样式尺寸与 Canvas 内部像素尺寸:仅设置 canvas.style.width/height(如通过 CSS)会拉伸画布,导致模糊或变形;必须直接修改 canvas.width 和 canvas.height 属性,以重置其位图缓冲区分辨率。
在您的 background.js 中,初始尺寸设置正确(canvas.width = window.innerWidth;),但缺少对窗口缩放的响应机制。以下是完整、健壮的修复方案:
✅ 正确做法:监听 resize 并重置 Canvas 与状态
const canvas = document.getElementById('background_canvas');
const context = canvas.getContext('2d');
// 初始尺寸设置
function resizeCanvas() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}
// 初始化雨滴状态(需在 resize 后重新计算)
let fontSize = 16;
let columns;
let rainDrops;
function initRain() {
columns = Math.floor(canvas.width / fontSize);
rainDrops = Array(columns).fill(1);
}
// 首次初始化
resizeCanvas();
initRain();
// 监听窗口缩放,同步更新
window.addEventListener('resize', () => {
resizeCanvas();
initRain(); // 重要:重算列数 & 重置雨滴起始位置
});? 注意事项与最佳实践
- 避免 setTimeout 或防抖滥用:resize 事件高频触发,但 Canvas 重置开销极低,无需复杂节流;若后续加入复杂计算(如图像重采样),再考虑 requestAnimationFrame 或 debounce。
- CSS 定位保持一致:您已在 CSS 中设 position: fixed; top: 0; left: 0;,确保 Canvas 始终覆盖视口 —— 这是前提,无需额外调整。
- 清除旧动画帧:当前使用 setInterval 是可行的,但更推荐 requestAnimationFrame 以提升性能与同步性:
function animate() {
context.fillStyle = 'rgba(0, 0, 0, 0.05)';
context.fillRect(0, 0, canvas.width, canvas.height);
context.fillStyle = '#0F0';
context.font = `${fontSize}px Monocraft`;
for (let i = 0; i < rainDrops.length; i++) {
const text = alphabet.charAt(Math.floor(Math.random() * alphabet.length));
context.fillText(text, i * fontSize, rainDrops[i] * fontSize);
if (rainDrops[i] * fontSize > canvas.height && Math.random() > 0.975) {
rainDrops[i] = 0;
}
rainDrops[i]++;
}
requestAnimationFrame(animate);
}
animate(); // 启动动画- 字体加载保障:确保 @font-face 中的 Monocraft.ttf 路径正确且已加载完成,否则 context.font 可能回退到默认字体,影响视觉效果。
✅ 总结
Canvas 自适应 ≠ CSS 缩放,而是重置位图尺寸 + 重初始化依赖尺寸的状态变量。只需三步:
1️⃣ 监听 resize 事件;
2️⃣ 更新 canvas.width/height;
3️⃣ 重计算 columns 并重置 rainDrops 数组。
如此,无论用户缩放、旋转设备或拖拽窗口,您的「数字雨」背景都将精准铺满屏幕,保持清晰流畅的视觉体验。



















