stroke(描边)和fill(填充)是svg中非常重要的属性,用于定义和控制形状的外观和可视效果
直接上效果
属性介绍
- stroke:定义svg的轮廓线 常用css属性有
stroke-dasharray(描边的样式),stroke-dashoffset(起始位置),stroke-color(描边的颜色),stroke-opacity(描边的透明度),stroke-linejoin(描边的拐角样式)等等 - fill:定义svg内部颜色或图案 ,常用css属性有
fill-opacity(定义填充的透明度),fill-rule(定义填充规则),fill-pattern(定义填充的图案)
一般svg标签还包含这几个属性
<svg
xmlns="http://www.w3.org/2000/svg" <!-- 命名空间声明,指定文档类型 -->
viewBox="0 0 50 50" <!-- 定义可视区域的坐标系统,范围是从 (0, 0) 到 (50, 50) -->
width="400px" <!-- svg宽度为400px -->
height="400px" <!-- svg高度为400px -->
fill="#EE3E55" <!-- svg填充颜色为 #EE3E55 -->
stroke="#000000" <!-- svg描边颜色为 #000000 -->
>
stroke-dasharray
提供一个数列,其中数与数之前用逗号隔开,交替指定短划线和缺口的长度 比如说
<svg
width="200"
height="200"
viewPort="0 0 200 300"
version="1.1"
xmlns="http://www.w3.org/2000/svg">
<line stroke-dasharray="5, 5" x1="10" y1="10" x2="190" y2="10" />
<style>
<![CDATA[
line{
stroke: black;
stroke-width: 2;
}
]]>
</style>
</svg>
stroke-dasharray="5, 5" x1="10" y1="10" x2="190" y2="10"表示在坐标(10,10)到(190,10)这条水平线上,短划线和缺口都为5个单位
再举个奇数个数的数列,(如果为奇数个, 那个会将这个数列复制一个补上成为偶数数列,比如"10, 5, 20" -> "10, 5, 20, 10, 5, 20")
<line stroke-dasharray="10, 5, 20" x1="10" y1="10" x2="190" y2="10" />
stroke-dashoffset
定义沿SVG路径的短划线的开始位置,数字越大,虚线将沿着路径开始得越远
.path {
stroke-dasharray: 1000;
stroke-dashoffset: 0;
animation: dash 5s linear alternate infinite;
}
@keyframes dash {
to {
stroke-dashoffset: 1000;
}
}
我们给svg的path定义三个属性,设置dasharray为1000,并且起始的offset为0,animation的结束状态offset定义为1000,也就是虚线的短划线最末位置
那么就可以实现从无到有,短划线慢慢连接整个path
fill-opacity
fill-opacity如果不设置默认为1,即不透明。可设置为小数,百分数和css属性
<svg viewBox="0 0 400 100" xmlns="http://www.w3.org/2000/svg">
<!-- 默认 fill opacity: 1 -->
<circle cx="50" cy="50" r="40" />
<circle cx="150" cy="50" r="40" fill-opacity="0.7" />
<circle cx="250" cy="50" r="40" fill-opacity="50%" />
<circle cx="350" cy="50" r="40" style="fill-opacity: .25;" />
</svg>
效果
实现 Naruto logo
这个icons8网站icons种类很多,一般都能找到想要的
挑选一个icons
SVG形式download下来
html结构
结构非常简单,就是一个h标签,svg图片居中和图片animation
<body>
<h1>Svg animation</h1>
<div>
<svg
fill="#EE3E55"
stroke="#000000"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 50 50"
width="400px"
height="400px"
>
<path
d="M 27.001953 4.7832031 C 21.502168 4.7913231 16.084635 7.0942615 11.775391 11.712891 C 8.9776265 14.711466 7.3813325 18.362441 6.9257812 22.123047 L 6.8945312 22.111328 L 0.60546875 39.65625 A 2.50025 2.50025 0 0 0 2.9570312 43 L 24.5 43 L 24.5 42.988281 C 29.014184 43.021879 33.503253 41.295882 36.75 37.816406 C 41.787713 32.417359 41.661726 23.713513 36.474609 18.341797 C 34.205785 15.991774 31.257883 14.347174 28.025391 14.019531 C 24.792898 13.691889 21.300039 14.850176 18.636719 17.679688 C 14.965423 21.580089 15.030888 27.929371 18.804688 31.802734 C 20.110475 33.143171 21.837673 34.081121 23.804688 34.400391 C 25.771701 34.71966 28.124829 34.278332 29.849609 32.615234 C 31.25841 31.256679 31.700263 29.427641 31.544922 27.736328 C 31.389581 26.045015 30.586537 24.270043 28.878906 23.21875 A 2.50025 2.50025 0 1 0 26.257812 27.476562 C 26.327182 27.519272 26.526044 27.775172 26.564453 28.193359 C 26.602863 28.611547 26.428106 28.96818 26.378906 29.015625 C 25.894687 29.482527 25.393955 29.592824 24.605469 29.464844 C 23.816982 29.336863 22.88993 28.831017 22.386719 28.314453 A 2.50025 2.50025 0 0 0 22.384766 28.3125 C 20.700564 26.583864 20.694592 22.79102 22.279297 21.107422 C 23.990977 19.288933 25.695227 18.809033 27.521484 18.994141 C 29.347742 19.179248 31.31973 20.199476 32.878906 21.814453 C 36.177789 25.230737 36.226037 31.049298 33.09375 34.40625 C 28.927093 38.871575 21.59531 39.235442 16.800781 35.132812 C 10.557183 29.79014 9.9899143 20.955356 15.431641 15.123047 C 18.908396 11.396676 22.853849 9.7893348 27.007812 9.7832031 C 31.161777 9.7770731 35.595243 11.454532 39.703125 14.78125 A 2.50025 2.50025 0 0 0 42.771484 14.84375 L 48.537109 10.541016 A 2.50025 2.50025 0 1 0 45.546875 6.5332031 L 41.220703 9.7617188 C 36.786163 6.6077415 31.90364 4.7759677 27.001953 4.7832031 z M 8.546875 32.314453 C 9.4995553 34.379835 10.825268 36.313663 12.541016 38 L 6.5097656 38 L 8.546875 32.314453 z"
/>
</svg>
</div>
<button>animation</button>
</body>
style基本样式
基本样式也很简单 flex一把梭
body {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
height: 100vh;
padding: 200px;
margin: auto;
text-wrap: nowrap;
}
div {
width: 400px;
height: 400px;
padding: 100px;
border-radius: 50%;
background-color: #ceece5;
display: flex;
justify-content: center;
align-items: center;
margin: 2rem 0;
}
button {
border: 1px solid #000;
color: #000;
background-color: white;
padding: 1rem 2rem;
}
stroke fill实践
svg path {
stroke-dasharray: 500;
stroke-dashoffset: 0;
stroke-width: 1;
fill-opacity: 0;
}
.animation {
animation: line 3s linear forwards, fill 1s linear forwards 2s;
}
@keyframes line {
to {
stroke-dashoffset: 500;
}
}
@keyframes fill {
to {
fill-opacity: 1;
}
}
stroke-dasharray: 500;设短划线的长度为500个单位stroke-dashoffset: 0;初始偏移单位为0stroke-width: 1;描边宽度为1单位fill-opacity: 0;透明度为0 不可见line animation是画线的,to 设置结束状态偏移单位为500个单位,即划线长度的末端 也就是说line animation会从无到慢慢连接整个pathfill animationto设置结束状态透明度为1 完全可见
button控制animation触发
当DOMContentLoaded 文档内容加载完后执行,然后path直接添加animation样式
btn被点击时先移除animation,再用setTimeout重新添加animation,在下一个事件循环中,path.classList.add('animation') 被添加到宏任务队列中 It works!
document.addEventListener('DOMContentLoaded', () => {
const path = document.querySelector('svg path')
const btn = document.querySelector('button')
path.classList.add('animation')
btn.addEventListener('click', () => {
path.classList.remove('animation')
setTimeout(() => {
path.classList.add('animation')
})
})
})
完整代码