响应式Canvas核心是保持内容清晰、比例正确、坐标可用,需同步处理物理尺寸、CSS显示尺寸和坐标系缩放;必须用ResizeObserver监听容器变化,结合devicePixelRatio动态设置width/height并调用ctx.scale(),禁用混合缩放。
Canvas 实现响应式布局,核心不是“让画布跟着页面缩放”,而是“让绘制内容在不同尺寸容器中保持清晰、比例正确、坐标可用”。这需要同时处理三个层面:画布物理尺寸、CSS显示尺寸、绘图坐标系缩放。
Canvas 的 width 和 height 属性决定其内部像素缓冲区大小,不是 CSS 样式。仅改 style.width/style.height 会导致拉伸模糊;仅改 width/height 不调 CSS 尺寸,则画布默认按 300×150 占位。
container.clientWidth)window.devicePixelRatio 得到 canvas.width / canvas.height 值canvas.style.width = '100%' 和 canvas.style.height = '100%'
在 Retina 或高 DPI 屏幕上,若忽略设备像素比,图形会发虚——因为 CSS 显示 200px 宽的区域,只用了 200 个逻辑像素绘制,而屏幕实际需要 400 个物理像素填充。
ctx.scale(dpr, dpr),使 drawRect(0,0,10,10) 真正画出 10×10 物理像素window.onresize 对 Flex/Grid 布局、组件折叠展开等场景完全失效,且移动端横竖屏切换时可能触发多次或滞后。
new ResizeObserver(() => resizeCanvas()) 监听父容器container.offsetWidth 是否变化ctx.save()),重设后清空并重绘是否用 ctx.scale() 做视觉缩放,取决于你是否需要精确点击、碰撞检测或坐标映射。