卡片是使用 3D 变换的良好起步,但它们只在使用过渡的时候展示 3D效果。为了在静止的状态下展示3D,我们必须创建真正的3D对象:棱柱体。我们将从一个立方体开始。
立方体的HTML结构和卡片类似。这次我们需要为立方体的所有 6 个面添加 6 个子元素。
<div class="scene"> <div class="cube"> <div class="cube__face cube__face--front">front</div> <div class="cube__face cube__face--back">back</div> <div class="cube__face cube__face--right">right</div> <div class="cube__face cube__face--left">left</div> <div class="cube__face cube__face--top">top</div> <div class="cube__face cube__face--bottom">bottom</div> </div> </div>
在容器里设置6 个面的基本的位置和尺寸样式,并让他们彼此叠加。
.scene { width: 200px; height: 200px; perspective: 600px; } .cube { width: 100%; height: 100%; position: relative; transform-style: preserve-3d; } .cube__face { position: absolute; width: 200px; height: 200px; }
所有面彼此覆盖,准备旋转。.cube__face--top
和.cube__face--bottom
将使用rotateX()
让它们垂直围绕X轴旋转。
.cube__face--front { transform: rotateY( 0deg); } .cube__face--right { transform: rotateY( 90deg); } .cube__face--back { transform: rotateY(180deg); } .cube__face--left { transform: rotateY(-90deg); } .cube__face--top { transform: rotateX( 90deg); } .cube__face--bottom { transform: rotateX(-90deg); }
(我们可以删除样式,因为此转换不起作用,但为了保持一致性,让我们将其保留下来。rotateY( 0deg)
现在面已旋转,只有正面和背面可见。4 个侧面都垂直于观察者的视角,因此它们显示在边缘几乎不可见。为了将它们推到适当的一侧,需要将它们从其位置的中心移出。立方体的每一边都是200px宽。从立方体的中心开始,它们需要平移出一半的距离,也就是100px
。
.cube__face--front { transform: rotateY( 0deg) translateZ(100px); } .cube__face--right { transform: rotateY( 90deg) translateZ(100px); } .cube__face--back { transform: rotateY(180deg) translateZ(100px); } .cube__face--left { transform: rotateY(-90deg) translateZ(100px); } .cube__face--top { transform: rotateX( 90deg) translateZ(100px); } .cube__face--bottom { transform: rotateX(-90deg) translateZ(100px); }
这里需要注意的是translate
函数紧随rotate
之后。转换函数的顺序是有意义的,每个面首先向其位置旋转,然后向外偏移。
我们已经渲染了一个立方体,但尚未完成。
再看一下上面立方体中的文本"front",效果是模糊的。
3D 转换会影响文本渲染。应用 3D 变换时,浏览器会拍摄元素的快照,然后在应用了 3D 变换的情况下重新渲染这些像素。因此,鉴于字体转换后的大小,字体没有相同的抗锯齿功能。
font-size: 2.5em transform: scale(2.5) transform: perspective(500px) translateZ(250px)
考虑到用户视觉感受,3D 变换不应扭曲界面。为了解决失真并恢复立方体的像素完美度,我们可以将 3D 对象向后推,这样正面将被定位回 Z 原点。
.cube { transform: translateZ(-100px); }
要暴露立方体的任何面,我们需要一种旋转立方体以显示该面的样式。我们在.cube
上切换必要的类以应用适当的转换。
.cube.show-front { transform: translateZ(-100px) rotateY( 0deg); } .cube.show-right { transform: translateZ(-100px) rotateY( -90deg); } .cube.show-back { transform: translateZ(-100px) rotateY(-180deg); } .cube.show-left { transform: translateZ(-100px) rotateY( 90deg); } .cube.show-top { transform: translateZ(-100px) rotateX( -90deg); } .cube.show-bottom { transform: translateZ(-100px) rotateX( 90deg); }
请注意转换函数的顺序是如何颠倒的。首先,我们用 translateZ
把对象向后推,然后旋转它。
最后,我们可以添加一个过渡来动画状态之间的旋转。
.cube { transition: transform 1s; }