开发了很多数据大屏了,今天突发奇想有没有办法给这些项目中的图标增加一些动画效果呢?让这些图标活起来,接下来我们来实现效果。
动态效果
动画实现原理
动画实现的主要原理:
-
SVG路径属性:
stroke-dasharray
:定义路径的虚线模式。strokeDashoffset
:定义虚线模式的偏移量。
-
初始化设置:
- 获取每个路径的总长度:
path.getTotalLength()
- 设置初始状态:
gsap.set(path, { strokeDasharray: length, strokeDashoffset: length });
这使得路径初始时完全不可见,因为虚线长度等于偏移量。
- 获取每个路径的总长度:
-
动画实现:
- 使用GSAP创建时间线动画。
- 对每个路径应用动画,将
strokeDashoffset
从初始值(路径长度)变为0:tl.to(path, { strokeDashoffset: 0, duration: 2, ease: "power2.inOut" }, index * 0.5);
这个过程中,路径会逐渐显示出来,创造出描边的动画效果。
-
错开动画:
使用index * 0.5
来错开每个路径动画的开始时间,实现依次绘制的效果。
这个动画利用了SVG的stroke-dasharray
和strokeDashoffset
属性,结合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>