背景
小程序的想要使用不同颜色的svg只能通过引入多个svg文件。之前就有过动态改变svg颜色的需求,这几天看到也有其他同学想拥有这个功能。就想着能不能自己造一个。
解决方案
需求:
1.可以动态设置svg颜色。
2.最好不要改动svg源文件。
3.使用方便。
调查:
1.svg文件的颜色可以通过fill=“{color}”的值设置。所以基本思路就是,用正则替换改变color值,实现颜色的变化。
2.不想改变源文件,所以考虑以utf-8的格式读取svg文件,然后用正则替换后,将其转化为base64格式直接显示,而不是替换后写回文件。了解了一下,image已经支持base64。
3.为了使用方便,功能实现后,考虑做成自定义组件。
代码
代码部分并不复杂,就三步: 读取文件,正则替换, base64编码。其中base64编码部分使用Dorian大佬分享的工具,非常感谢!
- 使用wx.getFileSystemManager()读取文件
const fs = wx.getFileSystemManager() getSvgFile(src, color) { let that = this; fs.readFile({ filePath: src, encoding: 'UTF-8', position: 0, success(res) { let sourceFile = res.data; }, fail(res) { console.error(res) } }) },
- 正则替换(考虑到部分svg没有默认fill属性,所以在svg头部主动增加了fill属性)
changeColor(sourceFile, color) { let newSvg; if (/fill=".*?"/.test(sourceFile)) { newSvg = sourceFile.replace(/fill=".*?"/g, `fill="${color}"`); // SVG有默认色 } else { newSvg = sourceFile.replace(/<svg /g, `<svg fill="${color}" `); // 无默认色 } return newSvg }
- base64编码
import { Base64 } from './base64.js'; const base64 = new Base64() getSvgFile(src, color) { let that = this; fs.readFile({ filePath: src, encoding: 'UTF-8', position: 0, success(res) { let sourceFile = res.data; let newFile = that.changeColor(sourceFile, color); let svgBase64File = base64.encode(newFile); that.setData({ svgData: 'data:image/svg+xml;base64,' + svgBase64File }) }, fail(res) { console.error(res) } }) },
到这里主体功能完成,再封装成自定义组件就完工啦。自定义组件的代码片段可以自取:
https://developers.weixin.qq.com/s/GrQhtZmg7yCJ
使用方法及效果
1.打开代码片段,把svg文件夹复制到自己项目的component文件夹下
2.在需要引入svg的页面引入组件
3.使用svg标签,可以自定义宽高,和颜色,以及文件路径。
color也支持使用JS动态控制,实现颜色变化的效果。
4.目前就用了阿里icon的一些svg进行测试。有bug请多多反馈,也希望大家能提出更好的思路。
对应了iOS真机不显示的问题:
https://developers.weixin.qq.com/s/8gRJHYmK77Hv
和我之前的做法一样,当时还担心转canvas后有底色呢
感谢分享
有些svg文件需要自己手动修改一下,不过好使
直接用fontawesome插件来不是更简单,可以填充颜色(Doutone双色),设置动画等
真机上不显示,楼主有遇到这个问题吗