如何在客户端重写从服务器获取的 svg 文件?
Posted
技术标签:
【中文标题】如何在客户端重写从服务器获取的 svg 文件?【英文标题】:How do I rewrite on client side a svg file I fetched from the server? 【发布时间】:2018-08-20 15:15:11 【问题描述】:背景:
我正在运行一个快速服务器,其中包含指向我所有静态文件的路由。
在静态文件中,我有一个充满地图.svg
的文件夹。
在客户端 (React),我获取地图并将它们添加到组件中。
问题:
我需要重写.svg
,并将其添加到它们的路径属性中:fill=url(#some_flag)
。
Svg 之前:
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 1024 1024"
preserveAspectRatio="xMidYMid meet">
<g transform="translate(0,1024) scale(0.1,-0.1)"
fill="#000000" stroke="none">
<path d="... numbers...-78 -28 -115 "/>
</g>
</svg>
Svg 之后:
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 1024 1024"
preserveAspectRatio="xMidYMid meet">
<g transform="translate(0,1024) scale(0.1,-0.1)"
fill="#000000" stroke="none">
<path d="... numbers...-78 -28 -115"
fill="url(#some_flag)"/> <!--THE ADDED ATTRIBUTE -->
</g>
</svg>
我想到了几个方向:
Pure Javascript:setAttribute
of path
,这意味着我必须给每个路径一个 id?
不知何故用 CSS 穿透.svg
? 我试过了,它不可能覆盖内联 SVG 属性
您以前处理过它吗(当然...)?我有哪些选择?
【问题讨论】:
即使没有 ID 也可以在 DOM 中获取元素 谁说你不能:)?我只是大声思考什么是最好的做法。当然,您几乎可以定位 DOM 内的任何内容。但最好保持简单、干净和健壮。 【参考方案1】:我认为您已经发现,通过 img 标签包含 SVG 是有限制的。避免它。
您可以设置一种代理组件来获取 SVG 内容,将它们转换为 JSX,并允许您内联包含 SVG 内容。这将允许它们使用 CSS 和 javascript 轻松操作。
这是一个将文件转换为 JSX 格式的库。
https://www.npmjs.com/package/svg-to-jsx
【讨论】:
最后,我决定在服务器端做这个 SVG 操作,所以我还没有机会尝试,但我相信有一天它会很有用:) @ueeieiie 实际上,这就是我们所做的。我认为这是一个很好的电话。 你的意思是在服务器端进行操作?你是用 nodejs 做的吗? @ueeieiie,我们还没有到那个时候。目前,只是基于一些 SVG 作为输入创建 JSX,基本上是手工创建的。您可能需要做的比我们做的更多。 嘿,关于svg-to-jsx
,如何将SVG 文件导入其中?他们展示的所有示例都是:svg = '<svg>...string string string..</svg>'
。我正在尝试将 import
一个 SVG 文件放入我的组件中并将其传递给 svgtojs(importedSVG)
,但我得到的结果是空的,我这里是不是漏了一步?【参考方案2】:
我正在回答这部分:我心中有几个方向: 1-纯Javascript:路径的setAttribute,这意味着我必须给每个路径一个ID? >>.
这可能是最好的解决方案,但我不会使用“id”,因为它不够可靠(没有唯一性保证,如果无意中重复)。 您想添加一个属性 fill="url(#some_flag)",而您的 #some_flag 可能在某处被索引(flag [i]),并且可以链接到 path 的序列。如果 #some_flag 必须从几何图形中计算出来,你可以将它预处理成一个数组,或者在运行时计算。 CSS 选择器也可以更复杂,这取决于您的需要。这可能会回答您的部分问题:
document.querySelectorAll("g > path")
.forEach((x,i) => x.setAttribute("fill",`url($flag[i])`));
实际上,我确实使用摘自经济学人巨无霸指数(本地副本)的 svg 地图进行了实验:
fetch("./bigMacSvg1.txt", method:"GET")
.then(res => res.text())
.then(res =>
//console.log(res);
document.querySelector(".here").innerhtml = res; //div for svg
document.querySelectorAll("path:nth-child(n+2)")
.forEach(x => x.setAttribute("fill","#a1b2c3"));
)
.catch(err => console.log(err));
上面的代码为每个国家设置了浅色,但没有设置到海洋(第一条路径)。
【讨论】:
以上是关于如何在客户端重写从服务器获取的 svg 文件?的主要内容,如果未能解决你的问题,请参考以下文章
使用 qrencode 生成 png/svg 二维码,用于 Wireguard 客户端配置