用TweenMax实现收集水滴效果
之前在CodePen上接触了TweenMax, 被它能做到的酷炫效果震撼了. (文末放了5个GSAP的效果GIF)
最近要做一个”收集水滴”的动效, 于是就试用了一下TweenMax实现这个效果.
什么是TweenMax
TweenMax是GSAP(GreenSock Animation Platform)创作的动画工具库. GSAP的产品除了TweenMax, 还有:
- TweenLite: TweenMax的精简版, 9kb.
- TimelineMax: 将动画串联起来的库, 6kb.
- TimelineLite: TimelineMax的精简版, 4kb.
- Draggable: 让元素可以拖来拖去, 12kb.
- SplitText: 让文字逐个/词/行展现酷炫动效.
- DrawSVGPlugin: 动态绘制SVG.
- MorphSVGPlugin: 很酷炫的SVG变换插件
- 其他若干插件
TweenMax就是GSAP的”全家桶”, 包含了TweenLite, TimelineLite, TimelineMax, CSSPlugin, AttrPlugin, RoundPropsPlugin, DirectionalRotationPlugin, BezierPlugin 和 EasePack.
想起步, 先看看这个Get Started里的视频就好了.
最简单的用法就是TweenMax.to(element, duration, options);
, 例如
TweenMax.to('.drop', 3, { x: 100, scale: 2, backgroundColor: #aaa })
可以让.drop
元素在3秒内, 水平移动100px, 放大一倍, 背景色变为#aaa
.
实现
<!-- jade -->
.container
.drop
.tank
HTML很简单, 就是.container
里面一个.drop
一个.tank
.
以下JS让.drop
飘起来飞向.tank
.
var collectDrop = function() {
var $drop = $('.drop:not(.anim)'),
$tank = $('.tank'),
from = $drop.position(),
to = $tank.position(),
// 计算从水滴中心到水缸中心所需要的偏移量.
x = to.left - from.left + ($tank.width() - $drop.width()) / 2,
y = to.top - from.top + ($tank.height() - $drop.height()) / 2,
// 创建动画用水滴
$el = $drop.clone().addClass('anim').appendTo('.container'),
tl = new TimelineMax();
// 水滴升起
tl.to($el, 2, {
y: -$el.height() * 3,
scale: 2,
ease: Elastic.easeOut.config(1, 0.4)
})
// 水滴飞向水缸
.to($el, .5, {
x: x,
y: y,
backgroundColor: '#832fc2',
scale: .5,
ease: Power1.easeIn,
onComplete: function() {
$el.remove();
}
})
// 水缸动效
.to($tank, .1, {
scale: 1.3
})
.to($tank, .1, {
scale: .8
})
.to($tank, .1, {
scale: 1
});
};
这里为了实现一连串动画, 所以使用了TimelineMax. 由于script
中引入了TweenMax, 所以TimelineMax也就自动被引入了.
CodePen如下, 你只要点击水滴就可以看到收集效果了.
See the Pen tweenmax collect drop by Richard Liu (@lzl124631x) on CodePen.
上面的代码中关于动效的选项, 用到了x
和y
以利用transform
变换位置, scale
改变大小, backgroundColor
修改颜色, onComplete
为动画完成时的callback, ease
设置动画的easing效果.
在GSAP Ease Visualizer中可以看到更多的easing效果, 你还可以在这里修改参数, 查看效果, 然后将满意的代码复制出来.
水滴CSS
题外话, 本来只是做个动效, 元素的外观是次要的. 不过好奇能不能直接用CSS做出水滴效果, 就搜了一下”droplet css”, 竟然真有这么做的. 其实原理不难(可就是想不到啊=,.=), 就是利用border-radius
生成一个斜着的水滴, 然后旋转45度.
.droplet {
width: 4em;
height: 4em;
border-radius: 80% 0 55% 50% / 55% 0 80% 50%;
background-color: #07C;
transform: rotate(-45deg);
}
效果如下:
旋转45度后⟹
enjoycss.com上还有不少有意思的实现, 比如爱心.
(不过刚发现enjoycss.com还是alpha版本, 很多bug…比如这个爱心点进去看到的css就是有问题的)
我在这个爱心css的基础上加了个CSS动效, 让心脏活了起来, CodePen.
动画过程中水滴的毛边问题
细心的人应该注意到了, 我上面的效果图中, 水滴在放大之后有比较明显的毛边. 我测试了下, 一旦动画停止, 毛边就消失了.
针对这个问题搜了一下, CodePen上有一个解决方案.
它的解决方法是: 假设动画中最大的放大比例是2倍, 那么一开始绘制元素的时候就用2倍的大小去绘制, 初始使用transform: scale(.5)
缩小到正常比例, 然后动画放大的时候用scale(1)
.
我试了一下, 的确管用. 更新后的CodePen如下:
See the Pen tweenmax collect drop by Richard Liu (@lzl124631x) on CodePen.
效果图如下:
但是这个方法不够优雅, 于是继续搜了搜, 比如这个SO问题. 可是我试遍了文中讲的方法, 包括translateZ(0)
, -webkit-backface-visibility: hidden;
, filter: blur(0);
, 可惜都不管用(T_T).
请大神出手.
参考
附上几个GSAP的酷炫CodePen, 大家感受下, CodePen上搜索GSAP或TweenMax还有很多.
- Draft Countdown
- Making muscles with MorphSVG
- Paranoid vs shy birds (很搞笑, 移动鼠标会让中间那只鸟转头, 两边的两只鸟会偷偷地看中间那只, 如果被中间那只发现了会脸红低头)
- holy running cow (有一种MineCraft的赶脚)
- morph guy