web前端开发个人技术博客
当前位置: HTML/CSS > SVG动画快速入门实例教程

SVG动画快速入门实例教程

2019-03-20 分类:HTML/CSS 作者:码云 阅读(4912)

SVG意为可缩放矢量图形(Scalable Vector Graphics),在web中用来解决位图放大失真的问题。说到这儿可能有人问了SVG和CSS、canvas有关系吗?这里可以很认真的告诉你他们之间是独立的,互不影响。SVG使用XML格式定义图像。

SVG有3个基本概念分别是:

  • Viewport 物理窗口;
  • Viewbox 实物窗口;
  • preserveAspectRatio 保留横纵比。

接下来,我会分别介绍它们。

Viewport

1
<svg x=”0px” y=”0px” width=”200px” height=”100px”></svg>

通过上面代码就很明显看出viewport代表的意思,即利用x,y,width,height四个属性在页面上固定矩形区域。

Viewbox

SVG元素在viewport的具体尺寸比例。

1
2
3
4
<svg width="500" height="200" viewBox="0 0 50 20" >
 <rect x="20" y="10" width="10" height="5"
          style="stroke: #000000; fill:none;"/>
</svg>

viewport为[0,0]到[500,200]

viewbox为[0,0]到[50,20]

在默认情况下SVG是自动填充满viewport的。但需注意的事,在SVG中,子标签的所有尺寸都是不能带单位的,因为初始单位就是根据上面两个概念确定。

当以上情况,SVG中基本的尺寸则不是1px,而是500/50=10px。所以,如下的图形大小为:

1
<rect x="20" y="10" width="10" height="5" style="stroke: #000000; fill:none;"/>

也就是在SVG里面定义的rect图形,它的实际尺寸为[200,100]到[100,50]。

preserveAspectRatio

该属性就是用来定义上面viewport和viewbox相互对齐的方式。换句话就是说,它的属性可以改变viewbox的具体位置。基本格式为:

1
<align> [<meetOrSlice>

align:定义viewport和viewbox的对齐方式,分为x,y轴两个方向。X轴方向有三种方式:左边重合(xMin),x轴中点重合(xMid),右边重合(xMax)。同理,Y轴也有顶边重合(YMin),y轴中点重合(YMid),底边边重合(YMax)

meetOrSlice:主要就是定义该SVG是内嵌,还是裁剪或是none(听天有命)。

其中,align需要着重理解一下。首先,它的默认值为xMidYMid,即为中点重合。

preserveAspectRatio

可以从图中看出,viewbox是通过中心进行延展的。注意,它的原点坐标还是在viewbox的左上角。如果你是动态增加尺寸的话,此时并不是从左到右增加,而是从中心向两端扩张。同理,如果你使用的是xMinYMin的话,那么如果存在尺寸变化,那么相对点则是从左上角开始的。简单来说,align相对点其实一共有9个。

align 相对点其实一共有 9 个

然后就是meet||slice||none这三个属性具体干的事情。

在这之前,我们需要了解一个公式–缩放比计算公式:

vb_hrat_y=vp_h;或者vb_wrat_x=vp_w;

其中,vb_为viewbox简写,vp_为viewport的简写。vb_h代表就是viewbox height。vb_w代表就是viewbox width。rat_x/y代表的是x,y轴的缩放比例。

假设有下列情况:

1
2
3
<svg width="400" height="200" viewBox="0 0 200 200" preserveAspectRatio="xMinYMin slice" style="border:1px solid #cd0000;">
    <rect x="10" y="10" width="150" height="150" fill="#cd0000"/>
</svg>

那么,rat_x 和 rat_y 分别为:

1
2
rat_x = 400/200 = 2
rat_y = 200/200 = 1

现在,针对上面meet/slice不同的取值,实际应用到svg里面的缩放比例是不同的。

  • meet(默认值):本意是让svg尽可能的显示在viewport里,即,会在rat_x和rat_y中选择最小的值作为缩放标准。
  • slice:本意是让svg完全铺满viewport,即,会在rat_x和rat_y中选择最大的值作为缩放标准。

所以针对不同的取值,基准比例也不同。

当为meet的情况,那么实际缩放比例为1。则里面实际矩形的大小就为(10,10)到(150,150)。

当为 meet 的情况,那么实际缩放比例为 1

当为slice的情况,那么实际缩放比例为2。则里面实际矩形的大小就为(20,20)到(300,300)。

当为 slice 的情况,那么实际缩放比例为 2

如果你的值为none的话,他会直接铺满整个viewport,即,实际矩形大小为:(20,10)到(300,150)。

如果你的值为 none 的话,他会直接铺满整个 viewport

响应式SVG

虽然讲起响应式,一些童鞋会想这TM又是啥奇技淫巧?

对不起,并不是。。。就是一个viewbox并且不带width/height而已。

看个实际的例子吧:

1
2
3
4
5
6
7
8
9
<svg viewBox="0 0 218.8 87.1">
     <g fill="none" stroke="#000">
       <path d="M7.3 75L25.9 6.8s58.4-6.4 33.5 13-41.1 32.8-11.2 30.8h15.9v5.5s42.6
         18.8 0 20.6"
/>
       <path d="M133.1 58.2s12.7-69.2 24.4-47.5c0 0 4.1 8.6 9.5.9 0 0 5-10 10.4.9 0
         0 12.2 32.6 13.6 43 0 0 39.8 5.4 15.8 15.4-13.2 5.5-53.8
         13.1-77.4 5.9.1 0-51.9-15.4 3.7-18.6z"
/>
</g>
</svg>

可以看到,上面的svg标签并没有带上啥width/height属性,只是简单描述了viewBox的范围而已。当然,里面的尺寸标准都是在这viewBox的范围内进行设置的。

另外,在这里声明一下,本文章并不是新手教程,也就是说,不会教你一步一步的画直线啊,圆啊,矩形啊等等这些基本图形。这些直接google一下,一搜一大把。所以,这里假设大家的水平是处于,能对SVG基本的图形属性熟悉即可,对一些高级属性还不是很清楚和熟练。OK,继续~

在SVG中,能够直接使用的图形有:

  • rect
  • circle
  • ellipse
  • line
  • polyline
  • polygon

上面没有啥说的,后面我详细说一下两个比较重要的概念,分组和Path。

分组和Path

通常Path和分组通常是一起使用的,如下:

1
2
3
4
5
6
7
<g fill="none" stroke="#000">
    <path d="M7.3 75L25.9 6.8s58.4-6.4 33.5 13-41.1 32.8-11.2 30.8h15.9v5.5s42.6
      18.8 0 20.6"
/>
    <path d="M133.1 58.2s12.7-69.2 24.4-47.5c0 0 4.1 8.6 9.5.9 0 0 5-10 10.4.9 0
      0 12.2 32.6 13.6 43 0 0 39.8 5.4 15.8 15.4-13.2 5.5-53.8
      13.1-77.4 5.9.1 0-51.9-15.4 3.7-18.6z"
/>
</g>

分组我们放到后面进行讲解,这里先看一下Path。

Path

Path在SVG中的地位应该是比较高的,实际上,利用Path这个一个标签可以画出任意的图形。path中d(data)属性是用来定义相关线条数据,通常是以M/m为起始,代表的就是move to的意思。在path中,一共可以定义10种不同的图形。例如M/m,L/l。大家可以注意,每种标识符有两种书写方式,即,大小写。

  • 大写: 参照的是绝对坐标,即,SVG 的右上角
  • 小写: 参照的相对坐标,即,前一个点的坐标。

而在10中不同表示符中,又可以分为直线和曲线两种不同的标识符。这里,我们分类来讲解一下。

线型

M/m

该使用定义起始点的,没啥特殊的作用。

1
<path d="M10 10"/>

表示,以(10,10)为起始点。

L/l

原意是Line to,用来画线段的。格式和M/m差不多:

1
L x y (or l dx dy)

H/h

用来画水平线,即,Horizontal。既然方向已经定了,剩下的就是距离,格式很简单:

1
H x (or h dx)

V/v

用来画竖直线,即,vertical。同上,方向也定了,格式为:

1
V y (or v dy)

举个栗子吧:

1
<path d="M10 10 H 90 V 90 H 10 L 10 10"/>

该path实际上就是画了一个正方形,宽=高=90。

path 实际上就是画了一个正方形

Z/z

该标识符用来表示path的结束,并且将最后一点和M/m标识开头的一点连接起来。所以,它不存在什么表示点之类的,格式为:

1
Z (or z)

而上面也可以进行相关的优化,最终的结果为:

1
2
3
<path d="M10 10 H 90 V 90 H 10 L 10 10"/>
// 使用 Z
<path d="M10 10 H 90 V 90 H 10 Z" fill="transparent" stroke="black"/>

曲线

曲线就是Web画图中常见的Bezier Curves(贝塞尔),Arcs,several Bezier curves(很多贝塞尔-.-)等。

我们简单看一下:

C/c

这是正统的贝塞尔曲线,需要4个参考点,下图应该说比较确切表示了二次贝塞尔所需要的点。所以,C/c需要定义三个点。

表示了二次贝塞尔所需要的点

基本格式为:

1
C x1 y1, x2 y2, x y (or c dx1 dy1, dx2 dy2, dx dy)

例如:

1
<path d="M10 10 C 20 20, 40 20, 50 10" stroke="black" fill="transparent"/>

S/s

该标识符实际上使用来表示一个反射贝塞尔,即,在原有贝塞尔上再加一段贝塞尔曲线,所以,S/s一般和C/c一起使用。

基本格式为:

1
S x2 y2, x y (or s dx2 dy2, dx dy)

实际样式图为:

在原有贝塞尔上再加一段贝塞尔曲线

相当于原有的贝塞尔曲线的最后一段进行反向延长并对称。然后加上新定义的一段限制曲线。

具体实例为:

1
<path d="M10 80 C 40 10, 65 10, 95 80 S 150 150, 180 80" stroke="black" fill="transparent"/>

Q/q

该标识符是用来定义二次(quadratic)贝塞尔曲线,该曲线相当于上面传统的贝塞尔来说,更加简单,它只需要定义三个点,即可完整一个贝塞尔曲线,具体作图过程如下:

定义二次(quadratic)贝塞尔曲线

基本格式为:

1
Q x1 y1, x y (or q dx1 dy1, dx dy)

即为图上点,P1(x1,y1),P2(x,y)

起始点为M定义的点,例如:

1
<path d="M10 80 Q 95 10 180 80" stroke="black" fill="transparent"/>

T/t

该标识符和S差不多,也是一个贝塞尔曲线的延长。相当于原曲线的控制点P1相当于和点P2做对称,然后,只需要定义一个终点即可,即,T/t只需要定义贝塞尔曲线里面的终点即可:

1
T x y (or t dx dy)

如图:

T/t 只需要定义贝塞尔曲线里面的终点

所以,简单来说,C/S,Q/T是两两搭配一起使用的。在使用的时候,千万不要搞混即可。

弧线

A/a

该曲线是用来画弧线(Arcs),而,弧线通常是圆/椭圆的一部分。当,椭圆的两个轴径长相等则为圆,所以,A/a是按照椭圆作为基准格式:

1
2
A rx ry x-axis-rotation large-arc-flag sweep-flag x y
a rx ry x-axis-rotation large-arc-flag sweep-flag dx dy

说实在的,这个比较复杂。因为,他画椭圆的方式和我们平常不一样,一般情况下,椭圆只要确定一个中心,然后是长短轴,然后是弧度范围即可。

但是,它这里是通过椭圆上的两点来确定的,在加上旋转角度,俩轴径等因素来确定的。另外,需要注意,它的起始点是从上一个命令的结束点位置开始计算的。OK,我们首先简单了解一下格式里面的参数:

  • rx,ry:代表的就是长轴短轴,没得说。
  • x,y:代表的是弧长的结束点。开始点就是上一个命令的终点。
  • x-axis-rotation:x轴的旋转角度,顺时针为正。
  • large-arc-flag[0,1]:表示取大弧还是小弧。因为两点之间的弧长有两部分。
  • sweep-flag[0,1]:取顺时针的弧,还是逆时针的弧长。参考点是以起始点开始的。

上面几个属性中,比较难理解的就是large-arc-flag和sweep-flag。这么说吧,前面几个属性充其量只能确定椭圆的位置,和经过椭圆的两个点,不过,一般能通过指定两点的椭圆有两个,而通过这两点划分又会出现4段弧长。为了确定4个弧长中,是哪一个,需要两个值来确定。即,4抽2,2抽1。

该曲线是用来画弧线(Arcs)

简单说一种,例如当,laf和sf都为0的情况。首先,laf为0选择的是小弧长。所以,里面两段比较小的弧长被抽出来。然后,sf为0选择的是逆时针。即,以起始点为参考,选择通过逆时针方向到达终点的那段弧。即,2抽1。最终得出我们需要的弧。

说实在的,这个是真TM复杂。。。

给一个参考codepen。

一般情况下,我们并不需要手动来确定path,有工具为啥不用工具呢!

比如,Illustrator,Sketch等,都可以自动生成SVG。不过,生成之后,需要对代码做相关的压缩优化,这些都可以直接在编译器里面找到。

你也可以用一下可视化工具SVGOMG来简单看一下。

分组

SVG中的分组你可以理解为PS中的图层,一块图层里面通常只会放一下高内聚的图形,这样既方便移动又方便做动画。SVG中的分组标签就是g,使用g标签包裹的所有子元素都认同为一组。

例如:

1
2
3
4
5
6
7
8
<g>
    <circle cx="20" cy="20" r="20" fill="green" />
    <circle cx="70" cy="70" r="20" fill="purple" />
  </g>
  <g>
    <rect x="110" y="110" height="30" width="30" fill="blue" />
    <rect x="160" y="160" height="30" width="30" fill="red" />
  </g>

需要注意的是,使用g进行分组,并不会改变原有元素的在屏幕上展示的效果。

不过,g标签除了分组,还有另外一个很重要的功能–动画

分组动画

在分组重定义动画是直接写在transform属性当中的。实际上,每个子标签都可以使用transform的相关属性。

1
2
3
<g transform="translate(...) scale(...) rotate(...) translate(...) rotate(...)">
  ...
</g>

每种变换动画之间是通过空格或逗号连接的。它的执行顺序是从右到左。为啥呢?实际上可以理解为,这就是几个嵌套的g叠在一起。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<g transform="translate(...) scale(...) rotate(...) translate(...) rotate(...)">
    ...
  </g>
 
  // Being Equivalent to this:
  <g transform="translate(...)">
   <g transform="scale(...)">
     <g transform="rotate(...)">
       <g transform="translate(...)">
         <g transform="rotate(...)">
           ...
         </g>
       </g>
     </g>
   </g>
 </g>

具体可以使用的动画形式和CSS动画一模一样。

结束语:

以上就是码云笔记前端博客为大家带来的关于SVG动画快速入门的教程,希望对正在学习使用SVG的童鞋有所帮助,文章语句有不通顺的地方,敬请担待,也欢迎大家在下方技术讨论尽情拍砖。

「本文为原创文章,版权归码云笔记所有,欢迎分享本文,转载请保留出处!」

赞(21) 打赏

觉得文章有用就打赏一下文章作者

支付宝
微信
21

觉得文章有用就打赏一下文章作者

支付宝
微信

上一篇:

下一篇:

你可能感兴趣

共有 2 条评论 - SVG动画快速入门实例教程

  1. 赫拉力 Linux Chrome 62.0.3202.84

    讲的很好

    1. 码云 Windows 7 Chrome 69.0.3497.100

      @赫拉力谢谢,哈哈

博客简介

码云笔记: mybj123.com,一个关注Web前端开发技术的博客,主要记录和总结前端工作中常用的知识及我的生活。
更多博客详情请看关于博客

精彩评论