微信小程序中如何实现动态改变SVG颜色和尺寸

目录
  • 前言
  • 1. 创建一个微信小程序项目,准备好SVG素材
  • 2. 封装修改svg颜色的工厂函数
  • 3. 封装一个自定义组件,方便使用svg图标
  • 4. 注册组件,使用
  • 结语
  • 总结

前言

最近在做项目的时候总是因为组件库的图标无法满足需求而烦恼,而每次需要新的图标又要去找字体图标、生成新的css代码而苦恼。

所以想到用svg来代替,体积也小,主要就是方便一点,不用每次还重新生成代码。但是一个最重要的问题也随之出现,小程序中不支持svg代码....但是也有曲线救国的方式,image可以显示svg,还好没有赶尽杀绝。

但随之而来的又是一个新的问题,虽然能显示svg,但是并不能动态改变颜色呀!偶天哪。。。又但是,image的src支持base64,哎呀,这思路不就来了吗,既然你能base64,我还不能修改base64了?说干就干,那就来吧!

1. 创建一个微信小程序项目,准备好SVG素材

创建好项目之后,就到iconfont上找两个图标的svg吧!那么怎么管理svg呢?首先我们需要将svg代码base64编码

例如:

<svg t="1656728349217" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2589" width="200" height="200"><path d="M874.666667 467.2c-10.666667-10.666667-29.866667-12.8-42.666667 0l-343.466667 341.333333c-74.666667 74.666667-198.4 74.666667-275.2 0-36.266667-36.266667-57.6-85.333333-57.6-136.533333s19.2-100.266667 57.6-136.533333L556.8 192c46.933333-46.933333 121.6-46.933333 168.533333 0 23.466667 23.466667 34.133333 53.333333 34.133334 83.2 0 32-12.8 61.866667-34.133334 83.2L384 704c-17.066667 17.066667-44.8 17.066667-64 0-8.533333-8.533333-12.8-19.2-12.8-32s4.266667-23.466667 12.8-32l317.866667-315.733333c10.666667-10.666667 12.8-29.866667 0-42.666667-10.666667-12.8-29.866667-12.8-42.666667 0L277.333333 597.333333c-19.2 19.2-29.866667 46.933333-29.866666 74.666667S258.133333 725.333333 277.333333 746.666667c40.533333 40.533333 106.666667 40.533333 147.2 0L768 403.2c34.133333-34.133333 53.333333-78.933333 53.333333-125.866667s-19.2-93.866667-53.333333-125.866666a178.986667 178.986667 0 0 0-253.866667 0l-341.333333 341.333333c-46.933333 46.933333-74.666667 110.933333-74.666667 179.2s25.6 132.266667 74.666667 179.2c49.066667 49.066667 115.2 74.666667 179.2 74.666667s130.133333-25.6 179.2-74.666667l343.466667-341.333333c10.666667-12.8 10.666667-32 0-42.666667z" p-id="2590"></path></svg>

转为image支持的base64代码

data:image/svg+xml;base64,PHN2ZyB0PSIxNjU2NzI4MzQ5MjE3IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjI1ODkiIHdpZHRoPSIyMDAiIGhlaWdodD0iMjAwIj48cGF0aCBkPSJNODc0LjY2NjY2NyA0NjcuMmMtMTAuNjY2NjY3LTEwLjY2NjY2Ny0yOS44NjY2NjctMTIuOC00Mi42NjY2NjcgMGwtMzQzLjQ2NjY2NyAzNDEuMzMzMzMzYy03NC42NjY2NjcgNzQuNjY2NjY3LTE5OC40IDc0LjY2NjY2Ny0yNzUuMiAwLTM2LjI2NjY2Ny0zNi4yNjY2NjctNTcuNi04NS4zMzMzMzMtNTcuNi0xMzYuNTMzMzMzczE5LjItMTAwLjI2NjY2NyA1Ny42LTEzNi41MzMzMzNMNTU2LjggMTkyYzQ2LjkzMzMzMy00Ni45MzMzMzMgMTIxLjYtNDYuOTMzMzMzIDE2OC41MzMzMzMgMCAyMy40NjY2NjcgMjMuNDY2NjY3IDM0LjEzMzMzMyA1My4zMzMzMzMgMzQuMTMzMzM0IDgzLjIgMCAzMi0xMi44IDYxLjg2NjY2Ny0zNC4xMzMzMzQgODMuMkwzODQgNzA0Yy0xNy4wNjY2NjcgMTcuMDY2NjY3LTQ0LjggMTcuMDY2NjY3LTY0IDAtOC41MzMzMzMtOC41MzMzMzMtMTIuOC0xOS4yLTEyLjgtMzJzNC4yNjY2NjctMjMuNDY2NjY3IDEyLjgtMzJsMzE3Ljg2NjY2Ny0zMTUuNzMzMzMzYzEwLjY2NjY2Ny0xMC42NjY2NjcgMTIuOC0yOS44NjY2NjcgMC00Mi42NjY2NjctMTAuNjY2NjY3LTEyLjgtMjkuODY2NjY3LTEyLjgtNDIuNjY2NjY3IDBMMjc3LjMzMzMzMyA1OTcuMzMzMzMzYy0xOS4yIDE5LjItMjkuODY2NjY3IDQ2LjkzMzMzMy0yOS44NjY2NjYgNzQuNjY2NjY3UzI1OC4xMzMzMzMgNzI1LjMzMzMzMyAyNzcuMzMzMzMzIDc0Ni42NjY2NjdjNDAuNTMzMzMzIDQwLjUzMzMzMyAxMDYuNjY2NjY3IDQwLjUzMzMzMyAxNDcuMiAwTDc2OCA0MDMuMmMzNC4xMzMzMzMtMzQuMTMzMzMzIDUzLjMzMzMzMy03OC45MzMzMzMgNTMuMzMzMzMzLTEyNS44NjY2NjdzLTE5LjItOTMuODY2NjY3LTUzLjMzMzMzMy0xMjUuODY2NjY2YTE3OC45ODY2NjcgMTc4Ljk4NjY2NyAwIDAgMC0yNTMuODY2NjY3IDBsLTM0MS4zMzMzMzMgMzQxLjMzMzMzM2MtNDYuOTMzMzMzIDQ2LjkzMzMzMy03NC42NjY2NjcgMTEwLjkzMzMzMy03NC42NjY2NjcgMTc5LjJzMjUuNiAxMzIuMjY2NjY3IDc0LjY2NjY2NyAxNzkuMmM0OS4wNjY2NjcgNDkuMDY2NjY3IDExNS4yIDc0LjY2NjY2NyAxNzkuMiA3NC42NjY2NjdzMTMwLjEzMzMzMy0yNS42IDE3OS4yLTc0LjY2NjY2N2wzNDMuNDY2NjY3LTM0MS4zMzMzMzNjMTAuNjY2NjY3LTEyLjggMTAuNjY2NjY3LTMyIDAtNDIuNjY2NjY3eiIgcC1pZD0iMjU5MCI+PC9wYXRoPjwvc3ZnPg==

这里对转换之后的结果做一个说明,共分成三部分:

  • data:image/svg+xml;base64首部的这一串作为固定值,让image能够识别你给它的是什么东西,是一个图片、svg+xml格式的、经过了base64编码的,这个解释不是专业的哈,能看懂就行。
  • 一个英文逗号,将前后隔离开。
  • 逗号后面的就是svg代码base64编码之后得到的字符串,这就是我们可操作的字符串啦

接下来,在小程序中新建一个文件/asstes/SvgManager.js用来管理我们全部的svg代码,因为要操作svg的base64,最好就直接在项目中存储,将转换为base64字符串的svg通过export导出去

export default {
    attachment: 'data:image/svg+xml;base64,PHN2ZyB0PSIxNjU2NzI4MzQ5MjE3IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjI1ODkiIHdpZHRoPSIyMDAiIGhlaWdodD0iMjAwIj48cGF0aCBkPSJNODc0LjY2NjY2NyA0NjcuMmMtMTAuNjY2NjY3LTEwLjY2NjY2Ny0yOS44NjY2NjctMTIuOC00Mi42NjY2NjcgMGwtMzQzLjQ2NjY2NyAzNDEuMzMzMzMzYy03NC42NjY2NjcgNzQuNjY2NjY3LTE5OC40IDc0LjY2NjY2Ny0yNzUuMiAwLTM2LjI2NjY2Ny0zNi4yNjY2NjctNTcuNi04NS4zMzMzMzMtNTcuNi0xMzYuNTMzMzMzczE5LjItMTAwLjI2NjY2NyA1Ny42LTEzNi41MzMzMzNMNTU2LjggMTkyYzQ2LjkzMzMzMy00Ni45MzMzMzMgMTIxLjYtNDYuOTMzMzMzIDE2OC41MzMzMzMgMCAyMy40NjY2NjcgMjMuNDY2NjY3IDM0LjEzMzMzMyA1My4zMzMzMzMgMzQuMTMzMzM0IDgzLjIgMCAzMi0xMi44IDYxLjg2NjY2Ny0zNC4xMzMzMzQgODMuMkwzODQgNzA0Yy0xNy4wNjY2NjcgMTcuMDY2NjY3LTQ0LjggMTcuMDY2NjY3LTY0IDAtOC41MzMzMzMtOC41MzMzMzMtMTIuOC0xOS4yLTEyLjgtMzJzNC4yNjY2NjctMjMuNDY2NjY3IDEyLjgtMzJsMzE3Ljg2NjY2Ny0zMTUuNzMzMzMzYzEwLjY2NjY2Ny0xMC42NjY2NjcgMTIuOC0yOS44NjY2NjcgMC00Mi42NjY2NjctMTAuNjY2NjY3LTEyLjgtMjkuODY2NjY3LTEyLjgtNDIuNjY2NjY3IDBMMjc3LjMzMzMzMyA1OTcuMzMzMzMzYy0xOS4yIDE5LjItMjkuODY2NjY3IDQ2LjkzMzMzMy0yOS44NjY2NjYgNzQuNjY2NjY3UzI1OC4xMzMzMzMgNzI1LjMzMzMzMyAyNzcuMzMzMzMzIDc0Ni42NjY2NjdjNDAuNTMzMzMzIDQwLjUzMzMzMyAxMDYuNjY2NjY3IDQwLjUzMzMzMyAxNDcuMiAwTDc2OCA0MDMuMmMzNC4xMzMzMzMtMzQuMTMzMzMzIDUzLjMzMzMzMy03OC45MzMzMzMgNTMuMzMzMzMzLTEyNS44NjY2NjdzLTE5LjItOTMuODY2NjY3LTUzLjMzMzMzMy0xMjUuODY2NjY2YTE3OC45ODY2NjcgMTc4Ljk4NjY2NyAwIDAgMC0yNTMuODY2NjY3IDBsLTM0MS4zMzMzMzMgMzQxLjMzMzMzM2MtNDYuOTMzMzMzIDQ2LjkzMzMzMy03NC42NjY2NjcgMTEwLjkzMzMzMy03NC42NjY2NjcgMTc5LjJzMjUuNiAxMzIuMjY2NjY3IDc0LjY2NjY2NyAxNzkuMmM0OS4wNjY2NjcgNDkuMDY2NjY3IDExNS4yIDc0LjY2NjY2NyAxNzkuMiA3NC42NjY2NjdzMTMwLjEzMzMzMy0yNS42IDE3OS4yLTc0LjY2NjY2N2wzNDMuNDY2NjY3LTM0MS4zMzMzMzNjMTAuNjY2NjY3LTEyLjggMTAuNjY2NjY3LTMyIDAtNDIuNjY2NjY3eiIgcC1pZD0iMjU5MCI+PC9wYXRoPjwvc3ZnPg=='
}

2. 封装修改svg颜色的工厂函数

开始之前,我们要先明白,svg是如何改变颜色的。

svg中有一个属性fill,这里就是用来填写svg的填充颜色的,支持十六进制,例如#ff0000就是红色,也可以填写red,跟css差不多,明白这一点就可以进行接下来的操作了。

工厂函数代码: 实现思路就是将SVG的base64字符串解码之后得到svg代码,替换svg的fill属性来改变颜色,然后再Base64编码回去。Base64的代码网上随便找一份就行,文章尾部会贴出代码片段,内含Base64代码

import { Base64 } from "./Base64";
export const getColorSVG = (svgBase64, color) => {
    try {
        svgBase64 = svgBase64.substring(svgBase64.indexOf(',') + 1, svgBase64.length); // 取出第三部分
        const svg = Base64.decode(svgBase64); // 解码得到svg代码

        if (/<svg /.test(svg)) { // 先简单判断是一下否是一个svg
            let newSvg;
            if (/fill=".*?"/.test(svg)) {
                newSvg = svg.replace(/fill=".*?"/, `fill="${color}"`);  // SVG有默认色
            } else {
                newSvg = svg.replace(/<svg /, `<svg fill="${color}"`); // 无默认色
            }
            return 'data:image/svg+xml;base64,' + Base64.encode(newSvg); // 替换完之后再组合回去
        }
    } catch { }
    return '';
};

3. 封装一个自定义组件,方便使用svg图标

新建一个组件,保存在/components/m-icon/index

  • JS
import SvgManager from "../../asstes/SvgManager"
import { getColorSVG } from "../../utils/tools"

Component({
    options: {
        styleIsolation: 'apply-shared',
        virtualHost: true
    },
    properties: {
        /** 图标名称 */
        name: {
            type: String,
            value: ''
        },
        /** 图标颜色 */
        color: {
            type: String,
            value: '#000000'
        },
        size: {
            type: String,
            value: '28rpx'
        }
    },
    observers: {
        // 监听名称和颜色变化
        'name,color': function (name, color) {
            this.changeIcon(name, color);
        }
    },
    data: {
        svgData: ''
    },

    methods: {
        changeIcon(name, color) {
            let svgBase64 = SvgManager[name]; // 从svg管理器中取出对应svg
            svgBase64 = getColorSVG(svgBase64, color); // 替换它的颜色
            this.setData({
                svgData: svgBase64 // 渲染
            });
        }
    }
})
  • WXML
<view class="m-icon" style="width: {{ size }};">
    <image
        src="{{ svgData }}"
        mode="widthFix"
    ></image>
</view>
  • WXSS
.m-icon image {
    width: 100%;
}

4. 注册组件,使用

  • 注册,在要使用的页面注册或全局注册,我这里就全局注册了,在app.json添加以下配置
{
    ...setting,
    "usingComponents": {
        "m-icon": "/components/m-icon/index"
    },
}

然后就可以愉快地在任何页面使用我们自己的icon组件了

<m-icon
    name="attachment"
    color="red"
    size="30rpx"
/>
<m-icon
    name="attachment"
    color="green"
    size="60rpx"
/>
<m-icon
    name="attachment"
    color="blue"
    size="90rpx"
/>

结语

动态改变svg就一个思路,image支持base64,svg有fill属性可以改变颜色,我们可以操作字符串替换fill,ok,就到这里结束啦!有更好的思路欢迎大家提出.。 本文项目代码:github.com/daofeng-cod…

总结

到此这篇关于微信小程序中如何实现动态改变SVG颜色和尺寸的文章就介绍到这了,更多相关小程序动态改变SVG颜色尺寸内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 微信小程序里使用SVG矢量图标方法详解

    在微信小程序开发过程中需要在小程序里使用SVG矢量图标,至于为什么要使用SVG图标相信看到这篇文章的你应该明白,如果你不明白请百度一下 微信小程序里使用SVG矢量图标有2种引入方法: 一.SVG图标转换为BASE64编码 使用 http://tools.jb51.net/transcoding/img2base64 工具把需要引入的SVG图标转换成BASE64编码 注意:生成BASE64编码时需要把开头的 data:image/svg; 修改成 data:image/svg+xml; 这个在线工

  • 微信小程序里引入SVG矢量图标的方法

    引言 因为微信小程序的限制,引入外部图片或者矢量图,只能通过设置背景图片background-image : url("base64转码后的代码");的方式来进行操作.同时还是因为微信小程序的限制,我们要先把svg的xml编码转码为base64编码 首先,说明以下我们常见的svg矢量图是什么?下面引用百度百科的话: svg是基于可扩展标记语言(标准通用标记语言的子集),用于描述二维矢量图形的一种图形格式 可能还是比较迷糊,那我们来看看,用记事本打开一个svg,里面的编码是什么: <

  • 详解如何愉快的在微信小程序中使用SVG图标

    SVG近几年因各种优势被大量的应用,遗憾的是到目前为止微信小程序并不支持以XML的形式使用SVG,这使得SVG的灵活性大大下降,大多数人选择放弃在微信小程序中使用SVG图标方案. 那么,真的就没有办法在微信小程序中愉快的使用SVG图标了吗?我们先来分析一下,对于使用SVG图标我们有哪些需求: 能够引入使用 能够调整颜色 首先第一点是没有问题的,微信小程序支持以Image.src的形式引入SVG.接下来就是本文的重点部分了,如何让使Image形式的SVG可以改变颜色. 在最近对CSS的学习中,我发

  • 微信小程序中如何实现动态改变SVG颜色和尺寸

    目录 前言 1. 创建一个微信小程序项目,准备好SVG素材 2. 封装修改svg颜色的工厂函数 3. 封装一个自定义组件,方便使用svg图标 4. 注册组件,使用 结语 总结 前言 最近在做项目的时候总是因为组件库的图标无法满足需求而烦恼,而每次需要新的图标又要去找字体图标.生成新的css代码而苦恼. 所以想到用svg来代替,体积也小,主要就是方便一点,不用每次还重新生成代码.但是一个最重要的问题也随之出现,小程序中不支持svg代码....但是也有曲线救国的方式,image可以显示svg,还好没

  • 微信小程序基于slider组件动态修改标签透明度的方法示例

    本文实例讲述了微信小程序基于slider组件动态修改标签透明度的方法.分享给大家供大家参考,具体如下: 1.效果展示 2.关键代码 index.wxml <view class="img" style="opacity:{{imgOpacity}}"></view> <slider min="0" max="1" step="0.1" show-value value=&quo

  • 微信小程序中的店铺评分组件及vue中用svg实现的评分显示组件

    在微信小程序中,有遇到要展示店铺评分,或者是订单完成后对商品进行评价,用到了星星展示,查了下,在微信中无法使用svg实现图片,微信中只能将svg图片转成base64来显示,所以是在vue中使用的svg来实现评分 1.效果图 微信中的可以点击及显示,但是,显示的话,在4.2分,4点多分的时候,显示的是半颗星 vue中用的是svg实现,所以用的是占比的形式,可以有一点点的星 2.微信实现店铺评分显示及商品评价星星展示 子组件index.wxml,可以动态的控制星星的大小 <!-- (size * s

  • 详解微信小程序中var、let、const用法与区别

    微信小程序可以使用Javascript的最新ES6标准来开发所以微信小程序中var.let.const用法与区别可以视为Javascript ES6标准中var.let.const用法与区别 let命令 基本用法 ES6 新增了let命令,用来声明变量.它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效. { let a = 10; var b = 1; } a // ReferenceError: a is not defined. b // 1 上面代码在代码块之中,分

  • 微信小程序 动态绑定数据及动态事件处理

    微信小程序 动态绑定数据及动态事件处理 关键核心代码 <image class="midimage" data-Type="{{item.Type}}" data-BillCode="{{item.BillCode}}" data-src="{{item.imgurl}}" src="{{item.imgurl}}" mode="scaleToFill" bindtap="

  • 微信小程序 input输入及动态设置按钮的实现

    微信小程序 input输入及动态设置按钮的实现 [需求]实现当手机号已填写和协议已勾选时,"立即登录"按钮变亮,按钮可点击:若有一个不满足,按钮置灰,不可点击:实现获取短信验证码,倒计时提示操作:对不满足要求内容进行toast弹窗提示. <view class="container"> <!--手机号--> <view class="section"> <text class="txt"

  • 微信小程序中hidden不生效原因的解决办法

    微信小程序中hidden不生效原因的解决办法 例如如下布局: <view hidden="true" style="display:flex;flex-direction: row;"> <text>text1</text> <text>text2</text> </view> 你会发现hidden没生效.经我实验发现hidden元素对块状布局才生效,所以这段代码里导致hidden没生效的罪魁祸

  • 详解微信小程序中的页面代码中的模板的封装

    详解微信小程序中的页面代码中的模板的封装 最近在进行微信小程序中的页面开发,其实在c++或者说是js中都会出现这种情况,就是相同的代码会反复出现,这就是进行一定的封装,封装的好处就是可以是程序中在于减少一定的代码量,并且可是使代码结构更加清晰.那今天所要记录的就是关于微信小程序中的页面的模板封装. 在微信小程序中的文件名都带有wxml等样式,在wxml中提供了模板,即可以在模板中定义代码片段,然后可以在页面中的不同位置进行调用,模板的定义: <templatename="products&

  • 微信小程序中为什么使用var that=this

    前言: 在小程序或者js开发中,经常需要使用var that = this;开始我以为是无用功,(原谅我的无知),后来从面向对象的角度一想就明白了,下面简单解释一下我自己的理解,欢迎指正批评. 代码示例: Page({ data: { test:10 }, testfun1: function () { console.log(this.data.test) // 10 function testfun2(){ console.log(this.data.test) //undefined }

  • 解决微信小程序中的滚动穿透问题

    Mask-Scroll > 原码地址 * 蒙层防穿透问题 > 蒙层穿透就是,当你用fixed 布局让蒙层显示的时候, 手指滑动屏幕会出现底部内容也滑动的现象. 如图: 当蒙层出现的时候,你滚动屏幕,底部内容也一起跟着滚动. 这就是蒙层穿透, 也可以叫 '滚动穿透'. 当然出现这种情况, 用户体验当然是不好的了. 所以作为一个有点追求的工程师当然是不允许这种情况的发生了(手动狗头...) ## 解决方案 这种要分情况, 当蒙层没有滚动条的时候. 当蒙层出现滚动条的时候 1. 当弹窗没有滚动条的时

随机推荐