SVG动画快速入门实例教程

目录
文章目录隐藏
  1. Viewport
  2. Viewbox
  3. 弧线
  4. 分组
  5. 分组动画
  6. preserveAspectRatio
  7. 响应式 SVG
  8. 分组和 Path
  9. Path
  10. 曲线
  11. 弧线
  12. 分组
  13. 分组动画

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

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

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

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

Viewport

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

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

Viewbox

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

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

基本格式为:

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

例如:

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

S/s

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

基本格式为:

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

实际样式图为:

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

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

具体实例为:

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

Q/q

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

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

基本格式为:

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

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

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

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

T/t

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

T x y (or t dx dy)

如图:

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

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

弧线

A/a

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

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 标签包裹的所有子元素都认同为一组。

例如:

<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 的相关属性。

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

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

<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 的童鞋有所帮助,文章语句有不通顺的地方,敬请担待,也欢迎大家在下方技术讨论尽情拍砖。

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

<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。所以,如下的图形大小为:

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

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

preserveAspectRatio

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

<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 轴的缩放比例。

假设有下列情况:

<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 分别为:

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 而已。

看个实际的例子吧:

<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 和分组通常是一起使用的,如下:

<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

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

<path d="M10 10"/>

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

L/l

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

L x y (or l dx dy)

H/h

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

H x (or h dx)

V/v

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

V y (or v dy)

举个栗子吧:

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

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

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

Z/z

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

Z (or z)

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

<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 需要定义三个点。

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

基本格式为:

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

例如:

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

S/s

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

基本格式为:

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

实际样式图为:

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

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

具体实例为:

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

Q/q

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

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

基本格式为:

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

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

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

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

T/t

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

T x y (or t dx dy)

如图:

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

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

弧线

A/a

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

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 标签包裹的所有子元素都认同为一组。

例如:

<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 的相关属性。

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

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

<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 的童鞋有所帮助,文章语句有不通顺的地方,敬请担待,也欢迎大家在下方技术讨论尽情拍砖。

「点点赞赏,手留余香」

22

给作者打赏,鼓励TA抓紧创作!

微信微信 支付宝支付宝

还没有人赞赏,快来当第一个赞赏的人吧!

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
码云笔记 » SVG动画快速入门实例教程

2 评论

回复 码云 取消回复