coords批量改写必须基于图片原始尺寸(naturalwidth/height),不可正则全局替换数字;需按shape类型分别解析:rect需4个值、circle需3个值、poly需偶数个顶点;缩放时rect四值同乘比例,poly各顶点xy分别乘scalex/scaley,circle半径乘min(scalex,scaley)。

coords 坐标批量改写必须基于原始尺寸,不能直接替换数字
直接用正则全局替换 coords 里的数字会出错——因为不同 shape 要求数量不同:rect 要 4 个、circle 要 3 个、poly 至少 6 个且必须偶数。硬替“所有逗号分隔的数字”大概率把 circle 的半径改成负数,或截断 poly 的顶点对。
真正安全的做法是:先解析每个 <area> 的 shape,再按规则拆解 coords 字符串,逐组换算后重拼。例如缩放图片时,rect 的四个值都要乘同一比例,而 poly 的每个 x 和 y 需分别乘 scaleX 和 scaleY。
- 用
img.naturalWidth和img.naturalHeight读原始尺寸,不是offsetWidth - 不要信任设计稿标注的“px 值”——如果标注来自 @2x 图,得先除以
window.devicePixelRatio(或固定除以 2) - 坐标字符串里不能有空格:
"100, 200"中的空格会让第二值被截成"200",后面全丢
Python 脚本批量重算 coords(适配缩放/高清屏)
下面这个脚本读取 HTML 文件,找到所有 <area>,按其 shape 类型分别处理 coords,输出新 HTML。它不依赖外部库,只用标准库 xml.etree.ElementTree,能处理嵌套、换行、属性乱序等真实场景。
import xml.etree.ElementTree as ET
from pathlib import Path
<p>def rescale_coords(coords_str, shape, scale_x, scale_y):
nums = [int(x.strip()) for x in coords_str.split(",") if x.strip()]
if shape == "rect" and len(nums) == 4:
x1, y1, x2, y2 = nums
return f"{int(x1<em>scale_x)},{int(y1</em>scale_y)},{int(x2<em>scale_x)},{int(y2</em>scale_y)}"
elif shape == "circle" and len(nums) == 3:
cx, cy, r = nums
return f"{int(cx<em>scale_x)},{int(cy</em>scale_y)},{int(r<em>min(scale_x,scale_y))}"
elif shape == "poly" and len(nums) >= 6 and len(nums) % 2 == 0:
pts = []
for i in range(0, len(nums), 2):
x, y = nums[i], nums[i+1]
pts.append(f"{int(x</em>scale_x)},{int(y*scale_y)}")
return ",".join(pts)
return coords_str # fallback</p><p>html_path = Path("input.html")
tree = ET.parse(html_path)
root = tree.getroot()</p><h1>假设页面只有一个 img[usemap],且已知原始尺寸</h1><p>img = root.find(".//img[@usemap]")
if img is not None and "src" in img.attrib:</p><h1>实际中应加载图片获取 naturalWidth/naturalHeight,此处简化为手动填</h1><pre class="brush:php;toolbar:false;">orig_w, orig_h = 1200, 800
render_w, render_h = img.get("width"), img.get("height")
# 粗略估算缩放比(生产环境建议用 JS onload 后读 offsetWidth)
scale_x = float(render_w or orig_w) / orig_w
scale_y = float(render_h or orig_h) / orig_h
for area in root.findall(".//area[@shape][@coords]"):
shape = area.get("shape")
coords = area.get("coords")
if shape in ("rect", "circle", "poly") and coords:
new_coords = rescale_coords(coords, shape, scale_x, scale_y)
area.set("coords", new_coords)tree.write("output.html", encoding="utf-8", xml_declaration=True)
注意:脚本中的 orig_w/orig_h 必须是你图片的真实像素尺寸(img.naturalWidth),不能是 CSS 渲染宽高。如果 HTML 里没写 width/height,就按原始尺寸算,scale_x = scale_y = 1。
VS Code 正则批量修 coords 的边界条件
如果你只是微调、且确定所有 area 都是同一种 shape(比如全是 rect),可以用 VS Code 的正则查找替换,但必须加锚点防止误伤:
- 查
<area> → 替换为 <code><area shape="rect" coords="$1,$2,$3,$4">(先确认匹配是否准确) - 想把所有
rect宽高统一放大 1.5 倍?查<area>,替换为 <code><area shape="rect" coords="${1*1.5},${2*1.5},${3*1.5},${4*1.5}">(VS Code 支持简单数学表达式) - 千万别用
coords="([^"]*)"这种泛匹配——它会跨标签、吞掉href甚至闭合符
为什么 JS 动态重算比静态脚本更可靠
静态脚本只能处理“已知原始尺寸 + 固定缩放”的情况。但真实页面常有这些变量:
-
<img>用srcset切换不同分辨率图源,naturalWidth异步变化 - CSS 使用
max-width: 100%或aspect-ratio,渲染尺寸随容器变,但原始尺寸不变 - 用户缩放浏览器(Ctrl +)、系统 DPI 设置、暗色模式触发图片重载
这时候只有 JS 在 img.onload 和 ResizeObserver 里实时读 offsetWidth / naturalWidth,再逐个 area 重写 coords 属性,才能保证每次渲染都精准。静态脚本生成的 HTML,在响应式环境里撑不过第一次 resize。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











