同学们可以私信我加入学习群!
正文开始
前言
我开发的桌面端软件最近增加了在线更新功能,其中更新动画部分是由gsap实现的,整体实现思路已经在electron系列文章中简单介绍过,因为关注我的桌面软件------中二少年工具箱开发的同学,不一定会关注gsap动画插件,所以这里单独拿出来,详细介绍如何使用gsap实现路径动画。
一、引入并使用gsap
下载:
c
npm i gsap
引入页面:
c
import {gsap} from "gsap/all";
制作路径动画,还需要MotionPathPlugin插件,此 插件是内置免费插件,可直接使用:
c
import {MotionPathPlugin} from "gsap/MotionPathPlugin";
gsap.registerPlugin(MotionPathPlugin)
调用gsap.to()方法,为页面元素创建动画:
c
function createAnimation(movementRange = 3) {
// 使用GSAP创建动画
particlesList.value.forEach((particle, index) => {
// 使用GSAP创建动画
gsap.to(particleRefs.value[index], {
motionPath: {
path: '#svg',
align: '#svg',
alignOrigin: [Math.random() * 10 - 5, Math.random() * 10 - 5]
},
repeat: -1, // 无限重复
duration: 3 * Math.random() + 2, // 随机持续时间
ease: 'linear', // 线性运动
delay: Math.random() * 2 // 随机延迟
})
})
}
因为我的项目基于vue3,所以gsap.to的第一个参数,使用的是利用ref创建的对象,而不是类名或者id。
particlesRefs创建的方法是:
c
const particleRefs = ref({})
function setItemRef(index, el) {
if (el) {
// 如果元素存在,则将其存储在对象中
particleRefs.value[index] = el
} else {
// 如果元素不存在(可能是被销毁了),则从对象中删除
delete particleRefs.value[index]
}
}
setItemRef方法则挂在在页面元素上:
c
<div v-for="(particleItem,index) in particlesList"
:key="index"
:ref="el => setItemRef(index, el)"
:style="{left: particleItem.left+'px',top:particleItem.top+'px',backgroundColor:particleItem.color}"
class="particle">
</div>
这样就可以循环生成每个div的动态ref
二、详解gsap.to的各参数
- motionPath
动画路径参数,这是MotionPathPlugin插件提供的能力。 - motionPath.path
动画的路径设置,有两种设置方式:(1)手写路径数组:[{x:100, y:50}, {x:200, y:0}, {x:300, y:100}](2)为svg中的path标签设置id,在此处关联id,本文采用第二种方式。 - motionPath.align
align设置成 '#svg',将动画目标的运动路径与SVG元素的路径对齐。 - motionPath.alignOrgin
元素与路径的重合程度,或者说是元素与路径的偏离程度。alignOrgin设置为[0.5,0.5]表示动画元素在路径中央。本文设置成-5至5之间的随机数,是为了制造粒子发散的效果。 - repeat
重复次数,设置为-1,指无限重复 - duration
动画持续时间,这里设置成随机数,是为了让动画元素的运动速度有差别 - ease
运动的方式,设置成linear指的是线性运动,这个可以查看gsap官网,有对各种运动方式的直观示例。 - delay
动画延迟时间,这里设置成随机数,不同的页面元素开始运动的事件就会有差别。
三、路径svg
svg标签中定义了path,只要在path的id和motionPath中定义的id一致,动画就会沿着path定义的路径运动。
c
<svg style="position: absolute" height="95%" viewBox="-160 -160 320 320" width="95%"
xmlns="http://www.w3.org/2000/svg">
<path id="svg"
d="M 0 160
A 160 160 0 0 1 0 -160
A 160 160 0 0 1 0 160 Z"
fill="transparent" stroke="none"/>
</svg>
上面是一个以原点为起始点的路径。
如果path设置成
c
<path id="svg" d="M 0 0
m -160, 0
a 160,160 0 1,0 320,0
a 160,160 0 1,0 -320,0"
fill="transparent" stroke="black" stroke-width="2"/>
最终的路径仍然是个圆,但是因为起始点不为原点,最终动画沿着运动的圆会偏离我们想要的轨道。
最终效果如下:
四、其他路径
圆形路径实现后,如果要实现其他路径也只需要更换svg即可。其他代码我们都不改变,只是修改svg代码:
c
<svg style="position: absolute" height="95%" viewBox="0 0 100 50" width="95%"
xmlns="http://www.w3.org/2000/svg">
<path id="svg" d="
M 0,25
C 10,30 20,18 30,25
C 40,32 50,15 60,25
C 70,35 80,18 90,25
L 100,25
" stroke="black" fill="none" stroke-width="2"/>
</svg>
将原来的圆形路径svg改成上面的正弦函数路径。渲染动画效果如下:
可以看到粒子沿着新的路径运动了。之所以显示上面的黑色路径,是因为我在svg中设置了stroke-width="2"。
由此延伸,我们还可以把粒子改成文字,把上面代码做一些简单修改:
c
<div id="test">
中二少年工具箱
</div>
gsap.to('#test', {
motionPath: {
path: '#svg',
align: '#svg',
alignOrigin: [0.5,0.5]
},
repeat: -1, // 无限重复
duration: 3 * Math.random() + 2, // 随机持续时间
ease: 'linear', // 线性运动
delay: Math.random() * 2 // 随机延迟
})
最终效果:
文字路径动画
上面的多个文字一起运动,看起来还是有些生硬,大家经常看到在某些炫酷网站,会有一些文字沿着曲线运动的动画,使用gsap如何快速实现这种效果呢?
核心代码如下:
c
const charList=ref(['中','二','少','年','工','具','箱'])
function createAnimation(movementRange = 3) {
const pathLength = document.querySelector('#svg').getTotalLength();
const spacing = pathLength / 7;
// 使用GSAP创建动画
charList.value.forEach((particle, index) => {
const initialOffset = spacing * index;
// 使用GSAP创建动画
console.log(particleRefs.value[index])
gsap.set(particleRefs.value[index], {
motionPath: {
path: '#svg',
align: '#svg',
autoRotate: true,
alignOrigin: [initialOffset / pathLength, 0.5]
}
});
// gsap.set(particleRefs.value[index],{x:50-index*7,y:100})
gsap.to(particleRefs.value[index], {
motionPath: {
path: '#svg',
align: '#svg',
alignOrigin: [initialOffset / pathLength, 0.5]
},
repeat: -1, // 无限重复
duration: 3, // 随机持续时间
ease: 'linear', // 线性运动
delay: index * 0.1 // 依次增加延迟时间
})
})
}
上面多加了一个方法gsap.set,这是在设置各元素的初始状态,让所有的汉字在开始动画时,便沿着曲线分布。
在gsap.to中,aliginOrigin也设置成有间隔地沿着曲线分布,并且每个文字延迟的时间不同,造成文字前后运动的视觉效果。
最终效果如下,当然初步实现的demo还很粗糙,主要讲解其原理:
总结
学会路径动画,可以实现很多酷炫效果,我曾经在gsap的资源网站,见到有人用它实现了一个移动的城堡,相当震撼。
大家如果需要联系博主,或者获取博主各系列文章对应的资源,可以通过中二少年学编程的个人主页来获取。
有任何前端项目、demo、教程需求,都可以联系博主,博主会视精力更新,免费的羊毛,不薅白不薅!~