在日常的网络生活中,我们经常会看到一些土味相册,尤其是父母辈的朋友圈通过各种链接去制作各种花里胡哨的土味相册集,今天我们就利用css3制作一个立方体的土味相册。
制作3D立方体首先需要了解一个在摄影里面的一个重要概念:景深
在摄影中镜头焦距越长景深越浅、反之景深越深。主体越近,景深越浅,主体越远,景深越深。
而在css3中制作3D图形也有这个类似概念,即perspective:
注意:perspective 属性只影响 3D 转换元素。
近大远小的效果可以如图:
perspective需要结合perspective-origin等其它属性来设置立方体。
使用transform-style属性设置preserve-3d让当前元素形成一个3D的空间。然后充分利用translate位移和旋转进行展现。
首先观察立方体,立方体的六个不同面需要全部存放在一个容器内,将这个容器设置为一个3D的空间
HTML代码,设置盒子并且存放六个面
<div class="cube">
<!-- 正面 -->
<span class="front"></span>
<!--后面 -->
<span class="back"></span>
<!-- 左面 -->
<span class="left"></span>
<!-- 右面 -->
<span class="right"></span>
<!-- 上面 -->
<span class="top"></span>
<!-- 下面 -->
<span class="bottom"></span>
</div>
CSS代码:将盒子设置为3D
.cube{
width: 200px;
height: 200px;
position: relative;
transform-style: preserve-3d;
}
然后将每个面通过旋转,位移等方式,拼接成一个立方体,并且通过img标签放上我们的照片。
.cube>span{
display: block;
width: 200px;
height: 200px;
border: 2px solid pink;
position: absolute;
left: 50px;
top: 50px;
opacity: .8;
transition: all 3s;
}
.cube span.front{
/*设置前面的这一面在z轴上的移动*/
transform: translateZ(100px);
}
.cube span.back{
/*设置后面的那一面在Z轴上的后退*/
transform: translateZ(-100px);
}
.cube span.left{
transform: translateX(-100px) rotateY(-90deg);
}
.cube span.right{
transform: translateX(100px) rotateY(90deg);
}
.cube span.top{
transform: translateY(-100px) rotateX(90deg);
}
.cube span.bottom{
transform: translateY(100px) rotateX(-90deg);
}
此时呈现的效果,似乎只能看到前面的一张图,但其实只是其他面没有在我们的视线里呈现出来。
为了让其他面也能够很好的呈现,我们接下来设置动画效果,让立方体动起来。
给所有的元素套上一个大盒子,并且设置perspective。
.wrapper{
width: 200px;
height: 200px;
margin-top: 100px;
perspective: 1000px;
margin: 200px auto;
}
.cube{
width: 200px;
height: 200px;
position: relative;
transform-style: preserve-3d;
transform: rotateX(-30deg) rotateY(-50deg) rotateZ(0deg) ;
animation: run 8s infinite linear;
}
@keyframes run{
0%{
transform: rotateX(0deg) rotateY(0deg) rotateZ(0deg) ;
}
100%{
transform: rotateX(720deg) rotateY(360deg) rotateZ(360deg) ;
}
}
通过上面动画的设置,可以很明显的看到立方体运动起来,并且开始呈现每一个面。
为了让相册不太过于单调,此时,我们加上hover效果
.cube:hover .front{
transform: rotateY(0deg) translateZ(200px);
}
.cube:hover .back{
transform: translateZ(-200px) rotateY(0deg);
}
.cube:hover .left{
transform: rotateY(-90deg) translateZ(200px);
}
.cube:hover .right{
transform: rotateY(90deg) translateZ(200px);
}
.cube:hover .top{
transform: rotateX(90deg) translateZ(200px);
}
.cube:hover .bottom{
transform: rotateX(-90deg) translateZ(200px);
}
最后我们制作的相册就如下:(图片来源于“一条小团团ovo”)
在最后,我们发现perspective理解上并不是清楚,单独的理解为人的视角距离元素的位置与值越小,元素越大并不准确。
body {
perspective: 1000px;
perspective-origin: center center;
height: 100%;
}
div {
position: absolute;
width: 100px;
height: 100px;
left: calc(50% - 50px);
top: calc(50% - 50px);
background-color: black;
transform: translatez(-100px);
}
设置一个盒子沿着z轴向屏幕后方偏移了100px。父级上设置了perspective的值为1000px。
但如果再把perspective设成300px,这个盒子居然看起来会更小。
这是因为我们所看到的是盒子在浏览器上的投影,浏览器的屏幕就如同电影院的幕布一样,而人的眼睛可以理解为放映时的光源。
当translateZ为正数时
当perspective的值越小,那么元素距离眼睛越近,投影出来的就越大。但是translateZ是负数时
perspective的值越小,那么眼睛距离元素会越近,但是我们看到的投影就会相应的变小。
以上就是perspective成像的原理,可以就很容易理解。