Canvas在Retina屏发虚是因为未适配devicePixelRatio,需同步设置width/height属性为物理像素值并缩放绘图坐标,否则仅CSS缩放会导致插值模糊。
Canvas 在 Retina 屏上发虚是因为没处理
浏览器默认用 1 个 CSS 像素对应 1 个物理像素,但 Retina 屏(如 MacBook、iPhone)的
是 2 或 3——意味着 1 个 CSS 像素要铺开成 4 或 9 个物理像素。Canvas 的
/
属性是按物理像素设置的,而 CSS 样式(比如
)控制的是 CSS 像素。两者不匹配,浏览器只能靠插值拉伸,结果就是模糊。
必须同时改 canvas 元素的
和
属性,不能只改 CSS
只写
不起作用:它只缩放显示区域,画布缓冲区还是原始大小,绘图内容被拉伸。真正要改的是 canvas 元素的 DOM 属性
和
(不是 CSS),让缓冲区物理像素数匹配设备密度。
实操建议:
读取
,向下取整或四舍五入(通常用
避免小数导致渲染异常)
先保存原始 CSS 尺寸(比如
),再换算成物理像素值
赋值前清空 canvas(
),否则旧缓冲区残留会干扰重绘
别在
事件里频繁重设——加防抖,或者只在
变化时响应(监听
的
更可靠)
是补救手段,不是替代方案
如果你已经用 CSS 控制了 canvas 大小,又不想动
/
属性,可以用
把所有绘图坐标放大。但它只是“骗”绘图 API,实际缓冲区仍不足,文字、线条抗锯齿效果差,且
、
输出的仍是低分辩率图像。
立即学习
“
前端免费学习笔记(深入)
”;
使用HTML,CSS,JavaScript开发Android应用程序 英文文字pdf版附源文件
如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Android友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Android应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更
下载
常见错误现象:
文字边缘毛刺、小图标出现灰边——
后没调用
重新设字号,或没对
手动乘
鼠标坐标错位——没把
除以
再传给
动画卡顿——每帧都做
+
组合变换,不如直接提升缓冲区分辨率来得干净
兼容性与性能注意点:高
下内存和绘制成本陡增
为 3 时,同样 300×200 CSS 尺寸的 canvas,缓冲区变成 900×600 物理像素,内存占用 ×9,
和
开销也显著上升。低端 Android 设备可能直接 OOM 或掉帧。
使用场景建议:
图标、图表、游戏主画布——值得适配;纯装饰性 canvas(比如背景粒子)可降级为
服务端生成图片(
)不涉及
,别套用这套逻辑
iOS Safari 15.4+ 支持
提升性能,但和 dpr 无关,别混淆
最常被忽略的一点:canvas 元素插入 DOM 后才可读取
,动态创建时别在
后立刻计算尺寸。
devicePixelRatiodevicePixelRatiowidthheightstyle="width: 300px; height: 200px;"widthheightcanvas.style.width = "300px"widthheightwindow.devicePixelRatioMath.floorgetComputedStyle(canvas).widthctx.clearRect(0, 0, canvas.width, canvas.height)resizedevicePixelRatiomatchMedia"(resolution: ...dppx)"ctx.scale(dpr, dpr)widthheightctx.scale(dpr, dpr)getImageDatatoDataURLscalectx.fontlineWidthdprclientX/clientYdprisPointInPathscaletranslatedprdevicePixelRatioclearRectdrawImagedpr = 1node-canvasdevicePixelRatiocanvas.getContext("2d", { alpha: false })getComputedStylenew Canvas()