CSS3 3D transform变换制作简易动画

0. 感谢

感谢张鑫旭老师的博文好吧,CSS3 3D transform变换,不过如此!对我的指导。看完这篇文章之后,我对CSS 3D transform有了蛮多的理解,并且自己制作了一个小demo。在这里和大家分享一下我的理解以及制作过程。

1. 效果展示

demo效果

效果图

2. 先看3D transform

1. 方法

3D transform中主要包含这几个方法

  • rotateX(angle)
  • rotateY(angle)
  • rotateZ(angle)
  • translateX(x)
  • translateY(y)
  • trasnlateZ(z)

其分别表示

  • 绕X轴旋转
  • 绕Y轴旋转
  • 绕Z轴旋转
  • 沿X轴平移
  • 沿Y轴平移
  • 沿Z轴平移

其写法例如:

transform: rotateX(20deg) translateZ(300px)

2. 轴?

轴的简单认识

说实话我第一次看见这个图的时候也是很难理解,也是多亏了张鑫旭老师的简单易懂的例子,加上之后自己的一些实践才慢慢掌握。

1. x轴,y轴

假设我们此时正面向电脑,目光直视电脑屏幕的正中。

面向电脑

红线即代表X轴,黄线就代表Y轴。

沿X轴平移就表示一个物体在屏幕上进行左右方向上的移动。同理可以想象沿Y轴平移

沿X轴旋转,则可以想象我的电脑屏幕,以红线为转轴进行转动。同理可以想象沿Y轴旋转

2. z轴

z轴概念有些抽象。我们可以想象有一根坐标轴从电脑屏幕的正中,垂直于电脑屏幕向外射出,这就是Z轴。

沿Z轴平移,直观的说就是一个物体在你眼前忽近忽远。(将电脑拿近一点,其实就是电脑在沿着Z轴移动)

沿Z轴旋转,直观的说就是一个物体绕着你的视线旋转。(站在一个闹钟的前方,我们可以看见时针分针秒针正绕着Z轴不断旋转)

3. 从CSS上来看简单的3D效果

demo源代码

1. rotate旋转

rotate

2. translate平移

translate

3. perspective属性

1. 解读

perspective的中文意思为透视。

perspective属性的存在与否决定了你所看见的效果是2D的还是3D的。

在上面"从CSS上来看简单的3D效果"的例子中,如果我们把perspective属性全部删除,则看到的效果会变成这样

没有3d

这样就没有3D效果了。

perspective属性的值表示视距。简单的说,在上面的例子中,我将perspective属性的值设置成了300px,则这些物体的3d效果就相当于人眼在距离他们300px的位置上观察到的效果。

2. 再看translateZ

大家都知道,对于一个物体来说,人的直观感受就是“近大远小”。

在页面上,我们已经对一个元素实现了“透视”,那么怎么样才能让这个元素离我们更“近”呢?

答案很简单,就是通过translateZ属性。

在上文中讲过,translateZ表示将一个物体沿着Z轴平移,Z轴是垂直于电脑平面的轴,沿着Z轴平移的意思也就是将这个物体“拿近”或者“拿远”。

我们可以使用开发者工具对demo源代码里的translateZ元素进行修改,修改其translateZ的值,我们可以发现,这个元素的大小“变化”了。

修改translateZ大小变化

当然,这种大小变化并不是说这个元素真实的width和height发生了变化,而是反应出一种“靠近”和“远离”的变化。

当我们将translateZ的大小,改成299的时候,会发现这个元素铺满了整个屏幕。

299时铺满整个屏幕

这是因为,我们perspective的值设置的是300,你就想象,我离着300px的距离观察一个物体是这么大,当我离着1px的距离去观察这个物体,那这个物体应该会铺满我的整个视线。

当translateZ的值改为300或300以上,这个元素“消失”了。其实并不是消失,而是因为他沿Z轴平移到了我们的视距之外。

300时消失

3. 书写方案

对于perspective的值,有两种书写方案。

第一种是写在动画元素的父元素上,表示对展示动画元素的舞台,拥有一个视距。

例如:

.stage {
    perspective: 300px;
}

第二种是写在动画元素上,表示对于每一个动画元素,都拥有一个视距。

例如:

.block {
    transform: perspective(300px) rotateY(30deg);
}

其两种写法的效果,可以参考我实现的perspective书写demo

可以看出,这两种写法的效果是不同的。因为如果对于整个舞台我们有一个透视,那么其每个子元素的效果就会不一样。如果对于每个子元素都有一个透视,那么其展示效果就会相同(因为在demo中rotateY的值相同)。

4. perspective-origin

perspective-origin属性指的是默认我们所观测的中心点。默认是正中,我们也可以进行改变,比如:

perspective-origin:30px 30%

5. transform-style

transform-style属性很重要。在3d变换中,我们将其设置为

transform-style: preserve-3d

一般给做3D变换的父元素设置这个属性。如果不设置的话,视觉效果会展示2D的效果。

6. backface-visibility

该属性用于设置元素的背后是否可见,一般可以设置为

backface-visibility:hidden;

不可见。

3. 实现小动画

3D效果横竖就是前文说的那些属性,只要利用好,可以做出很多酷炫的效果。

1. 静态

我这里学习张鑫旭老师的结构,即

舞台
    容器
        block
        block
        block
        ...

就像上文说的那样,对于舞台我们先加一个视距

perspective: 800px

对于做3D变换的block的父元素容器,我们加上

transform-style: preserve-3d

使其展示效果为3D。

此时代码应该长这样

代码01

我们再加上9个小方块,并且给舞台,容器,方块设置一些必要的属性。

首先给小方块设置好长宽高,背景颜色,然后使用position:absolute让小方块重叠在一起,共用一个中心点。再给舞台和容器设置好一些长宽,位置的属性。因为观测的中心点(perspective-origin)默认是舞台(设置过perspective属性的元素)的正中,所以我们要让容器位于舞台正中,或者让舞台大小和容器大小一致。这里我选择大小一致的写法

代码02

最重要的要来啦!

接下来让小方框有3d效果!因为有9块方块,360 / 9 = 40,所以每个小方块的角度间隔为40°

代码03

然后看一下效果

效果01

好像有什么地方不对…

这时候应该想到,小方块都黏在了一起,实际效果是小方块应该距离中心有一个距离才对。

我们使用translateZ属性。

那么translateZ属性的值应该设置为多少呢?

我在这里先设置为180px。其实是有一个计算的公式的,只要设置的值大于等于我们计算出来的值就可以。大家可以自己想想如何计算。

代码04

看看效果

效果02

大功告成!静态3D效果完成啦!

2. 动态

让它动起来!

首先我们先实现一个绕Y轴旋转的动画。

代码05

然后给容器加上这个动画,让容器“动”起来!

代码06

之后,如果想实现像我那样一开始飞出的效果,就需要用js或者多定义一些动画来实现啦!

大家可以自己尝试实现一下~

3. Q&A

正在编辑

4. 请尽情使用吧!

****

Thanks for Reading

Jiahao.Zhang
NetEase Inc. Hangzhou 
        Front-End Developer