zoukankan      html  css  js  c++  java
  • 快速实现SVG动态图标

    转载自:

    作者:阿远Carry
    链接:https://juejin.cn/post/6916146797328990216
    来源:稀土掘金
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    有些小伙伴看到标题就在想

    我做这动态图片肯定不那么麻烦,我随便找几个图贴上去啊!

    我只能说:小了,格局小了!

    像有些业务场景:比如大屏项目,如果使用png.gif这类,总会失真!

    但SVG不会,SVG永远的神!

    所以,这篇文章教大家如何快速实现SVG动态图标!

    类似这样~

    1.寻找图标素材(SVG标签)

    我推荐大家去 iconfont 网站,随便找个图标

    把鼠标放在图标上,点击下载按钮

    会出现如下页面,点击复制SVG代码

    你就会得到如下代码

    <svg t="1610274780071" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="35827" width="200" height="200">
        <path d="M722.944 501.76h173.568c13.312 0 24.576-10.752 24.576-24.576 0-13.312-10.752-24.576-24.576-24.576h-173.568c-27.136 0-53.76 9.216-75.264 25.088L296.96 734.72c-3.072 2.048-6.144 3.584-9.728 4.096-8.704 1.024-17.408 1.536-26.112 1.536-39.424-1.536-75.776-18.432-102.912-48.128-27.136-30.208-40.448-69.12-37.376-109.056 5.12-69.632 55.808-123.392 121.344-132.608 1.536 29.184 7.68 57.344 18.944 84.48 4.096 9.216 12.8 15.36 22.528 15.36 3.072 0 6.144-0.512 9.216-2.048 12.288-5.12 18.432-19.456 13.312-31.744-10.24-25.088-15.36-51.712-15.36-78.848C290.816 323.584 384 230.4 498.176 230.4c92.672 0 174.592 61.952 199.68 151.04 3.584 12.8 17.408 20.48 30.208 16.896 12.8-3.584 20.48-17.408 16.896-30.208-30.72-110.08-132.096-186.88-246.784-186.88-129.024 0-236.032 95.744-253.44 219.648-93.184 8.192-165.888 82.432-173.056 178.688-3.584 52.736 14.336 105.984 50.176 145.408 35.84 39.936 84.48 62.464 137.728 64.512H266.24c9.728 0 18.944-0.512 28.672-2.048 11.776-1.536 23.04-6.656 32.256-13.312l350.72-257.024c12.288-9.728 28.672-15.36 45.056-15.36zM897.024 740.352h-301.568c-13.312 0-24.576 10.752-24.576 24.576 0 13.312 10.752 24.576 24.576 24.576h301.568c13.312 0 24.576-10.752 24.576-24.576 0-13.824-11.264-24.576-24.576-24.576z" fill="#1875F0" p-id="35828"></path>
        <path d="M643.072 598.016c-13.312 0-24.576 10.752-24.576 24.576 0 13.312 10.752 24.576 24.576 24.576h141.312c13.312 0 24.576-10.752 24.576-24.576 0-13.312-10.752-24.576-24.576-24.576h-141.312zM928.256 598.016h-62.464c-13.312 0-24.576 10.752-24.576 24.576 0 13.312 10.752 24.576 24.576 24.576h62.464c13.312 0 24.576-10.752 24.576-24.576 0-13.312-11.264-24.576-24.576-24.576zM510.464 740.352H448c-13.312 0-24.576 10.752-24.576 24.576 0 13.312 10.752 24.576 24.576 24.576h62.464c13.312 0 24.576-10.752 24.576-24.576 0-13.824-11.264-24.576-24.576-24.576z" fill="#1875F0" p-id="35829"></path>
    </svg>
    

    有的小伙伴就觉得这是啥玩意啊?我看不懂啊!

    小伙伴们,先别慌,hold住!

    其实这段代码很简单!

    就是 svg 标签嵌套了两个 path 标签罢了

    svg 标签中 viewBox="0 0 1024 1024" 属性代表是 1024 × 1024 视图

    path 标签中的 d 属性定义路径

    简单准确理解:就是在 1024 × 1024 的虚拟画布上作画

    width="200" height="200" 是控制实际svg的大小

    也就是等比例缩放,把 1024 × 1024 图片缩放到 200 × 200,还不会失真,真好!

    最后一个 path 标签中的 fill="#1875F0" 是填充色

    2. 编写动画样式 (CSS)

    再编写样式之前,我们还需要对之前svg的内容进行处理

    在每个 path 标签中

    删除 fill="#1875F0" 原本的填充颜色属性

    添加 fill="#fff" 与背景相同的填充颜色

    增加 class="icon-path" class类名

    增加 stroke="#1875F0" 描绘路径颜色属性

    增加 stroke-width="3" 描绘路径的宽度

    如下:

    
    
    <svg t="1610274780071" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="35827" width="200" height="200">
        <path class="icon-path" stroke="#1875F0" stroke-width="3" d="M722.944 501.76h173.568c13.312 0 24.576-10.752 24.576-24.576 0-13.312-10.752-24.576-24.576-24.576h-173.568c-27.136 0-53.76 9.216-75.264 25.088L296.96 734.72c-3.072 2.048-6.144 3.584-9.728 4.096-8.704 1.024-17.408 1.536-26.112 1.536-39.424-1.536-75.776-18.432-102.912-48.128-27.136-30.208-40.448-69.12-37.376-109.056 5.12-69.632 55.808-123.392 121.344-132.608 1.536 29.184 7.68 57.344 18.944 84.48 4.096 9.216 12.8 15.36 22.528 15.36 3.072 0 6.144-0.512 9.216-2.048 12.288-5.12 18.432-19.456 13.312-31.744-10.24-25.088-15.36-51.712-15.36-78.848C290.816 323.584 384 230.4 498.176 230.4c92.672 0 174.592 61.952 199.68 151.04 3.584 12.8 17.408 20.48 30.208 16.896 12.8-3.584 20.48-17.408 16.896-30.208-30.72-110.08-132.096-186.88-246.784-186.88-129.024 0-236.032 95.744-253.44 219.648-93.184 8.192-165.888 82.432-173.056 178.688-3.584 52.736 14.336 105.984 50.176 145.408 35.84 39.936 84.48 62.464 137.728 64.512H266.24c9.728 0 18.944-0.512 28.672-2.048 11.776-1.536 23.04-6.656 32.256-13.312l350.72-257.024c12.288-9.728 28.672-15.36 45.056-15.36zM897.024 740.352h-301.568c-13.312 0-24.576 10.752-24.576 24.576 0 13.312 10.752 24.576 24.576 24.576h301.568c13.312 0 24.576-10.752 24.576-24.576 0-13.824-11.264-24.576-24.576-24.576z" fill="#fff" p-id="35828"></path>
        <path class="icon-path" stroke="#1875F0" stroke-width="3" d="M643.072 598.016c-13.312 0-24.576 10.752-24.576 24.576 0 13.312 10.752 24.576 24.576 24.576h141.312c13.312 0 24.576-10.752 24.576-24.576 0-13.312-10.752-24.576-24.576-24.576h-141.312zM928.256 598.016h-62.464c-13.312 0-24.576 10.752-24.576 24.576 0 13.312 10.752 24.576 24.576 24.576h62.464c13.312 0 24.576-10.752 24.576-24.576 0-13.312-11.264-24.576-24.576-24.576zM510.464 740.352H448c-13.312 0-24.576 10.752-24.576 24.576 0 13.312 10.752 24.576 24.576 24.576h62.464c13.312 0 24.576-10.752 24.576-24.576 0-13.824-11.264-24.576-24.576-24.576z" fill="#fff" p-id="35829"></path>
    </svg>
    
    
    
    

    增加css代码:

    
    
    .icon-path {
       animation: icon-path-animation 8s ease-in infinite;
    }
    @keyframes icon-path-animation {
      0% {
        stroke-dasharray: 4917;
        stroke-dashoffset: 4917;
      }
    
      40% {
        stroke-dasharray: 4917;
        stroke-dashoffset: 0;
        fill: #fff;
      }
    
      60% {
        stroke-dasharray: 4917;
        stroke-dashoffset: 0;
        fill: #1875F0;
      }
    
      100% {
        stroke-dasharray: 4917;
        stroke-dashoffset: 0;
        fill: #1875F0;
      }
    }
    
    
    
    

    大功告成!

    哈哈哈,别急

    这里有些细节你应该明白!

    首先我们用了animation 动画属性:

    指定了 icon-path-animation 关键帧的名称

    持续时间为 8s

    ease-in 由慢到快的 动画过程

    infinite 无限次数循环

    而,在关键帧中:

    小伙伴们比较陌生的应该是 stroke-dasharraystroke-dashoffset 两个属性

    stroke-dasharray 表示 路径之间的空白间隙长度

    比如将上述 css 替换成这段代码

    
    
    .icon-path {
        stroke-dasharray: 1000;
    }
    
    
    

      

    肉眼可见的他有 1000 的间隙值

    还有,细心的小伙伴会发现 有个array的字眼

    确实他可以传“数组”进去

    例如

    
    
    .icon-path {
      stroke-dasharray: 60, 50, 60;
    }
    
    
    

     

    他就会出现

    接着就是 stroke-dashoffset 空白间隙的偏移量

    
    
    .icon-path {
      stroke-dasharray: 1000;
      stroke-dashoffset: 200;
    }
    
    
    

      

    其实你可以发现,就是空白间隙就被偏移 200

    所以,stroke-dashoffset: 4917;stroke-dashoffset: 0;

    应该是 从无到有的过程

    这个图标 最长的 path 约为 4917

    毕竟,stroke-dashoffset 空白间隙偏移为4917,那就是 4917 - 4917 = 0,此时的 path 应该 0

    而当 stroke-dashoffset 空白间隙偏移为 0, 4917 - 0 = 4917,也就是这个图标足够显示的路径长度

    或许,有的小伙伴最莫名其妙的是:你怎么知道这个图标路径长度是 4917 啊?胡说八道吗?

    其实不是我算的,我用了以下的JS代码获得的

    
    
    const iconPath = document.getElementsByClassName('icon-path') // 获取 path 标签
    for (let i = 0; i < iconPath.length; i++) {
      const item = iconPath[i]
      console.log(item.getTotalLength()) // 获得 path 路径长度
    }
    
    
    

     

    可以发现,最长度是 4916.69335937, 约为 4917

    所以,我们只要选取最长path作为最大间隙就足够!

    CSS代码连贯流程应该是:

    从 0 到 40% 绘制全部描边路径

    从 40% 到 60% 填充颜色

    从 60% 100% 保持不变

    整个过程从慢到快,持续 8s, 无限循环

    所以,看完以上你应该可以快速开发一个动态SVG图标了吧

    附上全部代码(html文件)

    
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>SVG动态图标</title>
        <style>
            .icon-path {
                animation: icon-path-animation 8s ease-in infinite;
            }
            @keyframes icon-path-animation {
                0% {
                    stroke-dasharray: 4917;
                    stroke-dashoffset: 4917;
                    fill: #fff;
                }
    
                40% {
                    stroke-dasharray: 4917;
                    stroke-dashoffset: 0;
                    fill: #fff;
                }
    
                60% {
                    stroke-dasharray: 4917;
                    stroke-dashoffset: 0;
                    fill: #1875F0;
                }
    
                100% {
                    stroke-dasharray: 4917;
                    stroke-dashoffset: 0;
                    fill: #1875F0;
                }
            }
        </style>
    </head>
    <body>
    <svg t="1610274780071" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="35827" width="200" height="200">
        <path class="icon-path" stroke="#1875F0"stroke-width="3" d="M722.944 501.76h173.568c13.312 0 24.576-10.752 24.576-24.576 0-13.312-10.752-24.576-24.576-24.576h-173.568c-27.136 0-53.76 9.216-75.264 25.088L296.96 734.72c-3.072 2.048-6.144 3.584-9.728 4.096-8.704 1.024-17.408 1.536-26.112 1.536-39.424-1.536-75.776-18.432-102.912-48.128-27.136-30.208-40.448-69.12-37.376-109.056 5.12-69.632 55.808-123.392 121.344-132.608 1.536 29.184 7.68 57.344 18.944 84.48 4.096 9.216 12.8 15.36 22.528 15.36 3.072 0 6.144-0.512 9.216-2.048 12.288-5.12 18.432-19.456 13.312-31.744-10.24-25.088-15.36-51.712-15.36-78.848C290.816 323.584 384 230.4 498.176 230.4c92.672 0 174.592 61.952 199.68 151.04 3.584 12.8 17.408 20.48 30.208 16.896 12.8-3.584 20.48-17.408 16.896-30.208-30.72-110.08-132.096-186.88-246.784-186.88-129.024 0-236.032 95.744-253.44 219.648-93.184 8.192-165.888 82.432-173.056 178.688-3.584 52.736 14.336 105.984 50.176 145.408 35.84 39.936 84.48 62.464 137.728 64.512H266.24c9.728 0 18.944-0.512 28.672-2.048 11.776-1.536 23.04-6.656 32.256-13.312l350.72-257.024c12.288-9.728 28.672-15.36 45.056-15.36zM897.024 740.352h-301.568c-13.312 0-24.576 10.752-24.576 24.576 0 13.312 10.752 24.576 24.576 24.576h301.568c13.312 0 24.576-10.752 24.576-24.576 0-13.824-11.264-24.576-24.576-24.576z" fill="#fff" p-id="35828"></path>
        <path class="icon-path" stroke="#1875F0" stroke-width="3" d="M643.072 598.016c-13.312 0-24.576 10.752-24.576 24.576 0 13.312 10.752 24.576 24.576 24.576h141.312c13.312 0 24.576-10.752 24.576-24.576 0-13.312-10.752-24.576-24.576-24.576h-141.312zM928.256 598.016h-62.464c-13.312 0-24.576 10.752-24.576 24.576 0 13.312 10.752 24.576 24.576 24.576h62.464c13.312 0 24.576-10.752 24.576-24.576 0-13.312-11.264-24.576-24.576-24.576zM510.464 740.352H448c-13.312 0-24.576 10.752-24.576 24.576 0 13.312 10.752 24.576 24.576 24.576h62.464c13.312 0 24.576-10.752 24.576-24.576 0-13.824-11.264-24.576-24.576-24.576z" fill="#fff" p-id="35829"></path>
    </svg>
    <script>
        const iconPath = document.getElementsByClassName('icon-path') // 获取 path 标签
        for (let i = 0; i < iconPath.length; i++) {
            const item = iconPath[i]
            console.log(item.getTotalLength()) // 获得 path 路径长度
        }
    </script>
    </body>
    </html>
    
    
    

      

    最后:

    本篇只是实现了简单动画效果

    如果想要复杂效果,无非是写好几个不同 animation

    如果小伙伴们认真看完明白其中原理,就可以完实现出来的

  • 相关阅读:
    Hibernate_一对多映射_2
    Hibernate框架_1 单表映射 _2
    JS
    Hibernate框架_1 单表映射
    Spring_1
    Javabean
    JAVA注解(JDK1.5开始)
    JAVA方法的反射
    JAVA-Reflect(反射)1
    Android初学:Gradle 'HelloWorld' project refresh failed
  • 原文地址:https://www.cnblogs.com/jeacy/p/15726275.html
Copyright © 2011-2022 走看看