SVG animation from entry to actual combat, improve the performance of your website

In SVG, if we want to achieve an animation effect, we can use CSS , JS , or directly use the  animate elements that come with SVG ( SMIL ).

Here we mainly discuss some common animation effects realized by SVG and CSS.

(The basic knowledge of SVG to be used below is described in detail in  SVG from entry to icon drawing and component encapsulation and Transform in SVG - translation, rotation and zooming  . It will not be repeated here, if necessary Friends can go to check it out.)

Basics of SVG + CSS animation implementation

HTML5 supports inline SVG, we can use it SVG元素as htmla kind of tag directly in the page structure and become part of the DOM, which also allows us to use CSS to style it, which is also the basis for SVG + CSS animation.

<svg>
   <rect width="100" height="100" fill="gold" />
</svg>
复制代码

The above code snippet draws a golden square with a width and height of 100px on the page. Here we use tag attributes to describe its width, height and fill color. In fact, we can also write these styles in CSS.

<svg>
   <rect />
</svg>
复制代码
rect{
   width: 100px;
   height: 100px;
   fill: gold;
}
复制代码

Since CSS can be used for SVG style development, then combining animation, transition, transform, makes the style of SVG elements change dynamically, and then we can achieve the desired animation effect.

rect{
   width: 100px;
   height: 100px;
   fill: gold;
   transition: fill 1s linear;
}
rect:hover{
   fill: greenyellow;
}
复制代码

hover-color-change.gif

Transform-based shape transformation animation

Like ordinary HTML elements, SVG elements can be transformed by transformtranslation, rotation, and scaling.

But the transformation reference points of the two are different. For ordinary HTML elements, the reference point for transformation, the default value is 50% 50% of the center position of the element itself in the x and y directions (only the two-dimensional plane is considered here), that is, the rotation, shift, scaling and other operations of the element are all It is based on the center position of the element itself in the x and y directions.

而SVG元素,变换的参考点,是在SVG画布的0 0的位置(默认是<svg>元素的左上角)。

image.png

理解这一点对于理解SVG元素的transform变换非常重要,我们在前面的两篇文章中进行了非常详尽的讲解:

SVG从入门到图标绘制和组件封装

SVG中的Transform详解---平移、旋转和缩放

仿B站直播图标

动画实现

<svg height="100" width="100" viewBox="0 0 100 100">
    <line class="beat" x1="15" y1="40" x2="15" y2="100" stroke="lightblue" stroke-width="10" stroke-linecap="round"></line>
    <line class="beat" x1="50" y1="40" x2="50" y2="100" stroke="lightblue" stroke-width="10"  stroke-linecap="round"></line>
    <line class="beat" x1="85" y1="40" x2="85" y2="100" stroke="lightblue" stroke-width="10"  stroke-linecap="round"></line>
</svg>
复制代码

使用<line>标签绘制三条竖直的线条,(x1,y1)是线条起始点的坐标,(x2,y2)是线条终点的坐标。

image.png

(为了方便观察,我们给svg设置一个蓝色边框。)

接着,通过keyframes动画,不断改变scaleY,让线条在Y方向进行缩放。

.beat{
    transform-origin: bottom;   //将变换参考点设置成`<svg>元素`的底部
    animation: beat-scale 1.4s linear infinite;
}
        
@keyframes beat-scale{
    25%{
         transform: scaleY(0.3);
    }
    50%{
         transform: scaleY(1);
    }
    75%{
         transform: scaleY(0.3);
    }
}
复制代码

beat-0.gif

最后,通过设置animation-delay,让三段线条交错运动。

.beat:nth-child(1){
    animation-delay: 0.4s;
}
.beat:nth-child(2){
    animation-delay: 0.2s;
}
复制代码

beat-11.gif

组件封装

实现了动画,接下来就是把图标进行组件封装,以便一次定义,多处引用。

参考:SVG组件封装

两个改造点:

  • 1、将<line>标签都放到<symbol>中,<symbol>标签设置viewBox="0 0 100 100"
  • 2、将stroke="lightblue"改成stroke="currentColor",在使用svg图标时,颜色就会从父元素的color属性继承。
<svg height="0" width="0">
    <symbol id="beats" viewBox="0 0 100 100" >
        <line class="beat" x1="15" y1="40" x2="15" y2="100" stroke="currentColor" stroke-width="10" stroke-linecap="round"></line>
        <line class="beat" x1="50" y1="40" x2="50" y2="100" stroke="currentColor" stroke-width="10"  stroke-linecap="round"></line>
        <line class="beat" x1="85" y1="40" x2="85" y2="100" stroke="currentColor" stroke-width="10"  stroke-linecap="round"></line>
    </symbol>
</svg>
复制代码

使用:

<span style="color:#ff6699; border: 1px solid #ff6699;border-radius: 5px; padding-left: 5px; font-size: 24px;">
    <svg height="30" width="30">
         <use href="#beats"></use>   <!--href="#beats"所指向的就是上面<symbol>标签的id-->
    </svg>
    <span>直播中</span>
</span>
复制代码

beat-3.gif

加载时钟

<svg height="100" width="100" viewBox="-52 -52 104 104">
   <circle fill="none" stroke="#DE3E35" stroke-width="6" stroke-miterlimit="10" cx="0" cy="0" r="48"/>
   <line class="fast-hand" fill="none" stroke-linecap="round" stroke="#DE3E35" stroke-width="6" stroke-miterlimit="10" x1="0" y1="0" x2="35" y2="0.5"></line>
   <line class="slow-hand" fill="none" stroke-linecap="round" stroke="#DE3E35" stroke-width="6" stroke-miterlimit="10" x1="0" y1="0" x2="-0.5" y2="-24"></line>
</svg>
复制代码

<circle>标签绘制时钟轮廓,两个<line>绘制长针和短针。

image.png

长短针的旋转,我们希望绕图标自身中心点进行。

我们知道,SVG元素变换的参考点,是在SVG画布的0 0的位置。那么如果图标的中心点SVG画布0 0的位置重叠,那图标岂不就绕自身中心点进行旋转。

因此,我们将<circle>标签圆心坐标设为(0,0)(cx="0" cy="0"),同时长短针的起点坐标也设为(0,0)。为了图形显示完全,设置<svg>元素的viewBox属性为"-52 -52 104 104"

image.png

动画的实现就是通过keyframes动画,不断改变长短针的rotate角度,由于两者旋转速度不同,所以动画时间设置不同。

.fast-hand{
   animation: clock-rotate 2s linear infinite;  /*动画时间设置不同*/
}
.slow-hand{
   animation: clock-rotate 15s linear infinite;  /*动画时间设置不同*/
}
@keyframes clock-rotate{
   0%{
        transform: rotate(0deg);
   }
   100%{
        transform: rotate(360deg);
   }
}
复制代码

clock-1.gif

封装成组件的代码和使用案例如下:

<svg height="0" width="0">
   <symbol id="clock" viewBox="-52 -52 104 104">
       <circle fill="none" stroke="currentColor" stroke-width="6" stroke-miterlimit="10" cx="0" cy="0" r="48"/>
       <line class="fast-hand" fill="none" stroke-linecap="round" stroke="currentColor" stroke-width="6" stroke-miterlimit="10" x1="0" y1="0" x2="35" y2="0.5"></line>
       <line class="slow-hand" fill="none" stroke-linecap="round" stroke="currentColor" stroke-width="6" stroke-miterlimit="10" x1="0" y1="0" x2="-0.5" y2="-24"></line>
   </symbol>
</svg>
<div style="color:#fa8919; font-size: 16px;" >        
    <svg height="26" width="26" style="vertical-align: top; margin-top: -2px;margin-right:3px;">
        <use href="#clock"></use>
    </svg>
    <span>等待中</span>  
</div>
复制代码

clock-2.gif

描边动画

常用 SVG + CSS 来实现的,除了transform + animation/transition这种组合实现图标的形状变换动画,另一种用处非常广泛的就是描边动画。

stroke-dasharray & stroke-dashoffset

描边动画的核心是 SVG 的两个显示属性,分别是 stroke-dasharraystroke-dashoffset

stroke-dasharray用于创建虚线。它的值是一个序列,可以传入多个值,分别指定虚线中线段和间隔的长度。

stroke-dasharray = '10, 20' 表示:线段10,间距20,然后重复 线段10,间距20。。。

该参数序列可以是一到多个数值,当数值的个数为奇数时,会自动复制一份,再生效。

比如stroke-dasharray = '10'相当于stroke-dasharray = '10, 10'

stroke-dasharray = '10, 20, 30'相当于stroke-dasharray = '10, 20, 30, 10, 20, 30',此时的绘制规则是:线段10,间距20,线段30,间距10,线段20,间距30,然后重复。。。

image.png stroke-dashoffset: 描述相对于起始点的偏移。它的值是一个数值X,X>0时,相当于往左移动了X个长度单位; X<0时,相当于往右移动了X个长度单位。

stroke-dashoffset只有在设置了stroke-dasharray的情况下,才生效,非虚线的话,是无法看出偏移的。

image.png

对于一条线l,如果设置stroke-dasharray = 'l.length',那么显示出来的就只有线段,没有间隔,相当于实线效果。而此时如果stroke-dashoffset='l.length',那线l就往左移动了l.length个长度单位,显示出来的就只有间隔,没有线段,相当于空白的效果。

如果stroke-dashoffset的值从l.length-->0,线段就会逐渐显示出来。从而产生描边的效果。

offset3.gif

描边效果的动画在开发中有很多应用场景,比如各种形状的进度条,图标或文字的描边,以及一些酷炫的按钮边框动画等。

案例实现

环形进度条

首先,我们将stroke-dasharraystroke-dashoffset都设为圆环的周长;然后根据进度progress计算动态计算出新的stroke-dashoffset,即(1-progress) * 圆环的周长

circle-progress.gif

计算圆环周长的方法:

  • 1、在已知半径的情况下,可以根据公式2*Pi*r求得周长。
  • 2、SVG的形状元素都有一个getTotalLength的方法,可以获取该形状的路径总长度,对于规则和不规则的形状都适用。
//页面结构
<div data-name="loading" data-percent="26%" class="progress">
    <svg height="200" width="200" viewBox="0 0 100 100">
        <!--灰色的背景圆环-->
        <circle cx="50" cy="50" r="40" stroke-width="5" stroke="#d1d3d7" fill="none"></circle>
        <!--蓝色的动态圆环-->
        <circle       
              class="process-circle" 
              cx="50" cy="50" r="40" 
              transform="rotate(-90 50 50)"
              stroke-width="5" 
              stroke="#00a5e0" 
              fill="none" 
              stroke-linecap="round"
              stroke-dasharray="251"></circle>
      </svg> 
</div>
<div class="adjust">
     调整进度:<input value="26" type="range" min="0" max="100" id="range" />
</div>
复制代码
//js代码,获取圆环周长,并在调整进度后改变蓝色圆环的stroke-dashoffset
<script>
    const progressDom = document.querySelector('.progress')
    const percent = progressDom.dataset.percent
    const circleDom = document.querySelector('.process-circle')
    //通过getTotalLength方法获取圆环周长
    const circleLen = circleDom.getTotalLength()
    console.log(circleLen)
     
    circleDom.style.strokeDashoffset = circleLen * ( 1 - parseInt(percent) / 100 )
    //监听进度改变的事件,实际开发中的数据可能通过ajax获取
    document.querySelector('#range').addEventListener('change', (e) => {
        circleDom.style.strokeDashoffset = circleLen * ( 1 - parseInt(e.target.value) / 100 )
        progressDom.dataset.percent = e.target.value + '%'
    })
</script>
复制代码
//css代码
.progress{
    display: inline-block;
    position: relative;
}
.progress::before{
    content: attr(data-percent);
    position: absolute;
    width: 100%;
    top: 50%;
    left: 0;
    transform: translateY(-50%);
    font-size: 20px;
    text-align: center;
}
.progress::after{
    content: attr(data-name);
    position: absolute;
    width: 100%;
    top: 100%;
    left: 0;
    font-size: 25px;
    text-align: center;
}
.process-circle{
    stroke-dashoffset:251;
    transition: stroke-dashoffset 3s;
}       
.adjust{
    margin-top: 50px;
}
复制代码

环形加载动画

stroke-dashoffsetanimation结合还可以实现环形的加载动画,这是一种非常常见的加载动画。 circle-loading1.gif

<svg class="container" height="100" width="100" viewBox="-50 -50 100 100">
    <!--灰色的背景圆环-->
    <circle cx="0" cy="0" r="40" stroke-width="5" fill="none" stroke="rgba(209, 211, 215, 0.5)"/>
    <!--蓝色的动态圆环-->
    <circle class="progress" cx="0" cy="0" r="40" stroke-width="5" stroke-linecap="round" stroke-dasharray="251" fill="none"/>
</svg>
复制代码
.progress{
    stroke: #F7C223;
    animation: move 2s linear infinite;  
}
.container{
    animation: container 2s linear infinite;      
}
//给外框也加上旋转动画,两个旋转叠加,效果更自然
@keyframes container {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(270deg); }
}    
@keyframes move{  //在改变stroke-dashoffset的同时也让圆环旋转
    0%{
        stroke-dashoffset: 251px;
    }
    50%{
        stroke-dashoffset: calc(251px * 0.2);
        transform:rotate(135deg);
    }
    100%{
        stroke-dashoffset: 251px;
        transform:rotate(450deg);
    }
}
复制代码

还可以再加上变色的动画,效果更绚丽。

circle-loading3.gif

.progress{
    stroke: #F7C223;
    animation: 
         move 2s linear infinite,
         color-change 2s linear infinite;
}
@keyframes color-change {
    0% { stroke: #4285F4; }
    25% { stroke: #DE3E35; }
    50% { stroke: #F7C223; }
    75% { stroke: #1B9A59; }
    100% { stroke: #4285F4; }
}
复制代码

文字描边

以描边动画的方式出场可以使人对logo或者文字的印象更加深刻。

text-miaobian.gif

<body>
    <svg width="500" height="106" viewBox="0 0 249 53" fill="none">
        <path d="M35.9334 13.232C35.9334 13.552 35.4854 13.712 34.5894 13.712C33.6934 13.712 33.2454 13.52 33.2454 13.136C32.3494 10.192 31.4854 8.528 30.6534 8.144C27.9654 7.184 23.9974 6.70399 18.7494 6.70399C17.8534 6.768 17.2454 7.024 16.9254 7.472C16.6054 7.92 16.4454 8.72 16.4454 9.872V25.616C24.3174 25.36 28.6374 25.008 29.4054 24.56L30.0774 20.528C30.2054 20.208 30.6534 20.048 31.4214 20.048C32.2534 20.048 32.6694 20.272 32.6694 20.72C32.4134 22.576 32.2854 24.656 32.2854 26.96C32.2854 29.2 32.4134 31.248 32.6694 33.104C32.6694 33.488 32.2214 33.68 31.3254 33.68C30.4934 33.68 30.0774 33.552 30.0774 33.296L29.3094 29.168C28.5414 28.72 24.2534 28.368 16.4454 28.112V39.728C16.4454 44.592 17.0854 47.024 18.3654 47.024H23.1654C23.6774 47.024 23.9334 47.536 23.9334 48.56C23.9334 49.52 23.7414 50 23.3574 50L12.2214 49.904L2.62137 50.192C2.17337 50.192 1.94937 49.712 1.94937 48.752C1.94937 47.792 2.14137 47.312 2.52537 47.312H6.84537C7.54937 47.312 7.96537 47.184 8.09337 46.928C8.22137 46.608 8.28537 45.808 8.28537 44.528V14.288C8.28537 9.168 7.64537 6.608 6.36537 6.608H2.90937C2.14137 6.608 1.75737 6.128 1.75737 5.168C1.75737 4.144 2.10937 3.632 2.81337 3.632L12.6054 3.824H32.6694V2.288C32.6694 1.904 33.0854 1.712 33.9174 1.712C34.8134 1.712 35.2614 1.904 35.2614 2.288L35.9334 13.232Z"/>
        <path d="M43.5031 50L35.9191 50.192C35.4711 50.192 35.2471 49.776 35.2471 48.944C35.2471 48.112 35.4711 47.696 35.9191 47.696H38.9911C39.6951 47.696 40.2071 47.408 40.5271 46.832C41.9991 44.4 44.9431 37.936 49.3591 27.44C53.7751 16.88 56.9431 8.88 58.8631 3.44C59.1191 2.864 59.7271 2.576 60.6871 2.576C61.7111 2.576 62.3511 2.896 62.6071 3.536C63.3751 6.736 65.6151 12.784 69.3271 21.68C73.1031 30.576 76.3991 38 79.2151 43.952C79.9831 45.488 80.6871 46.48 81.3271 46.928C81.9671 47.376 82.9591 47.6 84.3031 47.6C84.6871 47.6 84.8791 48.048 84.8791 48.944C84.8791 49.776 84.7191 50.192 84.3991 50.192L75.1831 50L64.8151 50.192C64.4311 50.192 64.2391 49.776 64.2391 48.944C64.2391 48.112 64.4311 47.696 64.8151 47.696H69.4231C70.1271 47.696 70.4791 47.408 70.4791 46.832C70.4791 46.768 68.6871 41.84 65.1031 32.048H51.7591C48.6231 39.792 47.0551 44.336 47.0551 45.68C47.0551 46.96 47.4391 47.6 48.2071 47.6H52.1431C52.6551 47.6 52.9111 48.048 52.9111 48.944C52.9111 49.776 52.7191 50.192 52.3351 50.192L43.5031 50ZM63.8551 28.784C63.6631 28.208 61.9991 23.344 58.8631 14.192H58.5751C57.0391 18.608 55.2151 23.472 53.1031 28.784H63.8551Z"/>
        <path d="M132.826 3.824L141.658 3.632C142.042 3.632 142.234 4.112 142.234 5.072C142.234 5.968 142.042 6.416 141.658 6.416H138.298C137.402 6.416 136.826 6.64 136.57 7.088C135.418 9.072 134.842 23.472 134.842 50.288C134.842 50.928 134.298 51.248 133.21 51.248C132.186 51.248 131.45 51.024 131.002 50.576C118.202 35.344 107.898 22.992 100.09 13.52H99.8019C99.9939 24.848 100.186 34.32 100.378 41.936C100.378 45.264 100.858 46.928 101.818 46.928H105.658C106.042 46.928 106.234 47.44 106.234 48.464C106.234 49.424 106.042 49.904 105.658 49.904H97.6899L88.9539 50.096C88.6339 50.096 88.4739 49.648 88.4739 48.752C88.4739 47.792 88.6339 47.312 88.9539 47.312H91.2579C93.2419 47.312 94.2659 46.672 94.3299 45.392C95.2899 35.024 95.7699 22.896 95.7699 9.008C94.7459 7.792 93.8819 7.088 93.1779 6.896C92.4739 6.704 91.1619 6.608 89.2419 6.608C88.8579 6.608 88.6659 6.128 88.6659 5.168C88.6659 4.144 88.8579 3.632 89.2419 3.632L102.778 3.824C118.33 23.536 127.482 35.216 130.234 38.864H130.426C130.17 22.096 129.946 12.528 129.754 10.16C129.562 7.792 129.05 6.608 128.218 6.608H124.858C124.41 6.608 124.186 6.128 124.186 5.168C124.186 4.144 124.41 3.632 124.858 3.632L132.826 3.824Z" />
        <path d="M174.709 51.248C166.901 51.248 160.437 49.168 155.317 45.008C150.197 40.848 147.637 35.152 147.637 27.92C147.637 20.624 150.389 14.576 155.893 9.776C161.397 4.976 167.957 2.576 175.573 2.576C179.285 2.576 182.933 3.504 186.517 5.36V3.728C186.517 3.28 186.901 3.056 187.669 3.056C188.501 3.056 188.917 3.28 188.917 3.728C188.917 7.76 189.237 11.952 189.877 16.304C189.941 16.496 189.813 16.688 189.493 16.88C189.237 17.008 188.821 17.072 188.245 17.072C187.669 17.072 187.317 16.816 187.189 16.304L186.421 11.216C182.837 7.824 178.709 6.128 174.037 6.128C169.429 6.128 165.461 8.112 162.133 12.08C158.869 16.048 157.237 21.008 157.237 26.96C157.237 32.912 158.965 37.872 162.421 41.84C165.877 45.744 169.941 47.696 174.613 47.696C179.285 47.696 183.701 46.32 187.861 43.568L188.341 38.096C188.341 37.584 188.789 37.328 189.685 37.328C190.581 37.328 191.029 37.552 191.029 38L190.453 50.192C190.453 50.576 190.005 50.768 189.109 50.768C188.277 50.768 187.861 50.576 187.861 50.192V48.56C183.445 50.352 179.061 51.248 174.709 51.248Z"/>
        <path d="M219.962 49.904L210.362 50.192C209.914 50.192 209.69 49.712 209.69 48.752C209.69 47.792 209.882 47.312 210.266 47.312H214.586C215.29 47.312 215.706 47.184 215.834 46.928C215.962 46.608 216.026 45.808 216.026 44.528V29.264H215.93C215.994 27.344 211.482 21.168 202.394 10.736C199.898 7.792 197.978 6.32 196.634 6.32H194.426C193.914 6.32 193.658 5.904 193.658 5.072C193.658 4.176 193.85 3.728 194.234 3.728L203.354 3.824L213.338 3.728C213.722 3.728 213.914 4.144 213.914 4.976C213.914 5.808 213.754 6.224 213.434 6.224H208.634C208.634 6.352 209.434 7.376 211.034 9.296C216.346 15.632 219.802 20.432 221.402 23.696H221.69C222.65 22.096 224.602 19.44 227.546 15.728C230.49 12.016 232.154 9.776 232.538 9.008C232.986 8.176 233.21 7.536 233.21 7.088C233.21 6.576 232.954 6.32 232.442 6.32H229.754C229.434 6.32 229.274 5.904 229.274 5.072C229.274 4.176 229.498 3.728 229.946 3.728L238.874 3.824L246.458 3.728C246.906 3.728 247.13 4.144 247.13 4.976C247.13 5.808 246.874 6.224 246.362 6.224H244.634C243.482 6.224 242.49 6.576 241.658 7.28C238.522 9.904 234.938 13.488 230.906 18.032C226.938 22.512 224.698 25.648 224.186 27.44V39.728C224.186 44.592 224.826 47.024 226.106 47.024H230.906C231.418 47.024 231.674 47.536 231.674 48.56C231.674 49.52 231.482 50 231.098 50L219.962 49.904Z"/>
    </svg>
</body>
复制代码

这里每个字母都是由path元素绘制的图标,这种比较复杂的图形一般是由设计软件绘制,然后生成svg代码,我们这里使用的是figma。

对于这种不规则图形,只能用getTotalLength方法可以获取该形状的路径总长度,然后设置stroke-dasharraystroke-dashoffset的值。

const words = document.querySelectorAll('path')
for(let i=0; i<words.length; i++){
    console.log(words[i].getTotalLength())
}
复制代码

image.png

body{
    background: #2e4057;
    display: flex;
    justify-content: center;
    align-items: center;
}
svg{
    stroke: hsl(189, 68%, 75%);
    stroke-width:1px;
    fill:hsl(189, 68%, 75%, 0%);
    animation: color-change 1s ease-in forwards 3.8s;
}
//每个字母的描边动画执行时间和开始时间不同
path:nth-child(1){
    stroke-dasharray: 246;
    stroke-dashoffset: 246;
    animation: show 1s linear forwards;
}
path:nth-child(2){
    stroke-dasharray: 253;
    stroke-dashoffset: 253;
    animation: show 1.2s linear forwards .5s;
}
path:nth-child(3){
    stroke-dasharray: 334;
    stroke-dashoffset: 334;
    animation: show 1.4s linear forwards 1s;
}
path:nth-child(4){
    stroke-dasharray: 246;
    stroke-dashoffset: 246;
    animation: show 1.6s linear forwards 1.5s;
}
path:nth-child(5){
    stroke-dasharray: 240;
    stroke-dashoffset: 240;
    animation: show 1.8s linear forwards 2s;
}
@keyframes show{
     to{
           stroke-dashoffset: 0;
     }
}
@keyframes color-change{
     to{
           stroke: transparent;
           fill:hsl(189, 68%, 75%)
     }
}
复制代码

按钮hover效果

btn-hover.gif

Non-hover state: stroke-dasharray: 170 540, the line segment and the interval are 170 and 540 respectively; stroke-dashoffset: -459it means that the offset is 459 to the right (clockwise offset) relative to the starting point (the upper left corner of the rectangle), and the line segment is drawn directly below the text.

Hover state: stroke-dasharray: 760, 760 is the perimeter of the rectangle, stroke-dashoffset: 0there is no offset at this time, and the drawing effect is a complete rectangle.

<body>
    <div class="wrapper">
        <svg height="60" width="320">
            <rect class="border-rect" height="60" width="320" />
        </svg>
        <div class="text">Check it!</div>
    </div>
</body>
复制代码
html, body {
    background: #333;
    height: 100%;
    overflow: hidden;
    text-align: center;
}
.wrapper {
    height: 60px;
    margin: 0 auto;
    position: relative;
    top: 50%;
    transform: translateY(-50%);
    width: 320px;
}
.border-rect {
    fill: transparent;
    stroke-dasharray: 170 540;
    stroke-dashoffset: -459;
    stroke-width: 8px;
    stroke: #d20be4;
    transition: all linear 0.5s;
}
.text {
    color: #fff;
    font-family: 'Roboto Condensed';
    font-size: 22px;
    letter-spacing: 8px;
    line-height: 32px;
    position: relative;
    top: -48px;
}
.wrapper:hover .border-rect {
    stroke-dasharray: 760;
    stroke-dashoffset: 0;
    stroke-width: 2px;
}
复制代码

Summarize

This article mainly discusses the basics of SVG combined with CSS to achieve animation, as well as the implementation of some common animations. As browsers support web standards better and better, the use of SVG is becoming more and more convenient. When interacting with a website, you can use SVG animation appropriately to improve the performance of your website. That's it for today, see you next time!

Guess you like

Origin juejin.im/post/7083262239569870856