目前有两个主流的方法在web上创建动画:使用CSS或JS。到底选择哪种方法来实现动画,完全取决于你的项目以及你想要达到的效果。
tips:
- 对于简单的只出现一次的过渡效果,可以采用CSS动画,比如切换UI元素的状态
- 在需要高级的效果,比如弹跳、停止、暂停、倒回或者减速这种效果,就需要用JS来实现动画
- 如果用JS实现动画,可以用
TweenMax
,或者如果需要轻量级的解决方案,就用TweenLite
很多基础的动画都可以通过CSS或JS来实现,但两者的效果和时间会有差别。两种方式各有千秋:
-
对UI元素小而独立的状态添加动画,可以使用CSS。CSS的
transition
和animation
是一个好办法,比如把导航栏从侧边移过来,或者展示一个提示框tooltip。这种情况下最好用CSS而不是JS - 在需要对动画进行精确控制的时候需要用JS实现。JS可以动态跟踪触发动画的位置,像一些停止、暂停、减速或者反转的效果都需要JS实现。
如果你已经用了类似jQuery的包含动画函数的JS框架,你会发现用它来控制动画比CSS方便的多。
CSS动画
毫无疑问CSS动画是最简单的一种让屏幕上的元素动起来的方式。
下面的CSS代码会将一个元素在X轴和Y轴上移动100px。完成这个功能需要CSS trasition,并设置为500ms。当move
这个class被添加时,transform
的值会发生改变,过渡开始
.box {
-webkit-transform: translate(0, 0);
-webkit-transition: -webkit-transform 500ms;
transform: translate(0, 0);
transition: transform 500ms;
}
.box.move {
-webkit-transform: translate(100px, 100px);
transform: translate(100px, 100px);
}
你如果像上面的代码片段一样添加了CSS类来控制动画,那么接下来就需要用JS来控制切换动画的开始和结束
box.classList.add('move');
采用这种方式会对你的app有很好的平衡。你只需要用JS来控制状态,然后对目标元素设置恰当的class,让浏览器来控制动画。接下来你可以对目标元素监听transitionend
事件,不过这种情况只适用于IE10+。这个事件在CSS完成过渡以后触发。
var box = document.querySelector('.box');
box.addEventListener('transitionend', onTransitionEnd, false);
function onTransitionEnd() {
// Handle the transition finishing.
}
除了用CSS transitions,你也可以使用CSS animations,它能让你对动画的帧、时长及重复次数有更多的控制。
Note
如果你是动画新手,对于手绘动画而言关键帧(keyframes)是很重要的概念。动画会生成一些特殊的帧来实现一个动作,这种帧叫做keyframes,这种帧能够捕捉某些动作的最极端的部分。CSS动画也有相似的过程,通过设置CSS的相关属性在目标点的时候什么值就可以了。
举一个例子,让盒子的动画跟上例一样,只是不需要任何像click的事件触发,并且无限重复。你可以同时改变多个属性:
/**
* This is a simplified version without
* vendor prefixes. With them included
* (which you will need) things get far
* more verbose!
*/
.box {
/* Choose the animation */
animation-name: movingBox;
/* The animation’s duration */
animation-duration: 1300ms;
/* The number of times we want
the animation to run */
animation-iteration-count: infinite;
/* Causes the animation to reverse
on every odd iteration */
animation-direction: alternate;
}
@keyframes movingBox {
0% {
transform: translate(0, 0);
opacity: 0.3;
}
25% {
opacity: 0.9;
}
50% {
transform: translate(100px, 100px);
opacity: 0.2;
}
100% {
transform: translate(30px, 30px);
opacity: 0.8;
}
}
通过CSS动画,你可以为目标元素单独定义动画,并使用animation-name
属性来选择需要的动画。CSS动画目前还需要写前缀,在Chrome,Safari,Opera,Safari Mobile以及Android Browser中均需要添加-webkit-
前缀。IE和Firefox均不需要写前缀。有很多工具会帮你在需要添加前缀的属性上添加前缀,这样在源代码中就可以不需要一个个添加前缀了。
JS动画
跟CSS动画相比,JS动画更复杂一些,但会给开发者更多的动画能力。推荐的做法是使用requestAnimationFrame
,在动画的每个帧上来确定元素的每个属性值。(关于requestAnimationFrame
,可参考HTML5探秘:用requestAnimationFrame优化Web动画)
Note
你应该见到过很多用setInterval或者setTimeout来实现动画的代码。然而这是一个不好的方法,动画会不能跟屏幕同步刷新,而且很容易剧烈变化或者跳出。你需要避免这样的代码,尽量使用requestAnimationFrame,它能够正确的同步。
下面的例子是你需要写的JS代码,实现上面用CSS实现的效果:
function Box () {
var animationStartTime = 0;
var animationDuration = 500;
var target = document.querySelector('.box');
this.startAnimation = function() {
animationStartTime = Date.now();
requestAnimationFrame(update);
};
function update() {
var currentTime = Date.now();
var positionInAnimation = (currentTime - animationStartTime) / animationDuration;
var xPosition = positionInAnimation * 100;
var yPosition = positionInAnimation * 100;
target.style.transform = 'translate(' + xPosition + 'px, ' + yPosition + 'px)';
if (positionInAnimation <= 1)
requestAnimationFrame(update);
}
}
var box = new Box();
box.startAnimation();
上面的代码看起来很复杂,你可以尝试将其扩展到多种情况。如果你正在使用jQuery,可以用.animate()
函数。如果不是,你可以参考强大的Greensock’s TweenMax,还有一个轻量级的TweenLite。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。