JS动画 | 用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);
}
效果如下:
.droplet {
display: inline-block;
width: 4em;
height: 4em;
border-radius: 80% 0 55% 50% / 55% 0 80% 50%;
background-color: #07C;
transform: rotate(-45deg);
}
.droplet.before {
transform: none;
}
旋转45度后⟹
enjoycss.com上还有不少有意思的实现, 比如爱心.
(不过刚发现enjoycss.com还是alpha版本, 很多bug...比如这个爱心点进去看到的css就是有问题的)
我在这个爱心css的基础上加了个CSS动效, 让心脏活了起来, CodePen.
.heart {
display: block;
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
width: 100px;
height: 90px;
position: relative;
animation: heartbeat .5s infinite;
}
.heart:before,
.heart:after {
display: block;
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
width: 50px;
height: 80px;
position: absolute;
content: "";
-webkit-border-radius: 50px 50px 0 0;
border-radius: 50px 50px 0 0;
background: red;
}
.heart:before {
top: 0;
left: 50px;
-webkit-transform: rotateZ(-45deg);
transform: rotateZ(-45deg);
-webkit-transform-origin: 0 100% 0;
transform-origin: 0 100% 0;
}
.heart:after {
top: 0;
left: 0;
-webkit-transform: rotateZ(45deg);
transform: rotateZ(45deg);
-webkit-transform-origin: 100% 100% 0;
transform-origin: 100% 100% 0;
}
@keyframes heartbeat {
80% {
transform: scale(1.2);
}
100% {
transform: scale(1);
}
}
动画过程中水滴的毛边问题
细心的人应该注意到了, 我上面的效果图中, 水滴在放大之后有比较明显的毛边. 我测试了下, 一旦动画停止, 毛边就消失了.
针对这个问题搜了一下, 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
JS动画 | 用TweenMax实现收集水滴效果的更多相关文章
- 原生js动画效果(源码解析)
在做页面中,多数情况下都会遇到页面上做动画效果,大部分都是用jquery来实现动画,今天正好看到一篇原生js实现动画效果的代码,特分享在此. 原文地址:http://www.it165.net/pro ...
- js 动画效果实现
1. 实现方式 - 应用场景 自己写 - 简单的.不用 jq 的项目 jq - 普通动画 成熟插件 - 复杂动画 2. 相关文章 JavaScript基于时间的动画算法 九种原生js动画效果 Twee ...
- TouchPoint.js – 可视化展示 HTML 原型点击效果
TouchPoint.js 是一个用于 HTML 原型展示的 JavaScript 库(作为UX过程的一部分),通过视觉表现用户在屏幕上的点击.TouchPoint 是高度可定制,非常适合屏幕录制,用 ...
- 【06-23】js动画学习笔记01
<html> <head> <style> * { margin:0; padding:0; } #div1{ width:200px; height:200px; ...
- css动画与js动画的区别
CSS动画 优点: (1)浏览器可以对动画进行优化. 1. 浏览器使用与 requestAnimationFrame 类似的机制,requestAnimationFrame比起setTimeout ...
- CSS VS JS动画,哪个更快[译]
英文原文:https://davidwalsh.name/css-js-animation 原作者Julian Shapiro是Velocity.js的作者,Velocity.js是一个高效易用的js ...
- Midnight.js – 实现奇妙的固定头部切换效果
Midnight.js 是一款 jQuery 插件,在页面滚动的时候实现多个头设计之间的切换,所以你总是有一个头与它下面的内容层叠,看起来效果很不错. Midnight.js 可以让你轻松实现这种切换 ...
- 使用 HTML5 Canvas 绘制出惊艳的水滴效果
HTML5 在不久前正式成为推荐标准,标志着全新的 Web 时代已经来临.在众多 HTML5 特性中,Canvas 元素用于在网页上绘制图形,该元素标签强大之处在于可以直接在 HTML 上进行图形操作 ...
- Space.js – HTML 驱动的页面 3D 滚动效果
为了让我们的信息能够有效地沟通,我们需要创建用户和我们的媒体之间的强有力的联系.今天我们就来探讨在网络上呈现故事的新方法,并为此创造了一个开源和免费使用的 JavaScript 库称为 space.j ...
随机推荐
- 反编译.o到.cpp
反编译.o到.cpp 现在有很多反编译是对Java的,而.cpp的很少 因为不同的平台.cpp生成的.o是不一样的,但是Java因为有虚拟机的中间作用,生成的.o在不同平台是一样的 反编译的机理 (通 ...
- 返璞归真vc++之感言
本人自述,大专学历,感觉自己也属于好学型学生,历任班上学习委员3年有余,参与学校项目几多个,不知道不觉从11年毕业已有3个年头,3年来,不敢苟同自己的生活方式,奈何人生无奈..从刚开始的电子商务公司转 ...
- Unity3D编程回忆录,Unity3d视频教程,教父团队倾情之作
之前一直在看Unity3d的视频教程,包括很多老外的视频教程,老外的教程确实不错,技术含量很高,而且讲得很激情,让我有种恨不得一秒钟就想吧unity3d学个精通的冲动,只是,毕竟是英语教程,没办法,哎 ...
- select绑定json数组对象 asp.net
ashx处理页 string JsonList = "["; IList<Models.Channel> ilist = BLL.ChannelManager.GetA ...
- php微信支付(仅pc端扫码支付模式二)详细步骤.----仅适合第一次做微信开发的程序员
本人最近做了微信支付开发,是第一次接触.其中走了很多弯路,遇到的问题也很多.为了让和我一样的新人不再遇到类似的问题,我把我的开发步骤和问题写出来,以供参考. 开发时间是2016/8/10,所以微信支付 ...
- ECSHOP购物流程收货人信息详细地址显示省市区
方法一: 1.在flow.php中的 elseif ($_REQUEST['step'] == 'checkout') 中 $_SESSION['flow_consignee'] = $consign ...
- Python 信号量
信号的概念 信号(signal)-- 进程之间通讯的方式,是一种软件中断.一个进程一旦接收到信号就会打断原来的程序执行流程来处理信号. 几个常用信号: SIGINT 终止进程 中断进 ...
- 帝国cms中 内容分页的SEO优化
关于内容页如果存在分页的话,我们想区分第一页和后面数页,当前的通用做法是在标题上加入分页码,帝国cms中如何做到呢.我们可以修改在e/class/functions.php中的源码.找到找到GetHt ...
- lua5.3调用C/C++
马上面临毕业设计,打算做点跟网游有关的,先从做周边工具开始,目前正在做一个协议序列化和反序列化的东西,广告一波先: https://github.com/Anti-Magic/rproto 目前非常简 ...
- 微信公众号jssdk使用的惨痛经历
最近一直在做微信公众号开发,遇到个DT的问题: 大家都知道使用jssdk的时候开发人员必须在后台按照官方文档给定的规则生成签名,我前前个月就写好了这个测试demo页面,而且完全正常能用,像分享等这些功 ...