初识gsap动画库

在Vue文档的Transition章节发现了介绍的gsap动画库,可以实现高级动画效果,使用了一下发现体验很不错,于是记录一下。

<!--more-->

参考

  • gsap教学,官方文档介绍的非常详细了

1. 动画属性

动画思路基本是:给定初识状态和结束状态,然后由gsap绘制节点动画过程中每一帧的状态

1.1. 基础API

gsap.togsap.from是两个最基础的API

gsap.to设置某个dom节点的动画结束状态END,然后就会根据该节点的初始状态START和指定的结束状态END之间展示过渡动画

gsap.to(".box", { rotation: 360, x: 100, y: 50, duration: 1 });

第一个参数可以是选择器、数组,也可以直接是一个通过querySelector等接口获取到的DOM节点

gsap.from设置某个dom节点的动画初识状态START,并以该节点的初始状态作为动画结束状态END,然后展示START和END之间的过渡动画。

这种情况下,由于在第一帧会将节点的初始状态设置为指定的初始状态,如果节点已经被渲染,那么就会先闪烁到指定状态再执行动画,因此from一般用于节点首次渲染时的动画,同时还要指定opacity:0

gsap.from(".box", { rotation: 360, x: 100, y: 50, opacity:0, duration: 1 });

除了直接指定状态的绝对值之外,也可以通过x:"+=100"之类的字符串来计算相对值,非常灵活。

gsap.from(".box", { rotation: 360, x: "+=100", y: 50, opacity:0, duration: 1 });

此外还有fromToset两个不常用的API

  • fromTo,同时指定初识状态和结束状态
  • set,直接设置节点的状态,类似于to({duration:0, ...extra})

1.2. 动画属性

常用来展示动画的属性有:transformopacitycolor等,gsap支持绝大部分动画属性。

最常见的,比如下面这段CSS

transform: rotate(360deg) translateX(10px) translateY(50%);

对应的gsap动画属性配置项是

{ rotation: 360, x: 10, yPercent: 50 }

诸如background-color等属性也是支持的

{ backgroundColor: "#8d3dae" }

也可以设置svg相关的属性

gsap.to(".svg", { 
  duration: 2,
  attr: {
    fill: '#8d3dae',
    rx: 50, 
  },
});

1.3. 路径动画motionPath

除了基本的xy移动节点之外,可能还会有一些更特殊的动画路径(比如执行某个商品从列表沿某条贝塞尔曲线飞入右下角购物车的动画),如果想要节点按照指定路径执行动画,就需要使用motionPath配置项

// motionPath 需要先注册相关插件
gsap.registerPlugin(MotionPathPlugin)

// 配置motionPath
gsap.to(".green", {  motionPath: "M 100 350 l 150 -300", duration: 0.5, delay:0 })

其中motionPath即可以是svg路径参数,也可以是一个path对象

<path id="path" d="M 100 350 l 150 -300" stroke="red" stroke-width="3" fill="none"/>

还可以是贝塞尔曲线

{
    motionPath: {
        path: [{x:0, y:0}, {x:20, y:0}, {x:30, y:50},{x: 50, y: 50}],
        type: "cubic"
    }
}

我们要做的就是计算一段路径参数,然后传递给motionPath配置就行了。

2. timeline时间轴

上面的fromto接收的参数,都会被gsap同时计算每一个动画属性在对应帧的值,在复杂的动画场景中,还存在先执行A属性的动画、再执行B属性的动画的场景,节点最后的状态就是时间线所有点最后的叠加结果。

一种做法是通过delay延迟来实现,比如先水平移动100,再竖直移动50

gsap.to(".green", { x: 100, duration: 0.5, delay:0 })
gsap.to(".green", { y: 50, delay:0.5 })

这种写法虽然可以达到预期目标,但整体结构是很不稳定的,我们需要设置动画1的执行时间t1,然后要设置动画2的延迟时间值也为t1。

因此,更合适的做法是使用timeline时间线

const t = gsap.timeline();
t
    .to(".box", { x: 100, duration: 0.5 })
    .to(".box", { y: 50, });

这种链式调用非常直观,也很容易维护。

时间线除了编排单个节点的动画执行顺序,也可以控制不同节点的动画执行顺序,通过这个功能,可以实现非常复杂的组合动画!

const t = gsap.timeline();
t
    .to(".box", { x: 100, opacity: 0.5, duration: 1 })
    .to(".box", { y: 50, })
    .to(".box2", { y: 50, }); // 另外一个节点

此外,timeline还提供了playpausereverse等接口更灵活地控制动画播放

如果需要在动画的某些节点,获取状态数据并执行业务逻辑,可以使用相关的回调钩子,参考文档

3. ease缓动动画

gsap提供了一堆缓动函数,如linearbouncepower1等,这个文档提供了所有缓动函数的可视化预览界面。

对于每种缓动函数,gsap定义了三种缓动ease效果: inoutinOut,在配置动画参数的时候,就可以通过ease配置项传递指定对应缓动效果

  • in,开始慢、结束快,像自由落体的重物一样
  • out,开始快、结束慢,像一个滚动的小球由于摩擦力逐渐停止,这是UI中比较常用的缓动效果,使用户感受到UI的响应速度快,自然感受比较好
  • inOut,开始慢、结束也慢,像汽车的加速和减速

使用方式为${easeName}.${easeType},比如power1.out

const t = gsap.timeline();

t.to(".box", { x: 100, opacity: 0.5, duration: 1, ease:'power1.out' })

4. stagggers交错效果

如果需要在某一堆节点上展示相同的动画,按统一的时间节点执行相同的动画会显得有点枯燥,添加一点交错效果看起来会更酷炫。

所谓交错效果,也就是在不同节点上延迟执行对应的动画,gsap提供了stagger配置项来快速实现这个效果

// 首次渲染,有一堆 .box 节点
gsap.from(".box", {
  duration: 2,
  scale: 0.5,
  opacity: 0,
  delay: 0.5,
  stagger: 0.2,
  ease: "elastic",
  force3D: true,
});

document.querySelectorAll(".box").forEach(function (box) {
  box.addEventListener("click", function () {
    gsap.to(".box", {
      duration: 0.5,
      opacity: 0,
      y: -100,
      stagger: 0.1,
      ease: "back.in",
    });
  });
});

在做列表动画时,这个功能比较有用,无需手动控制每个节点的动画延迟或设置timeline了

5. 小结

本文介绍了gsap的基本使用,大部分都是从官方文档上整理总结的,用以加深印象,还是需要多练习多使用才行。