css3带你实现3D转换效果

  • A+
所属分类:Web前端
摘要

在css3中允许使用3D转换来对元素进行格式化,在原本只是2D转化的平面中引入了Z轴。在这之前我们讲解了css3中的2D转换 ,也就是二维空间变换,本篇的3D转换就是基于原来的2D转换而来,与2D转换的功能相似。


前言

在css3中允许使用3D转换来对元素进行格式化,在原本只是2D转化的平面中引入了Z轴。在这之前我们讲解了css3中的2D转换,也就是二维空间变换,本篇的3D转换就是基于原来的2D转换而来,与2D转换的功能相似。

三维坐标系

相信学过数学的效果版对这一概念多多少少是知道的,我们要想有一个3D空间效果,也就是立体空间感,比如:正方体、长方体.....再比如我们生活所居住的房间也是3D立体空间的,主要有X轴、Y轴Z轴共同组成

css3带你实现3D转换效果

x轴 : 水平向右,x右边是正值,左边是负值。

y轴 : 垂直向下,y下面是正值,上面是负值。

z轴 : 垂直屏幕,往外面是正值,往里面是负值。

 

转换属性

属性 描述
transform 使得元素向2D或3D转换
transform-origin 改变转换元素的位置
transform-style 规定被嵌套元素如何在 3D 空间中显示
perspective 规定 3D 元素的透视效果
perspective-origin 规定 3D 元素的底部位置
backface-visibility 定义元素在不面对屏幕时是否可见

这里transform 属性和transform-origin 属性在前一篇《有趣的transform形变》中已经讲解了,这里就不再细说。不同的是在3D转换中,transform-origin 属性会接收第三个值,表示Z轴方向位置

(1)transform-style

transform-style 设置元素的子元素是位于 3D 空间中还是平面中。

语法:

div{     transform-style: flat|preserve-3d; }

  • flat:设置元素的子元素位于该元素的平面中(子元素不设置3D空间)
<!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <meta name="viewport" content="width=device-width, initial-scale=1.0">     <meta http-equiv="X-UA-Compatible" content="ie=edge">     <title>Document</title>     <style>         .box{             position: relative;             width: 200px;             height: 200px;             margin: 100px auto;             transition: .5s;             /* flat:子元素不存在3D空间 */             transform-style: flat;             background-color: #eee;         }         .box:hover{             transform: rotateY(60deg);         }         .s{             position: absolute;             top: 0;             left: 0;             width: 100%;             height: 100%;             background-color: pink;         }         .s2{             background-color: orange;             transform: rotateX(45deg);         }     </style> </head> <body>     <div class="box">         <div class="s s1"></div>         <div class="s s2"></div>     </div> </body> </html>

设置flat值,子元素就只位于平面中,效果如下:

css3带你实现3D转换效果

  • preserve-3d:设置元素的子元素应用于3D空间中

基于上述栗子,将transform-style 属性值改为preserve-3d :

.box{   /* 让子元素保持3d立体空间环境 */   transform-style: preserve-3d; }

得到3D空间效果:

css3带你实现3D转换效果

3D视觉是不是感觉一下就来啦~

(2)perspective

perspective指定了观察者与 z=0 平面的距离,使具有三维位置变换的元素产生透视效果。如果不指定透视,则Z轴空间中的所有点将平铺到同一个2D视平面中,并且变换结果中将不存在景深概念

z>0 的三维元素比正常大,而 z<0 时则比正常小,大小程度由该属性的值决定

“perspective”本身就具有透视的意思,就是设置用于户和元素3D空间Z平面之间的距离(视距),简单理解就是将电脑屏幕当做一个平面,用户眼睛到屏幕的垂直方向。值越大用户与屏幕距离越远,视觉效果很小,值越小3D效果就越明显。

css3带你实现3D转换效果

语法

div{    perspective:none | <length> }

  • none:默认值,与 0 相同,不设置透视
  • length:元素距离视图的距离,以像素

这里还是以上述栗子进行演示:

body{     perspective: 900px; } 

或者

.box{     perspective: 900px; }

只要设置在父盒子上就可以,效果如下:

css3带你实现3D转换效果

从第一眼就可以看出与上面不同,没有设置景深是这样:

css3带你实现3D转换效果

 设置了景深是这样的:

css3带你实现3D转换效果

 注意perspective属性只影响 3D 转换元素,并且同时使用perspective-origin 属性,可以改变 3D 元素的底部位置

(3)perspective-orgin

perspective-origin 属性定义 3D 元素所基于的 X 轴和 Y 轴。该属性允许您改变 3D 元素的底部位置。

语法

perspective-origin: x-axis y-axis;

x-position:指定消失点的横坐标,其值有以下形式:

  • <length-percentage> 长度值或相对于元素宽度的百分比值,可为负值。
  • left, 关键字,0值的简记。
  • center, 关键字,50%的简记。
  • right, 关键字,100%的简记。

y-position:指定消失点的纵坐标,其值有以下形式:

  • <length-percentage> 长度值或相对于元素高度的百分比值,可为负值。
  • top, 关键字,0值的简记。
  • center, 关键字,50%的简记。
  • bottom, 关键字,100%的简记

介绍完语法使用,我们知道了怎么取值,下面还是基于上述例子继续演示:

  • 值为长度值:
.box{     perspective-origin: 300px; }

效果如下:

css3带你实现3D转换效果

  • 值为关键字:
.box{     perspective: 900px;     perspective-origin: left; }

效果如下:

css3带你实现3D转换效果

  • 值为百分比:
.box{     perspective: 900px;     perspective-origin: 300%; }

效果如下:

css3带你实现3D转换效果

  • 两个值:
.box{     perspective: 900px;     perspective-origin: left top; }

效果如下:

css3带你实现3D转换效果

(4)backface-visibility

backface-visibility 指定当元素背面朝向观察者时是否可见

元素的背面是其正面的镜像,虽然在 2D 中不可见,但是当变换导致元素在 3D 空间中旋转时,背面可以变得可见。 (此属性对 2D 变换没有影响,它没有透视。)

语法:

backface-visibility: visible|hidden;

  • visible:默认值。 背面是可见的。
  • hidden:背面是不可见的

这里借鉴了MDN上面的例子:

css3带你实现3D转换效果css3带你实现3D转换效果

<!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <meta name="viewport" content="width=device-width, initial-scale=1.0">     <meta http-equiv="X-UA-Compatible" content="ie=edge">     <title>Document</title>     <style>         .showbf div {           backface-visibility: visible;         }                  .hidebf div {           backface-visibility: hidden;         }         .container {           width: 150px;           height: 150px;           margin: 75px 0 0 75px;           border: none;         }                  .cube {           width: 100%;           height: 100%;           perspective: 550px;           perspective-origin: 150% 150%;           transform-style: preserve-3d;         }                  .face {           display: block;           position: absolute;           width: 100px;           height: 100px;           border: none;           line-height: 100px;           font-family: sans-serif;           font-size: 60px;           color: white;           text-align: center;         }                  .front {           background: rgba(0, 0, 0, 0.3);           transform: translateZ(50px);         }                  .back {           background: rgba(0, 255, 0, 1);           color: black;           transform: rotateY(180deg) translateZ(50px);         }                  .right {           background: rgba(196, 0, 0, 0.7);           transform: rotateY(90deg) translateZ(50px);         }                  .left {           background: rgba(0, 0, 196, 0.7);           transform: rotateY(-90deg) translateZ(50px);         }                  .top {           background: rgba(196, 196, 0, 0.7);           transform: rotateX(90deg) translateZ(50px);         }                  .bottom {           background: rgba(196, 0, 196, 0.7);           transform: rotateX(-90deg) translateZ(50px);         }                  th, p, td {           background-color: #EEEEEE;           margin: 0px;           padding: 6px;           font-family: sans-serif;           text-align: left;         }     </style> </head> <body>     <table>       <tr>         <th><code>backface-visibility: visible;</code></th>         <th><code>backface-visibility: hidden;</code></th>       </tr>       <tr>         <td>           <div class="container">             <div class="cube showbf">               <div class="face front">1</div>               <div class="face back">2</div>               <div class="face right">3</div>               <div class="face left">4</div>               <div class="face top">5</div>               <div class="face bottom">6</div>             </div>           </div>           <p>             Since all faces are partially transparent,             the back faces (2, 4, 5) are visible             through the front faces (1, 3, 6).           </p>         </td>         <td>           <div class="container">             <div class="cube hidebf">               <div class="face front">1</div>               <div class="face back">2</div>               <div class="face right">3</div>               <div class="face left">4</div>               <div class="face top">5</div>               <div class="face bottom">6</div>             </div>           </div>           <p>             The three back faces (2, 4, 5) are             hidden.           </p>         </td>       </tr>     </table> </body> </html>

View Code

 

3D转换

旋转单位:deg(角度)、rad(弧度)、grad(梯度)、turn(圈)

  • 弧度 = 角度*π/180

  • grad = 360度(一圈)

(1)3D位移

3D位移在2D基础上多加了一个可以z轴移动的方向

3D位移主要演示translateZtranslate3d两个属性:

translate3d() CSS 函数在3D空间内移动一个元素的位置,这个移动由一个三维向量来表达,分别表示他在三个方向上移动的距离

<!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <meta name="viewport" content="width=device-width, initial-scale=1.0">     <meta http-equiv="X-UA-Compatible" content="ie=edge">     <title>3D位移</title>     <style> body{     perspective: 800px; }  .box{     position: relative;     width: 200px;     height: 200px;     margin: 100px auto;     transition: .5s;     background-color: pink;     text-align: center;     line-height: 200px; } .box:hover{     /* transform: translateX(50px) translateY(100px) translateZ(200px); */     /* 简写 */     transform: translate3d(50px,100px,200px); }     </style> </head> <body>     <div class="box">3D位移</div> </body> </html>

效果如下:

css3带你实现3D转换效果

注意

  • 首先要设置perspectiv属性在被观察元素的父盒子上,不然不会有Z轴效果。
  • 如果只是单独设置Z轴视距,可以直接使用translateZ属性。
  • Z轴设置的值越大,距离我们眼睛就越近,也就是简单理解元素被放大了
  • Z轴设置的值越小,或者为负数,则会离我们眼睛越远,元素缩小

(2)3D旋转

rotateX:让元素围绕X轴转

rotateY:让元素围绕Y轴旋转

rotateZ:让元素围绕Z轴旋转

rotate3d:让元素围绕固定轴旋转不变形

旋转量由角度决定,角度为正则顺时针旋转,反之逆时针旋转

<!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <meta name="viewport" content="width=device-width, initial-scale=1.0">     <meta http-equiv="X-UA-Compatible" content="ie=edge">     <title>3D旋转</title>     <style> body{     perspective: 800px; }  .box{     position: relative;     width: 200px;     height: 200px;     margin: 100px auto;     transition: .5s;     background-color: pink;     text-align: center;     line-height: 200px; } .box:hover{     transform: rotateX(180deg); /* X轴旋转180° */     transform: rotateY(180deg); /* Y轴旋转180° */     transform: rotateZ(180deg); /* Z轴旋转180° */ }     </style> </head> <body>     <div class="box">3D旋转</div> </body> </html>

X轴旋转效果:

css3带你实现3D转换效果

Y轴旋转效果:

css3带你实现3D转换效果

Z轴旋转效果:

css3带你实现3D转换效果

这里单独将rotate3d函数拎出来讲

语法:

rotate3d(x, y, z, a)

取值分析:

  • x:可以是0到1之间的数值,表示旋转轴X坐标方向的矢量
  • y:可以是0到1之间的数值,表示旋转轴Y坐标方向的矢量
  • z:可以是0到1之间的数值,表示旋转轴Z坐标方向的矢量
  • a:表示旋转角度。正的角度值表示顺时针旋转,负值表示逆时针旋转

也就是说 rotateX(a) === rotate3d(1,0,0,a) 、 rotateY(a) === rotate3d(0,1,0,a) 、 rotateZ(a) === rotate3d(0,0,1,a) 

.box:hover{     transform: rotate3d(1,1,0,50deg); /* 表示在X轴和Y轴旋转50° */ }

效果如下:

css3带你实现3D转换效果

 

.box:hover{     transform: rotate3d(1,1,1,1turn); /* 围绕3轴旋转一圈 */ }

效果如下:

css3带你实现3D转换效果

 

综合案例

基于上述所学内容,我们来实操做一个3D盒子旋转:

 html结构 :

<!DOCTYPE html> <html lang="zh-CN">     <head>         <meta charset="UTF-8" />         <meta name="viewport" content="width=device-width, initial-scale=1.0" />         <title>3D盒子旋转</title>         <link rel="stylesheet" href="css/index.css" />     </head>     <body>         <section>             <div><img src="images/1.jpg" alt="" /></div>             <div><img src="images/2.jpg" alt="" /></div>             <div><img src="images/3.jpg" alt="" /></div>             <div><img src="images/4.jpg" alt="" /></div>             <div><img src="images/5.jpg" alt="" /></div>             <div><img src="images/6.jpg" alt="" /></div>             <div><img src="images/1.jpg" alt="" /></div>             <div><img src="images/2.jpg" alt="" /></div>             <div><img src="images/3.jpg" alt="" /></div>             <div><img src="images/4.jpg" alt="" /></div>             <div><img src="images/5.jpg" alt="" /></div>             <div><img src="images/6.jpg" alt="" /></div>         </section>     </body> </html>

 css部分 :

* {     /* 初始化 */     padding: 0;     margin: 0; } body {     /* 弹性布局*/     display: flex;     justify-content: center;     align-items: center;     height: 100vh;     /* 视距 */     perspective: 1000px; } section {     position: relative;     width: 150px;     height: 150px;     /* 让子元素保留其3D位置 */     transform-style: preserve-3d;     /* 动画 名称 时长 linear 是匀速运动 infinite是无限次播放 */     animation: rotate 5s linear infinite; } section div {     position: absolute;     top: 0;     left: 0;     width: 100%;     height: 100%;     background-color: #fff;     transition: all 1s; } section div img {     width: 100%;     height: 100%; } /* 这里使用的伪类选择器 */ section div:nth-child(1) { /* 选择第1个元素 */     transform: translateZ(75px); } section:hover div:nth-child(1) {     transform: translateZ(200px); } section div:nth-child(2) { /* 选择第2个元素 */     transform: rotateX(-180deg) translateZ(75px); } section:hover div:nth-child(2) {     transform: rotateX(-180deg) translateZ(200px); } section div:nth-child(3) { /* 选择第3个元素 */     transform: rotateX(90deg) translateZ(75px); } section:hover div:nth-child(3) {     transform: rotateX(90deg) translateZ(200px); } section div:nth-child(4) { /* 选择第4个元素 */     transform: rotateX(-90deg) translateZ(75px); } section:hover div:nth-child(4) {     transform: rotateX(-90deg) translateZ(200px); } section div:nth-child(5) { /* 选择第5个元素 */     transform: rotateY(90deg) translateZ(75px); } section:hover div:nth-child(5) {     transform: rotateY(90deg) translateZ(200px); } section div:nth-child(6) { /* 选择第6个元素 */     transform: rotateY(-90deg) translateZ(75px); } section:hover div:nth-child(6) {     transform: rotateY(-90deg) translateZ(200px); } section div:nth-child(7) { /* 选择第7个元素 */     transform: translateZ(75px); } section div:nth-child(8) { /* 选择第8个元素 */     transform: rotateX(-180deg) translateZ(75px); } section div:nth-child(9) { /* 选择第9个元素 */     transform: rotateX(90deg) translateZ(75px); } section div:nth-child(10) { /* 选择第10个元素 */     transform: rotateX(-90deg) translateZ(75px); } section div:nth-child(11) { /* 选择第11个元素 */     transform: rotateY(90deg) translateZ(75px); } section div:nth-child(12) { /* 选择第12个元素 */     transform: rotateY(-90deg) translateZ(75px); }  /* 定义动画 */ @keyframes rotate {     0% {         transform: rotateY(0) rotateX(0);     }     100% {         transform: rotateY(360deg) rotateX(360deg);     } }

 效果如下 

 css3带你实现3D转换效果