效果
工程网架线路图状态播放svg版实现效果
思路:
1.从UI设计师那里拿到具备id属性的网架SVG文件(这一步是关键。UI设计师不懂编码,常常给到研发的是无id的SVG,因此很难进行有效开发。我将给出解决思路)
2.与UI设计师约定好提供的svg id的规则,方便进行分类渲染和动态修改内容
3.研发编程SVG
实施细节
第一二步导出带有id的SVG
1.先教会UI设计师启用figma导出SVG时携带id, 把导出面板 【include"id" attribute】选项勾选上

2.左边图层,右键可以唤出面板,进行【重命名】,重命名后的名称便是图层的id。研发和UI设计师约定好图层名称命名的规则。比如我的是图形图层用"xxx_G",文字图层用"xxx_T"来命名

下面展开SVG文件源码,可以看到svg元素中带有id

第三步编程
1.加载SVG
html
<body>
<object id="jssvgobj" data="/javascript.svg" type="image/svg+xml"></object>
</body>
2.访问SVG拿到contentDOM
javascript
const jssvgobj = document.getElementById("jssvgobj");
jssvgobj.addEventListener("load", ()=>{
const jssvgDom = jssvgobj.contentDocument;
})
3.拿到svgdom,id若有汉字,需要转码
javascript
/**
* 递归遍历svg , 把图形标签和文本标签的含中文乱码ID 转成 正常utf8的 中文汉字 正常ID
* @param node
*/
function recurseResetId(node) {
console.log('源头', node)
if (!node) {
return console.log('node为空')
}
if (node.id !== '' && node.id !== undefined) {
let decodeId = decodeURIComponent(escape(node.id));
console.log('原id: '+ node.id + '--后id: '+ decodeId);
node.id = decodeId;
if (decodeId.includes('_G')) {
shapeIDs.push(decodeId);
}else if (decodeId.includes('_T')) {
textIDs.push(decodeId);
}
}
if (node.hasChildNodes()) {
node.childNodes.forEach(node => recurseResetId(node))
}
console.log('recurseResetId', 'shapedid:'+shapeIDs)
console.log('recurseResetId', 'textids:'+textIDs)
}
4.根据需要改变svg的属性和内容
javascript
//改变svg节点的属性
function recurseSetNodeAttr(node, attr, value) {
// console.log('当前svg图形的节点', node);
if (!node) {
return console.log('node为空')
}
if (typeof node == 'object' && node.hasChildNodes()) {
node.childNodes.forEach(node => recurseSetNodeAttr(node, attr, value))
}else {
try {
node.setAttribute(attr, value)
console.log(node+'修改'+attr+'为'+value+'成功')
}catch (e) {
// console.log(e)
}
}
}
//改变svg节点文本
function recurseSetNodeText(parentNode,currentNode, text) {
console.log('recurseSetNodeText-当前svg图形的节点', currentNode);
if (!currentNode) {
return console.log('node为空')
}
if (typeof currentNode == 'object' && currentNode.hasChildNodes()) {
currentNode.childNodes.forEach(node => recurseSetNodeText(currentNode, node, text))
}else {
try {
parentNode.innerHTML = text;
console.log(parentNode+'修改内容'+'为'+text+'成功')
}catch (e) {
console.log(e)
}
}
}
最后,补全svg object侦听器里的逻辑,传入svgDom,调用上面几个函数
javascript
const jssvgobj = document.getElementById("jssvgobj");
jssvgobj.addEventListener("load", ()=>{
const jssvgDom = jssvgobj.contentDocument;
recurseResetId(jssvgDom);
setTimeout(()=>{
recurseSetNodeAttr(jssvgDom.getElementById(shapeIDs[0]), 'fill', 'green')
recurseSetNodeText(null, jssvgDom.getElementById(textIDs[0]), '标题改变')
}, 3000)
})