retina屏下canvas高清关键在于匹配物理像素:用devicepixelratio动态设置canvas.width/height,并css缩放回设计尺寸,再ctx.scale(dpr,dpr)保持坐标逻辑;需避免非整数坐标、线条宽度设为dpr整数倍、启用textrendering优化文字。

要在 Retina 屏下让 Canvas 游戏场景真正高清,关键不是“画得更细”,而是让物理像素数量匹配设备能力——Canvas 默认按 CSS 像素工作,而 Retina 屏 1 个 CSS 像素对应多个物理像素(如 2×2 或 3×3)。若不主动适配,浏览器就会拉伸低分辨率内容,导致模糊、锯齿、线条发虚。
动态设置 canvas 物理尺寸,匹配 devicePixelRatio
必须用 canvas.width 和 canvas.height 设置实际绘图缓冲区大小(单位:物理像素),而不是只靠 CSS 缩放。
- 获取设备像素比:
const dpr = window.devicePixelRatio || 1 - 读取期望的显示尺寸(CSS 像素):
const rect = canvas.getBoundingClientRect() - 设置物理缓冲区:
canvas.width = Math.floor(rect.width * dpr); canvas.height = Math.floor(rect.height * dpr); - 再用 CSS 把画布“压回”设计尺寸:
canvas.style.width = rect.width + 'px'; canvas.style.height = rect.height + 'px';
重置并缩放绘图上下文,保持坐标逻辑不变
改完 canvas 尺寸后,如果不调整绘图坐标系,所有 draw 调用都会错位或缩小。必须用 ctx.scale(dpr, dpr) 补偿,让 (10, 10) 这样的坐标仍落在预期位置。
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
- 每次重设尺寸后,先清除旧变换:
ctx.setTransform(1, 0, 0, 1, 0, 0) - 再应用缩放:
ctx.scale(dpr, dpr) - 这样你写
ctx.fillRect(0, 0, 100, 100),它就真画出 100×100 CSS 像素的清晰矩形
游戏渲染中特别要注意的细节
高清不只是“不糊”,还要保证动效稳定、边缘锐利、文字可读。
-
避免非整数坐标绘制:比如画线时用
Math.round(x)对齐像素网格,防止抗锯齿软边 -
线条宽度设为 dpr 的整数倍:如
ctx.lineWidth = 2 * dpr,否则 1px 线在 2x 屏上会变成半像素模糊带 -
文字渲染优先用整数字号 + 启用清晰模式:
ctx.font = '16px sans-serif'; ctx.textRendering = 'optimizeLegibility'; -
导出帧或截图时,确保未遗漏缩放:调用
toDataURL()前确认 canvas 已按 dpr 设置好,且 ctx 没被重复 scale
响应式与运行时适配不能少
用户可能缩放页面、旋转 iPad、切换窗口大小——这些都会影响 getBoundingClientRect() 和实际布局,但 devicePixelRatio 不一定实时变化。
- 监听
resize和orientationchange事件,重新计算 canvas 尺寸和缩放 - 在 iOS Safari 中,
orientationchange后需强制触发一次重绘,否则部分机型会残留模糊缓存 - 对长期运行的游戏,建议每秒检查一次
window.devicePixelRatio是否变化(如 Windows 系统缩放切换)










