使用gsap给svg图标增加线条动画

vue yekong

开发了很多数据大屏了,今天突发奇想有没有办法给这些项目中的图标增加一些动画效果呢?让这些图标活起来,接下来我们来实现效果。

使用gsap给图标增加线条动画

动态效果

动画实现原理

动画实现的主要原理:

  1. SVG路径属性:

    • stroke-dasharray:定义路径的虚线模式。
    • strokeDashoffset:定义虚线模式的偏移量。
  2. 初始化设置:

    • 获取每个路径的总长度:path.getTotalLength()
    • 设置初始状态:
      gsap.set(path, {
        strokeDasharray: length,
        strokeDashoffset: length
      });
      

    这使得路径初始时完全不可见,因为虚线长度等于偏移量。

  3. 动画实现:

    • 使用GSAP创建时间线动画。
    • 对每个路径应用动画,将strokeDashoffset从初始值(路径长度)变为0:
      tl.to(path, {
        strokeDashoffset: 0,
        duration: 2,
        ease: "power2.inOut"
      }, index * 0.5);
      

    这个过程中,路径会逐渐显示出来,创造出描边的动画效果。

  4. 错开动画:
    使用index * 0.5来错开每个路径动画的开始时间,实现依次绘制的效果。

这个动画利用了SVG的stroke-dasharraystrokeDashoffset属性,结合GSAP的动画能力,实现了路径的逐步描绘效果。

实现代码

<template>
  <div>
    <svg
        class="icon"
        viewBox="0 0 1024 1024"
        version="1.1"
        xmlns="http://www.w3.org/2000/svg"
        width="200"
        height="200"
    >
      <path
          ref="path1"
          d="M392.533 549.726c43.986 0 79.644 33.781 79.644 75.453v188.632c0 41.671-35.658 75.453-79.644 75.453H193.422c-43.986 0-79.644-33.781-79.644-75.453V625.179c0-41.671 35.658-75.453 79.644-75.453z"
          fill="none"
          stroke="#808080"
          stroke-width="40"
      />
      <path
          ref="path2"
          d="M830.578 549.726c43.986 0 79.644 33.781 79.644 75.453v188.632c0 41.671-35.658 75.453-79.644 75.453H631.467c-43.986 0-79.644-33.781-79.644-75.453V625.179c0-41.671 35.658-75.453 79.644-75.453z"
          fill="none"
          stroke="#808080"
          stroke-width="40"
      />
      <path
          ref="path3"
          d="M392.533 134.736c43.986 0 79.644 33.781 79.644 75.453v188.632c0 41.671-35.658 75.453-79.644 75.453H193.422c-43.986 0-79.644-33.781-79.644-75.453V210.189c0-41.671 35.658-75.453 79.644-75.453z"
          fill="none"
          stroke="#808080"
          stroke-width="40"
      />
      <path
          ref="path4"
          d="M731.022 134.736c98.97 0 179.2 76.008 179.2 169.768s-80.23 169.768-179.2 169.768c-98.97 0-179.2-76.008-179.2-169.768s80.23-169.768 179.2-169.768z"
          fill="none"
          stroke="#808080"
          stroke-width="40"
      />
    </svg>
  </div>
</template>

<script>
import { gsap } from 'gsap';

export default {
  mounted() {
    this.$nextTick(() => {
      const paths = [
        this.$refs.path1,
        this.$refs.path2,
        this.$refs.path3,
        this.$refs.path4
      ];

      paths.forEach(path => {
        const length = path.getTotalLength();
        gsap.set(path, {
          strokeDasharray: length,
          strokeDashoffset: length
        });
      });

      const tl = gsap.timeline();

      paths.forEach((path, index) => {
        tl.to(path, {
          strokeDashoffset: 0,
          duration: 2,
          ease: "power2.inOut"
        }, index * 0.5);
      });
    });
  },
};
</script>

<style scoped>
.icon {
  width: 200px;
  height: 200px;
}
</style>

喜欢