前端svg精微操作局部动态改变呈现工程网架状态程度可视播放效果

效果

工程网架线路图状态播放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)
  
})

完整代码完整可运行代码【gitcode仓库】

相关推荐
cxxcode几秒前
搞懂 JS 异步的底层真相:从 V8 源码看微任务与宏任务
前端
欧阳的棉花糖几秒前
React 小误区:派生值 vs useEffect
前端
马可菠萝4 分钟前
从零开始,用 Tauri + Vue 3 打造轻量级桌面应用
前端
陆枫Larry5 分钟前
JavaScript 字符串处理实战:从 `startsWith` 到链式 `replace` 的避坑指南
前端
天蓝色的鱼鱼22 分钟前
你的项目真的需要SSR吗?还是只是你的简历需要?
前端·架构
恋猫de小郭1 小时前
移动端开发稳了?AI 目前还无法取代客户端开发,小红书的论文告诉你数据
前端·flutter·ai编程
文心快码BaiduComate1 小时前
百度云与光本位签署战略合作:用AI Agent 重构芯片研发流程
前端·人工智能·架构
闲云一鹤2 小时前
nginx 快速入门教程 - 写给前端的你
前端·nginx·前端工程化
QCY2 小时前
「完全理解」1 分钟实现自己的 Coding Agent
前端·agent·claude
一拳不是超人3 小时前
Electron主窗口弹框被WebContentView遮挡?独立WebContentView弹框方案详解!
前端·javascript·electron