要使canvas在高清屏清晰显示,必须同时设置canvas元素的width/height属性(乘以devicepixelratio)和css宽高,并用ctx.scale缩放绘图上下文,鼠标事件坐标也需按比例换算。

在 HTML5 中,让 canvas 在高清屏(如 Retina)上清晰显示,**不能只靠 CSS 设置 display 宽高**。CSS 的 width 和 height(比如 style.width = "600px")只控制画布的“视觉尺寸”,即它在页面上占多大空间;而真正决定绘制是否清晰的,是 canvas 元素自身的 width 和 height 属性——它们代表绘图缓冲区的物理像素数量。
必须同步设置两组尺寸
高清屏下,设备像素比(window.devicePixelRatio,简称 DPR)通常为 2 或更高。若你希望画布视觉上是 600×400px,就得让内部缓冲区放大:
- 设 canvas 元素的
width和height属性为:canvas.width = 600 * window.devicePixelRatio;canvas.height = 400 * window.devicePixelRatio; - 再用 CSS 把它“缩回”目标尺寸:
canvas.style.width = "600px";canvas.style.height = "400px";
响应式场景推荐用 getBoundingClientRect()
如果画布宽度随容器变化(比如填满一个 flex 项),不要硬写 600px,而是动态读取当前显示尺寸:
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
- 用
canvas.getBoundingClientRect()获取它在视口中的 CSS 像素宽高(rect.width/rect.height) - 再乘以 DPR 得到真实缓冲区大小:
canvas.width = rect.width * window.devicePixelRatio;canvas.height = rect.height * window.devicePixelRatio; - 最后仍要设
style.width和style.height回rect.width + "px"和rect.height + "px"
别忘了校正绘图上下文
光改尺寸还不够。否则你调用 ctx.fillRect(10, 10, 50, 30) 画出来的仍是模糊的 10×10 物理像素块:
- 在设置完 canvas 尺寸后,立即执行:
ctx.scale(window.devicePixelRatio, window.devicePixelRatio); - 这样所有坐标和尺寸都按 CSS 像素理解,你照常写
(10, 10),底层自动映射到高密度像素
鼠标事件也要换算
用户点击位置(clientX/clientY)是基于 CSS 像素的,但 canvas 内部已是 DPR 倍分辨率:
- 拿到
getBoundingClientRect()的rect - 计算缩放因子:
const scaleX = canvas.width / rect.width;const scaleY = canvas.height / rect.height; - 把鼠标坐标转成绘图坐标:
const x = (e.clientX - rect.left) * scaleX;const y = (e.clientY - rect.top) * scaleY;
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










