thanks kirupa


使动画有趣的很大一部分就是让物体在屏幕上四处游走。适当的使用它们,为你的内容添加更多色彩,突显一些UI元素、提供一些动画交互等等。这是相当酷滴。

看下面这个比较疯狂的动画:

也可看一下更加微妙的动画,比如下面例子,当鼠标移到方框上时发生的变化:

在上面的两个例子中,动画效果完成使用CSS完成的。CSS中的Animations和Transitions很容易能让元素从静止状态变成运动状态。尽管是那么容易,这也需要你保证一些东西确保动画平滑的运行。本节内容帮助你如何创建它们。

Onwards!

Say Hello to the translate3d() Transform

当你移动一个元素,你要改变它的垂直和水平位置。在CSS里有很多属性可做到,但我仍建议你使用 transform 属性的translate3d 函数。在后面我会证明,为什么用这个属性而不用一般的属性如margin,padding,left,top。 最基本的原因是translate3d`能生产出流畅和平滑的动画。

Translate3d 函数有3个参数,我们主要看下前两个参数,用于元素移动的横向和纵向坐标:

Animation Img

指定的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次的使用或修改它们的值是非常不好的。

你可能设置元素的positionfixedabsolute.。能避免浏览器对整个文档的重新布局。这也是一种优化,浏览器仍然会在盒模块元素上做一些布局的计算。这仍是不必要的,因为设置margin, padding和使用translate3d 的结果是一样的。好吧,下节中你会看到,这也不是100%全部的原因。

Hardware Acceleration

当处理在屏幕上显示的元素,背后通过CPU或GPU来计算这些它们。一般来说,你更应该依靠GPU来做所有的显示工作...尤其是像动画这种任务:

Animation Img

原因是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