成果展示

上面这个动画就是一个简单的svg
描边动画的实现,下面来看看如何一步一步得到吧,
步骤
- 先用 svg 画出一条直线。

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
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> <style> .p { stroke: black; } </style> </head>
<body> <svg class="icon" width="50" ,height="50"> <line class="p" x1="0%" y1="50%" x2="100%" y2="50%" /> </svg> </body> </html>
|
- 接着添加
stroke-dasharray
和stroke-width
样式,使得直线变粗以及有间隙
1 2 3 4 5 6 7
| .p { stroke: black; stroke-width: 10; stroke-dasharray: 10; }
|

再添加一个stroke-dashoffset
:偏移量,左正右负。

有了上面这两个样式,就可以通过一个动画来实现线段的描边了。 - 先将虚线间隔调整为线段长度
css stroke-dasharray: 10;
- 将整条线左移整个宽
css stroke-dashoffset: 50;
- 添加一个动画并应用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| .p { stroke: black; /_ 描边的宽度 _/ stroke-width: 10; /_ 虚线间隔 _/ stroke-dasharray: 50; stroke-dashoffset: 50; animation: stroke 2s forwards; }
@keyframes stroke { to { stroke-dashoffset: 0; } } ``` 就可以得到这样子的动画 
<center><big>以为这样子就结束了?no~ no~ no~😉</big></center>
|
由于上面的虚线长度和偏移量都是固定的,当svg
图标长度发生变化时就不能自适应了,因此需要改成一个变量,这里采用js
实现。
- 先将长度都用变量表示
1 2 3 4 5 6 7 8 9
| .p { stroke: black; stroke-width: 10; stroke-dasharray: var(--l); stroke-dashoffset: var(--l); animation: stroke 2s forwards; }
|
- 加入
js
代码1 2 3 4 5 6 7 8
| <script> const paths = document.querySelectorAll(".icon .p"); paths.forEach(path => { const len = path.getTotalLength(); path.style.setProperty('--l', len + 1); }) </script>
|
最后将<line/>
换成其它的svg代码
1
| <svg t="1688872979658" class="icon" viewBox="0 0 1213 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1041" width="200" height="200"><path d="M1024 0c104.561778 0 189.62963 85.067852 189.62963 189.62963v644.74074c0 104.561778-85.067852 189.62963-189.62963 189.62963H900.740741a47.407407 47.407407 0 1 1 0-94.814815h123.259259c52.280889 0 94.814815-42.533926 94.814815-94.814815V189.62963c0-52.280889-42.533926-94.814815-94.814815-94.814815H189.62963c-52.280889 0-94.814815 42.533926-94.814815 94.814815v130.37037a47.407407 47.407407 0 1 1-94.814815 0V189.62963C0 85.067852 85.067852 0 189.62963 0zM878.231704 213.333333c67.309037 0 122.064593 54.755556 122.064592 122.064593V497.777778a47.407407 47.407407 0 1 1-94.814815 0V375.61837L766.160593 516.683852A188.397037 188.397037 0 0 1 791.703704 611.555556V834.37037c0 104.561778-85.067852 189.62963-189.62963 189.62963H189.62963C85.067852 1024 0 938.932148 0 834.37037V611.555556c0-104.561778 85.067852-189.62963 189.62963-189.62963h412.444444c35.678815 0 69.082074 9.91763 97.611852 27.117037L838.84563 308.148148H715.851852a47.407407 47.407407 0 1 1 0-94.814815zM602.074074 516.740741H189.62963c-52.280889 0-94.814815 42.533926-94.814815 94.814815V834.37037c0 52.280889 42.533926 94.814815 94.814815 94.814815h412.444444c52.280889 0 94.814815-42.533926 94.814815-94.814815V611.555556c0-52.280889-42.533926-94.814815-94.814815-94.814815z" p-id="1042"></path></svg>
|
将svg
标签的类增加一个icon
,在path
标签中增加一个p
类,对于p
类的样式增加一个fill:none
的样式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| .p { fill: none; stroke: black; stroke-width: 10; stroke-dasharray: var(--l); stroke-dashoffset: var(--l); animation: stroke 2s forwards; }
@keyframes stroke { to { stroke-dashoffset: 0; fill: black; } }
|
最终代码
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
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> <style> .p { fill: none; stroke: black; stroke-width: 10; stroke-dasharray: var(--l); stroke-dashoffset: var(--l); animation: stroke 2s forwards; }
@keyframes stroke { to { stroke-dashoffset: 0; fill: black; } } </style> </head>
<body> <svg t="1688872979658" class="icon" viewBox="0 0 1213 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1041" width="50" height="50"> <path class="p" d="M1024 0c104.561778 0 189.62963 85.067852 189.62963 189.62963v644.74074c0 104.561778-85.067852 189.62963-189.62963 189.62963H900.740741a47.407407 47.407407 0 1 1 0-94.814815h123.259259c52.280889 0 94.814815-42.533926 94.814815-94.814815V189.62963c0-52.280889-42.533926-94.814815-94.814815-94.814815H189.62963c-52.280889 0-94.814815 42.533926-94.814815 94.814815v130.37037a47.407407 47.407407 0 1 1-94.814815 0V189.62963C0 85.067852 85.067852 0 189.62963 0zM878.231704 213.333333c67.309037 0 122.064593 54.755556 122.064592 122.064593V497.777778a47.407407 47.407407 0 1 1-94.814815 0V375.61837L766.160593 516.683852A188.397037 188.397037 0 0 1 791.703704 611.555556V834.37037c0 104.561778-85.067852 189.62963-189.62963 189.62963H189.62963C85.067852 1024 0 938.932148 0 834.37037V611.555556c0-104.561778 85.067852-189.62963 189.62963-189.62963h412.444444c35.678815 0 69.082074 9.91763 97.611852 27.117037L838.84563 308.148148H715.851852a47.407407 47.407407 0 1 1 0-94.814815zM602.074074 516.740741H189.62963c-52.280889 0-94.814815 42.533926-94.814815 94.814815V834.37037c0 52.280889 42.533926 94.814815 94.814815 94.814815h412.444444c52.280889 0 94.814815-42.533926 94.814815-94.814815V611.555556c0-52.280889-42.533926-94.814815-94.814815-94.814815z" p-id="1042"></path> </svg> <script> const paths = document.querySelectorAll('.icon .p'); paths.forEach((path) => { const len = path.getTotalLength(); path.style.setProperty('--l', len); }); </script> </body> </html>
|