(1)JS 动态更改svg格式字符串的颜色
JS动态更改svg颜色,以及将svg格式字符串转为url,并使用background-image显示。
// 修改 svg 颜色, svg 代表svg格式的字符串
changeColor(svg, color) {
let res
// 先简单判断一下是否是一个svg
if (/<svg/.test(svg)) {
// .*? 表示匹配任意字符到下一个符合条件的字符
if (/fill=".*?"/.test(svg)) {
// svg 有默认色
res = svg.replace(/fill=".*?"/g, `fill="${color}"`)
} else {
// svg 无默认色
res = svg.replace(/<svg /g, `<svg fill="${color}"`)
}
}
//转义后的#等于%23,利用正则表达式,替换所有%23后6位为新的十六进制六位数。
// let res = svg.replace(/%23[a-zA-Z0-9]{6}/g, color.replace("#", "%23")).replace(/currentColor/g, color);
return res;
},
(2)svg格式字符串转url
// svg 格式字符串转 Url
svgToUrl(url) {
var encoded = url
.replace(/<!--(.*)-->/g, "")
.replace(/[\r\n]/g, " ")
.replace(/"/g, `'`)
.replace(/%/g, "%25")
.replace(/&/g, "%26")
.replace(/#/g, "%23")
.replace(/{/g, "%7B")
.replace(/}/g, "%7D")
.replace(/</g, "%3C")
.replace(/>/g, "%3E");
let res = '"' + `data:image/svg+xml,${encoded}` + '"'; //需要在字符串前后加上一对引号(非常关键!)
return res;
},
这个函数的作用是将SVG图片的URL转换为可嵌入HTML文档中的DataURL格式,以便在网页上显示SVG图片。
思路:
-
首先,使用正则表达式 replace 方法将SVG中的注释内容去除,即
<!--(.*)-->
替换为空字符串。 -
然后,使用正则表达式 replace 方法将换行符和回车符替换为空格,即
[\r\n]
替换为 " "。 -
接下来,使用 replace 方法将双引号 " 替换为单引号 ',即 " 替换为 '。
-
使用 replace 方法对特殊字符进行URL编码,包括百分号 % 替换为 %25,和符号 & 替换为 %26,井号 # 替换为 %23,左大括号 { 替换为 %7B,右大括号 } 替换为 %7D,小于号 < 替换为 %3C,大于号 > 替换为 %3E。
-
最后,使用字符串拼接的方式,添加
data:image/svg+xml,
前缀和引号,将编码后的字符串包装为DataURL,并将该字符串作为函数的返回值。
需要注意的是,在字符串前后加上引号是非常关键的。
总结起来,这个函数的作用是将SVG图片的URL转换为可嵌入HTML文档中的DataURL格式,以便在网页上显示SVG图片。
请留意,这段代码并不提供异常处理或验证输入的功能,因此在使用时需要确保传入的参数是有效的URL格式。
(3)使用svg加载器svg-sprite-loader动态改变svg颜色
参考:在vue项目中使用svg,并能根据需要修改svg大小颜色等样式
vue项目中使用svgIcon(svg-sprite-loader安装、配置及使用)
1. 安装svg-sprite-loader
npm i svg-sprite-loader -D
2. 封装组件 - 在components路径下新建SvgIcon文件夹,然后新建index.vue。
<template>
<div v-if="isExternal" :style="styleExternalIcon" class="svg-external-icon svg-icon" v-on="$listeners" />
<svg v-else :class="svgClass" aria-hidden="true" v-on="$listeners">
<use :xlink:href="iconName" />
</svg>
</template>
<script>
import { isExternal } from '@/utils/validate'
export default {
name: 'SvgIcon',
props: {
iconClass: {
type: String,
required: true
},
className: {
type: String,
default: ''
}
},
computed: {
isExternal() {
return isExternal(this.iconClass)
},
iconName() {
return `#icon-${this.iconClass}`
},
svgClass() {
if (this.className) {
return 'svg-icon ' + this.className
} else {
return 'svg-icon'
}
},
styleExternalIcon() {
return {
mask: `url(${this.iconClass}) no-repeat 50% 50%`,
'-webkit-mask': `url(${this.iconClass}) no-repeat 50% 50%`
}
}
}
}
</script>
<style scoped>
.svg-icon {
width: 1em;
height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
.svg-external-icon {
background-color: currentColor;
mask-size: cover!important;
display: inline-block;
}
</style>
3. 组件封装 - 在assets目录下新建icons文件夹,然后新建svg文件夹(用于存放需要使用的.svg文件)和index.js文件。
index.js 文件:
import Vue from 'vue'
import SvgIcon from '@/components/SvgIcon'// svg component
// 全局注册组件
Vue.component('svg-icon', SvgIcon)
const req = require.context('./svg', false, /\.svg$/)
// 定义一个加载目录的函数
const requireAll = requireContext => requireContext.keys().map(requireContext)
// 加载目录下的所有 svg 文件
requireAll(req)
4. 配置svg-sprite-loader
找到vue.config.js ,添加以下配置:
chainWebpack(config) {
config.plugins.delete('preload') // TODO: need test
config.plugins.delete('prefetch') // TODO: need test
config.externals({ './cptable': 'var cptable' })
// set svg-sprite-loader
// set svg-sprite-loader
config.module
.rule('svg')
.exclude.add(resolve('src/assets/icons'))
.end()
config.module
.rule('icons')
.test(/\.svg$/)
.include.add(resolve('src/assets/icons'))
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]'
})
.end()
config
.when(process.env.NODE_ENV !== 'development',
config => {
config
.plugin('ScriptExtHtmlWebpackPlugin')
.after('html')
.use('script-ext-html-webpack-plugin', [{
// `runtime` must same as runtimeChunk name. default is `runtime`
inline: /runtime\..*\.js$/
}])
.end()
config
.optimization.splitChunks({
chunks: 'all',
cacheGroups: {
libs: {
name: 'chunk-libs',
test: /[\\/]node_modules[\\/]/,
priority: 10,
chunks: 'initial' // only package third parties that are initially dependent
},
elementUI: {
name: 'chunk-elementUI', // split elementUI into a single package
priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm
},
commons: {
name: 'chunk-commons',
test: resolve('src/components'), // can customize your rules
minChunks: 3, // minimum common number
priority: 5,
reuseExistingChunk: true
}
}
})
config.optimization.runtimeChunk('single'), {
from: path.resolve(__dirname, './public/robots.txt'), //防爬虫文件
to: './' //到根目录下
}
}
)
}
5. 在 main.js 项目入口文件中导入 icons 文件
// 在main.js 中引入
import './assets/icons' // icon
6.使用svg组件(使用的svg文件必须放在icons/svg目录下)
- icon-class:svg图片的文件名
- class-name:svg图片的样式类名 ,在类名中设置需要的样式,包括颜色,svg的样式就会随之改变。
// icon-class:svg图片的文件名
// class-name:svg图片的样式类名
<svg-icon icon-class="time" class-name="icon" />
.icon {
color: red;
}
上面有一段修改修改svg color的代码,必须在一定条件下才能生效。
注意:有时会出现改变颜色图标颜色不会发生改变的情况,这时需要打开svg文件,删除 style 标签里的每一项 fill 样式设置,这样就可以实现颜色自由切换了。或者是把 fill属性需要改成currentColor(当前颜色,如果没有则继承父节点颜色)
(4)使用CSS3 滤镜 filter 中的 drop-shadow修改图片颜色
filter drop-shadow语法:
filter: drop-shadow(x偏移 y偏移 模糊大小 颜色);
原理: drop-shadow 滤镜可以给元素或图片非透明区域添加投影,对于背景透明的png/svg小图标而言,如果我们施加一个不带模糊的投影,然后再修改css样式将这个赋色后的阴影定位到原先图片的位置,再将原先的图片隐藏不可见,我们的目的就这么轻松达成了,原先橙色的笑脸图片在鼠标经过后就变成了蓝色笑脸。
注意: 这个只适合修改纯色图片。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>使用drop-shadow改变图片颜色</title>
<style>
.logo-box {
width: 200px;
height: 200px;
border-radius: 10px;
background-color: aliceblue;
overflow: hidden;
text-align: center;
line-height: 200px;
}
.logo {
width: 60px;
height: 60px;
}
.logo:hover {
filter: drop-shadow(1000px 0 0 #1296db);
transform: translateX(-1000px);
}
</style>
</head>
<body>
<div class="logo-box">
<img src="./assets/images/smile.png" alt="" class="logo">
</div>
</body>
</html>