coords必须动态调整,因其仅认原始图片尺寸(naturalwidth/naturalheight),不认css渲染宽高;缩放后硬编码坐标会偏移,需用js按scalex/scaley重算每个坐标值并取整。

coords 坐标为什么必须动态调整
因为 coords 属性只认原始图片尺寸(naturalWidth/naturalHeight),不认 CSS 渲染后的宽高。只要 被缩放(比如
max-width: 100%、width: 50vw 或容器限制),硬编码的 coords="100,200,300,400" 就会偏移——点不准不是 JS 没跑,是坐标系根本对不上。
这不是浏览器 bug,是 HTML 规范明确限定:coords 值始终以原始像素为单位,且仅接受整数、逗号分隔、无空格。
用 JavaScript 重算 coords 的关键三步
核心逻辑就是:拿到原始尺寸 → 拿到当前渲染尺寸 → 按比例缩放每个坐标值。
- 必须等图片加载完成再读
naturalWidth和naturalHeight,否则值为 0;推荐监听img.onload,而不是仅靠DOMContentLoaded -
offsetWidth/offsetHeight要在图片已 layout 完成后取,否则可能受父容器未渲染影响;可配合ResizeObserver监听尺寸变化(比window.resize更精准) - 缩放时注意 x/y 方向独立计算:
scaleX = offsetWidth / naturalWidth,scaleY = offsetHeight / naturalHeight;矩形、圆形、多边形都得分别处理每个数值
示例代码片段(适用于 shape="rect" 和 shape="poly"):
const img = document.querySelector('img[usemap]');
const map = document.querySelector(`map[name="${img.usemap.slice(1)}"]`);
const areas = map.querySelectorAll('area');
<p>const updateCoords = () => {
if (!img.naturalWidth || !img.naturalHeight) return;</p><p>const scaleX = img.offsetWidth / img.naturalWidth;
const scaleY = img.offsetHeight / img.naturalHeight;</p><p>areas.forEach(area => {
const coords = area.coords.split(',').map(Number);
const scaled = coords.map((v, i) =>
Math.round(i % 2 === 0 ? v <em> scaleX : v </em> scaleY)
);
area.coords = scaled.join(',');
});
};</p><p>img.addEventListener('load', updateCoords);
new ResizeObserver(updateCoords).observe(img);</p>
shape="poly" 多边形容易踩的坑
多边形 coords 是顶点序列,顺序错一位、少一对、或混入小数/空格,整个区域就失效。
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
-
coords字符串必须严格为偶数个整数,如"100,200,150,180,180,220"(3 个点);写成"100,200,150,180,180,220,100,200"(手动闭合)也行,但非必需——浏览器自动闭合 - 缩放时不能整体乘一个比例,必须按“x,y,x,y…”交替处理:第 0、2、4… 位是 x 坐标,用
scaleX;第 1、3、5… 位是 y 坐标,用scaleY - 导出工具(比如 Photoshop 热点图插件、Figma 插件)常输出带小数或百分比的坐标,要先
Math.round()再塞进coords,否则部分浏览器直接忽略整条<area>
比 JS 动态适配更稳的替代方案
如果项目允许改结构,优先用 <svg></svg> 替代 <map></map> + <area>。
<svg></svg> 天然支持响应式:viewBox 控制缩放逻辑,x/y/width/height 可直接写百分比,<rect></rect>、<circle></circle>、<polygon></polygon> 都能绑定 click 事件,还兼容 media query 和 dpr 缩放。
难点在于图像嵌入方式:把原图作为 <image href="..."></image> 放进 SVG,并设 preserveAspectRatio="xMidYMid meet",再叠上矢量热点——这样所有坐标都不用手算比例。
真正容易被忽略的是:JS 重算 coords 在 dpr > 1(如 Retina 屏)下仍可能偏移,因为 offsetWidth 返回的是 CSS 像素,而 naturalWidth 是物理像素;此时需额外乘上 window.devicePixelRatio 校正,或直接切 SVG。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










