数据可视化-Snap、GSAP

818 阅读4分钟

一、Snap

1.1 介绍

  • 什么是Snap.svg?

    • Snap.svg 是一个专门用于处理SVG的 JavaScript 库 ( 类似jQuery )。

    • Snap 为 Web 开发人员提供了干净、直观、功能强大的API,这些API专门用来操作SVG。

    • Snap 可用于创建动画,操作现有的 SVG 内容,以及生成 SVG 内容。

  • 为什么选择Snap.svg?

    • Snap 是由 Dmitry Baranovskiy 从零开始编写,专为现代浏览器(IE9 及更高版本、Safari、Chrome、Firefox 和 Opera)而设计。并且Snap可以支持遮罩、剪辑、图案、全渐变、组等功能

    • Snap 还有一个独特功能是能够与现有的 SVG一起工作。意味着 SVG 内容不必使用 Snap 生成,就可使用 Snap 来处理它。

      • 比如可以在 Illustrator 或 Sketch 等工具中创建 SVG 内容,然后使用 Snap 对其进行动画处理和操作。
    • Snap 还支持动画。提供了简单直观的与动画相关的JavaScript API,Snap 可以帮助你的 SVG 内容更具交互性和吸引力

    • Snap.svg 库处理 SVG 就像 jQuery 处理 DOM 一样简单,并且 Snap 是 100% 免费和 100% 开源的。

1.2 初体验

  • Snap.svg常用的API:

    • Snap: 工厂函数,创建或获取SVG

      • Snap(w, h) 、Snap(selector)….
    • Paper: 纸张 | SVG画布

      • circle、rect、line、path、text….
    • Element:元素

      • animate、attr、select、before、after…
    • mina:通常用到的一些动画时间函数。

      • mina.linear、mina.easeIn、mina.easeOut….
  • Snap更多的API文档

  • 代码演示

    • 绘制一个圆形

      <!DOCTYPE html>
      <html lang="en">
      <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
      </head>
      <body>
        <script src="./libs/snap.svg-min.js"></script>
        <script>
          window.onload = function() {
            // 1.创建一个svg
            const svg = Snap(300, 300)
            // svg对象会克隆一份保存在paper中
            console.log(svg === svg.paper) // true
      
            // 2.在svg画布中绘制一个圆
            // const c = svg.circle(100, 100, 50)
            const c = svg.paper.circle(100, 100, 50)
      
            // 3.给圆添加属性
            c.attr({
              fill: 'blue'
            })
      
            // 拿到svg的元素对象
            // console.log(svg)
            // 4.将svg添加到body中
            document.body.appendChild(svg.node)
          }
        </script>
      </body>
      </html>
      
      image.png
    • 操作Svg

      <!DOCTYPE html>
      <html lang="en">
      <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style>
          body {
            margin: 0;
            padding: 0;
            background-image: url(../images/grid.png);
          }
          svg {
            background-color: rgba(255, 0, 0, 0.1);
          }
        </style>
      
      </head>
      <body>
      
        <svg id="svg" width="300" height="300" xmlns="http://www.w3.org/2000/svg" >
          <rect id="rectangle1" x="0" y="0" width="100" height="50"></rect>
        </svg>
      
        <script src="./libs/snap.svg-min.js"></script>
        <script>
          window.onload = function() {
            const svg = Snap("#svg")
            const paper = svg.paper
      
            // 绘制一个矩形
            const rectangle = paper.rect(0, 100, 100, 50)
            rectangle.attr({
              fill: 'red'
            })
      
            // 选择已有的矩形进行操作
            const rectangle1 = paper.select('#rectangle1')
            rectangle1.attr({
              fill: 'purple'
            })
          }
        </script>
      </body>
      </html>
      
      image.png

1.3 实现动画

  • 基本使用

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
      <style>
        body {
          margin: 0;
          padding: 0;
          background-image: url(../images/grid.png);
        }
        svg {
          background-color: rgba(255, 0, 0, 0.1);
        }
      </style>
    
    </head>
    <body>
    
      <svg id="svg" width="300" height="300" xmlns="http://www.w3.org/2000/svg" >
        <rect id="rectangle1" x="0" y="0" width="100" height="50"></rect>
      </svg>
    
      <script src="./libs/snap.svg-min.js"></script>
      <script>
        window.onload = function() {
          const svg = Snap("#svg")
          const paper = svg.paper
    
          // 绘制一个矩形
          const rectangle = paper.rect(0, 100, 100, 50)
          rectangle.attr({
            fill: 'red'
          })
    
          // 选择已有的矩形进行操作
          const rectangle1 = paper.select('#rectangle1')
          rectangle1.attr({
            fill: 'purple'
          })
    
          // 实现动画,requestAnimationFrame 1s 61次
          // Snap.animate(
          //   0, // from
          //   200, // to
          //   function(val) {
          //     console.log('val', val)
          //     // 回调 61 次,将 0-200 拆分成61份
          //     rectangle1.attr({
          //       x: val
          //     })
          //   },
          //   1000, // 毫秒 
          //   mina.linear,
          //   function() {
          //     console.log('动画结束了')
          //   }
          // )
    
          Snap.animate(
            [0, 0], // from
            [200, 200], // to
            function(val) {
              // console.log('val', val)
              // 回调 61 次,将 0-200 拆分成61份
              rectangle1.attr({
                x: val[0],
                y: val[1]
              })
            },
            3000, // 毫秒
            mina.easeout,
            function() {
              console.log('动画结束了')
            }
          )
        }
      </script>
    </body>
    </html>
    
    image.png
  • 鳄鱼动效

    • 下面的 SVG 代码有省略(太长了)
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
      </head>
      <body>
        <svg
          version="1.1"
          id="crocodile"
          xmlns="http://www.w3.org/2000/svg"
          xmlns:xlink="http://www.w3.org/1999/xlink"
          x="0px"
          y="0px"
          width="375px"
          height="300px"
          viewBox="0 0 500 400"
          enable-background="new 0 0 500 400"
          xml:space="preserve"
        >
          <polyline
            id="path-eye"
            opacity="0.25"
            fill="none"
            stroke="#000000"
            stroke-width="2"
            stroke-miterlimit="10"
            enable-background="new    "
            points="
                  121.714,247.568 66.427,193.472 66.427,149.497 "
          />
          <polyline
            id="path-pie"
            opacity="0.25"
            fill="none"
            stroke="#000000"
            stroke-width="2"
            stroke-miterlimit="10"
            enable-background="new    "
            points="
                  272.069,237.568 226.782,193.472 226.782,155.497 "
          />
          <polyline
            id="path-map"
            opacity="0.25"
            fill="none"
            stroke="#000000"
            stroke-width="2"
            stroke-miterlimit="10"
            enable-background="new    "
            points="
                  412.069,227.568 376.782,193.472 376.782,145.497 "
          />
          <g id="diagram-eye">
            <linearGradient
              id="SVGID_2_"
              gradientUnits="userSpaceOnUse"
              x1="238.8165"
              y1="619.2575"
              x2="320.3815"
              y2="700.8225"
              gradientTransform="matrix(1 0 0 1 -171 -537.5)"
            >
              <stop offset="0" style="stop-color: #000000; stop-opacity: 0.15" />
              <stop offset="0.9331" style="stop-color: #000000; stop-opacity: 0" />
            </linearGradient>
            <polygon
              fill="url(#SVGID_2_)"
              points="91.848,220.855 10.283,139.291 125.35,24.224 206.915,105.789  "
            />
            <rect x="10" y="24.507" fill="#00A99D" width="115.35" height="115.35" />
            
            <path
              fill="#60C6BA"
              d="M28.023,82.182c0,0,18.023-28.837,39.652-28.837s39.652,28.837,39.652,28.837s-18.023,28.837-39.652,28.837
                      S28.023,82.182,28.023,82.182z"
            />
            <g>
              <circle fill="#9BEADF" cx="67.675" cy="82.182" r="24.031" />
            </g>
            <path
              fill="#00A99D"
              d="M67.675,65.017c0,0,3.433,6.866,3.433,17.165s-3.433,17.165-3.433,17.165s-3.433-6.866-3.433-17.165
                      S67.675,65.017,67.675,65.017z"
            />
            <circle
              opacity="0.5"
              fill="#FFFFFF"
              enable-background="new    "
              cx="57.921"
              cy="67.48"
              r="4.806"
            />
            <circle
              opacity="0.5"
              fill="#FFFFFF"
              enable-background="new    "
              cx="50.712"
              cy="74.689"
              r="2.403"
            />
          </g>
    
          <g id="diagram-pie">
            <linearGradient
              id="SVGID_6_"
              gradientUnits="userSpaceOnUse"
              x1="400.0527"
              y1="624.0652"
              x2="473.0262"
              y2="697.0389"
              gradientTransform="matrix(1 0 0 1 -171 -537.5)"
            >
              <stop offset="0" style="stop-color: #000000; stop-opacity: 0.25" />
              <stop offset="0.9" style="stop-color: #000000; stop-opacity: 0" />
            </linearGradient>
            <path
              fill="url(#SVGID_6_)"
              d="M272.351,43.267l-86.596,86.597l72.973,72.973l86.596-86.596L272.351,43.267z"
            />
            <circle fill="#60C6BA" cx="226.973" cy="83.304" r="61.828" />
            <path
              fill="#00A99D"
              d="M197.727,137.784c8.708,4.684,18.665,7.347,29.246,7.347c34.146,0,61.828-27.681,61.828-61.828
                        s-27.681-61.828-61.828-61.828v59.767L197.727,137.784z"
            />
            <g>
              <g>
                <g>
                  <g>
                    <g>
                      <defs>
                        <circle id="SVGID_7_" cx="226.973" cy="83.304" r="61.828" />
                      </defs>
                      <clipPath id="SVGID_8_">
                        <use xlink:href="#SVGID_7_" overflow="visible" />
                      </clipPath>
    
                      <linearGradient
                        id="SVGID_9_"
                        gradientUnits="userSpaceOnUse"
                        x1="397.6839"
                        y1="619.334"
                        x2="444.7831"
                        y2="666.433"
                        gradientTransform="matrix(1 0 0 1 -171 -537.5)"
                      >
                        <stop
                          offset="0"
                          style="stop-color: #000000; stop-opacity: 0.25"
                        />
                        <stop
                          offset="1"
                          style="stop-color: #000000; stop-opacity: 0"
                        />
                      </linearGradient>
                      <path
                        clip-path="url(#SVGID_8_)"
                        fill="url(#SVGID_9_)"
                        d="M258.189,50.329l-4.726,4.726
                                            c6.853,6.853,11.092,16.321,11.092,26.779c0,20.916-16.955,37.871-37.871,37.871c-10.458,0-19.926-4.239-26.779-11.092
                                            l-4.726,4.726l47.099,47.099l63.009-63.009L258.189,50.329z"
                      />
                    </g>
                  </g>
                </g>
              </g>
            </g>
            <path
              fill="#9BEADF"
              d="M226.973,83.304V21.476c-9.586,0-18.663,2.183-26.76,6.077L226.973,83.304z"
            />
            <circle fill="#60C6BA" cx="226.973" cy="83.304" r="45.34" />
            <path
              fill="#00A99D"
              d="M272.313,83.304c0-25.041-20.3-45.34-45.34-45.34v90.681C252.013,128.644,272.313,108.345,272.313,83.304z"
            />
            <path
              fill="#9BEADF"
              d="M184.162,68.37l42.811,14.934v-45.34C207.166,37.963,190.337,50.669,184.162,68.37z"
            />
          </g>
    
          <g id="diagram-map">
            <linearGradient
              id="SVGID_10_"
              gradientUnits="userSpaceOnUse"
              x1="505.6437"
              y1="570.8013"
              x2="608.6902"
              y2="673.8477"
              gradientTransform="matrix(1 0 0 1 -171 -537.5)"
            >
              <stop offset="0" style="stop-color: #000000; stop-opacity: 0.25" />
              <stop offset="1" style="stop-color: #000000; stop-opacity: 0" />
            </linearGradient>
            <polygon
              fill="url(#SVGID_10_)"
              points="387.104,186.934 330.897,130.727 334.644,33.301 432.069,29.554 488.276,85.761    "
            />
            <path
              fill="#60C6BA"
              d="M435.816,117.612c0,9.313-7.549,16.862-16.862,16.862h-78.69c-9.313,0-16.862-7.549-16.862-16.862v-78.69
                      c0-9.313,7.549-16.862,16.862-16.862h78.69c9.313,0,16.862,7.549,16.862,16.862V117.612z"
            />
            <g>
              <path
                fill="#00A99D"
                d="M412.875,101.541c-0.173,1.625-0.483,1.955,1.618,1.847C414.559,102.355,414.023,101.464,412.875,101.541
                          C412.822,102.037,414.083,101.46,412.875,101.541z M425.12,118.865c0.869-1.597-3.166-1.674-3.927-1.848
                          c0.801-2.307-0.758-1.445-2.301-1.944c-0.981-0.317-2.751-2.095-3.72-2.83c-1.12-0.849-2.495-0.625-3.695-1.162
                          c-1.639-0.734-1.6-2.245-3.661-2.818c-1.15-0.319-4.17,0.105-4.623-0.454c-0.808-0.996-2.685-0.572-3.697-0.255
                          c-1.204,0.376-2.472,1.029-3.236,2.068c-0.416,0.566-1.26,2.358-1.168,2.545c0.776-0.172,8.085-5.264,8.085-2.542
                          c0,1.436,4.053,1.143,4.328,2.108c0.547,1.92,3.575,1.939,5.144,1.819c-0.561,2.424,2.1,3.612,3.927,4.158
                          c-0.159,0.952-1.499,1.761-1.156,2.771C417.782,120.22,423.477,120.739,425.12,118.865
                          C425.957,117.328,424.645,119.407,425.12,118.865z M395.784,80.974c2.509,0.069,1.327,2.668,3.205,3.107
                          c1.935,0.453-0.559,5.006,0.952,6.131c0.372-0.824,0.346-1.347,1.385-1.155c-0.047,1.523-1.881,2.833-0.23,4.158
                          c0.298,0.492,1.155,0.373,1.155,1.155c0,1.539,2.068,4.913,3.927,5.543c0.575-2.302,1.155-4.685,1.155-6.365
                          c0-1.209-0.534-4.18-1.617-4.722c0.234-1.168,0.235-0.913,0-1.617c-1.028-0.69-0.525-1.354-0.692-2.311
                          c-0.154-0.88-0.925-2.092-0.925-3.601c0-0.721-1.258-1.364-0.991-2.097c0.381-1.047,0.734-0.752,0.53-2.386
                          c-0.003,0.008,1.055-2.113,1.155-2.31c-0.512-1.531,2.031-2.269,2.31-3.927c1.698,0.566,1.654-1.618,2.541-1.618
                          c0.788,0,0.751-1.144,0.924-1.848c1.387,0.347,1.32-0.378,2.541-0.924c1.275-0.651,2.202-2.903,3.696-3.234
                          c-0.136-0.579-0.367-1.118-0.692-1.617c0.854,0.015,1.187-0.092,1.617-0.462c-0.15-0.595-0.834-1.288-1.155-1.617
                          c0.57,0.157,1.109,0.08,1.617-0.231c0.407,1.22,1.495,0.917,2.079,0.001c-0.588-0.451-0.413-0.236-0.923-0.924
                          c-2.706-0.516-1.321-0.662,0.231-1.616c-0.508-1.524-0.092-1.592-1.791-2.426c-0.48-0.236-0.99-1.303-1.212-1.731
                          c0.616-0.077,1.232-0.154,1.848-0.231c-0.155-0.74-0.927-1.502-1.387-1.848c0.231,0,0.463,0,0.694,0
                          c-0.272-0.855-1.376-1.159-1.617-2.079c0.231,0,0.461,0,0.692,0c-0.252-1.762,0.278-1.826,0.693-3.696
                          c0.709,0.076,0.709-0.463,0-1.617c1.639-0.328,0.885-0.792,2.541-0.462c0.214-0.626-0.062-0.534,0.463-0.923
                          c0.867,1.135-1.279,2.217-1.617,3.232c0.154,0,0.308,0,0.462,0c-1.142,0.548-1.308,3.691-0.692,4.158
                          c0.473,0.359,2.247-1.061,1.616,1.155c1.652-0.881,1.439-0.474,1.848-1.848c0.158-0.533,0.368-0.674,0.462-1.387
                          c0.103-0.818-1.031-2.294-0.924-3.927c0.761,0.339,1.825,1.343,2.773,0.923c1.198-0.58,0.322-2.588,1.848-2.079
                          c0.399-1.329,0.309-4.388-0.001-4.388c0.589,0,1.487-2.163,2.078-2.541c0.9-0.576,2.577-0.124,3.003-1.387
                          c1.198-0.054,2.052,0.555,2.54,0.231h0.231c0.197-0.515-0.382-0.574-0.462-0.924h0.231c0.151-0.347,0.186-0.377,0.231-0.923
                          c0.028,0.006,0.057,0.011,0.085,0.017c-2.69-5.74-8.502-9.725-15.261-9.725h-78.69c-9.313,0-16.862,7.549-16.862,16.862v61.411
                          c0.458,0.918,1.198,2.159,1.477,2.364c1.681,0.128,2.141,3.274,3.465,4.157c0.577,1.067,0.775,2.05,1.617,3.233
                          c1.367,0.688,2.337,7.623,1.154,7.623c-1.059,0,1.12,6.006,3.004,6.006c0.52,0,2.246,1.595,2.77,2.077
                          c0.742,0.577,0.698,1.476,1.617,2.08c0.316,0.204,1.355,0.566,1.847,0.693c3.485,0.901,6.774,5.433,10.857,4.619
                          c0.077,0.231,0.154,0.462,0.231,0.693c0.995,0.053,0.783,0.142,1.386,0.462v0.134h29.595c0.209-0.462-0.014-0.922,0.199-1.524
                          c0.298-0.276,1.803-5.585-0.229-5.775c0.296-0.644,0.87-1.52,1.155-1.848c0.112,0.498,0.035,0.96-0.231,1.386
                          c2.802,0.691,0.126-0.015,0.924,0.692c0.154,0,0.307,0,0.461,0c-0.322-2.284,1.188-4.774,0.654-6.635
                          c-0.335-1.168,1.194-2.637,1.194-3.528c0-1.734,0.816-2.275-0.924-3.233c-0.694-0.382-1.948-0.727-3.234,0
                          c-2.284,3.036-5.775,0.71-5.775,6.072c0,1.772-2.141,5.815-3.927,6.167c-0.333-0.267-0.576-0.568-0.693-0.923
                          c-0.542,0.181-1.804,0.217-2.238,0.526c-0.244,0.173-0.924,1.288-0.996,1.321c-0.92-0.453-2.549,0.335-3.552,0.408
                          c-1.738,0.126-1.403-2.025-3.031-2.025c-2.078,0-1.885-0.493-2.893-2.494c-0.721-1.432-0.569-2.181-2.075-3.05
                          c-0.257-0.257-0.254-0.6-0.461-0.924c-0.567-0.888-1.997-2.877-2.079-4.156c-0.198,0.127-0.568,0.36-0.692,0.462
                          c0.316-1.902,0.693-4.139,0.692-5.775c0-0.996-0.947-2.768-0.678-3.571c0.325-0.972-0.078-2.736-0.015-3.357
                          c-0.317-1.908,0.494-1.278,0.692-3.004c0.212-0.369,1.095-0.273,1.467-1.403c0.323-0.98,0.135-0.973-0.544-1.138
                          c0.512-1.53-0.621-1.696-0.924-3.002c-0.274-1.181-0.879-3.683,0.461-3.234c0.399-1.043,0.425-3.002,1.849-3.002
                          c1.109,0,1.63-0.648,1.385-1.617c1.057-0.677,2.649-0.532,3.464-1.155c0.065-1.455,1.375-1.531,0.925-3.003
                          c0.285,0.095,1.319,0.703,1.385,0.693c0.705-0.106,2.3-0.59,2.079-1.617c0.962,0.485,1.113-0.14,1.848,0
                          c0.005,0,2.327,0.773,1.848,0.693c0.46,0.104,0.876-0.271,1.617-0.463c-0.211,1.814,1.416,1.576,2.541,0.923
                          c0,0.154,0,0.308,0,0.462c-2.585,1.273,2.05,1.263,2.54,1.385c-0.253-0.934-0.693-1.484,0.231-2.309
                          c0.628,0.173,3.465,2.134,3.465,2.308c0,0.726,0.493,0.553,0.924,0.232c-0.194-0.973-2.545-2.14-0.23-2.541
                          c-0.047-0.174-0.433-1.023-0.693-0.925c-1.103,0.498-0.558-0.805-2.079-0.231c-0.159-0.163-0.461-0.61-0.692-0.923
                          c0.769-0.104,1.539-0.104,2.31,0c-0.053-0.479,0.108-0.734,0.484-0.766c0.406-0.116,1.422-0.167,1.364-0.159
                          c0.818-0.111,2.554,1.765,2.309-0.462c0.154,0,0.308,0,0.462,0c0.353,2.143,1.659,1.379,2.078,0.001
                          c0.584,1.551,1.801,0.262,3.004,0.462c-0.496,1.646,1.971,1.348,2.541,2.772c0.799,0.348,1.109,0.703,2.078,0.461
                          c-0.381,0.052,2.847-1.321,2.667-0.991C396.719,81.347,395.595,81.32,395.784,80.974
                          C398.309,81.043,395.457,81.572,395.784,80.974z M428.351,115.631c0.024-0.304-0.19-0.311-0.461-0.231
                          C428.152,115.658,427.888,115.498,428.351,115.631z M399.478,112.396c0.78,0.312,0.3,1.138-0.462,1.618
                          C402.647,115.73,399.785,108.812,399.478,112.396z M434.824,120.714c-0.447-0.188-1.037,0.024-1.386,0.462
                          c-1.893,0.693-2.513-1.081-4.39-0.694c1.479,1.363,0.753,1.063,1.385,2.772c0.088,0.149,1.346,2.124,0.709,2.146
                          c-0.981,0.035-2.859-0.336-3.845-0.597c-1.739-0.46-3.358,1.223-1.391,1.38c2.47,0.198,4.858,0.304,7.367,0.304
                          c1.102-1.774,1.884-3.761,2.265-5.893C435.299,120.634,435.062,120.674,434.824,120.714
                          C434.377,120.526,435.062,120.674,434.824,120.714z M418.188,125.793c-0.611-1.214-4.706-1.446-5.446-0.186
                          c-0.362,0.616,5.189,3.353,6.758,1.667C419.879,126.867,418.13,125.748,418.188,125.793
                          C417.857,125.135,418.525,126.058,418.188,125.793z"
              />
            </g>
    
            <linearGradient
              id="SVGID_11_"
              gradientUnits="userSpaceOnUse"
              x1="548.6378"
              y1="585.9402"
              x2="596.8632"
              y2="634.1658"
              gradientTransform="matrix(1 0 0 1 -171 -537.5)"
            >
              <stop offset="0" style="stop-color: #000000; stop-opacity: 0.25" />
              <stop
                offset="0.7305"
                style="stop-color: #000000; stop-opacity: 0.0245"
              />
              <stop offset="0.9282" style="stop-color: #000000; stop-opacity: 0" />
            </linearGradient>
            <polygon
              fill="url(#SVGID_11_)"
              points="413.91,108.619 377.844,71.522 389.591,36.487 434.519,83.888     "
            />
            <path
              fill="#9BEADF"
              d="M391.297,48.623h-0.169c0.508-1.435,0.799-2.971,0.799-4.58c0-7.588-6.151-13.739-13.739-13.739
                      s-13.739,6.151-13.739,13.739c0,1.608,0.291,3.145,0.799,4.58h-0.169l0.504,0.88c0.395,0.911,0.892,1.764,1.466,2.56l11.14,19.459
                      l11.14-19.459c0.574-0.796,1.071-1.649,1.466-2.56L391.297,48.623z M373.607,44.043c0-2.529,2.051-4.58,4.58-4.58
                      s4.58,2.05,4.58,4.58c0,2.529-2.051,4.58-4.58,4.58S373.607,46.572,373.607,44.043z"
            />
          </g>
          <rect
            id="hit-eye"
            x="6.5"
            y="22.061"
            opacity="0"
            fill="#FF0000"
            width="122.667"
            height="123.071"
          />
          <rect
            id="hit-pie"
            x="165.658"
            y="22.061"
            opacity="0"
            fill="#FF0000"
            width="122.667"
            height="123.071"
          />
          <rect
            id="hit-map"
            x="316.855"
            y="22.061"
            opacity="0"
            fill="#FF0000"
            width="122.667"
            height="123.071"
          />
        </svg>
    
        <script src="./libs/snap.svg-min.js"></script>
        <script>
          window.onload = function() {
            const crocodileSvgEl = Snap('#crocodile')
    
            const ids = ['eye', 'pie', 'map']
    
            ids.forEach(id => {
              const diagramEl = Snap.select(`#diagram-${id}`)
              const iconEl = Snap.select(`#hit-${id}`)
              iconEl.hover(function() {
                showIcon(diagramEl)
              })
            })
    
            // 封装动画函数
            function showIcon(diagramEl) {
              Snap.animate(
                0.8,
                1,
                function(val) {
                  diagramEl.attr({
                    transform: `scale(${val})`
                  })
                },
                500,
                mina.bounce, // 抖动效果
                function() {
                  console.log('动画结束')
                }
              )
            }
          }
        </script>
      </body>
    </html>
    
    鳄鱼.gif

二、GSAP

2.1 介绍

  • 什么是GSAP

    • GSAP全称是( GreenSock Animation Platform)GreenSock 动画平台。

    • GSAP 是一个强大的 JavaScript 动画库,可让开发人员轻松的制作各种复杂的动画。

  • GSAP动画库的特点

    • 与Snap.svg不一样,GSAP无论是HTML 元素、还是SVG、或是Vue、React组件的动画,都可以满足你的需求。

    • GSAP的还提供了一些插件,可以用最少的代码创建令人震惊的动画,比如:ScrollTrigger插件和MorphSVG插件。

    • GSAP 的核心是一个高速的属性操纵器,随着时间的推移,它可以极高的准确性更新值。它比 jQuery 快 20 倍!

    • GSAP 使用起来非常灵活,在你想要动画的地方基本都可以使用,并且是零依赖。

  • GSAP官网

2.2 初体验

  • 移动SVG中的一个矩形
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
      <style>
        body, ul {
          margin: 0;
          padding: 0;
          background-image: url(../images/grid.png);
        }
        svg {
          background-color: rgba(255, 0, 0, 0.1);
        }
      </style>
    
    </head>
    <body>
    
      <svg width="300" height="300" xmlns="http://www.w3.org/2000/svg" >
        <rect id="rectangle" x="0" y="0" width="100" height="50" fill="red"></rect>
      </svg>
    
       <script src="./libs/gsap.min.js"></script>
       <script>
        window.onload =function() {
          // selector( document.querySelectorAll() ) | domEL
          gsap.to('#rectangle', {
            x: 200,
            duration: 2 // 秒
          })
        }
       </script>
    </body>
    </html>
    

2.3 补间动画(Tween)

  • GSAP的Tween动画有4种类型:

    • gsap.from(targets | selector, vars) - 元素从from定义的状态过渡到元素当前的状态。

      • targets | selector : 需动画的元素对象,支持字符串的选择器

      • vars: 需过度动画的属性和GSAP扩展的duration、ease、transformOrigin、repeat、delay、yoyo、stagger、onComplete 等

      • 官网gsap.from文档

      • ease速率曲线

    • gsap.to(targets | selector, vars) - 元素从当前的状态过渡到to状态。

    • gsap.fromTo(targets | selector, fromVars, toVars) -元素从from定义状态过渡到to定义的状态

    • gsap.set(targets | selector, vars) - 立即设置属性(无过度效果)。

      • 本质上是一个 duration = 0 的 to 补间动画。
  • 哪些属性可以设置动画?

    • GSAP几乎可以为任何属性制作动画

      • 包括 CSS 属性、元素属性、自定义对象属性。
      • 甚至 CSS 变量和复杂的字符串。
      • 最常见的动画属性、变换和不透明度等。
    • GSAP还专门给CSS形变(transform)相关属性提供了简写,如下图所示:

      image.png
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
      <style>
        body, ul {
          margin: 0;
          padding: 0;
          background-image: url(../images/grid.png);
        }
        svg {
          background-color: rgba(255, 0, 0, 0.1);
        }
      </style>
    
    </head>
    <body>
    
      <svg width="300" height="300" xmlns="http://www.w3.org/2000/svg" >
        <rect id="rectangle" onclick="scaleRectangle()" x="100" y="100" width="100" height="100" fill="red"></rect>
      </svg>
    
       <script src="./libs/gsap.min.js"></script>
       <script>
        function scaleRectangle() {
          // 支持数组
          // gsap.to(["#rectangle"], {
          //   scale: 0.5, // 1 -> 0.5
          //   duration: 1
          // })
    
          // gsap.from(["#rectangle"], {
          //   scale: 0.3, // 0.3 -> 1
          //   duration: 1
          // })
    
          // gsap.fromTo(["#rectangle"], {
          //   scale: 0, // 0%
          //   // duration: 2  // 默认是0.5,此处可省略
          // }, {
          //   scale: 1, // 100%
          //   duration: 2,
          //   repeat: -1 // 重复次数,默认不重复,-1为无限循环
          // })
    
          // gsap.to(["#rectangle"], {
          //   scale: 0.5, // 1 -> 0.5
          //   duration: 1,
          //   // 修改动画的坐标原点
          //   // transformOrigin: 'center'
          //   // transformOrigin: 'left'
          //   // transformOrigin: 'top'
          //   // transformOrigin: 'right'
          //   // transformOrigin: 'bottom'
          // })
    
          gsap.to(["#rectangle"], {
            scale: 0.5, // 1 -> 0.5
            duration: 1,
            transformOrigin: 'center',
            ease: 'bounce.out' // 默认值 power1.out
          })
        }
       </script>
    </body>
    </html>
    
    gsap补间动画.gif

2.4 动画时间线(TimeLine)

  • 什么是动画时间线(TimeLine):

    • 时间线(TimeLine)是用来创建易于调整、有弹性的动画序列

    • 当我们将补间添加到时间线(Timeline)时,默认情况下,它们会按照添加到时间轴的顺序一个接一个地播放

  • TimeLine的使用步骤:

    • 第一步:通过gsap.timeline( vars ) 拿到时间线对象

    • 第二步:调用时间线上的 Tween 动画方法,比如:form、to 等。

  • 案例

    • delay

      <!DOCTYPE html>
      <html lang="en">
      <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style>
          body, ul {
            margin: 0;
            padding: 0;
            background-image: url(../images/grid.png);
          }
          svg {
            background-color: rgba(255, 0, 0, 0.1);
          }
        </style>
      
      </head>
      <body>
      
        <svg width="300" height="300" xmlns="http://www.w3.org/2000/svg" >
          <rect id="rectangle1" onclick="scaleRectangle()" x="0" y="0" width="50" height="50" fill="red"></rect>
          <rect id="rectangle2" x="100" y="0" width="50" height="50" fill="red"></rect>
          <rect id="rectangle3" x="200" y="0" width="50" height="50" fill="red"></rect>
        </svg>
      
         <script src="./libs/gsap.min.js"></script>
         <script>
          function scaleRectangle() {
            gsap.to('#rectangle1', {
              scale: 0.5,
              duration: 1
            })
            gsap.to('#rectangle2', {
              scale: 0.5,
              duration: 1,
              delay: 1
            })
            gsap.to('#rectangle3', {
              scale: 0.5,
              duration: 1,
              delay: 2
            })
          }
         </script>
      </body>
      </html>
      
      delay.gif
    • timeline(推荐)

      <!DOCTYPE html>
      <html lang="en">
      <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style>
          body, ul {
            margin: 0;
            padding: 0;
            background-image: url(../images/grid.png);
          }
          svg {
            background-color: rgba(255, 0, 0, 0.1);
          }
        </style>
      
      </head>
      <body>
      
        <svg width="300" height="300" xmlns="http://www.w3.org/2000/svg" >
          <rect id="rectangle1" onclick="scaleRectangle()" x="0" y="0" width="50" height="50" fill="red"></rect>
          <rect id="rectangle2" x="100" y="0" width="50" height="50" fill="red"></rect>
          <rect id="rectangle3" x="200" y="0" width="50" height="50" fill="red"></rect>
        </svg>
      
         <script src="./libs/gsap.min.js"></script>
         <script>
          function scaleRectangle() {
            const timeline = gsap.timeline()
      
            // 支持链式调用
            timeline.to(['#rectangle1', '#rectangle2'], {
              scale: 0.5,
              duration: 1
            })
      
            // .to('#rectangle2', {
            //   scale: 0.5,
            //   duration: 1
            // })
      
            .to('#rectangle3', {
              scale: 0.5,
              duration: 1
            })
          }
         </script>
      </body>
      </html>
      
      timeline.gif

2.5 滑板车案例

  • 使用timeline实现

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
      </head>
      <body>
        <!-- 滑板车 -->
        <svg
          id="scooter"
          height="512"
          width="512"
          viewBox="0 0 512.004 512.004"
          xmlns="http://www.w3.org/2000/svg"
        >
          <path
            id="footer-block"
            d="m175.669 463.803c-8.283 0-15-6.716-15-15 0-53.743-43.723-97.467-97.467-97.467-14.622 0-28.673 3.153-41.762 9.371-7.483 3.555-16.432.371-19.986-7.112-3.555-7.482-.37-16.431 7.113-19.985 17.143-8.143 35.525-12.273 54.635-12.273 70.286 0 127.467 57.182 127.467 127.467 0 8.283-6.714 14.999-15 14.999z"
            fill="#c5e1e6"
          />
          <path
            id="footboard2"
            d="m442.768 321.476c-63.027 2.945-113.414 51.086-120.563 112.327h-210.801c-8.285 0-15 6.716-15 15s6.715 15 15 15h224.932c8.285 0 15-6.716 15-15 0-52.162 40.777-94.928 92.832-97.36 8.275-.387 14.67-7.408 14.283-15.684-.387-8.275-7.402-14.684-15.683-14.283z"
            fill="#008adf"
          />
          <path
            id="footboard1"
            d="m442.768 321.476c-63.027 2.945-113.414 51.086-120.563 112.327h-66.204v30h80.335c8.285 0 15-6.716 15-15 0-52.162 40.777-94.928 92.832-97.36 8.275-.387 14.67-7.408 14.283-15.684-.387-8.275-7.402-14.684-15.683-14.283z"
            fill="#0065a3"
          />
          <path
            id="scooter-head"
            d="m448.787 415.604c-7.721 0-14.279-5.923-14.932-13.755l-28.796-345.572c-1.291-15.484-11.852-26.275-20.521-26.275-8.283 0-15-6.716-15-15s6.717-15 15-15c12.9 0 25.295 5.971 34.9 16.811 8.852 9.99 14.361 23.12 15.518 36.972l28.797 345.573c.688 8.256-5.447 15.506-13.703 16.194-.425.035-.847.052-1.263.052z"
            fill="#8db9c4"
          />
          <circle id="wheel4" cx="63.203" cy="448.803" fill="#c5e1e6" r="48.2" />
          <path
            id="wheel3"
            d="m63.203 512.002c-34.848 0-63.199-28.351-63.199-63.199 0-34.849 28.352-63.199 63.199-63.199 34.85 0 63.201 28.35 63.201 63.199 0 34.848-28.352 63.199-63.201 63.199zm0-96.398c-18.306 0-33.199 14.893-33.199 33.199 0 18.307 14.894 33.199 33.199 33.199 18.307 0 33.201-14.893 33.201-33.199s-14.895-33.199-33.201-33.199z"
            fill="#1d4659"
          />
          <circle id="wheel2" cx="448.803" cy="448.803" fill="#8db9c4" r="48.2" />
          <g fill="#0e232c">
            <path
              id="wheel1"
              d="m448.803 512.002c-34.848 0-63.199-28.351-63.199-63.199 0-34.849 28.352-63.199 63.199-63.199 34.85 0 63.201 28.35 63.201 63.199 0 34.848-28.352 63.199-63.201 63.199zm0-96.398c-18.307 0-33.199 14.893-33.199 33.199 0 18.307 14.893 33.199 33.199 33.199 18.307 0 33.201-14.893 33.201-33.199s-14.895-33.199-33.201-33.199z"
            />
            <path
              id="head-block"
              d="m352.402.002c-8.283 0-15 6.716-15 15s6.717 15 15 15h32.135v-30h-32.135z"
            />
          </g>
        </svg>
        <script src="./libs/gsap.min.js"></script>
        <script>
         window.onload = function() {
          const tl = gsap.timeline({
            repeat: 1, //重复一次
            // yoyo: true // 反向执行动画
          })
    
          // 车轮
          tl.from(
            [
              '#wheel1', // begin= 0s
              '#wheel2', // 0.2
              '#wheel3', // 0.4
              '#wheel4' // 0.6
            ], 
            {
              scaleX: 0,
              scaleY: 0,
              duration: 1,
              transformOrigin: 'center',
              ease: 'bounce.out',
              stagger: 0.2 // 间隔时间
          })
    
          // 底座
          .from(
            [
              "#footboard1",
              "#footboard2"
            ]
            , {
              scaleX: 0,
              duration: 1,
              transformOrigin: 'left',
              ease: 'bounce.out',
            })
    
          // 立柱
          .from(
            [
              "#scooter-head"
            ]
            , {
              scaleY: 0,
              duration: 1,
              transformOrigin: 'bottom',
              ease: 'bounce.out',
            })
    
          // 手把和尾部
          .from(
            [
              "#head-block",
              "#footer-block"
            ]
            , {
              scaleX: 0,
              duration: 1,
              transformOrigin: 'right',
              ease: 'bounce.out',
            })
         }
        </script>
      </body>
    </html>
    
  • 效果

    滑板车.gif

三、动画案例

  • 补充Svg上的两个方法
    • getTotalLength

      • SVG路径对象.getTotalLength(),该方法返回用户代理对路径总长度(以用户单位为单位)的计算值
    • getPointAtLength

      • SVG路径对象.getPointAtLength(len),该方法返回路径上指定距离的点的坐标 len 0~SVGPathElement.getTotalLength() 的浮点数, 超出范围会换算成最大值或最小值

3.1 运行轨迹

  • CSS3 实现

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
        <style>
          .three-box {
            width: 630px;
            height: 330px;
            background: url(https://mapopen-website-wiki.cdn.bcebos.com/index/newIndex/track.jpg);
            background-size: 100% 100%;
          }
    
          #loc {
            animation: move 1.2s linear infinite alternate;
          }
    
          @keyframes move {
            0% {
              y: 30;
            }
    
            100% {
              y: 50;
            }
          }
    
          #linePath1 {
            stroke-width: 3;
            stroke-dasharray: 416;
            animation: linePath1 7s linear infinite;
          }
          @keyframes linePath1 {
            0% {
              stroke-dashoffset: 416;
            }
            100% {
              stroke-dashoffset: 0;
            }
          }
          #linePath2 {
            stroke-width: 3;
            stroke-dasharray: 458;
            animation: linePath2 7s linear infinite;
          }
          @keyframes linePath2 {
            0% {
              stroke-dashoffset: -458;
            }
            100% {
              stroke-dashoffset: 0;
            }
          }
        </style>
      </head>
      <body>
        <div class="box-left three-box">
          <svg
            id="svg"
            height="400"
            version="1.1"
            width="744"
            xmlns="http://www.w3.org/2000/svg"
          >
            <desc>Created with Snap</desc>
            <defs>
              <linearGradient
                x1="100%"
                y1="40.7087699%"
                x2="4.9797314%"
                y2="60.8683027%"
                id="botLine"
              >
                <stop stop-color="#F5533D" stop-opacity="0" offset="0%"></stop>
                <stop stop-color="#F5533D" offset="44.5180532%"></stop>
                <stop stop-color="#F5533D" stop-opacity="0" offset="100%"></stop>
              </linearGradient>
              <linearGradient
                y2="58.3724103%"
                x2="96.9326332%"
                y1="42.713995%"
                x1="0%"
                id="topLine"
              >
                <stop
                  offset="0%"
                  stop-opacity="0.09801"
                  stop-color="#F5533D"
                ></stop>
                <stop offset="50.3914618%" stop-color="#F5533D"></stop>
                <stop offset="100%" stop-opacity="0" stop-color="#F5533D"></stop>
              </linearGradient>
            </defs>
            <image
              id="loc"
              xlink:href="https://mapopen-website-wiki.cdn.bcebos.com/shouye/redPoint.png"
              preserveAspectRatio="none"
              x="345"
              y="41.230000000000004"
              width="55"
              height="74"
            ></image>
            <image
              xlink:href="https://mapopen-website-wiki.cdn.bcebos.com/index/newIndex/pillar.png"
              preserveAspectRatio="none"
              x="478"
              y="118"
              width="3"
              height="79"
            ></image>
            <g transform="matrix(1,0,0,1,170,140)">
              <path
                id="linePath1"
                d="m-11.20703,177c44.13802,-17.33333 100.54036,-41 169.20703,-71c68.66667,-30 138.1224,-64.91471 208.36719,-104.74414"
                fill="rgba(0,0,0,0)"
                transform="matrix(1,0,0,1,-32,-5)"
                stroke="url(#botLine)"
              ></path>
            </g>
            <image
              xlink:href="https://mapopen-website-wiki.cdn.bcebos.com/index/newIndex/path-qiao.png"
              preserveAspectRatio="none"
              x="383"
              y="151"
              width="75"
              height="48"
            ></image>
            <g transform="matrix(1,0,0,1,225,105)">
              <path
                id="linePath2"
                d="m2,2c73.33333,21.17188 140.37374,42.06462 201.12121,62.67823c60.74748,20.61362 136.04041,54.05421 225.87879,100.32177"
                fill="rgba(0,0,0,0)"
                transform="matrix(1,0,0,1,-32,-5)"
                stroke="url(#topLine)"
              ></path>
            </g>
            <image
              xlink:href="https://mapopen-website-wiki.cdn.bcebos.com/index/newIndex/path-lou.png"
              preserveAspectRatio="none"
              x="111"
              y="12"
              width="198"
              height="233"
            ></image>
            <image
              xlink:href="https://mapopen-website-wiki.cdn.bcebos.com/index/newIndex/pillar.png"
              preserveAspectRatio="none"
              x="247"
              y="182"
              width="3"
              height="79"
            ></image>
            <image
              xlink:href="https://mapopen-website-wiki.cdn.bcebos.com/index/newIndex/pillar.png"
              preserveAspectRatio="none"
              x="330"
              y="65"
              width="3"
              height="79"
            ></image>
          </svg>
        </div>
      </body>
    </html>
    
    运行轨迹.gif

3.2 导航动画

  • 路径动画+帧动画
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
        <style>
          body {
            /* border: 1px solid red; */
            padding-top: 100px;
          }
          .five-box {
            width: 600px;
            height: 314px;
            background: url(https://mapopen-website-wiki.cdn.bcebos.com/index/newIndex/service-left-loc.png);
            background-size: 100% 100%;
          }
    
          .line {
            transform: translate(50px, 90px);
          }
    
          .line path {
            stroke-width: 4;
    
            stroke-dasharray: 521;
            stroke-dashoffset: 0;
            animation: linePath 7s linear infinite;
          }
    
          @keyframes linePath {
            0% {
              stroke-dashoffset: 538;
            }
            100% {
              stroke-dashoffset: 0;
            }
          }
    
          #loc1 {
            animation: move1 1.2s linear infinite alternate;
          }
    
          #c1 {
            animation: moveC1 1.2s linear infinite alternate;
          }
    
          #c2 {
            animation: moveC2 1.2s linear infinite alternate;
          }
    
          @keyframes move1 {
            0% {
              y: 80;
            }
    
            100% {
              y: 100;
            }
          }
          @keyframes moveC1 {
            0% {
              y: 185;
            }
    
            100% {
              y: 230;
            }
          }
          @keyframes moveC2 {
            0% {
              y: 230;
            }
    
            100% {
              y: 185;
            }
          }
    
          #pics {
            /* 回到原点 */
            /* transform: translate(-100px, -100px); */
            /* 调整原点在图形中心位置 */
            /* transform: translate(-127.5px, -182px); */
            /* 路径平移: 50 + 90 */
            transform: translate(-77.5px, -170px);
          }
          svg {
            overflow: visible;
          }
        </style>
      </head>
      <body>
        <div class="box-left five-box">
          <svg
            height="400"
            version="1.1"
            width="744"
            xmlns="http://www.w3.org/2000/svg"
          >
            <desc>Created with Snap</desc>
            <defs>
              <linearGradient
                x1="100%"
                y1="40.7087699%"
                x2="4.9797314%"
                y2="60.8683027%"
                id="linearGradient-5"
              >
                <stop stop-color="#F5533D" stop-opacity="0" offset="0%"></stop>
                <stop stop-color="#F5533D" offset="44.5180532%"></stop>
                <stop stop-color="#F5533D" stop-opacity="0" offset="100%"></stop>
              </linearGradient>
            </defs>
            <image
              xlink:href="https://mapopen-website-wiki.cdn.bcebos.com/index/newIndex/projection.png"
              preserveAspectRatio="none"
              x="60"
              y="45"
              width="466"
              height="234"
            ></image>
            <g id="pics">
              <image
                id="loc1"
                xlink:href="https://mapopen-website-wiki.cdn.bcebos.com/shouye/redPoint.png"
                preserveAspectRatio="none"
                x="100"
                y="98.82"
                width="55"
                height="74"
                style="opacity: 1"
              ></image>
    
              <image
                xlink:href="https://mapopen-website-wiki.cdn.bcebos.com/index/newIndex/navLight.png"
                preserveAspectRatio="none"
                x="113"
                y="155"
                width="30"
                height="107"
                style="opacity: 1"
              ></image>
              <image
                id="c1"
                xlink:href="https://mapopen-website-wiki.cdn.bcebos.com/index/newIndex/bigCircle.png"
                preserveAspectRatio="none"
                x="112"
                y="195.73"
                width="32"
                height="11"
                style="opacity: 1"
              ></image>
              <image
                id="c2"
                xlink:href="https://mapopen-website-wiki.cdn.bcebos.com/index/newIndex/smCircle.png"
                preserveAspectRatio="none"
                x="117"
                y="214.27"
                width="21"
                height="8"
                style="opacity: 1"
              ></image>
              <image
                xlink:href="https://mapopen-website-wiki.cdn.bcebos.com/index/newIndex/nav-tuo.png"
                preserveAspectRatio="none"
                x="115"
                y="252"
                width="26"
                height="11"
                style="opacity: 1"
              ></image>
            </g>
            <g class="line">
              <path
                id="line-path"
                d="M0,194.179092 C141.464844,148.340947 237.798177,115.607166 289,95.9777477 C365.802734,66.5336204 453.195733,26 482.349179,1"
                fill="rgba(0,0,0,0)"
                stroke="url(#linearGradient-5)"
              ></path>
            </g>
            <animateMotion href="#pics" dur="7s" repeatCount="indefinite">
              <mpath href="#line-path" />
            </animateMotion>
          </svg>
        </div>
      </body>
    </html>
    
    导航.gif