分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 教程案例

CSS3景深、三维变换属性及旋转三维立方体的实现

发布时间:2023-09-06 01:09责任编辑:赖小花关键词:CSS

浏览器坐标系

在讲正式语法之前,首先需要了解浏览器坐标系 
这需要我们把浏览器界面想象成一个立体的场景

这是网上流传很广的浏览器坐标系图片 
从左到右的方向是浏览器x轴的正方向 
从上到下的方向是浏览器y轴的正方向 
而z轴正方向是面对于我们的 
了解这个很重要,因为下面我们旋转元素需要借助它来理解

3D旋转

我们在平面中使用的旋转只是单纯的让元素在平面旋转一定角度 
在三维旋转中稍微要复杂一下 
属性当然还是用我们的transform 
三维旋转有下面三个函数分别对应三个维度的旋转

  • rotateX(xxdeg)
  • rotateY(xxdeg)
  • rotateZ(xxdeg)

rotateX是让元素绕着x轴旋转,角度越大,元素绕着x轴顺时针旋转 
类似于我们的单杠运动

transform: rotateX(45deg);
  • 1

rotateY是让元素绕着y轴旋转,角度越大,元素绕着y轴顺时针旋转 
类似于钢管舞运动..

transform: rotateY(45deg);
  • 1

rotateZ是让元素绕着z轴旋转,角度越大,元素绕着z轴顺时针旋转 
这就是我们在二维平面的旋转,类似于转盘

transform: rotateZ(45deg);
  • 1

其实3D旋转还有一个合成的函数是rotate3d(num,num,num,deg) 
用的不是很多,我就简单说一下 
参数并不是我们想那样的3个角度值 
而是三个数字一个角度值 
前三个数字分别表示绕x、y、z轴旋转的矢量值 
最后一个表示在空间的旋转角度,等价关系如下 
rotate3d(1,0,0,xxdeg) <==> rotateX(xxdeg) 
rotate3d(0,1,0,xxdeg) <==> rotateY(xxdeg) 
rotate3d(0,0,1,xxdeg) <==> rotateZ(xxdeg)

3D位移与3D缩放

我们在2D中用到translateX()和translateY()在平面移动 
3D中我们多了translateZ()允许我们沿着z轴平移 
同样可以使用合成函数translate3d(x,y,z) 
注意前两个值可以使用百分比形式,但是沿z轴平移的值只能使用长度值

同理我们的3D缩放 
scaleX(num)、scaleY(num)、scaleZ(num)、scale3d(num,num,num) 
至于它们的用法下面再通过例子来说 
(3D的倾斜属性是不存在的,换句话说,不存在skew3d函数)

透视/景深属性perspective

景深这个名词,维基百科是这样就解释的

景深(英语:Depth of field, DOF)景深是指相机对焦点前后相对清晰的成像范围。在光学中,尤其是录影或是摄影,是一个描述在空间中,可以清楚成像的距离范围。虽然透镜只能够将光聚到某一固定的距离,远离此点则会逐渐模糊,但是在某一段特定的距离内,影像模糊的程度是肉眼无法察觉的,这段距离称之为景深。当焦点设在超焦距处时,景深会从超焦距的一半延伸到无限远,对一个固定的光圈值来说,这是最大的景深。

(看到这里,我的手默默的离开了键盘,仰天长叹,心想,这到底要什么样的学历才能看得懂) 
我们可以这样来理解 
景深就是我们的肉眼距离显示器的距离 
景深越大,元素离我们越远,效果就不好 
在我们CSS3中,perspective用于激活一个3D空间 
属性值就是景深大小(默认none无景深) 
有两种用法

.stage { ???perspective: 500px;}
  • 1
  • 2
  • 3

应用景深的元素称为“舞台元素” 
舞台元素的所有后代元素都会受影响 
(如果后代元素中也添加了perspective属性,效果会叠加而不是覆盖)


<div class="stage"> ???<div class="demo"></div></div>
  • 1
  • 2
  • 3
.stage { ???width: 200px; ???height: 200px; ???border: 1px solid black; ???margin: 100px auto;}.stage .demo { ???width: 200px; ???height: 200px; ???background-color: orangered; ???transform: rotateX(45deg);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

在这个例子中,我们把内部元素绕x轴旋转了45°后 
由于他只是在二次元旋转,所以我们根本看不出来它旋转 
但是我们现在加个景深

.stage { ???width: 200px; ???height: 200px; ???border: 1px solid black; ???margin: 100px auto; ???perspective: 500px; /*增*/}.stage .demo { ???width: 200px; ???height: 200px; ???background-color: orangered; ???transform: rotateX(45deg);} ????
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

这就相当于我们在舞台元素的中心位置往里看,这个子元素距离我们肉眼有500px 
由于子元素的顺时针旋转, 
元素上半部分离我们远,所以看起来很小 
元素下半部分离我们近,所以看起来稍大 
这样就会产生很强的立体感


刚才我说道我们的肉眼相当于在舞台元素中心的位置 
其实这个“眼睛”的位置是可以调整的 
这用到了perspective-origin属性 
默认的属性值就是 50% 50% 
也就是舞台元素的中心位置 
我们可以尝试调整视角

.stage { ???width: 200px; ???height: 200px; ???border: 1px solid black; ???margin: 100px auto; ???perspective: 500px; ???perspective-origin: 10px 10px; /*增*/}.stage .demo { ???width: 200px; ???height: 200px; ???background-color: orangered; ???transform: rotateX(45deg);} ????
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

这就相当于在舞台元素的距离原点(左上)10px,10px的位置往里看 
理解这个需要我们一定的空间立体感

注意:景深大小一定要比你的动画元素大(我们不可能看到眼睛后面的东西)


景深的另一种用法,是应用在动画元素(不是舞台元素)变形的函数中 
和其他变形函数写在一起

.stage .demo { ???...... ???transform: rotateX(45deg) perspective(100px);}
  • 1
  • 2
  • 3
  • 4

3D属性transform-style

这个属性指定了子元素如何在空间中展示 
只有两个属性值:flat(默认)和preserve-3d 
flat 表示所有子元素在2D平面呈现 
preserve-3d 表示所有子元素在3D平面呈现 
(prederve是保护、维持的意思,preserve-3d就是保持三维空间的意思) 
当然如果我们想要3D的效果,就要使用 transform-style: preserve-3d;


这个属性只是针对设置属性元素的子元素如何展示 
而对子元素的子元素无效 
而且对于设置了overflow: hidden;的元素,设置3D效果会失效 
道理很简单,跳出了父元素平面的子元素无法显示了,结果自然还是2D效果 
应用于这个属性的元素我们称作“容器” 
这个属性我们下面通过一个例子再来体会

背面可见属性backface-visibility

通过这个元素我们可以指定当元素背对我们时是否可见 
只有两个属性值visibility(默认)和hidden 
如果我们希望元素背对我们不可见 
就这样设置

.demo { ???... ???backface-visibility: hidden;}
  • 1
  • 2
  • 3
  • 4

下面我通过一个例子来把上面讲到的属性全部实践一下

示例:旋转的三维立方体

<div class="stage"> ?<!--舞台元素,视角所在--> ???<ul class="three-d-box"> ??<!--动画容器,通过它来控制整个立方体--> ???????<li>?</li> ?<!--动画元素,立方体的六个面--> ???????<li>?</li> ???????<li>?</li> ???????<li>?</li> ???????<li>?</li> ???????<li>?</li> ???</ul></div>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
ul { ?/*调整ul标签的样式,取消内边距、外边距,和“点”样式*/ ???padding: 0; ???margin: 0; ???list-style-type: none;}.stage { ?/*设置舞台元素在屏幕居中,设置合适的景深大小*/ ???position: relative; ???width: 800px; ???height: 800px; ???margin: 100px auto; ???perspective: 800px;}@keyframes move { /*设置动画关键帧*/ ???0% { ???????transform: rotateX(0deg); ???} ???25% { ???????transform: rotateX(180deg); ???} ???50% { ???????transform: rotateX(360deg) rotateY(0deg); ???} ???75% { ???????transform: rotateX(360deg) rotateY(180deg); ???} ??????????100% { ???????transform: rotateX(360deg) rotateY(360deg); ???}}.stage .three-d-box { ?/*动画容器居中在舞台元素中间*/ ???width: 200px; ???height: 200px; ???position: absolute; ???left: 50%; ???top: 50%; ???margin: -100px 0 0 -100px; ???transform-style: preserve-3d; /*设置3D属性让子元素三维空间呈现*/ ???animation: move 3s linear infinite; /*设置动画*/}.stage .three-d-box>li { /*设置动画子元素公共属性*/ ???position: absolute; ???width: 200px; ???height: 200px; ???left: 0; ???top: 0; ???font-size: 50px; ???line-height: 200px; ???text-align: center; ???opacity: 0.5;}/*为了保证我们对立方体位置的控制,我们需要让动画容器在立方体的中间位置*/.stage .three-d-box>li:nth-child(1) { ???background-color: red; ???transform: translateZ(-100px);}.stage .three-d-box>li:nth-child(2) { ???background-color: greenyellow; ???transform: translateZ(100px);}.stage .three-d-box>li:nth-child(3) { ???background-color: cornflowerblue; ???transform: rotateX(90deg) translateZ(100px);}.stage .three-d-box>li:nth-child(4) { ???background-color: orangered; ???transform: rotateX(-90deg) translateZ(100px);}.stage .three-d-box>li:nth-child(5) { ???background-color: deeppink; ???transform: rotateY(90deg) translateZ(100px);}.stage .three-d-box>li:nth-child(6) { ???background-color: lightcoral; ???transform: rotateY(-90deg) translateZ(100px);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76

大功告成 
这样我们就会得到如下酷炫的三维立方体

注意在3D变换transform中,旋转与位移函数的顺序不同,元素展现的位置是不同的 
这是因为元素的坐标轴是随着我们变换而变化的

上面的代码如果有不明白的地方,可以拷贝到浏览器进行调试 
整体的思路就是

  1. 设置舞台元素(perspective:xxxpx)
  2. 设置动画容器(transform-style:preserve-3d)
  3. 通过旋转、位移调整动画子元素的位置
  4. 对动画容器应用动画效果

最后我们通过这个正方体来加深三维变换相关属性的理解 
backface-visibility 
添加样式前的正方体

现在我们来添加样式

.stage .three-d-box>li { ???...... ???backface-visibility: hidden;}
  • 1
  • 2
  • 3
  • 4

大家来找茬 
可以看到背对我们的元素全部看不见了 
这就是backface-visibility: hidden;的作用

还有一些旋转、缩放、平移的属性这里我就不再测试了 
大家可以打开控制台自己体会一下,和2D中的用法是类似的

CSS3景深、三维变换属性及旋转三维立方体的实现

原文地址:http://www.cnblogs.com/zhangrui09/p/7488777.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved