观看这个视频

创建优雅愉悦的时间线动画的关键是理解position这个参数的作用,它在GSAP的很多方法中都存在。这个非常灵活的参数能控制非常多的东西,不仅仅是你动画的时间点,你可以通过它来让你的动画变得异常灵活可控!

这篇文章会主要聚焦于gsap.to这个方法(timeline.to也是一样的使用方式),但是其实这个方法和from、fromTo、add等等方法使用起来都是类似的。position这个参数是第三个参数的位置,就是变化数据对象参数后面的位置。

tl.to(element, 1, {x: 200})
  // 添加到整个时间线结束时间点后1秒,相当于是有了1秒的间隔
  .to(element, {duration: 1, y: 200}, "+=1")
  // 添加到整个时间线结束的时间点的前0.5秒,也就是有0.5秒的时间是和时间线原本的动画重叠
  .to(element, {duration: 1, rotation: 360}, "-=0.5")
  // 从时间线动画开头时间点往后6秒的时间点
  .to(element, {duration: 1, scale: 4}, 6);

Timeline Tip: Understanding the Position Parameter

这是position这个参数的一个基本的介绍视频(英文的),来自作者Snorkl.tv出的一个"GSAP 3 Express" 课程,这个也是官方推荐的教程,不过肯定还是英文的。

在使用gsap.to()的时候搭配position参数

.to( target, vars, position )

我们通常去设置那种链式的动画,就是依次执行的动画,而position这个参数的默认值就是'+=',这个值表示的就是从最后添加的意思,那么timeline.to(…).to(…)这样的写法就会默认把相应的动画依次从尾部添加。如果你只是想要这样的效果,那么完全可以不传入position这个参数。但是如果你想要添加的动画在开头或者覆盖某一段动画,又或者想要间隔一段时间再执行,这些需求我们该怎么来实现呢?

不同的添加方式

position参数非常的灵活,以下写法都能有不同的作用:

  • 绝对时间(秒)的方式,以动画的启动时间点为参考,也就是整个时间线的起始点,比如使用一个数字3

// 插入到时间线开始后三秒之后的位置
tl.to(".class", {x: 100}, 3);
  • label(标记),比如下面代码例子中的'someLabel',如果该标记不存在,那么该动画会被插入到时间线末尾

// 插入到"someLabel" 标记所在的位置
tl.to(".class", {x: 100}, "someLabel");
  • '<'符号表示前一个添加到时间线上的动画的起始时间点。如果使用这个符号,那么动画会插入到前面一个动画的起始时间点位置。

// 插入到前一个添加到时间线上动画的起始时间点
tl.to(".class", {x: 100}, "<");
  • '>'符号表示前一个添加到时间线上的动画的结束时间点。如果使用这个符号,那么动画会插入到前面一个动画的结束时间点位置。

// 插入到前一个添加到时间线上的动画的结束时间点
tl.to(".class", {x: 100}, ">");

复杂一些的字符串,像是'+=''-='这样的前缀,表达的是一种相对的值。当一个数字跟在'<' 或者'>'这两个符号后面,比如'<2',这样的表示法相当于'<+=2',比如下面这些写法:

  • '+=1' 表示当前时间线结束后再过1秒的时间点位置,相当于有个1秒的间隔

  • '-=1' 表示当前时间线结束时间点前1秒的时间点位置,相当于有个1秒的时间重叠

  • 'myLabel+=2' 表示在myLable这个标记后过两秒的时间点位置

  • '<+=3' 表示前一个动画起始点后3秒的位置

  • '<3' 和上面一个意思('<''>'直接跟数字,其实就是和'<+=3'或者'>+=3'是一样的意思)

  • '>-0.5' 前一个动画的结束时间点前0.5秒的时间点位置

基于百分比的复杂字符串形式。如果前缀是'+='或者'-=',那么表示的百分比是基于整个时间线已经添加的所有动画的总时长的。如果前缀是'<'或者'>',那么这个是基于前一个添加动画的时长的。注意,总时长是包含了重复或者yoyo效果的时长的。

注意,+= -= 这种是针对整个时间线动画来说的,而 >(结尾) 和 <(开头) 是针对前一个添加的动画来说的

  • '-=25%' 放到前面已经添加的动画总时长的末尾25%的位置

  • '+=50%' 以前面所有动画总时长的50%作为时间间隔

  • '<25%' 以前一个动画启动时间点为时间点,放到前一个动画时长的25%的位置。它这个写法等同于'>-75%',这个就是以前一个动画的结束点为准,往前这个前动画的75%时长的时间点位置

  • '<+=25%' 以前一个动画启动时间点为时间点,向后放到全部动画总时长25%的时间点的位置。使用百分比的时候,是否搭配'+='或者'-='是很重要的,当使用这两符号,用来计算百分比的时间长度都是整个时间线已经添加的动画的总时间长度。

  • 'myLabel+=30%'myLabel标记位置为起始点,向后挪以整个以添加到时间线上的动画总时长的30%的时长作为插入的时间点。

常见代码写法

也可以通过标记来添加,包括标记所在时间点和相对标记所在的时间点

// 在时间线2秒的时间点添加一个标记
tl.add("scene1", 2)
  // 把动画提添加到 scene1 这个标记所在的时间点
  .to(element, {duration: 4, x: 200}, "scene1")
  // 把动画添加到 scene1 这个标记点往后3秒的时间点
  .to(element, {duration: 1, opacity: 0}, "scene1+=3");

很多时候看这些技术术语和代码实例,可能并不是那么直观好理解,我们接下来看看下面这些直观的例子。

不设置位置参数直接写

// 根据添加的顺序,依次执行
var tl = gsap.timeline();
tl.to(".green", {duration: 1, x: 750})
  .to(".purple", {duration: 1, x: 750})
  .to(".orange", {duration: 1, x: 750})

如果不设置position参数,那么时间线上的动画按照添加的顺序依次执行

时间线

1s

2s

3s

设置相对的正值:实现间隔/延迟

//每一个动画之间都有1秒的间隔
var tl = gsap.timeline();
tl.to(".green", {duration: 1, x: 750})
  // 插入到当前时间线结束后1秒的位置
  .to(".purple", {duration: 1, x: 750}, "+=1")
  // 插入到当前时间线结束后1秒的位置
  .to(".orange", {duration: 1, x: 750}, "+=1")

用一个相对的写法,使用正值('+=X'),能和前一个动画产生一定的间隔。

时间线

1s

2s

3s

4s

5s

设置相对的负值:实现重叠

// 动画有一定的重叠
var tl = gsap.timeline();
tl.to(".green", {duration: 2, x: 750})
   // 插入当前时间线结尾前一秒的位置
  .to(".purple", {duration: 2, x: 750}, "-=1")
   // 插入当前时间线结尾前一秒的位置
  .to(".orange", {duration: 2, x: 750}, "-=1");

用一个相对的写法,使用负值('-=X'),能和前一个动画产生一定的重叠。

时间线

1s

2s

3s

4s

5s

单纯使用数字:任何时间点

// 使用数字把动画添加到时间上线某一个时间点
var tl = gsap.timeline();
tl.to(".green", {duration: 4, x: 750})
  // 把动画添加到时间线上的第1秒开始的时间点
  .to(".purple", {duration: 2, x: 750}, 1)
  // 把动画添加到时间线上的第1秒开始的时间点
  .to(".orange", {duration: 2, x: 750}, 1);
  

直接使用一个数字,可以精确地把动画添加到时间上的某个时间点

时间线

1s

2s

3s

4s

5s

使用标记

// 把动画添加到标记所在的位置
var tl = gsap.timeline();
tl.to(".green", {duration: 1, x: 750})
  //把blueGreenSpin标记添加到当前时间线末尾之后的1秒的时间点
  .add("blueGreenSpin", "+=1")
  // 把动画添加到blueGreenSpin这个标记所在的时间点
  .to(".purple", {duration: 2, x: 750, rotation: 360}, "blueGreenSpin")
  // 把动画添加到blueGreenSpin这个标记所在的时间点之后0.5秒的时间点
  .to(".orange", {duration: 2, x: 750, rotation: 360}, "blueGreenSpin+=0.5");

通过给时间上设置标记,然后把动画添加到相应标记的时间点位置

时间线

1s

2s

3s

4s

5s

blueGreenSpin

相对于最近添加的动画来确定时间点

// 通过前一个添加的动画的位置来添加
var tl = gsap.timeline();
tl.to(".green", {duration: 1, x: 750})
  // 添加到前一个动画结束点的时间点位置,也就是green的结尾
  .to(".purple", {duration: 2, x: 750}, ">")
  // 添加到前一个动画开始点的时间点位置,也就是purple的开始
  .to(".orange", {duration: 2, x: 750}, "<");

使用"<"来表示添加到最近添加动画起点所在的时间点位置。">"表示添加到最近添加动画的结束点的时间点位置。

时间线

1s

2s

3s

4s

5s

百分比值

GSAP3.7.0版本之后,你就可以只用百分比的值,下面这个视频来具体讲解(我们前面文字当中也有介绍)

可交互的Demo

希望通过这篇文章你能了解position这个参数的强大。同时,再一次强调,虽然我们文章中的案例讲解时用的都是timeline.to()方法,但是其实在timeline.from(),timeline.fromTo(),timeline.add(),timeline.call(),以及timeline.addPause()方法中都可以使用的。

*注意,百分比的写法是GSAP3.7.0版本之后才加入的。

*注意,所谓的前一个动画,是最近加入的那个动画,而不是时间线上最后完结的的那个动画。

视频资源需要科学上网才能播放