【问题标题】:Manipulating an SVG file from Illustrator to change Path names to text within that path从 Illustrator 操作 SVG 文件以将路径名称更改为该路径中的文本
【发布时间】:2023-01-14 02:24:58
【问题描述】:
请原谅我知识匮乏。我不是这样的程序员。我只是想学习一些具体的东西或为我目前的目标寻求帮助。
我目前在 Illustrator 上有一个文件需要处理。在文件 (SVG) 中,有许多这样命名的矩形或“路径”(路径)。在这些路径之上,有一些我想使用的文本,以便将文档中的所有路径重命名为它们的特定 (ID)。
enter image description here ID 只是位于文档路径顶部的文本。希望您能够在上图中看到我的意思。
目前,该文本和那些框是分开的,我需要使用位于它们顶部的相应文本重命名这些框。
我目前正在通过手动复制和粘贴文本并重命名框来执行此操作。
有谁知道如何编写可以为我自动化的东西?
我是编程界的菜鸟。我什至不知道从哪里开始。
我在想像 Snap.svg 这样的 JS 库会很好吗?
任何帮助将不胜感激,因为该文档非常大(不仅仅是那张图片)并且需要很长时间才能完成。
我试过查看 Snap.svg,但由于缺乏经验,我不知道从哪里开始。经验丰富的人可能会觉得这很简单,他们会花几分钟时间想出一个解决方案。
【问题讨论】:
标签:
javascript
adobe
snap.svg
【解决方案1】:
通过document.elementsFromPoint()搜索底层元素
请记住:svg <text> 元素不能嵌套在 <rects> 这样的形状中——因此我们无法查询子元素。
document.elementsFromPoint() 返回特定点坐标处的元素数组,并且是原生支持所有主要浏览器 - 不需要 snap.svg 或其他库。
- 查询所有
<text>元素
- 获取中心坐标:
let bb = label.getBoundingClientRect();
let x = bb.left + bb.width/2;
let y = bb.top + bb.height/2;
- 查找元素
let els = document.elementsFromPoint(x, y)
let svg = document.querySelector('svg');
let labels = document.querySelectorAll('text');
labels.forEach(label => {
let bb = label.getBoundingClientRect();
let x = bb.left + bb.width / 2;
let y = bb.top + bb.height / 2;
// sanitize id string
let id = label.textContent.replaceAll(' ', '-').replaceAll('#', '').toLowerCase();
// filter only geometry elements
let els = document.elementsFromPoint(x, y).filter(el => el instanceof SVGGeometryElement);
// optional: select only first underlying element
let onlyFirstUnderlying = false;
if (onlyFirstUnderlying) {
els = [els[0]];
}
els.forEach((el, i) => {
el.id = id
// add incremental suffix to prevent duplicate ids
if (els.length > 1 && i > 0) {
el.id += '_' + i
}
})
let newSvg = new XMLSerializer().serializeToString(svg);
output.value = newSvg;
})
svg {
max-width: 10em;
height: auto;
border: 1px solid #ccc;
}
text {
font-size: 10px
}
#output {
display: block;
width: 100%;
min-height: 20em;
}
<svg id="svg" viewBox="0 0 100 100">
<rect x="0" y="0" width="50" height="50" fill="yellow" />
<text x="10" y="25">Label 01</text>
<rect x="0" y="50" width="50" height="50" fill="orange" />
<rect x="0" y="50" width="40" height="50" fill="purple" />
<rect x="0" y="50" width="30" height="50" fill="pink" />
<text x="10" y="75">Label 02</text>
</svg>
<h3>Output</h3>
<textarea id="output"></textarea>