这是我参与8月更文挑战的第1天,活动详情查看:8月更文挑战
前文
今天突然心血来潮要做个loading动画,用css做总感觉哪里不对劲,于是决定用svg来做好了。 问题是没用过svg做加载动画,只好先看看教程了
先看今天的成果
首先了解一下svg怎么用
先去看看MDN文档,浏览一下标签和属性的大概作用,然后拿里面的demo玩玩先。
-
用img标签引用
<img src="loading.svg" />
-
用css的background-image
background-image: url(loading.svg);
-
用object、iframe、embed标签
<object data="loading.svg" type="image/svg+xml"></object>
<iframe src="loading.svg" frameborder="0"></iframe>
<embed src="loading.svg" type="" />
常见标签有这些
- text:文本元素
- line:直线元素
- rect:矩形元素
- circle:圆形元素
- ellipse:椭圆元素
- path:路径元素
- polyline:折线元素
- polygon:多边形元素
- g:元素组合/集合
常见属性有这些
- x:x轴坐标
- y:y轴坐标
- width:宽
- height:高
- rx:矩形圆角(椭圆)的x轴的半径
- ry:矩形圆角(椭圆)的y轴的半径
- r:圆的半径
- cx:圆(椭圆)中心点的x轴坐标
- cy:圆(椭圆)中心点的y轴坐标
- points:坐标点集合,逗号隔开
- d:点集数列以及其它关于如何绘制路径的信息
- stroke:画笔属性(描边用的)
- stroke-width:画笔大小
- fill:填充的颜色
举个栗子
// 文字
<text x="15" y="300" fill="blue" font-family="sans-serif" font-size="16pt">Text</text>
// 矩形
<rect x="10" y="10" width="30" height="30"></rect>
// 圆角矩形
<rect x="60" y="10" rx="10" ry="10" width="30" height="30"></rect>
// 圆形
<circle cx="140" cy="30" r="20"></circle>
// 椭圆
<ellipse cx="200" cy="30" rx="20" ry="5"></ellipse>
// 直线
<line stroke="#f44" x1="10" x2="50" y1="60" y2="90"></line>
// 折线
<polyline points="60 110, 65 120, 70 115, 75 130, 80 125, 85 140, 90 135, 95 150, 100 145" />
// 多边形
<polygon points="50 160, 55 180, 70 180, 60 190, 65 205, 50 195, 35 205, 40 190, 30 180, 45 180" />
// 路径 (路劲太复杂,我这个渣渣没学会,我是用AI画的)
<path d="M357.2,141v-24.2c0-3.1-2.5-5.6-5.6-5.6h-66.1c-3.1,0-5.6,2.5-5.6,5.6V141c0,3.1-2.5,5.6-5.6,5.6H129.7 c-3.1,0-5.6,2.5-5.6,5.6v43.1v8.1v30.9c0,3.1,2.5,5.6,5.6,5.6H167c3.1,0,5.6-2.5,5.6-5.6v-42.6c0-3.1,2.5-5.6,5.6-5.6h283.6 c3.1,0,5.6,2.5,5.6,5.6v42.6c0,3.1,2.5,5.6,5.6,5.6h31.7c3.1,0,5.6-2.5,5.6-5.6v-33.9v-8.1v-40.1c0-3.1-2.5-5.6-5.6-5.6H362.8 C359.7,146.5,357.2,144,357.2,141z"/>
我自己学到的路径是这个亚子的
<path>
元素是SVG基本形状中最强大的一个,可以用它创建线条, 曲线, 弧形等等。 path元素的形状是通过属性d
定义的,属性d
的值是一个“命令+参数”的序列
- M = moveto:移动画笔但不画,有坐标点两个参数(M x y)
- L = lineto:画一条直线,从当前位置到参数的坐标点(L x y)
- H = horizontal lineto:水平直线(H x)
- V = vertical lineto:垂直直线(V x)
- C = curveto:三次贝塞尔曲线,有三个坐标点作为参数(C x1 y1, x2 y2, x y)
- S = smooth curveto:可以创建多个和前面一样的贝塞尔曲线,从而创建连续的曲线,跟在C或S后面的话,它的第一个控制点将作为前一个曲线的第二个控制点的中心对称点
- Q = quadratic Belzier curve:二次贝塞尔曲线,有两个坐标点作为参数
- T = smooth quadratic Belzier curveto:可以创建多个二次贝塞尔曲线,从而创建连续的曲线
- A = elliptical Arc:弧线,和椭圆一样的参数
- Z = closepath:结束符号
在svg中使用css
前面说到的demo都是黑色的,是因为没上色,现在就用stroke和fill来上色
直线是没有填充的,所以fill是无效的,其他的用 stroke="red" fill="#4ff" 上色就好了
问题来了,这么多个上色那么麻烦,统一的办法有没有
答案是有的,用defs标签定义css样式,用法和html一毛一样
<defs>
<style type="text/css"><![CDATA[
.color {
stroke: red;
fill: #4ff;
}
]]></style>
</defs>
但是那么多个元素,一个个加样式也是麻烦,于是用g标签把所有的元素包含起来,加上样式就舒服多了
<g class="color">
<rect x="10" y="10" width="30" height="30"></rect>
......
</g>
其中有一个想样式不一样行吗?直接用style内联就可以了。
<text x="15" y="300" style="fill:blue" font-family="sans-serif" font-size="16pt">Text</text>
svg的渐变
这些都需要放到defs标签里面
- linearGradient:线性渐变 stop标签能够指定颜色,由offset控制偏移,stop-color控制颜色,stop-opacity控制透明度
<svg width="120" height="240" version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
// 水平渐变
<linearGradient id="Gradient1">
<stop class="stop1" offset="0%"/>
<stop class="stop2" offset="50%"/>
<stop class="stop3" offset="100%"/>
</linearGradient>
// 垂直渐变(想要什么方向,就自己修改两个坐标的指向)
<linearGradient id="Gradient2" x1="0" x2="0" y1="0" y2="1">
<stop offset="0%" stop-color="red"/>
<stop offset="50%" stop-color="black" stop-opacity="0"/>
<stop offset="100%" stop-color="blue"/>
</linearGradient>
<style type="text/css"><![CDATA[
#rect1 { fill: url(#Gradient1); }
.stop1 { stop-color: red; }
.stop2 { stop-color: black; stop-opacity: 0; }
.stop3 { stop-color: blue; }
]]></style>
</defs>
<rect id="rect1" x="10" y="10" rx="15" ry="15" width="100" height="100"/>
<rect x="10" y="120" rx="15" ry="15" width="100" height="100" fill="url(#Gradient2)"/>
</svg>
- radialGradient:径向渐变 使用方式和线性渐变几乎一样,多了个中心焦点
- fx和fy是焦点参数
- cx,cy和r是中心的参数
<?xml version="1.0" standalone="no"?>
<svg width="120" height="120" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<defs>
<radialGradient id="Gradient"
cx="0.5" cy="0.5" r="0.5" fx="0.25" fy="0.25">
<stop offset="0%" stop-color="red"/>
<stop offset="100%" stop-color="blue"/>
</radialGradient>
</defs>
<rect x="10" y="10" rx="15" ry="15" width="100" height="100"
fill="url(#Gradient)" stroke="black" stroke-width="2"/>
<circle cx="60" cy="60" r="50" fill="transparent" stroke="white" stroke-width="2"/>
<circle cx="35" cy="35" r="2" fill="white" stroke="white"/>
<circle cx="60" cy="60" r="2" fill="white" stroke="white"/>
<text x="38" y="40" fill="white" font-family="sans-serif" font-size="10pt">(fx,fy)</text>
<text x="63" y="63" fill="white" font-family="sans-serif" font-size="10pt">(cx,cy)</text>
</svg>
我要把我的加载动画拿出来了
如果有哪里写得不好,记得告诉我,让我们一起进步吧
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 640 640" style="enable-background:new 0 0 640 640;" xml:space="preserve">
<defs>
<linearGradient id="left-to-right">
<stop offset="0" stop-color="#e02e42">
<animate dur="1.5s" attributeName="offset" from="0" to="1.5" repeatCount="indefinite" />
</stop>
<stop offset="0" stop-color="#eee">
<animate dur="1.5s" attributeName="offset" from="0" to="1.5" repeatCount="indefinite" />
</stop>
</linearGradient>
</defs>
<g fill="url(#left-to-right)" stroke-width="10">
<path d="M357.2,141v-24.2c0-3.1-2.5-5.6-5.6-5.6h-66.1c-3.1,0-5.6,2.5-5.6,5.6V141c0,3.1-2.5,5.6-5.6,5.6H129.7
c-3.1,0-5.6,2.5-5.6,5.6v43.1v8.1v30.9c0,3.1,2.5,5.6,5.6,5.6H167c3.1,0,5.6-2.5,5.6-5.6v-42.6c0-3.1,2.5-5.6,5.6-5.6h283.6
c3.1,0,5.6,2.5,5.6,5.6v42.6c0,3.1,2.5,5.6,5.6,5.6h31.7c3.1,0,5.6-2.5,5.6-5.6v-33.9v-8.1v-40.1c0-3.1-2.5-5.6-5.6-5.6H362.8
C359.7,146.5,357.2,144,357.2,141z"/>
<path d="M317.3,378.8L178,426c-9,3-15,11.4-15,20.9v64.8c0,12.2,9.9,22.1,22.1,22.1h274.6c12.2,0,22.1-9.9,22.1-22.1
v-65c0-9.4-5.9-17.8-14.8-20.9l-135.3-47.1C327,377.2,322,377.2,317.3,378.8z M401.6,493.2H246.2c-12.2,0-22.1-9.9-22.1-22.1V471
c0-9.6,6.2-18.1,15.4-21l76.3-24.2c4.3-1.4,8.9-1.4,13.2-0.1l79.1,24.4c9.3,2.9,15.6,11.4,15.6,21.1l0,0
C423.7,483.3,413.8,493.2,401.6,493.2z"/>
<path d="M512.4,368l-120-43.5c-4.7-1.7-4.6-8.3,0.1-9.9l26.5-8.8l27.4-9.9c2.1-0.8,3.5-2.7,3.5-4.9v-38.6v-4.2V222
c0-2.9-2.3-5.2-5.2-5.2H241.4V206c0-1.8-1.4-3.2-3.2-3.2h-43c-1.8,0-3.2,1.4-3.2,3.2v70.8c0,1.8,1.4,3.2,3.2,3.2h43
c1.8,0,3.2-1.4,3.2-3.2v-20.6c0.3-2.7,2.5-4.7,5.2-4.7h150.8c2.9,0,5.2,2.3,5.2,5.2v13.1c0,2.2-1.4,4.2-3.5,4.9l-71.2,25.1
c-1.2,0.4-2.5,0.4-3.7-0.1l-44.9-18.1c-3.4-1.4-7.2,1.2-7.2,4.9v29.1c0,2.2-1.4,4.2-3.5,5L130.5,368c-2.1,0.7-3.5,2.7-3.5,5v36.7
c0,3.6,3.6,6.2,7,4.9L321.2,347c1.1-0.4,2.3-0.4,3.5,0L508.9,409c3.4,1.1,6.9-1.4,6.9-5v-31.1C515.9,370.7,514.5,368.7,512.4,368z"/>
</g>
<style>@keyframes r{0%{stroke-dasharray:15.5,3100;stroke-dashoffset:0;transform:rotate(0);}50%{stroke-dasharray:1395,2325;stroke-dashoffset:-620}100%{stroke-dasharray:1395,2325;stroke-dashoffset:-1860;transform:rotate(1turn)}}.rotate{transform-origin:50% 50%;animation:r 1.5s ease-in-out infinite;stroke:currentColor;stroke-width:20;stroke-linecap:round;color:#e02e42}</style>
<circle class="rotate" cx="320" cy="320" r="310" fill="none"></circle>
</svg>