本贴最后更新于 700 天前,其中的信息可能已经沧海桑田

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. 请尽情使用吧!

  • B3log

    B3log 是一个开源组织,名字来源于“Bulletin Board Blog”缩写,目标是将独立博客与论坛结合,形成一种新的网络社区体验,详细请看 B3log 构思。目前 B3log 已经开源了多款产品:PipeSoloSymWide 等,欢迎大家加入,贡献开源。

    3309 引用 • 3947 回帖 • 654 关注
  • 教程
    83 引用 • 306 回帖 • 3 关注
  • 前端

    前端技术一般分为前端设计和前端开发,前端设计可以理解为网站的视觉设计,前端开发则是网站的前台代码实现,包括 HTML、CSS 以及 JavaScript 等。

    156 引用 • 1122 回帖 • 1 关注
  • CSS

    CSS(Cascading Style Sheet)“层叠样式表”是用于控制网页样式并允许将样式信息与网页内容分离的一种标记性语言。

    70 引用 • 292 回帖
感谢    关注    收藏    赞同    反对    举报    分享