devicePixelRatio是BOM中获取设备物理像素与CSS像素比值的只读属性,用于高清屏适配;需结合canvas物理尺寸缩放、CSS尺寸控制及ctx.scale实现清晰渲染,并配合srcset或@2x资源与dpr变化监听确保多场景兼容。

在 JavaScript 中,devicePixelRatio 是 BOM(Browser Object Model)提供的一个只读属性,用于获取设备物理像素与 CSS 像素的比值,是实现高清屏(如 Retina 屏)适配的关键依据。
理解 devicePixelRatio 的含义
devicePixelRatio 表示 1 个 CSS 像素对应多少个物理像素。常见取值:
- 1:普通屏幕(如多数 Windows 笔记本、非 Retina Mac)
- 2:Retina MacBook、iPhone 6–12、部分安卓旗舰机
- 3 或更高:iPhone 14 Pro、Pixel 系列等超高密度屏
例如:window.devicePixelRatio === 2 意味着画布上 100×100px 的区域,实际需渲染 200×200 物理像素才能保持清晰。
用 devicePixelRatio 缩放 Canvas 以适配高清屏
Canvas 默认按 CSS 像素渲染,不自动响应高清屏,文字/图形易模糊。正确做法是:
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 用
canvas.width和canvas.height设置**物理像素尺寸**(即乘以 dpr) - 用 CSS 设置 canvas 的
width/height为**CSS 像素尺寸**(保持视觉大小不变) - 绘制时坐标和尺寸仍按 CSS 像素逻辑操作(无需手动放大)
示例代码:
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
const dpr = window.devicePixelRatio || 1;
<p>// 获取 CSS 尺寸
const rect = canvas.getBoundingClientRect();
const width = rect.width;
const height = rect.height;</p><p>// 设置 canvas 物理尺寸(缩放)
canvas.width = width <em> dpr;
canvas.height = height </em> dpr;</p><p>// 设置 CSS 尺寸(保持显示大小)
canvas.style.width = width + 'px';
canvas.style.height = height + 'px';</p><p>// 缩放绘图上下文,使坐标系对齐 CSS 像素
ctx.scale(dpr, dpr);</p><p>// 此时 drawRect(10, 10, 50, 50) 会清晰渲染在高清屏上
ctx.fillStyle = '#000';
ctx.fillRect(10, 10, 50, 50);
配合图片资源做高清适配
普通 <img> 标签可通过 srcset 让浏览器自动选高清图,但 JS 动态加载或 Canvas 绘图需手动处理:
- 检测
devicePixelRatio >= 2时,优先加载@2x.png等高倍图 - 加载后按 CSS 尺寸设置
img.width/img.height,再绘制到 canvas - 避免直接用
img.naturalWidth / dpr裁剪——应确保图片资源本身分辨率足够
简单判断逻辑:
function getHighResSrc(src) {
const dpr = window.devicePixelRatio || 1;
if (dpr >= 2) {
return src.replace(/(\.[\w]+)/, '@2x$1');
}
return src;
}
// 使用:const img = new Image(); img.src = getHighResSrc('/icon.png');
监听 dpr 变化(如系统缩放或横竖屏切换)
用户调整系统缩放、插拔外接屏、旋转 iPad 等都可能改变 devicePixelRatio。可监听 resize 或使用 matchMedia 检测变化:
// 简单方案:resize 时重适配(注意防抖)
let lastDpr = window.devicePixelRatio;
function handleDPRChange() {
const currentDpr = window.devicePixelRatio;
if (currentDpr !== lastDpr) {
lastDpr = currentDpr;
// 重新初始化 canvas / 图片 / 布局...
}
}
window.addEventListener('resize', handleDPRChange);
更精准可用 window.matchMedia('(resolution: 2dppx)') 监听,但兼容性略低,生产环境建议 resize + 首次加载双重保障。

















