详解用CSS绘制3D旋转立方体
前言
前段时间查询MDN的时候发现CSS里有一个实验中的属性叫
transform-style
,用来设置元素的子元素是位于 3D 空间中还是平面中,而这也是能够实现3D立方体的关键所在。那么既然是实验中的功能,自然会存在兼容性问题,然后发现🙄
最终效果展示
实现思路
呈现一个立方体需要六个面,上下,左右前后,每个面都代表着一个div,这里我们使用伪类元素来设置上下两个元素,因为左右前后四个面都是成90deg,所以我们使用CSS变量来控制他们的角度的旋转。
现在我们就需要在父元素上设置transform-style: preserve-3d;
从而让子元素位于3D空间中。四个面通过Y轴的旋转组合而成,上下元素通过一个div元素及伪类元素设置,不要忘记translateZ()
定义Z轴的3D转换。
最后是旋转的动画,Y轴方向360deg的旋转,X轴沿着坐标系反向旋转一定角度,只有一个方向的旋转都是平面的旋转。
代码示例
//HTML
<body>
<div class="cube">
<div class="top"></div>
<div>
<span style="--i: 0"></span>
<span style="--i: 1"></span>
<span style="--i: 2"></span>
<span style="--i: 3"></span>
</div>
</div>
</body>
//CSS
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
display: flex;
min-height: 100vh;
overflow: hidden;
justify-content: center;
align-items: center;
background: #050505;
}
.cube {
position: relative;
width: 300px;
height: 300px;
transform-style: preserve-3d;
animation: animate 4s linear infinite;
}
@keyframes animate {
0% {
transform: rotateX(-30deg) rotateY(0deg);
}
100% {
transform: rotateX(-30deg) rotateY(360deg);
}
}
.cube div {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
transform-style: preserve-3d;
}
.cube div span {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(#151515, #00ec00);
transform: rotateY(calc(90deg * var(--i))) translateZ(150px);
}
.top {
position: absolute;
top: 0;
left: 0;
width: 300px;
height: 300px;
background: #222;
transform: rotateX(90deg) translateZ(150px);
}
.top::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 300px;
height: 300px;
background: #0f0;
transform: translateZ(-380px);
filter: blur(20px);
box-shadow: 0 0 120px rgba(0, 255, 0, 0.2), 0 0 200px rgba(0, 255, 0, 0.4),
0 0 300px rgba(0, 255, 0, 0.6), 0 0 400px rgba(0, 255, 0, 0.8),
0 0 500px rgba(0, 255, 0, 1);
}
注意点总结
transform-style
在官方中的正式用法有flat | preserve-3d
,flat
设置元素的子元素位于该元素的平面中,元素的子元素将不会有 3D 的遮挡关系。preserve-3d
指定元素的子元素位于 3D 空间中。需要注意的是,该属性不会被继承,因此必须为元素的所有非叶子子元素设置它。- CSS声明变量的时候要在前面加两根连横线(--),比如代码中的--i。Sass中使用$,Less中使用@,值得一提的是变量名大小写是敏感的。
var()
函数用于读取变量,比如代码中的var(--i)
,该函数还能接受第二个值作为该变量的默认值,如果变量不存在,就会使用这个默认值。var()
函数还能用于变量的声明,但是变量值只能用于属性值,不能用于属性名。
//正确做法
.root{
--primary-color:green;
--i:var(--primary-color);
}
//错误做法
.root{
--primary-color:background-color;
--i:var(--primary-color);
}
3.如果CSS变量值是数值,不能直接与数值单位直接连用,必须使用calc()
函数将他们连接。比如代码中的calc(90deg * var(--i))
。如果变量值有单位,就不能使用字符串的形式。
//正确做法
.root{
--primary-size:20;
margin-top:calc(var(--primary-size)*1px);
}
.root{
--primary-size:20px;
margin-top:var(--primary-size);
}
//错误做法
.root{
--primary-size:20;
margin-top:var(--primary-size)px;
}
.root{
--primary-size:'20px';
margin-top:var(--primary-size);
}
转载自:https://juejin.cn/post/7071647395389538317