根本原因是高DPI屏下1 CSS像素对应多个物理像素,而HTML元素坐标依赖绝对像素,未按devicePixelRatio适配导致热区错位、Canvas/SVG坐标偏移。

没有“区域映射”这个标准概念,你实际想解决的,是点击热区错位、图片map标签失效、或Canvas/SVG坐标在不同屏幕下偏移的问题。
为什么<map></map>在手机上点不准
HTML 的 <map></map> + <area> 依赖绝对像素坐标,而移动端高DPI屏(如 iPhone Retina、安卓 2x/3x 屏)会把 1 CSS 像素渲染为多个物理像素。浏览器默认缩放 viewport 后,<area coords="10,20,100,80"> 这类坐标就不再对齐视觉位置。
- 必须确保
<meta name="viewport" content="width=device-width, initial-scale=1.0">已正确设置,否则坐标系基准混乱 -
<img>不能设width: 100%同时又用固定coords—— 宽度变了,但坐标没变 - 更稳妥的做法:改用 CSS 定位 +
pointer-events模拟热区,或用 SVG 替代<map>
Canvas 坐标适配要手动缩放
Canvas 的 canvas.width/canvas.height 是绘图缓冲区像素数,不是 CSS 显示尺寸。直接写 ctx.fillRect(50, 50, 100, 100) 在高清屏上会模糊且定位偏移。
- 获取设备像素比:
const dpr = window.devicePixelRatio || 1 - 设置 canvas 实际分辨率:
canvas.width = canvas.clientWidth * dpr,canvas.height = canvas.clientHeight * dpr - 然后用
ctx.scale(dpr, dpr)统一缩放绘图上下文,后续坐标按 CSS 尺寸写即可 - 监听
resize和orientationchange事件,动态重设
SVG 内部坐标天然适配,但要注意 viewBox
SVG 元素本身基于向量,坐标单位默认与 CSS 一致,只要不硬写 px 单位,就能随容器缩放。但常见错误是忽略 viewBox 设置。
立即学习“前端免费学习笔记(深入)”;
- 错误写法:
<svg width="300" height="200"><rect x="10" y="10" width="100" height="50"></svg>—— 宽高固定,无法响应式 - 正确写法:
<svg viewBox="0 0 300 200" width="100%" height="auto"><rect x="10" y="10" width="100" height="50"></svg> -
viewBox定义了 SVG 的逻辑坐标系,width/height控制显示尺寸,两者配合才能保证点击和渲染位置一致
真正难的不是写适配代码,而是意识到:所有基于像素坐标的交互层(<map>、Canvas、绝对定位的热区 div)都必须显式处理 devicePixelRatio 或改用相对坐标体系。漏掉这一层,再精细的布局也会在真机上点空。



















