
本文详解如何通过监听 resize 事件动态调整 <canvas> 元素的宽高,并同步重置绘图逻辑状态,确保全屏背景动画(如矩阵雨)始终适配视口尺寸。
本文详解如何通过监听 `resize` 事件动态调整 `
要实现 Canvas 随浏览器窗口实时自适应缩放,关键在于两点:正确设置 canvas 的像素宽高(canvas.width/canvas.height) 和 及时重置依赖尺寸的绘图状态(如列数、雨滴位置数组等)。仅修改 CSS 样式(如 width: 100vw; height: 100vh)无法改变 canvas 的渲染分辨率,会导致图像拉伸模糊;必须操作 canvas 元素的 DOM 属性 width 和 height,以重置其内部位图缓冲区。
在 background.js 中,需将初始尺寸设置与 resize 事件监听逻辑整合。以下是优化后的完整代码片段:
const canvas = document.getElementById('background_canvas');
const context = canvas.getContext('2d');
// 初始化尺寸与绘图状态
const fontSize = 16;
let columns;
let rainDrops;
const resizeCanvas = () => {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
columns = Math.floor(canvas.width / fontSize);
rainDrops = Array(columns).fill(1);
};
// 首次初始化
resizeCanvas();
// 监听窗口缩放,动态重置
window.addEventListener('resize', () => {
resizeCanvas();
});
// 主绘制循环
const draw = () => {
// 清空画布(使用透明度实现拖尾效果)
context.fillStyle = 'rgba(0, 0, 0, 0.05)';
context.fillRect(0, 0, canvas.width, canvas.height);
context.fillStyle = '#0F0';
context.font = `${fontSize}px Monocraft, monospace`; // 注意字体名一致性
for (let i = 0; i < rainDrops.length; i++) {
const text = 'アァカサタナハマヤャラワガザダバパイィキシチニヒミリヰギジヂビピウゥクスツヌフムユュルグズブヅプエェケセテネヘメレヱゲゼデベペオォコソトノホモヨョロヲゴゾドボポヴッンABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
.charAt(Math.floor(Math.random() * 128));
context.fillText(text, i * fontSize, rainDrops[i] * fontSize);
if (rainDrops[i] * fontSize > canvas.height && Math.random() > 0.975) {
rainDrops[i] = 0;
}
rainDrops[i]++;
}
};
setInterval(draw, 30);⚠️ 重要注意事项:
- 避免 CSS 与 JS 尺寸冲突:确保 CSS 中不要用 width/height 设置 canvas 的布局尺寸(当前 .background canvas 规则中 width: auto; height: auto; 是合理的),否则可能覆盖 JS 设置的像素值;若需响应式布局,应仅用 position: fixed; top: 0; left: 0; 等定位属性,让 canvas 布满视口。
- 字体加载保障:Monocraft 字体需确保已成功加载(可通过 document.fonts.load() 检测),否则回退到系统等宽字体。
- 性能优化建议:高频 resize 事件可能触发多次,可添加防抖(debounce)逻辑(如 setTimeout 延迟执行),但对简单全屏 canvas 场景影响较小,可暂不引入。
- 移动端兼容性:添加 viewport meta 标签(当前 HTML 已包含)并测试 iOS Safari 行为;必要时监听 orientationchange 事件补充处理。
通过以上实现,Canvas 将无缝响应窗口缩放、设备旋转及分屏等场景,始终保持精确像素级适配,为动态背景提供稳定可靠的渲染基础。
立即学习“前端免费学习笔记(深入)”;



















