thanks kirupa
使动画有趣的很大一部分就是让物体在屏幕上四处游走。适当的使用它们,为你的内容添加更多色彩,突显一些UI元素、提供一些动画交互等等。这是相当酷滴。
看下面这个比较疯狂的动画:
也可看一下更加微妙的动画,比如下面例子,当鼠标移到方框上时发生的变化:
在上面的两个例子中,动画效果完成使用CSS完成的。CSS中的Animations和Transitions很容易能让元素从静止状态变成运动状态。尽管是那么容易,这也需要你保证一些东西确保动画平滑的运行。本节内容帮助你如何创建它们。
Onwards!
Say Hello to the translate3d() Transform
当你移动一个元素,你要改变它的垂直和水平位置。在CSS里有很多属性可做到,但我仍建议你使用 transform
属性的translate3d
函数。在后面我会证明,为什么用这个属性而不用一般的属性如margin,
padding,
left,
top。 最基本的原因是
translate3d`能生产出流畅和平滑的动画。
Translate3d
函数有3个参数,我们主要看下前两个参数,用于元素移动的横向和纵向坐标:
指定的x参数表示元素水平移动的距离。指定的y参数表示元素垂直移动的距离。例如,你想让元素向右和上移动20像素,translate3d
函数的定义如下:
.foo {
transform: translate3d(20px, 20px, 0px);
}
我们先不去看的一个参数是指定元素移动的z方向(垂直于屏幕的方向)的移动。因为我们先主要关注2d的移动,将忽略它设置为0不做任何事。
正如你所看到的,translate3d
函数不是那么深奥或复杂。在下一节里,让我们进一步看下它作为CSS Transition或Animation的一部分来模拟运动。
Transition
在transition里使用这个属性,需要做两步。第一步,你在transition属性里添加对transform
属性的监听:
.pictureContainer img {
position: relative;
top: 0px;
transition: transform .2s ease-in-out;
}
根据transition里的定义,使用translate3d
函数声明transform
属性:
.pictureContainer img:hover {
transform: translate3d(0px, -150px, 0px);
}
就像本篇最前面一个例子展示一样,鼠标移到图片上后,触发transform,图片向上精确移动150像素。
Animation
对于animations,在@keyframes
定义的关键帧里,使用translate3d
函数声明transform
属性:
@keyframes bobble {
0% {
transform: translate3d(50px, 40px, 0px);
animation-timing-function: ease-in;
}
50% {
transform: translate3d(50px, 50px, 0px);
animation-timing-function: ease-out;
}
100% {
transform: translate3d(50px, 40px, 0px);
}
}
在 All About CSS Animations 可以看它的运行,那么我就不在这里重复。
Don't Forget About Vendor Prefixes
为了确定你的代码在各种浏览器上运行,需要对transform
属性添加前缀,或使用类似 -prefix-free的库。在我的关于这部分内容的视频里,能学到更多的内容。
Translating Using JavaScript
如果你碰巧在JavaScript里使用它们。也比较类似。只需在translate3d 中设置横纵位置,这块有稍微有点复杂。 The snippet of code you will need looks approximately as follows:
function getSupportedPropertyName(properties) {
for (var i = 0; i < properties.length; i++) {
if (typeof document.body.style[properties[i]] != "undefined") {
return properties[i];
}
}
return null;
}
var transform = ["transform", "msTransform", "webkitTransform", "mozTransform", "oTransform"];
var item = document.querySelector("#theItem");
var transformProperty = getSupportedPropertyName(transform);
if (transformProperty) {
item.style[transformProperty] = translate3d(someValueX, someValueY, 0px);
}
这段代码看起来比较繁琐而简单,因为要检测属性前缀,确保使用正确的transform
属性。在JavaScript里你可以学习更多关于属性前缀处理的内容,尤其是后面的教程里。
What's Wrong With Setting Margin, Top, Left, etc.?
当讨论translate3d
函数位移的时候,我都总是会问这个问题(使用margin,top,left进行位移怎么啦)。出于对动画的目的,除非你有特殊需要,不要使用 margin
, padding
, top
, left
, bottom
,或right
这些属性。的确是这样的。也许你使用这些属性用于一些不同定位相关(position相关:fixed, absolute...)的目的,我理解这有点违反常理。我最极端的理由就是性能问题。我来解释下吧...
Unnecessary Layout Calculations
每当你修改我上面列出的CSS属性,浏览器会做些额外的工作,去计算这些CSS如何影响你的整个文档的布局。我并不是反对你使用这些属性帮助布局。在文档加载和重新调整大小时使用它比较好。在animation 或transition里,每秒60次的使用或修改它们的值是非常不好的。
你可能设置元素的position
为fixed
或 absolute
.。能避免浏览器对整个文档的重新布局。这也是一种优化,浏览器仍然会在盒模块元素上做一些布局的计算。这仍是不必要的,因为设置margin
, padding
和使用translate3d
的结果是一样的。好吧,下节中你会看到,这也不是100%全部的原因。
Hardware Acceleration
当处理在屏幕上显示的元素,背后通过CPU或GPU来计算这些它们。一般来说,你更应该依靠GPU来做所有的显示工作...尤其是像动画这种任务:
原因是GPU只专注一件事---处理你的显示任务。另一方面,CPU,必须去处理其它的一些事件。确保你的动画顺畅运行,不优先在它的任务列表内。这种差异,尤其在功能强大的桌面电脑(笔记本电脑)和移动设备如iPad或iPhone之间更为明显。个人意见,使用CPU处理动画比使用GPU更加狂躁。
怎样确定你的动画运行在GPU硬件模式下呢?使用translate3d
!当你在元素上使用tranform,基于Webkit内核的浏览器中如Chrome和Safari(同样是iPhone和iPad中使用的)、IE9/20和最新版本的Firefox,该元素就会在GPU的控制范围内。在我书中介绍到translate3d
是明显胜出的。
What About JavaScript?
使用JavaScript创建的动画所有的插值都是通过代码处理的,我真的不知道是否启用了GPU。我想知道的是,用JavaScript设置CSS的transitions和animations的translate3d属性是否通过了GPU的帮助。这是很情理之中的。当用JavaScript设置animation或transion的重要属性,开始点到结束点之间的插值由浏览器的动画系统完成的。前面蓝色圆形的例子证明这一点。
God Bless Transforms
总之transforms有很高的性能,因为它不会影响到其它元素(no re-layout,没有重新布局)。任何操纵都适合该属性,浏览器不会重绘整个窗口。它只重绘屏幕上的一部分---移动的内容。这是独立的部分不管GPU有没有参与进来。使用transform的translate3d
,部分重绘仍旧有效,因为它仍就是transform属性。使用这个特殊的transform,你也得益于GPU处理的性能。
翻译水平有限,敬请各位同学批评指正。
Comments
comments powered by Disqus