数据大屏项目(三)svg动画相关的知识

1,034 阅读2分钟

概要:本篇文章主要介绍数据大屏中的主要svg技术,也是svg高级进阶知识。主要是svg的动画相关知识。svg和canvas不一样,svg是dom结构的是xml形式的dom结构,可以与css js进行交互,因此svg动画可以通过css3动画控制,结合补间动画,过渡动画可以实现svg的动画。另外svg还有一个smil(Synchronized Multimedia Integration Language同步多媒体综合语言)动画,是一种直接用标签形式就可以实现的动画语言。

svg结合css实现svg动画

svg的transform属性,和css中的非常类似,包含了 translate位移,rotate 旋转,skewX 和 skewY 斜切,scale 缩放,matrix 复杂变形。

translate(x,y)表示x轴 y轴偏移的像素值

  <!-- transform属性和css中的类似, translate(x,y)表示x轴 y轴偏移的像素值-->
  <svg width="200" height="200" viewBox="0 0 200 200">
    <rect x="0" y="0" width="50" height="50" transform="translate(0,10)" />
  </svg>

image.png

rotate(30) 按照rect的起始位置 00 顺时针旋转30度

  <!-- rotate(30) 按照rect的起始位置 00 顺时针旋转30度-->
  <svg width="200" height="200" viewBox="0 0 200 200">
    <rect x="0" y="0" width="50" height="50" transform="translate(0,10) rotate(30)" />
  </svg> 

image.png

  • skewY(10)沿着Y轴斜切旋转10度
  <!-- skewY(10)沿着Y轴斜切旋转10度 -->
  <svg width="200" height="200" viewBox="0 0 200 200">
    <rect x="0" y="0" width="50" height="50" transform="translate(0,0) skewY(10)" />
  </svg>

image.png

skewX(10)沿着X轴斜切旋转10度

  <!-- skewX(10)沿着X轴斜切旋转10度 -->
  <svg width="200" height="200" viewBox="0 0 200 200">
    <rect x="0" y="0" width="50" height="50" transform="translate(0,0) skewX(10)" />
  </svg>

image.png

scale(X) x大于1表示放大,小于1表示缩小

  <svg width="200" height="200" viewBox="0 0 200 200">
    <rect x="0" y="0" width="50" height="50" transform="translate(0,0) scale(10)" />
  </svg>
  <svg width="200" height="200" viewBox="0 0 200 200">
    <rect x="0" y="0" width="50" height="50" transform="translate(0,0) scale(0.5)" />
  </svg>

image.png image.png

matrix 复杂变形

svg的trasform中matrix复杂变形是一个难点也是一个比较重要的属性,可以利用它对坐标进行转换的同时还让svg图片变形放大或者缩小。 使用方法 transform="matrix(a b c d e f) 如下伪代码

<svg > <cilcle transform="matrix(a b c d e f)"></cicle><svg>

其中的 a b c d e f 表示的是数字,计算公式如下:

svg元素在使用matrix前的图形坐标点 _x _y,使用后的坐标点用 x y标记
将matrix中的参数分成两组,单数位为一组 双数位为一组
[a c e]
[b d f]
x = a*_x + c*_y + e
y = b*_x + d*_y + f
// 根据公式可以计算出转换后的图的四个顶点坐标是
// [50 80] [140 110] [30 140] [120 170]
  <svg width="400" height="400" viewBox="0 0 400 400">
    <rect x="0" y="0" width="50" height="50" fill="blue" />
    <rect x="0" y="0" width="50" height="50" transform="matrix(3 1 -1 3 30 40)" />
  </svg>

image.png

svg的smil(即同步多媒体综合语言)动画

smil动画,它允许我们通过 HTML 标签不需要css js来实现动画效果,它可以用于:

  • 实现过渡动画
  • 实现补间动画
  • 动画颜色变换
  • 路径运动动画(CSS3无法实现) SMIL 包含以下标签:
  • set 实现属性的延迟设置
  • animate 实现过渡动画
  • animateColor已经弃用,可以使用animate实现颜色变化
  • animateTransform 实现补间动画
  • animateMotion 实现路径运动动画

set 实现属性的延迟设置

   <!-- set改变svg的属性延时效果 -->
    <svg width="200" height="200">
      <rect x="0" y="0" fill="red" width="100" height="50">
        <!-- 写上需要实现动画的属性 to指属性值变到某个值 begin动画从几秒后开始-->
        <set attributeName="x" attributeType="XML" to="10" begin="1s"></set>
        <set attributeName="y" attributeType="XML" to="20" begin="2s"></set>
        <set attributeName="fill" attributeType="XML" to="blue" begin="3s"></set>
      </rect>
    </svg>

GIF 2021-7-21 12-06-43.gif

animate 基础动画元素。实现单属性的动画过渡效果.

      <svg width="200" height="200">
        <circle cx="0" cy="0" r="30" fill="blue" stroke="#333" stroke-width="1">
          <!-- attributeType有两个值XML和css 如果用来做动画的属性来自dom用XML 否则用css-->
          <!-- fill="freeze"表示动画结束停留原来的位置。和css animte的forwards相似
            fill="remove"表示动画结束回到初始位置-->
          <animate attributeName="cx" attributeType="XML" from="0" to="100" dur="5s" repeatCount="indefinite" fill="freeze"></animate>
          <animate attributeName="cy" attributeType="XML" from="0" to="50" dur="5s" repeatCount="indefinite" fill="freeze"></animate>
          <animate attributeName="stroke" attributeType="css" from="blue" to="red" begin="0" dur="5s" repeatCount="indefinite" fill="freeze"></animate>
          <animate attributeName="fill" attributeType="css" from="blue" to="red" begin="0" dur="5s" repeatCount="indefinite" fill="freeze"></animate>
        </circle>
      </svg>

000-36.gif

animateTransform 实现transform变换动画效果

      <svg width="200" height="200" viewBox="0 0 200 200">
        <rect x="0" y="0" width="60" height="60" fill="red">
          <!-- begin="0"表示从0s就开始执行动画 执行时间dur持续3s 改变属性transform的scale缩放 from 1到2-->
          <animateTransform attributeName="transform" begin="0s" dur="3s" type="scale" from="1" to="2" repeatCount="indefinite" />
        </rect>
      </svg>

00001.gif

animateMotion 标签路径运动动画(css中是无法实现的)

    <svg width="200" height="200">
      <rect x="0" y="0" fill="red" width="10" height="10">
        <!-- path表示运动的轨迹,dur运动持续的时间,
        rotate:沿路径动画的元素的旋转,通常是使其指向动画的方向, 
        freeze:相当于css动画中的forwar保持结束态
        repeatCount:重复次数-->
        <animateMotion
          path="M10 10 L110 10 L110 110 L10 110 Z"
          dur="5s"
          rotate="0"
          fill="freeze"
          repeatCount="2"></animateMotion>
      </rect>
      <path
        d="M10 10 L110 10 L110 110 L10 110 Z"
        fill="none"
        stroke="pink"></path>
    </svg>

000-31.gif