H5 动画大师 TweenMax.js/GSAP

手写过 CSS3 做 H5 动画,那过程很累,很低级。于是这次改用 TweenMax 库,感觉非常不错,原来它是做动画的老行尊,失敬失敬,早在 Adobe Flash 时代,这款就是知名的类库,直到现在还可以在其 GitHub 上找到它的 ActionScript 2/3 的开源代码,怪不得现在转到 JS 上面来,都那么的成熟。

  • 官网:https://greensock.com/
  • 源码:https://github.com/greensock/GSAP
  • 中文网 https://www.tweenmax.com.cn/ 弄得很不错,还有破解下载,良心

3.0 之后,TweenMax.js 业已改名为 GSAP,并统一了 API,没有那么多的分层,这对于用户来说好处就是更简单了,不用因为选择不同的库而犯难。不过笔者因为插件而尚未升级的关系,不敢贸然去使用新版,下文的代码仍然是 2.x 的,这里特此说明一下。

概念

Tweening 是 inbetweening 的缩写,在动画序列之间的状态创建帧,意思是放置在一个运动结束,要进行下一个运动前,中间创建一个流畅的过渡。这种概念在 Flash 时代早已有之,相信老玩家对这动画的概念不会陌生。显然这是建立在以帧尾单位的基础上,而网页上却是没有特定帧的概念的。保留下来的仍然有时间轴这个概念。

TweenMax 有个更准确的说法"状态操控器",一如官方教程开明宗义所说的“GSAP is a property manipulator”,——这怎么说呢?我们通过一个“数字脉冲器”的网页特效来说明之,如下图所示。
在这里插入图片描述
配合下面简单几行的代码,你应该可以猜出"状态操控器"之含义如何了。

TweenLite.to({n:0.1}, 1, { n:2.48, onUpdate: () => h3.innerHTML = n3.n.toFixed(2)})

类似于 JS 中访问 CSS 属性的写法,一些 CSS 属性对应到 TweenMax 中有所不同,比如 transform 中translate 在 TweenMax 中使用 x,y 就对应着 translate(x,y)。任何的 CSS 属性需要从有-的写法变为驼峰式的写法,比如 background-color 修改为 backgroundColor 等,以及 transform:rotate() 变为 rotation。更多的对应 CSS 属性如下。

  • CSS| TweenMax
  • translateX() x
  • translateY() y
  • translateZ() z
  • rotate() rotation
  • rotateY() rotationY
  • rotateX() rotationX
  • scaleX() scaleX
  • scaleY() scaleY
  • skewX() skewX
  • skewY() skewY

autoAlpha 方法是 TweenMax 中一个特别的属性,它把 opacity 和 visibility 两个属性合二为一了。

时间轴概念

TweenMax 与低级动画库的区别在于时间轴。我们知道,原生写 H5 动画,就算你不写 JS,纯 CSS 的,写 delay 都写到你烦,而且一大串的动画连起来的,修改一个时间点,后面全都跟着改~“牵一发动全身”。写 JS 的话,也要控制一大堆计时器——好不痛苦。为此,一般通过直观的时间轴(TimeLine)来解决动画时间点的控制问题。

采用 to().to()… 链式调用,实际是执行上一个动画之后,顺序线性执行下一个动画。TweenMax 还提供其他手段实现非线性的动画执行顺序。下面的例子遇到相应的代码中我们会进行介绍。

实例

入门教程方面网上已经很多了,这里不再赘述,都是一些 API 说明。下面我们就通过一个实际的例子来说说 TweenMax 的应用。下面是实际效果动图。

在这里插入图片描述动画脚本如下。

	new TimelineMax({delay:1})
		.to('.p1-1 .building', 1.2, {transform: 'scaleY(1)', ease : Bounce.easeOut}).add('start')
		.add(new TimelineMax({repeat: -1})
			.to('.p1-1 .plane', 2.8, {x: 600, opacity:1})
			.to('.p1-1 .plane', .5,  {x: '+=300', opacity:0}))
		.to('.p1-1 .tree', .8, {autoAlpha: 1, transform:'scaleX(1)',ease : Bounce.easeOut})
		.to('.p1-1 .train', 3.8, {x: 2600, repeat: -1}, 'start')
		.to('.p1-1 .car', 4.8, {x: 2490, repeat: -1, ease : Power1.easeIn}, 'start')
		.to('.p1-1 .r-1', .8,  { y:-170, ease: Power1.easeIn, opacity:1}, 'start')
		.to('.p1-1 .r-2', 1.2, { y:-130, ease: Power1.easeIn,opacity:1}, 'start')
		.staggerFrom(mySplitText.chars, 0.8, {opacity:0, scale:0, y:80, rotationX:180, transformOrigin:"0% 50% -50", ease:Back.easeOut}, 0.01)
		.to('.r-1', 1.5, { y:-195, ease: Power1.easeOut,yoyo:true,repeat:-1})
		.to('.r-2', .9,  { y:-120,ease: Power1.easeOut, yoyo:true,repeat:-1})
		.add(new TimelineMax({repeat: -1}).to('.light-1', 1, { opacity: .5}).to('.light-1', .6, {opacity: 1}))
		.add(new TimelineMax({repeat: -1}).to('.light-2', .5, { opacity: .3}).to('.light-2', .5, { opacity: 1}).to('.light-2', .6, {opacity: .5}))
		.add(new TimelineMax({repeat: -1}).to('.light-3', 1.5, { opacity: .2}).to('.light-3', .9, { opacity: 1}).to('.light-3', .5, {opacity: .2}))
		.add(new TimelineMax({repeat: -1}).to('.light-4', .5, { opacity: .3}).to('.light-4', .5, { opacity: 1}).to('.light-4', .6, {opacity: .5}))

new TimelineMax({delay:1}) 构造器参数表示该时间轴的全局参数,这里延时一秒钟。

执行一个动画之后,调用 add(‘start’) 表示一个时间点的标记,在下面的动画中可以令动画插入到该标记之后执行,例如 to(’.p1-1 .car’, 4.8, {x: 2490, repeat: -1, ease : Power1.easeIn}, ‘start’)。还可以 start+=.25 延时 0.25 秒进行微调,或者 -= 提前时间。

渐显(FadeIn)效果

如下做一个渐显(FadeIn)的效果,无非就是初始透明度为0,然后执行动画的话增加其透明度到1并且位移。

在这里插入图片描述
参数是目标元素,动画持续时间(单位:秒),目标配置。

.to('.p1-1 .plane', 2.8, {x: 600, opacity:1})

这里 x 即垂直位移 600 个像素,单位可以其他 CSS 合法单位例如 % 百分比,用字符串表示。这里 600 是绝对坐标的位置,但也可以相对位移的距离,写法如 “+=20”,表示在当前 x 坐标上升高 20 个像素。opacity 是透明度,你也可以用 autoAlpha : 1 代替。

呼吸效果

呼吸效果就是 yoyo,应用很广,在 TweenMax 中也很简单,同时设置无限循环 repeat: -1 和 yoyo: true 即可

.to('.r-1', 1.5, { y:-195, ease: Power1.easeOut,yoyo:true,repeat:-1})

在这里插入图片描述

加入另外的时间轴

有时候复杂的动画不能满足于一个时间轴,那么可以新建一个时间轴实例,然后再加入当前主时间轴中,例如:

.add(new TimelineMax({repeat: -1}).to('.light-4', .5, { opacity: .3}).to('.light-4', .5, { opacity: 1}).to('.light-4', .6, {opacity: .5}))

其他技巧

staggerTo() 支持传入元素数组

.staggerTo(document.querySelectorAll('.icon'), 1.1,  {opacity: 1}, .1)

备忘单(Cheat Sheet)

https://ihatetomatoes.net/greensock-cheat-sheet/

教程

  • https://greensock.com/get-started 官方入门 推荐
  • https://segmentfault.com/a/1190000005366176#comment-area
  • https://www.w3cplus.com/blog/tags/524.html 比较多 SVG 动画的例子
  • http://svgtrick.com/book/greensock/
  • https://www.cnblogs.com/tujia/category/898044.html
  • http://www.topfe.cn/javascript/524.html
  • https://blog.csdn.net/kaizi524/article/details/50339329

资源

  • 可视化工具 GSDevTools https://webdesign.tutsplus.com/tutorials/a-first-look-at-gsdevtools-by-greensock–cms-29531
  • https://wow.techbrood.com/fiddle/12084
  • 推荐一厂商 https://blog.csdn.net/xhload3d、http://www.hightopo.com/
©️2020 CSDN 皮肤主题: 岁月 设计师:pinMode 返回首页