• react hooks 封装svg 双色(可拓展多色)图标组件


    Ⅰ- 壹 - 功能展示和使用需求

    需求描述

    根据一个颜色属性,其他图层颜色透明度降低,类似于 ant 双色图标 (https://ant.design/components/icon-cn/)
    里面拓展了 颜色 鼠标移入动画 自由控制 svg

    动画参考 https://animista.net/play/basic/slide-bck/slide-bck-tl
    图标拓展可以直接使用 https://www.iconfont.cn/ 下载 复制svg 需要自己转换下,参考下面案例案例

    功能展示

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    Ⅱ - 贰 - 封装代码

    目录结构

    在这里插入图片描述

    index.less 目前只放了动画
    index.tsx 封装的内容
    svgEnum.js svg

    index.tsx

    注:
    set16ToRgb 方法为 16进制颜色转rgba 如下

    //【16进制转换为RGB 】
    export function set16ToRgb(str:any,a:any=0){
      var reg = /^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$/
      if(!reg.test(str)){return;}
      let newStr = (str.toLowerCase()).replace(/\#/g,'')
      let len = newStr.length;
      if(len == 3){
          let t = ''
          for(var i=0;i<len;i++){
              t += newStr.slice(i,i+1).concat(newStr.slice(i,i+1))
          }
          newStr = t
      }
      let arr = []; //将字符串分隔,两个两个的分隔
      for(var i =0;i<6;i=i+2){
          let s = newStr.slice(i,i+2)
          arr.push(parseInt("0x" + s))
      }
      return 'rgb(' + arr.join(",")  +','+ a+')';
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    /*
     * @Author: whq
     * @Date: 2022-09-07 14:17:24
     * @LastEditTime: 2022-09-08 15:29:03
     * @LastEditors: whq
     * @Description: 
     * @FilePath: \ubi-mis-web\src\components\SvgIcon\index.tsx
     */
    /*
    
     *  
                                            
        
     */
    import { set16ToRgb } from "@/utils/utils";
    import svgs from "./svgEnum";
    import './index.less';
    
    interface svgIconIn {
        icon: any,//图标名称
        type?: String,//  def  正常展示  hover 鼠标划过
        hoverColor?: String,// 划过颜色设置
        defColor?: String,//默认颜色 优先级 低于 双色颜色
        twoToneColor?: String,// 双色颜色 主副颜色  设置改颜色 的时候不建议设置  hoverColor  defColor
        animationClass?: String,// 划过动画
        //默认 18 px   
        height?: String,// 
        width?: String,// 
    }
    
    const SvgIcon = (props: svgIconIn) => {
        const { type = 'def', icon, hoverColor = '#fff', defColor = '#000', twoToneColor, animationClass = '', height = '18', width = '18' } = props
        let oneColor: any = ''
        let towColor: any = ''
        switch (type) {
            case 'def':
                if (twoToneColor) {
                    oneColor = set16ToRgb(twoToneColor || '#000', '.2')
                    towColor = twoToneColor
                } else {
                    oneColor = defColor
                }
                break;
            case 'hover':
          if (twoToneColor) {
                if (hoverColor) {
                      oneColor = twoToneColor
                      towColor = hoverColor
                  } else {
                      oneColor = twoToneColor
                      towColor = '#fff'
                  }
                } else {
                    if (hoverColor) {
                        oneColor = hoverColor
                        towColor = set16ToRgb(hoverColor || '#000', '.2')
                    } else {
                        oneColor = defColor
                        towColor = set16ToRgb(defColor || '#000', '.2')
                    }
    
                }
            default:
                break;
        }
    
        return svgs[icon].getSvg(width, height, oneColor, towColor, animationClass) || <></>
    }
    export default SvgIcon
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82

    svgEnum.js

    双色图标建议只用俩图层的 方便控制

    /*
     * @Author: whq
     * @Date: 2022-09-07 14:22:53
     * @LastEditTime: 2022-09-07 14:36:00
     * @LastEditors: whq
     * @Description: 
     * @FilePath: \ubi-mis-web\src\components\SvgIcon\svgEnum.js
     */
    // s默认设置
    const defaultSvgStyle = {
        width: 18,
        height: 18,
        oneColor: '#26A08E',
        towColor: 'rgba(38,160,142,.1)',
        hoverAnimation: ''
    }
    const svgEnum = {
        'dow': {
            n: '向上',
            getSvg: (width = defaultSvgStyle.width, height = defaultSvgStyle.height, oneColor = defaultSvgStyle.oneColor, towColor = defaultSvgStyle.towColor, hoverAnimation = defaultSvgStyle.hoverAnimation) =>
                <svg className={hoverAnimation} width={width + 'px'} height={height + 'px'} fill="currentColor" viewBox="0 0 1024 1024" version="1.1" p-id="931">
                    <path d="M64 512C64 264.576 264.576 64 512 64s448 200.576 448 448-200.576 448-448 448S64 759.424 64 512z"
                        fill={oneColor} p-id="932"></path>
                    <path d="M519.66 498.558a10.672 10.672 0 0 0-15.32 0c-21.14 21.718-82.92 84.97-147.134 148.374-14.508 14.328-35.158 19.874-51.414 7.74-6.656-4.968-14.186-11.574-22.272-20.344-11.03-11.94-18.39-23.302-23.274-32.774-8.022-15.514-3.948-33.674 6.228-47.758 79.574-110.25 165.484-185.438 211.606-221.8 20.288-15.994 47.552-15.994 67.84 0 46.122 36.362 132.032 111.55 211.606 221.8 10.176 14.084 14.25 32.244 6.228 47.758-4.884 9.472-12.244 20.836-23.274 32.774-8.086 8.77-15.616 15.376-22.272 20.342-16.256 12.136-36.906 6.59-51.414-7.74-64.212-63.4-125.994-126.654-147.136-148.372z"
                        fill={towColor} p-id="933"></path></svg>
        },
        'cxfx': {
            n: '产线分析',
            getSvg: (width = defaultSvgStyle.width, height = defaultSvgStyle.height, oneColor = defaultSvgStyle.oneColor, towColor = defaultSvgStyle.towColor, hoverAnimation = defaultSvgStyle.hoverAnimation) =>
                <svg className={hoverAnimation} width={width} height={height} fill="currentColor" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5093" >
                    <path d="M948.8 13.76a41.6 41.6 0 0 1 41.6 41.6v893.44a41.6 41.6 0 0 1-37.344 41.376l-4.256 0.224H55.36a41.6 41.6 0 0 1-41.6-41.6V55.36a41.6 41.6 0 0 1 41.6-41.6h893.44z"
                        fill={oneColor} p-id="5094"></path>
                    <path d="M1004 268.544h-27.2V55.36a28 28 0 0 0-28-28v-27.2c30.496 0 55.2 24.704 55.2 55.2v213.184z m0 544h-27.2v-272h27.2v272z m-402.912 191.456v-27.2h272v27.2h-272z m-544 0v-27.2h272v27.2h-272zM0.16 465.344h27.2v272h-27.2v-272zM130.528 0.16v27.2H55.36a28 28 0 0 0-28 28v137.984h-27.2V55.36C0.16 24.864 24.864 0.16 55.36 0.16h75.2z m544 0v27.2h-272v-27.2h272zM777.28 689.92a14.4 14.4 0 0 1 14.4 14.4v14.4a14.4 14.4 0 0 1-14.4 14.4H226.88a14.4 14.4 0 0 1-13.12-14.4v-14.4a14.4 14.4 0 0 1 14.4-14.4h550.4-1.28zM602.88 270.4a187.904 187.904 0 0 1 8.96 375.68H299.2a86.4 86.4 0 0 1-58.56-150.72l5.12-3.52 3.84-3.2 3.2-2.24 231.68-173.76 5.12-4.16 5.76-4.16a184.96 184.96 0 0 1 107.52-33.92z m0 43.2a143.36 143.36 0 0 0-77.12 22.4l-4.16 2.88-5.76 3.84-4.8 3.84-233.28 175.04-2.56 1.6h-2.24l-3.84 3.2-1.92 1.92a41.92 41.92 0 0 0-12.16 26.56v3.2a43.2 43.2 0 0 0 40.96 43.2h313.28a144.64 144.64 0 0 0-7.04-288l0.64 0.32z m-296.32 224a21.76 21.76 0 1 1 0 43.52 21.76 21.76 0 0 1 0-43.52z m296.32-165.12a87.04 87.04 0 1 1-86.72 87.04 86.72 86.72 0 0 1 86.72-87.04z m0 43.52a43.52 43.52 0 1 0 43.52 43.52A43.2 43.2 0 0 0 602.88 416z" fill={towColor} p-id="5095"></path>
                </svg>,
            'xsdd': {
            n: '销售订单',
            getSvg: (width = defaultSvgStyle.width, height = defaultSvgStyle.height, oneColor = defaultSvgStyle.oneColor, towColor = defaultSvgStyle.towColor, hoverAnimation = defaultSvgStyle.hoverAnimation) =>
                <svg t="1662614061099" className={hoverAnimation} width={width} height={height} fill="currentColor" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1025">
                    <path d="M288 736m-256 0a256 256 0 1 0 512 0 256 256 0 1 0-512 0Z" fill="#D7F1F0" p-id="1026"></path>
                    <path d="M776 640h-336a24 24 0 1 0 0 48h336a24 24 0 1 0 0-48z" fill={oneColor} p-id="1027"></path>
                    <path d="M897.28 111.04h-74.56v-23.136a24.352 24.352 0 0 0-27.68-23.744C793.92 64 792.864 64 791.68 64h-367.68c-17.024 0-30.816 13.344-30.816 29.792v16.864h-81.92c-12.416 0-22.528 12.576-23.136 28.384-0.096 0.96-0.16 1.92-0.16 2.88V802.24c0 16.448 13.792 29.792 30.816 29.792h578.368c17.024 0 30.816-13.344 30.816-29.792V140.8c0.064-16.48-13.728-29.824-30.72-29.824zM442.592 158.976V111.616H773.12v47.36H442.56z m436.16 625.216H337.504V158.336h55.68v18.56c0 16.48 13.792 29.824 30.816 29.824h373.92a24.352 24.352 0 0 0 24.736-23.936v-24.128h56.064v625.6z" fill={oneColor} p-id="1028"></path>
                    <path d="M795.104 320h-83.328c-11.52 0-20.832 8.704-20.832 19.52 0 10.784 9.28 19.488 20.8 19.488h33.024l-109.888 102.848-72.128-67.52c-0.448-0.48-0.864-0.96-1.376-1.376a21.568 21.568 0 0 0-14.784-5.76 21.44 21.44 0 0 0-14.784 5.76l-1.344 1.376-124.352 116.352a18.656 18.656 0 0 0 0 27.616 21.888 21.888 0 0 0 29.472 0l111.04-103.904 73.536 68.832a21.92 21.92 0 0 0 29.632-0.064l124.544-116.576v30.912c0 10.784 9.28 19.52 20.832 19.52 11.52 0 20.832-8.736 20.832-19.52v-78.016c-0.064-10.784-9.376-19.488-20.896-19.488z" fill={oneColor} p-id="1029"></path>
                </svg>
        },
        }
    }
    
    export default svgEnum
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    index.less

    
    
    //参考  https://animista.net/play/basic/slide-bck/slide-bck-tl
    //动画 
    @keyframes rotate-center {
        0% {
          -webkit-transform: rotate(0);
                  transform: rotate(0);
        }
        100% {
          -webkit-transform: rotate(360deg);
                  transform: rotate(360deg);
        }
      }
      
      
      .rotate-center {
    	-webkit-animation: rotate-center 0.6s ease-in-out both;
    	        animation: rotate-center 0.6s ease-in-out both;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    Ⅲ - 叁 - 使用

    import SvgIcon from "../SvgIcon";
    
    //双色模式 不建议设置  hoverColor  defColor
    <SvgIcon
    	 type="hover" // 默认def  控制 鼠标移入样式控制
    	 twoToneColor="#52c41a" // 颜色控制
    	 icon={'cxfx'}//对应 svgEnum.js  key
    	 height='80'
    	 width='80'
    	 animationClass='rotate-center' // 动画的类名
    />
    
    <SvgIcon
    	 type="def"
         twoToneColor="#52c41a"
         icon={'cxfx'}
         height='80'
         width='80'
      />
    
    //普通使用
    
    <SvgIcon
         type="hover"
         // twoToneColor="#0F9D97"
         hoverColor={"#0F9D97"}
         icon={'xsdd'}
         animationClass='rotate-center'
     /> 
     
     <SvgIcon
         type="def"
         defColor={'#666666'}
         icon={'xsdd'}
     />
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
  • 相关阅读:
    批量删除所有文件名称中的英文字母
    intellij plugin(插件)的项目解析及研读
    基于大数据的农产品价格信息监测分析系统
    JAVA 校验图片视频属性
    编程-设计模式 7:桥接模式
    代码随想录动态规划——不同的子序列
    基于springboot的个人博客管理系统
    操作系统知识学习——浅析七种操作系统的递进发展
    【JS】将字符串保存成文件到本地(.txt、.json、.md...)
    jdk11新特性——官方的更新列表
  • 原文地址:https://blog.csdn.net/weixin_42863800/article/details/126745598