▊ 透视(perspective)
- 视距是眼睛到屏幕的距离——近大远小
- 透视写在被观察元素的父盒子上
- z是物体到屏幕的距离(z可以是负值)
- 通常都是给父盒子加
perspective
固定视角,然后修改子元素的translateZ
▊ 3D移动(translate3d)
transform: translateX(n);
transform: translateY(n);
transform: translateZ(n);
transform: translate3d(x, y, z);
▊ 3D旋转(rotate3d)
transform: rotateX(n);
transform: rotateY(n);
transform: rotateZ(n);
transform: rotate3d(x, y, z, n); /*前三个参数是定义轴的矢量,最后一个参数是角度*/
- 单位为deg(度)
- 加上透视(perspective)后才有立体的效果
- 翻转方向根据左手准则:左手拇指指向轴的方向,其他手指的弯曲方向就是翻转的方向
- 旋转轴是在中间(无论是x还是y)
- 一个盒子旋转后,xyz轴是重新建立的;这也是有时我们需要先位移再旋转,有时先旋转再位移的原因
▊ 3D呈现(transform-style)
- 控制子元素是否开启三维立体环境
transform-style: flat
默认值,不开启3d立体空间transform-style: preserve-3d
子元素开启立体空间 ( 这尤其有必要!!!)- transform-style加在父级盒子上,但影响的实际上是子盒子
▊ 一些经典的案例
▶ 两面的硬币翻转
/* 基本思路是,两面背靠背贴在一起,共同组成一个box盒子;3D旋转时,转的是这个box盒子 */
.father {
perspective: 1000px; /* 视差写在做3d效果的盒子的父盒子中 */
}
.box {
position: relative;
margin: 200px auto;
width: 300px;
height: 300px;
transition: all .5s;
transform-style: preserve-3d; /* 为了保留子盒子(back面的立体空间,必须在back的父盒子加上这句) */
}
.box:hover {
transform: rotateY(180deg);
}
.front,
.back {
position: absolute; /* 两个盒子叠压在一起,需要用绝对定位(让它们都脱标) */
top: 0;
left: 0;
width: 100%;
height: 100%;
color: #fff;
font-size: 30px;
line-height: 300px;
text-align: center;
border-radius: 50%;
}
.front {
background-color: pink;
z-index: 1; /* 让front压在back上面 */
}
.back {
background-color: skyblue;
transform: rotateY(180deg); /* 为了让front和back盒子背靠背组成box,需要让底下的那个先原地反转180;这样box被翻转后front面才是正的 */
}
<!-- front盒子和back盒子是box盒子的两个子盒子;为了给box加上视差,还需要一个父级盒子 -->
<div class="father">
<div class="box">
<div class="front">萝莉</div>
<div class="back">赛高!!</div>
</div>
</div>
▶ 立方体翻转
/* ★☆★ */
/* 这类鼠标悬浮时的翻转效果的思路都是一样的 */
/* 用多个盒子(面)组成一个box,转的是box;还要给box加个transform-style;给box的父盒子加个透视 */
/* 旋转的是box这个整体 —— 这个整体由多个盒子作为面组合而成 */
/* 至于怎样组成,就是先把这些面先脱标(绝对定位)重合在一起,再进行旋转、移位组成整体 */
/* 需要注意的是旋转轴的位置?以及先旋转再位移?先位移再旋转? 发挥下空间想象力! */
ul li {
width: 120px;
height: 35px;
list-style: none;
perspective: 500px; /* 旋转的是box,因此透视加在li上(依据继承性,front和bottom盒子也能有视差效果) */
}
.box {
position: relative;
width: 100%;
height: 100%;
transform-style: preserve-3d;
transition: all .5s;
}
.box:hover {
transform: rotateX(90deg);
}
.front,
.bottom {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
}
.front {
background-color: pink;
z-index: 1;
transform: translateZ(17.5px)
}
.bottom {
background-color: skyblue;
transform: translateY(17.5px) rotateX(-90deg);
/* 注意移动和旋转的次序,顺序会影响结果的 */
/* 注意这里rotatX一定是负值,自己画一下图 */
}
<ul>
<li>
<div class="box">
<div class="front"></div>
<div class="bottom"></div>
</div>
</li>
</ul>
▶ “旋转木马”展示图片
/* 上面那两个都是鼠标hover时的效果,这个效果是做个动画 */
.father {
perspective: 12000px; /* 给box的父盒子加个透视 */
}
.box {
position: relative;
width: 360px;
height: 270px;
margin: 200px auto;
transform-style: preserve-3d; /* box加这句,开启子盒子的立体空间 */
animation: rotate 8s linear infinite; /* 动画名为rotate,线性匀速,无限 */
}
@keyframes rotate {
/* 这个动画效果是加在box上的,旋转的是box这个整体——这个整体由多个盒子作为面组合而成 */
0% {
transform: rotateY(0);
}
100% {
transform: rotateY(360deg)
}
}
.box div {
position: absolute; /* 和前两个效果一样,这些面先脱标,重合在一起,然后再变换、组合成box(一个整体) */
left: 0;
top: 0;
width: 100%;
height: 100%;
background: url(lolisuki.jpg) no-repeat;
}
/* 6个盒子,每个60 deg ; 先旋转再移动,因为旋转后每个面的xyz是重置的*/
.box div:nth-child(1) {
transform: rotateY(0) translateZ(400px);
}
.box div:nth-child(2) {
transform: rotateY(60deg) translateZ(400px);
}
.box div:nth-child(3) {
transform: rotateY(120deg) translateZ(400px);
}
.box div:nth-child(4) {
transform: rotateY(180deg) translateZ(400px);
}
.box div:nth-child(5) {
transform: rotateY(240deg) translateZ(400px);
}
.box div:nth-child(6) {
transform: rotateY(300deg) translateZ(400px);
}
<!-- 经典的三层盒子 -->
<div class="father">
<div class="box">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</div>
☀ 注
文章案例改编自《黑马程序员-web前端》
&Lolisaikou