前端动画技术概述
目前的用于html5的动画技术:
- DOM元素的位置、颜色、透明度、可见度等等属性变换
- CSS3 中有部分属性定义DOM元素的一些变换,主要是 Animation(动画),Transform(转换), Transition(过渡)
- SVG 矢量绘图技术,本身也属于DOM元素
- Canvas 更底层的绘图技术
如果追忆历史的话,以前独霸web天下的Flash技术,还有SilverLight技术,是三方的浏览器插件实现动画的。因为耗电量和安全问题,在移动平台淡出市场视线,html5的崛起彻底让这样的技术走下了舞台。
定时器函数
使用js操作dom属性和css属性实现动画,离不开定时器函数setTimeout和setInterval,现在又有了requestAnimationFrame 函数来更流畅的实现定时执行,最大程度避免卡顿。 requestAnimationFrame告诉浏览器执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。
常见的三方动画库
jQuery
一般来说tweening(补间,就是自动生成起始和结束中间的状态)对于一般很多的前端特性够用了。
jQuery中就有大量动画效果的过渡函数,比如淡入淡出fadeIn()和fadeOut(),滑动slideDown()和slideUp(),还有animate()方法都是补间动画类函数。
主要通过定时执行函数改变DOM的属性或者CSS属性。
//点击按键,把 <div> 元素往右边移动 250 像素
$("button").click(function(){
$("div").animate({left:'250px'});
});
Animate.css
CSS定义的动画优势较使用js补间方式计算生成的动画,效率上应当更高一些。
Animate.css 就是第三方CSS动画库,使用上还要借助于js。
tween.js
npm安装tween.js
npm install @tweenjs/tween.js
要注意的是有段比较手动更新动画的循环,似乎一直运行?
var TWEEN = require('@tweenjs/tween.js');
var t = new TWEEN.Tween( /* etc */ );
t.start();
// Setup the animation loop.
function animate(time) {
requestAnimationFrame(animate);
TWEEN.update(time);
}
requestAnimationFrame(animate);
在vue文档例子中这样改了下:
function animate () {
if (TWEEN.update()) {
requestAnimationFrame(animate)
}
}
animate()
GSAP
GreenSock 的产品包叫GSAP,包含了TweenLite,TweenMax,TimelineLite,TimelineMax组件以及一些插件,用于编程创建HTML5动画。
其补间变换的API使用起来很方便:
//将id为logo的元素水平移动100px
TweenMax.to("#logo", 1, {x:100});
Vue
Vue.js带了transition标签,结合CSS3的动画相关属性来实现过滤和动画。通过监听器和一些补间变换的三方库来实现状态过滤。
看下面的例子,是不是觉得有点繁琐,还是jQuery来的简单。不过这些对于开发vue组件来说非常有用。
<div id="example-1">
<button @click="show = !show">
Toggle render
</button>
<transition name="slide-fade">
<p v-if="show">hello</p>
</transition>
</div>
<script>
new Vue({
el: '#example-1',
data: {
show: true
}
})
</script>
<style>
/* 可以设置不同的进入和离开动画 */
/* 设置持续时间和动画函数 */
.slide-fade-enter-active {
transition: all .3s ease;
}
.slide-fade-leave-active {
transition: all .8s cubic-bezier(1.0, 0.5, 0.8, 1.0);
}
.slide-fade-enter, .slide-fade-leave-to
/* .slide-fade-leave-active for below version 2.1.8 */ {
transform: translateX(10px);
opacity: 0;
}
</style>