文章内包含个人理解,如有错误请指出。
往期文章
【CSS3】 float浮动与position定位常见问题(个人笔记)
详解 CSS3中最好用的布局方式——flex弹性布局(看完就会)
[前端CSS高频面试题]如何画0.5px的边框线(详解)
CSS3基础属性大全
CSS3动画属性 animation详解(看完就会)
CSS3 transform 2D转换之移动 旋转 缩放(详细讲解看完就会)
CSS3 Z—Index 详解
CSS3 positon定位详解(通俗易懂)
目录
前言
3D可以帮助我们实现更好的页面动画效果,我们生活的环境是 3D 的,照片就是 3D 物体在 2D 平面呈现的例子。
有什么特点
- 近大远小
- 物体后面遮挡不可见
当我们在网页上构建 3D 效果的时候参考这些特点就能产出 3D 效果。
教学
坐标轴
三维坐标系其实就是指立体空间,立体空间是由3个轴共同组成的。
在x,y轴的基础上,又增加了一条从外向内的Z轴,
移动
x 轴 | 水平向右(注意:x 右边是正值,左边是负值) |
y 轴 | 垂直向下(注意:y 下面是正值,上面是负值) |
z 轴 | 垂直屏幕(注意:往外面是正值,往里面是负值) |
注意重点:坐标轴原点为图形的左上角
<style>
#div1
{
position: relative;
height: 200px;
width: 200px;
margin: 100px;
padding:10px;
border: 1px solid black;
}
#div2
{
padding:50px;
position: absolute;
border: 1px solid black;
background-color: red;
transform: translateX(100px);
z-index: 1;
}
#div3
{
padding:50px;
position: absolute;
border: 1px solid black;
background-color: red;
}
</style>
</head>
<body>
<div id="div1">
<div id="div2">HELLO</div>
<div id="div3">HELLO</div>
</div>
</body>
左边的是原位置的,右边的是移动100px的。
3D 移动在 2D 移动的基础上多加了一个可以移动的方向,就是 z 轴方向。
- transform:translateX(100px):仅仅是在 X 轴上移动 (x轴右边)
- transform:translateY(100px):仅仅是在 Y 轴上移动 (Y轴下边)
- transform:translateZ(100px):仅仅是在 Z 轴上移动(注意:translateZ 一般用 px 单位,Z轴向外。)
- transform:translate3d(x, y, z):其中 x、y、z 分别指要移动的轴的方向的距离
因为 z 轴是垂直屏幕,由里指向外面,所以默认是看不到元素在 z 轴的方向上移动(要借助透视)。
旋转
<style>
#div1
{
position: relative;
height: 200px;
width: 200px;
margin: 100px;
padding:10px;
border: 1px solid black;
}
#div2
{
padding:50px;
position: absolute;
border: 1px solid black;
background-color: green;
transform: rotateX(100deg);
z-index: 1;
}
#div3
{
padding:50px;
position: absolute;
border: 1px solid black;
background-color: red;
}
</style>
</head>
<body>
<div id="div1">
<div id="div2">HELLO</div>
<div id="div3">HELLO</div>
</div>
</body>
以x轴旋转100°,就是向里旋转100°,看着变窄了是因为没有使用透视,绕Z轴旋转就跟2d旋转一样。
transform:rotate3d(0,1,0,45deg) 绕y轴旋转45°,前三位分别是 xyz ,写1就是选择某个坐标轴, 第四位写度数。
矢量旋转:transform:rotate3d(1,1,0,45deg) 第四域的对角线旋转45°。
注意重点:坐标轴原点为图形的中心点,实际上是由左上角的原点,通过transform-origin:50% 50% ;移动到了图形的中心点,transform-origin的默认值就是 50% 505 0;我们可以通过transform-origin属性来改变原点的位置, 注意中的注意就是 这个属性只是改变旋转的中心点,translate移动的的中心点不变,依然是左上角的。
透视
在 2D 平面产生近大远小视觉立体,但是效果只是二维的。
- 如果想要在网页产生 3D 效果需要透视(理解成 3D 物体投影在 2D 平面内)
- 模拟人类的视觉位置,可认为安排一只眼睛去看
- 透视我们也称为视距:视距就是人的眼睛到屏幕的距离
- 距离视觉点越近的,在电脑平面成像越大,越远成像越小
- 透视的单位是像素
我们给之前的3dX旋转加上透视效果,
<style>
#div1
{
position: relative;
height: 200px;
width: 200px;
margin: 100px;
padding:10px;
border: 1px solid black;
perspective: 500px;
}
#div2
{
padding:50px;
position: absolute;
border: 1px solid black;
background-color: green;
transform: rotateX(100deg);
z-index: 1;
}
#div3
{
padding:50px;
position: absolute;
border: 1px solid black;
background-color: red;
}
</style>
</head>
<body>
<div id="div1">
<div id="div2">HELLO</div>
<div id="div3">HELLO</div>
</div>
</body>
这样在平面上通过透视产生一种长短大小不一的3d效果。
perspective就相当于人眼到图像的距离,就相当于你看某个东西,你距离写的越大,你就站的越远,物体就越小,站的越近,距离写的越小,物体越大。
页面上显示的就相当于是你看到的物体的投影。
perspective尽可能写在直接父级上,写在大于父亲级的祖元素上有可能会失灵,但如果搭配transform-style: preserve-3d,两个一起用,又会起作用。
perspective只是实现了2d里的3d视觉显示,并不是一个3d空间,就比如前面的div向里倾斜,如果是3d的空间的话 那么会穿透后面的红色盒子,如何达到真正的3d效果呢 就是接下来要说的的属性。
打开3D空间
transform-style: preserve-3d;
看例子
<style>
#div1 {
position: relative;
height: 200px;
width: 200px;
margin: 100px;
padding: 10px;
border: 1px solid black;
perspective: 300px;
transform-style: preserve-3d;
transition: all 3s;
}
#div1:hover {
transform: rotateY(-120deg);
}
#div2 {
padding: 50px;
position: absolute;
border: 1px solid black;
background-color: green;
transform: rotateX(60deg);
z-index: 1;
}
#div3 {
padding: 50px;
position: absolute;
border: 1px solid black;
background-color: red;
}
</style>
</head>
<body>
<div id="div1">
<div id="div2">HELLO</div>
<div id="div3">HELLO</div>
</div>
</body>
下面是给box盒子加上透视的效果
总结
1.移动的中心点跟旋转中心点是分开的,transform-origin只是修改旋转的原点,移动位置不变依然是左上角。
2.3d旋转是坐标轴是跟随移动的,所以建议当完成某种效果时,先移动后旋转,先旋转改变坐标轴,移动的方向就会有差别。
3.想要完成一个3D效果 需要用到perspective: 500px;和 transform-style: preserve-3d;两个属性才能完全达到3D效果,注意perspective属性放在更高的父级上的效果区别,建议用在直接父级上。
案例
3D转换
<style>
* {
margin: 0;
padding: 0;
}
ul {
margin: 100px;
}
ul li {
width: 120px;
height: 35px;
list-style: none;
float: left;
margin-left: 10px;
text-align: center;
color: white;
}
.box {
position: relative;
width: 100%;
height: 100%;
perspective: 500px;
transform-style: preserve-3d;
transition: all 1s;
line-height: 35px;
}
.box:hover {
transform: rotateX(90deg);
}
.front,
.bottom {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
}
.front {
background-color: pink;
transform: translateZ(17.5px);
z-index: 1;
}
.bottom {
background-color: purple;
transform: translateY(17.5px) rotateX(-90deg);
}
</style>
</head>
<body>
<ul>
<li>
<div class="box">
<div class="front">黑马程序员</div>
<div class="bottom">pink老师</div>
</div>
</li>
<li>
<div class="box">
<div class="front">黑马程序员</div>
<div class="bottom">pink老师</div>
</div>
</li>
<li>
<div class="box">
<div class="front">黑马程序员</div>
<div class="bottom">pink老师</div>
</div>
</li>
<li>
<div class="box">
<div class="front">黑马程序员</div>
<div class="bottom">pink老师</div>
</div>
</li>
</ul>
</body>
3D翻转
<style>
.box {
width: 300px;
height: 300px;
margin: 100px auto;
position: relative;
transition: all 3s;
transform-style: preserve-3d;
}
.box:hover {
transform: rotateY(180deg);
}
.front {
backface-visibility: hidden;
}
.front,
.back {
position: absolute;
left: 0;
right: 0;
height: 100%;
border-radius: 50%;
color: #fff;
text-align: center;
font-size: 30px;
line-height: 300px;
}
.front {
background-color: pink;
z-index: 1;
}
.back {
background-color: purple;
transform: rotate3d(0, 1, 0, 180deg);
}
</style>
</head>
<body>
<div class="box">
<div class="front">黑马程序员</div>
<div class="back">pink老师</div>
</div>
</body>