SVG或PNG图片颜色修改:JS 动态更改svg格式字符串的颜色、svg格式字符串转url、使用svg加载器svg-sprite-loader动态改变svg颜色、使用drop-shadow修改图片颜色

(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

uniapp开发微信小程序——实现动态修改svg图标颜色

    // 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图片。

思路:

  1. 首先,使用正则表达式 replace 方法将SVG中的注释内容去除,即 <!--(.*)--> 替换为空字符串。

  2. 然后,使用正则表达式 replace 方法将换行符和回车符替换为空格,即 [\r\n] 替换为 " "。

  3. 接下来,使用 replace 方法将双引号 " 替换为单引号 ',即 " 替换为 '。

  4. 使用 replace 方法对特殊字符进行URL编码,包括百分号 % 替换为 %25,和符号 & 替换为 %26,井号 # 替换为 %23,左大括号 { 替换为 %7B,右大括号 } 替换为 %7D,小于号 < 替换为 %3C,大于号 > 替换为 %3E。

  5. 最后,使用字符串拼接的方式,添加 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>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值