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+')';
}

/*
 * @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
 */
/*

 * <SvgIcon
        type="hover"
        twoToneColor="#52c41a"
        icon={'cxfx'}
        height='80'
        width='80'
        hoverAnimation='rotate-center'
    /> 
                                        
    <SvgIcon
        type="def"
        twoToneColor="#52c41a"
        icon={'cxfx'}
        height='80'
        width='80'
    />
 */
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

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

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;
}

Ⅲ - 叁 - 使用

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'}
 />



猜你喜欢

转载自blog.csdn.net/weixin_42863800/article/details/126745598
今日推荐