跳至主要內容

基于 Anime.js 的 SVG 动画

Mr.LRHSVGSVG大约 4 分钟

基于 Anime.js 的 SVG 动画

动画库: animejsopen in new window

描边动画

<div class="line-draw">
  <svg x="0px" y="0px" viewBox="0 0 300 200" class="line-draw-svg">
    <path
      class="letter-i"
      d="M82.4,127.1V75.6h6.8v51.5H82.4z"
      stroke="none"
      fill="none"
    />
    <path
      class="letter-s"
      d="M98.9,110.6l6.4-0.6c0.3,2.6,1,4.7,2.1,6.3s2.8,3,5.2,4s5,1.5,7.9,1.5c2.6,0,4.9-0.4,6.9-1.2
    s3.5-1.8,4.4-3.2s1.5-2.8,1.5-4.4c0-1.6-0.5-3-1.4-4.2s-2.5-2.2-4.6-3c-1.4-0.5-4.4-1.4-9.2-2.5s-8.1-2.2-9.9-3.2
    c-2.5-1.3-4.3-2.9-5.5-4.8c-1.2-1.9-1.8-4-1.8-6.4c0-2.6,0.7-5,2.2-7.3c1.5-2.3,3.6-4,6.5-5.2c2.8-1.2,6-1.8,9.5-1.8
    c3.8,0,7.2,0.6,10.1,1.8s5.2,3,6.7,5.4s2.4,5.1,2.5,8.1l-6.5,0.5c-0.4-3.3-1.5-5.7-3.6-7.4c-2-1.7-5-2.5-9-2.5
    c-4.1,0-7.1,0.8-9,2.3s-2.8,3.3-2.8,5.5c0,1.9,0.7,3.4,2,4.6c1.3,1.2,4.7,2.4,10.3,3.7c5.5,1.3,9.3,2.4,11.4,3.3
    c3,1.4,5.2,3.1,6.6,5.3s2.1,4.6,2.1,7.3c0,2.7-0.8,5.3-2.4,7.8s-3.8,4.3-6.8,5.7s-6.3,2-9.9,2c-4.7,0-8.6-0.7-11.7-2
    c-3.2-1.4-5.6-3.4-7.4-6.1C99.9,117.1,99,114,98.9,110.6z"
      stroke="none"
      fill="none"
    />
    <path
      class="letter-u"
      d="M183.1,75.6h6.8v29.8c0,5.2-0.6,9.3-1.8,12.3s-3.3,5.5-6.3,7.4s-7.1,2.9-12,2.9c-4.8,0-8.8-0.8-11.8-2.5
    s-5.3-4.1-6.6-7.2s-2-7.5-2-12.9V75.6h6.8v29.7c0,4.5,0.4,7.8,1.2,9.9s2.3,3.8,4.3,4.9s4.5,1.7,7.4,1.7c5,0,8.6-1.1,10.7-3.4
    s3.2-6.6,3.2-13.1V75.6z"
      stroke="none"
      fill="none"
    />
    <path
      class="letter-x"
      d="M196,127.1l19.9-26.9l-17.6-24.7h8.1l9.4,13.2c1.9,2.7,3.3,4.9,4.1,6.3c1.1-1.9,2.5-3.8,4.1-5.9l10.4-13.7
    h7.4l-18.1,24.3l19.5,27.2h-8.4l-13-18.4c-0.7-1.1-1.5-2.2-2.2-3.4c-1.1,1.9-2,3.2-2.5,3.9l-12.9,18H196z"
      stroke="none"
      fill="none"
    />
  </svg>
  <button class="play-line-draw-btn">PLAY ISUX</button>
</div>
.line-draw {
  position: relative;
  margin: auto;
  width: 300px;
  height: 300px;
  text-align: center;
  background-color: #000;
}

.line-draw-svg {
  width: 300px;
  height: 200px;
}

.play-line-draw-btn {
  margin: 5% auto;
  padding: 5px 10px;
  font-weight: bold;
  color: white;
  border-radius: 4px;
  background: #007fff;
}
window.onload = function () {
  var script = document.createElement('script')
  script.setAttribute('type', 'text/javascript')
  script.setAttribute(
    'src',
    'https://cdn.jsdelivr.net/npm/animejs@3.2.1/lib/anime.min.js'
  )
  var heads = document.getElementsByTagName('head')
  if (heads.length) {
    heads[0].appendChild(script)
  } else {
    document.documentElement.appendChild(script)
  }
  script.onload = function () {
    initLineDrawing()
  }
}

function initLineDrawing() {
  var letterTime = 2000

  var lineDrawing = anime({
    targets: 'path', // 动画目标对象
    // 画线动画:anime.js 使用 anime.setDashoffset() 方法获取到 SVG 路径的长度并将此长度设置为 SVG 的 'stroke-dasharray' 值,并返回该长度,再使用 strokeDashoffset 将  SVG的 'stroke-dashoffset' 属性值在 from to 格式中产生动画从而创建路径绘制效果。
    // [anime.setDashoffset, 0] - 从起点开始画完
    strokeDashoffset: [anime.setDashoffset, 0],
    // 时间曲线:定义动画的时间曲线。 easeInOutCubic - 由快至慢,效果更强
    easing: 'easeInOutCubic',
    // 持续时间: 定义动画的持续时间(以毫秒为单位)
    duration: letterTime,
    // 延迟: 定义动画的延迟(以毫秒为单位)
    delay: function (el, i) {
      return letterTime * i
    },
    // begin 事件:当动画开始播放时,begin()回调被触发一次。动画完成后,会触发一次 complete() 回调。
    begin: function (anim) {
      var letters = document.querySelectorAll('path'),
        i
      for (i = 0; i < letters.length; ++i) {
        letters[i].setAttribute('stroke', 'white')
        letters[i].setAttribute('fill', 'none')
      }
    },
    // update 事件:动画开始播放后,每帧都会触发此回调。
    // update: function(anim) {
    //   if (anim.currentTime >= letterTime) {
    //     document.querySelector(".letter-i").setAttribute("fill", "#fff");
    //   }
    //   if (anim.currentTime >= 2 * letterTime) {
    //     document.querySelector(".letter-s").setAttribute("fill", "#fff");
    //   }
    //   if (anim.currentTime >= 3 * letterTime) {
    //     document.querySelector(".letter-u").setAttribute("fill", "#fff");
    //   }
    //   if (anim.currentTime >= 4 * letterTime) {
    //     document.querySelector(".letter-x").setAttribute("fill", "#fff");
    //   }
    // },
    autoplay: false,
  })
  // anime - restart(重新开始): 从动画的初始值重新开始动画。
  document.querySelector('.play-line-draw-btn').onclick = lineDrawing.restart
}

路径动画

<div id="motionPath">
  <div class="motion-path-wrapper">
    <div class="motion-path-square"></div>
    <svg width="500" height="300" viewBox="0 0 500 300">
      <path
        id="curpath"
        fill="none"
        stroke="currentColor"
        stroke-width="1"
        d="M11.6,246.9c0,0,143.1-274.1,267.8-137.9s124.7,136.2,124.7,136.2L11.6,246.9z"
      />
    </svg>
  </div>
</div>
.motion-path-wrapper {
  position: relative;
  width: 500px;
  height: 300px;
}
.motion-path-square {
  position: absolute;
  width: 30px;
  height: 30px;
  background-color: #000;
}
window.onload = function () {
  var script = document.createElement('script')
  script.setAttribute('type', 'text/javascript')
  script.setAttribute(
    'src',
    'https://cdn.jsdelivr.net/npm/animejs@3.2.1/lib/anime.min.js'
  )
  var heads = document.getElementsByTagName('head')
  if (heads.length) {
    heads[0].appendChild(script)
  } else {
    document.documentElement.appendChild(script)
  }
  script.onload = function () {
    var path = anime.path('path')

    anime({
      targets: '.motion-path-square',
      translateX: path('x'),
      translateY: path('y'),
      rotate: path('angle'),
      duration: 3000,
      loop: true,
      easing: 'linear',
    })
  }
}

Morphing 动画

<svg
  class="social"
  xmlns="http://www.w3.org/2000/svg"
  width="100"
  height="100"
  viewBox="0 0 100 100"
>
  <path
    class="path"
    style="
      fill: #3b5998;
      fill-rule: evenodd;
      stroke: #3b5998;
      stroke-width: 1px;
      stroke-linecap: butt;
      stroke-linejoin: miter;
      stroke-opacity: 1;
    "
    d="m 41.416254,90 c -0.327378,-7.4702 0.20833,-32.7284 0,-39.901 -5.386902,-0.2083 -4.521603,0.3274 -9.848987,0 0.20833,-5.50595 0.36436,-7.66666 0.126269,-13.32142 4.646472,0.0181 3.439989,-0.009 9.848987,-0.1894 0.09586,-3.7736 0.133082,-3.0791 0.126269,-7.38674 0.18259,-3.73943 -0.486609,-10.54308 4.293149,-14.96288 4.779758,-4.4198 13.606811,-3.64808 22.223356,-3.53554 -0.04417,5.73754 -0.03936,9.37986 0,12.87945 -5.049924,0.46388 -7.309188,-0.33689 -10.85914,1.26269 -1.403378,3.17794 -1.569601,4.80531 -1.262691,11.93242 3.147964,-0.13336 8.201788,-0.1378 12.626907,0 -0.995158,6.00899 -0.948285,7.62376 -1.767767,13.06882 -3.676625,0.088 -5.605721,-0.1488 -11.111678,0 -0.148814,6.756 0.357147,33.0107 0,40.1536 -6.428576,0.1786 -8.174438,-0.03 -14.394674,0 z"
  />
</svg>
window.onload = function () {
  var script = document.createElement('script')
  script.setAttribute('type', 'text/javascript')
  script.setAttribute(
    'src',
    'https://cdn.jsdelivr.net/npm/animejs@3.2.1/lib/anime.min.js'
  )
  var heads = document.getElementsByTagName('head')
  if (heads.length) {
    heads[0].appendChild(script)
  } else {
    document.documentElement.appendChild(script)
  }
  script.onload = function () {
    var socialTimeline = anime.timeline({
      autoplay: true,
      direction: 'alternate',
      loop: true,
    })

    socialTimeline
      .add({
        targets: '.social',
        opacity: 1,
        duration: 500,
      })
      .add({
        targets: '.path',
        d: {
          value: [
            'm 41.416254,90 c -0.327378,-7.4702 0.20833,-32.7284 0,-39.901 -5.386902,-0.2083 -4.521603,0.3274 -9.848987,0 0.20833,-5.50595 0.36436,-7.66666 0.126269,-13.32142 4.646472,0.0181 3.439989,-0.009 9.848987,-0.1894 0.09586,-3.7736 0.133082,-3.0791 0.126269,-7.38674 0.18259,-3.73943 -0.486609,-10.54308 4.293149,-14.96288 4.779758,-4.4198 13.606811,-3.64808 22.223356,-3.53554 -0.04417,5.73754 -0.03936,9.37986 0,12.87945 -5.049924,0.46388 -7.309188,-0.33689 -10.85914,1.26269 -1.403378,3.17794 -1.569601,4.80531 -1.262691,11.93242 3.147964,-0.13336 8.201788,-0.1378 12.626907,0 -0.995158,6.00899 -0.948285,7.62376 -1.767767,13.06882 -3.676625,0.088 -5.605721,-0.1488 -11.111678,0 -0.148814,6.756 0.357147,33.0107 0,40.1536 -6.428576,0.1786 -8.174438,-0.03 -14.394674,0 z',
            'm 10.44335,90 c 11.073313,0.3952 19.483106,-1.8358 23.901837,-7.1603 -7.9736,-1.4292 -11.832311,-4.1933 -15.078321,-11.0837 3.459698,0.8219 5.795894,0.6358 7.606781,-0.607 -7.19593,-1.719 -12.734543,-6.7971 -13.741664,-15.836 2.766355,1.55307 5.466848,2.66623 7.828682,2.0203 -4.336544,-2.92911 -9.838998,-10.47636 -5.555839,-22.47589 8.400675,11.87052 23.824269,17.67568 33.840111,17.67767 -0.936406,-9.74688 5.88057,-19.46521 15.302849,-19.97853 8.13118,-0.50719 10.57457,4.01944 12.476346,4.82624 3.644547,0.13419 7.393301,-1.74401 10.354063,-3.53553 -1.380842,4.47157 -5.06769,5.62903 -6.313453,8.58629 5.42317,0.41513 5.891376,-1.53111 8.333758,-2.0203 -2.071414,3.75017 -5.393863,5.00034 -7.323606,8.08122 -1.633654,16.12573 -5.16049,27.57123 -14.647212,36.36553 -13.825764,11.3764 -34.755458,17.369 -56.984332,5.14 z',
          ],
          duration: 700,
          delay: 200,
          easing: 'easeInOutQuart',
        },
        fill: {
          value: ['#3b5998', '#4099ff'],
          duration: 700,
          delay: 200,
          easing: 'easeInOutQuart',
        },
        stroke: {
          value: ['#3b5998', '#4099ff'],
          duration: 700,
          delay: 200,
          easing: 'easeInOutQuart',
        },
      })
      .add({
        targets: '.social',
        opacity: 1,
        duration: 500,
      })
  }
}
上次编辑于:
贡献者: lrh21g