Js修改Svg图片颜色

864 阅读1分钟

需求:

用户上传svg素材,前端展示素材图片,并可编辑颜色(取svg中的颜色并改变色值);

解决方案:

  1. 通过blob获取svg图片的文件字符串,存储原始字符串
  2. 通过match获取svg字符串中的16进制色值,通过colorList对象存贮
  3. 通过replace函数将变化颜色后的colorList遍例替换svg字符串,生成新的svg字符串
  4. 将新的svg字符串通过shadowDom插入到网页中

代码实现

let colorList = {}
let svgData = ''
// 获取svg字符串,查询色值列表
axios.get(img.imgUrl, {
  contentType: 'blob'
}).then((data) => {
  svgData = data.data
  let colors = data.data.match(/#(?:[0-9a-fA-F]{6})/g) || []
  colors.length > 0 && colors.map(color => {
    colorList[color]=color
  })
})
/**
 * 获取变色渲染后svg
 * @param svgData svg初始数据
 */
function getColorSvg(svgData){
  if (!svgData) return
  // 插入svg的容器
  let svgBody = document.getElementById(id)
  // 获取shadowDom根节点
  const shadowRoot = svgBody.shadowRoot || svgBody.attachShadow({mode: 'open'});
  if (!svgBody) return
  for(let key in props.colorList){
    if(key !== props.colorList[key]){
      let reg = new RegExp(`${key}`, 'g')
      svgData = svgData.replace(reg, props.colorList[key])
    }
  }
  let parser = new DOMParser();
  let doc = parser.parseFromString(svgData, "image/svg+xml");
  let svgDom = doc.getElementsByTagName('svg')[0]
  shadowRoot.innerHTML = ''
  shadowRoot.appendChild(svgDom)
}

为什么使用shadowDom

形成css沙箱,不会因为插入的svg字符串影响到已有样式和重复插入的图片