一文带你搞定svgAnimation(Svg动画)

svg 动画

transform 变换

translate 位移

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

rotate 旋转

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

skewX 和 skewY 斜切

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

scale 缩放

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

matrix 复杂变形

<svg viewBox="0 0 200 200">
  <rect x="10" y="10" width="30" height="20" fill="green" />
 
  
  <rect x="10" y="10" width="30" height="20" fill="red"
        transform="matrix(3 1 -1 3 30 40)" />
svg>

svg 动画(CSS)

案例1:环形进度条






关键知识点:

  • keyframes 动画
  • stroke-dasharray 使用技巧
  • matrix 计算公式

一文带你搞定svgAnimation(Svg动画)_第1张图片

同样的方法我们实现一个矩形进度条,核心代码:

<svg width="200" height="200" viewBox="0 0 200 200">
  <rect x="0" y="0" width="200" height="200" fill="none" stroke="grey" stroke-width="8">rect>
  <rect x="0" y="0" width="200" height="200" fill="none" stroke="blue" stroke-width="8" class="rect" transform="matrix(0,1,-1,0,200,0)">rect>
svg>

matrix 计算方法:
一文带你搞定svgAnimation(Svg动画)_第2张图片

案例2:LOGO 描边

  • 下载任意 SVG 格式的 LOGO
  • 获取 path 长度
const path = document.getElementById('taobao-logo')
const pathLen = path.getTotalLength() // 6885
  • 添加描边样式和动画
.taobao-path {
  fill: none;
  stroke: #333;
  stroke-width: 1;
  animation: taobao 5s linear infinite forwards;
}
@keyframes taobao {
  from {
    stroke-dasharray: 6885;
    stroke-dashoffset: 6885;
  }
  to {
    stroke-dasharray: 6885;
    stroke-dashoffset: 0;
  }
}

关键知识点:

  • stroke-dasharray
  • stroke-dashoffset

svg 动画(SMIL)

SMIL 全称 Synchronized Multimedia Integration Language,它允许我们通过 HTML 标签实现动画效果,它可以用于:

  • 实现过渡动画
  • 实现补间动画
  • 动画颜色变换
  • 路径运动动画(CSS3无法实现)

SMIL 包含以下标签:

<set>
<animate>
<animateColor>
<animateTransform>
<animateMotion>

::: tip
SMIL 兼容性:查看
:::

为什么要用 SMIL?

实现动画的全新方式:

  • 无需 CSS
  • 无需 JS
  • 几个标签轻松实现复杂动画,它不香吗?

set 标签

实现属性的延迟设置

<svg width="400" height="400">
  <rect x="0" y="0" width="100" height="100" fill="red">
    <set attributeName="x" attributeType="XML" to="10" begin="1s" />
    <set attributeName="x" attributeType="XML" to="20" begin="2s" />
    <set attributeName="x" attributeType="XML" to="30" begin="3s" />
    <set attributeName="x" attributeType="XML" to="40" begin="4s" />
    <set attributeName="x" attributeType="XML" to="50" begin="5s" />
  rect>
svg>

animation 标签

案例一:移动的小球

<svg width="500" height="200" viewBox="0 0 500 200">
  <circle cx="0" cy="0" r="30" fill="blue" stroke="black" stroke-width="1">
    <animate attributeName="cx" from="0" to="200" dur="5s" repeatCount="indefinite" />
    <animate attributeName="cy" from="0" to="200" dur="5s" repeatCount="indefinite" />
  circle>
svg>

案例二:形状补间动画

<svg width="400" height="400">
  <polygon points="30 30 70 30 90 70 10 70" fill="#fcc" stroke="black">
    <animate attributeName="points" attributeType="XML" to="50 30 70 50 50 90 30 50" dur="5s" fill="freeze" repeatCount="1" />
  polygon>
svg>

::: warning
注意点:

  • animation 作用域的问题
  • fill 属性:freeze 和 remove
    :::

animationColor 标签

已废弃,通过 animation 可实现同样效果(参考)

<svg width="200" height="200" viewBox="0 0 200 200">
  <rect x="0" y="0" width="100" height="50" fill="red">
    <animate attributeName="fill" from="red" to="blue" dur="5s" repeatCount="indefinite">animate>
  rect>
svg>

当然你想用这个属性也用不了,看看这个糟糕的兼容性:

一文带你搞定svgAnimation(Svg动画)_第3张图片

animateTransform 标签

<svg width="200" height="200" viewBox="0 0 200 200">
  <rect x="0" y="0" width="60" height="60" fill="red">
    <animateTransform attributeName="transform" begin="0s" dur="3s" type="scale" from="1" to="2" repeatCount="indefinite" />
  rect>
svg>

animateMotion 标签

案例一:按 path 轨迹运动的正方形

<svg width="200" height="200" viewBox="0 0 200 200">
  <rect x="0" y="0" width="10" height="10" fill="red">
    <animateMotion
      path="M 10 10 L 110 10 L 110 110 L 10 110 Z"
      dur="5s"
      rotate="auto"
      fill="freeze"
      repeatCount="indefinite"
    />
  rect>
  <path id="motion-path" d="M 10 10 L 110 10 L 110 110 L 10 110 Z" fill="none" stroke="green" />
svg>

案例二:混合动画

<svg viewBox="0 0 200 200" width="200" height="200">
    <rect x="0" y="0" rx="0" ry="0" width="10" height="10" fill="red">
      <animateMotion
        id="forward-rect"
        path="M 10 10 L 110 10 L 110 110 L 10 110"
        dur="2s"
        rotate="0"
        fill="freeze"
        begin="0; backward-rect.end + 0.5s"
      />
      <animateMotion
        id="backward-rect"
        path="M 10 110 L 110 110 L 110 10 L 10 10"
        dur="2s"
        rotate="0"
        fill="freeze"
        begin="forward-rect.end + 0.5s"
      />
      <animate
        id="red-to-blue"
        attributeType="XML"
        attributeName="fill"
        begin="0; blue-to-red.end + 1s"
        from="red"
        to="blue"
        dur="2s"
        fill="freeze"
      />
      <animate
        id="blue-to-red"
        attributeType="XML"
        attributeName="fill"
        begin="red-to-blue.end + 1s"
        from="blue"
        to="red"
        dur="2s"
        fill="freeze"
      />
    rect>
    <path d="M 10 10 L 110 10 L 110 110 L 10 110" fill="none" stroke-width="1" stroke="blue"/>
svg>

案例三:点击变色或位移

<svg viewBox="0 0 200 200" width="200" height="200">
    <g id="rect1">
      <rect x="0" y="0" rx="0" ry="0" width="100" height="100" fill="red">
        <animate
          attributeType="XML"
          attributeName="fill"
          from="red"
          to="green"
          begin="rect1.click"
          dur="2s"
          fill="freeze"
        />
      rect>
    g>
    <animateTransform
      attributeType="XML"
      attributeName="transform"
      type="translate"
      from="0, 0"
      to="50, 50"
      begin="rect1.click"
      dur="2s"
      fill="freeze"
    />
    <rect x="0" y="100" width="100" height="100" fill="blue">
      <animate
        attributeType="XML"
        attributeName="fill"
        from="blue"
        to="green"
        begin="rect1.click"
        dur="2s"
        fill="freeze"
      />
    rect>
svg>

::: tip
实现细节:

  • rotate: auto -> 0 可以更加流畅
  • begin: 可填入多个值,支持表达式
  • 多个 animateMotion 并行时,后者会覆盖前者
  • path 用法:查看
    :::

扩展

总结 svg 特点

  1. SVG 与 PNG、JPEG 和 GIF 图片相比,拥有很小的尺寸;
  2. SVG 是矢量图,可以伸缩,适用各种分辨率;
  3. SVG 采用开放标准,本质是 XML,可以被各种工具读取(浏览器、图片管理器、markdown 等);
  4. SVG 图像中的文本是可选的,同时也是可搜索的;
  5. SVG 可以与 CSS 结合,获得更强的扩展性。

SVG 实用工具

termtosvg

github地址

实现效果:

一文带你搞定svgAnimation(Svg动画)_第4张图片

SVG 压缩

github地址

你可能感兴趣的:(vue,html5,前端,echarts)