微信小程序,mpvue中使用svg圖標,並通過代碼改變圖標顏色
本文主要是mpvue開發小程序的代碼,不過微信小程序原生開發應該也是一樣的,思路都是通用的,按照這個思路微信小程序原生開發一樣可以實現同樣的功能。
首先先說下svg格式(給出官方說明):
- SVG 指可伸縮矢量圖形 (Scalable Vector Graphics)
- SVG 用來定義用於網絡的基於矢量的圖形
- SVG 使用 XML 格式定義圖形
- SVG 圖像在放大或改變尺寸的情況下其圖形質量不會有所損失
- SVG 是萬維網聯盟的標準
- SVG 與諸如 DOM 和 XSL 之類的 W3C 標準是一個整體
在mpvue中我們可以直接這樣使用svg圖標:
<img style="width:45rpx;height:45rpx;" src="/static/icon/index/zaixianzhanting.svg"/>
svg圖標的路徑:
我們知道svg是xml格式定義的一種圖標,是通過xml代碼中的fill屬性來修改圖標的顏色的,UI給的svg默認都是黑色,當我們需要其他顏色的圖標時,我們可以直接修改源碼中的fill屬性值達到修改顏色的目的。
(注意:svg中可能有多個fill,替換時根據需要替換即可)
但是如果我們需要在用戶執行的時候動態修改圖標的顏色呢?難道每種顏色都新建一個svg圖標再引用?答案肯定是否定的。
直接給思路:
既然svg是通過xml定義圖像的,那麼爲什麼我們不能先獲取svg圖標的源碼,再將其中fill的屬性值替換成我們需要的顏色呢?
然後再將替換後的源碼成base64格式,是不是就可以實現動態的改變圖標的顏色了?
小程序api中爲我們提供了讀取文件的方法:wx.getFileSystemManager().readFile()
通過這個方法我們可以獲取到svg文件的源碼。
mpvue 框架中我們直接可以封裝一個vue組件,方便各個頁面使用,組件已經給大家寫好了。直接複製到項目就可以使用。
組件代碼:
將字符串源碼轉化爲base64需要引入 JS-base64 這個js
npm直接安裝:
$ npm install --save js-base64
icons組件:
<template>
<img :style="iconstyle?iconstyle:('width:' + size + 'rpx;height:' + size + 'rpx;')" :src="imgurl" :model="model"/>
</template>
<script>
import { Base64 } from 'js-base64'
export default {
props: {
size: {
type: [Number, String],
default: 45
},
src: [String],
iconstyle: [String],
color: [String],
stroke: [String],
model: [String]
},
data () {
return {
imgurl: ''
}
},
watch: {
color: function (obj) {
this.initImage()
},
stroke: function (obj) {
this.initImage()
}
},
methods: {
initImage () {
if (this.color || this.stroke) {
// 先獲取svg源碼字符串,替換 file="#ffff" stroke='#FFFFFF' 顏色這個屬性,再將這個字符串轉化爲base64,達到修改顏色的目的
wx.getFileSystemManager().readFile({
filePath: this.src,
encoding: 'binary',
success: res => {
let basestr = res.data
if (this.color) {
const strArr = basestr.split(/fill="#?[a-zA-Z0-9]{0,6}"/g)
const oldcolorArr = basestr.match(/fill="#?[a-zA-Z0-9]{0,6}"/g)
const newcolorArr = this.color.split(',')
for (let i = 0; i < newcolorArr.length; i++) {
const color = newcolorArr[i]
if (color) {
oldcolorArr[i] = `fill="${color}"`
}
}
let str = ''
for (let i = 0; i < strArr.length; i++) {
str += (strArr[i] + (oldcolorArr[i] ? oldcolorArr[i] : ''))
}
basestr = str
}
if (this.stroke) {
const strArr = basestr.split(/stroke="#?[a-zA-Z0-9]{0,6}"/g)
const oldcolorArr = basestr.match(/stroke="#?[a-zA-Z0-9]{0,6}"/g)
const newcolorArr = this.stroke.split(',')
for (let i = 0; i < newcolorArr.length; i++) {
const color = newcolorArr[i]
if (color) {
oldcolorArr[i] = `stroke="${color}"`
}
}
let str = ''
for (let i = 0; i < strArr.length; i++) {
str += (strArr[i] + (oldcolorArr[i] ? oldcolorArr[i] : ''))
}
basestr = str
}
const base64 = Base64.encode(basestr)
this.imgurl = 'data:image/svg+xml;base64,' + base64
}
})
} else {
this.imgurl = this.src
}
}
},
created () {
this.initImage()
}
}
</script>
<style scoped>
img{
display: block;
}
</style>
組件使用:vue組件的使用不用我多說了吧~ 先在頁面註冊然後就能使用了。
考慮到svg還有stroke屬性也可以改變顏色。並且一個文件有多個fill,stroke屬性(color對應svg的fill屬性,stroke對應svg的stroke屬性)
我們來通過逗號”,“來分割顏色屬性,逗號分隔後的數組來確定我們要替換哪個fill屬性或者stroke屬性。
組件使用範例:
<!-- 第一個fill屬性值替換成#cccccc-->
<icons src="/static/icon/index/zaixianzhanting.svg" color="#cccccc" size="40"/>
<!-- 第三個fill屬性替值換成#cccccc,前兩個不替換-->
<icons src="/static/icon/index/zaixianzhanting.svg" color=",,#cccccc" size="40"/>
<!-- 第二個fill屬性值替換成#cccccc,第三個fill屬性換成#fff,第三個stroke屬性值替換成#cccccc-->
<icons src="/static/icon/index/zaixianzhanting.svg" color=",#cccccc,#fff" stroke=",,#cccccc" size="40"/>
好了,大功告成!
原創不易,轉載請註明出處!!