最新文章
泰课在线 | 微信拼团成功后如何获取课程?
08-09 17:57
Unity教程 | 使用ARKit为iOS开发AR应用
07-31 17:23
Unity Pro专业版7折订阅四选一工具包之VR开发与艺术设计
07-28 11:47
网友使用虚幻UE4实现CAVE 多通道立体渲染的沉浸式环境
07-27 11:57
VR晕动症调查:未来5年内大部分VR晕动症将得到解决
07-27 11:26
AMD CEO:未来3-5年最重要 希望5年达1亿VR用户
07-27 10:44
教你玩转 CSS3 3D 技术
CSS3 3D 起步
要玩转 CSS3 的 3D 技术,必须了解几个关键概念:透视(perspective)、旋转(rotate)和平移(translate)。
透视(perspective)
透视是指以现实视角看待屏幕上的 2D 事物,从而呈现出 3D 效果。在 CSS 中,perspective 属性用于模拟人眼与屏幕之间的距离,以此构建虚拟的 3D 场景。例如,perspective: 1000px 表示人眼与屏幕的距离为 1000 像素。当这个值较小时,物体看起来会更大且占据更多视线;随着距离增大,物体逐渐变小,立体感也随之增强。
旋转(rotate)
与 2D 平面上的旋转不同,CSS3 中的旋转是在三维坐标系中进行的,包括绕 X 轴、Y 轴和 Z 轴旋转。例如:
- 沿着 X 轴旋转
- 沿着 Y 轴旋转
- 沿着 Z 轴旋转
平移(translate)
平移同样是在三维坐标系中进行的,即物体可以在 X 轴、Y 轴和 Z 轴上移动。
透视相关属性详解
perspective
perspective 是实现 3D 效果的基础属性。若没有该属性,就无法形成 3D 效果。学过绘画的人应该对透视关系有所了解,CSS 中的 perspective 运用的就是相同原理。
perspective-origin
perspective-origin 用于指定视点的位置,即人眼视线的方向。默认情况下,视点位于中心,即 perspectice-origin: 50% 50%。第一个数值表示 3D 元素基于 X 轴的位置,第二个数值表示基于 Y 轴的位置。需要注意的是,当为元素定义 perspective-origin 属性时,其子元素会获得透视效果,而不是元素本身。该属性必须与 perspective 属性一同使用,且只影响 3D 转换元素(参考 W3school)。
transform-style
transform-style 属性决定了元素的子元素是在 2D 平面上呈现,还是在 3D 空间中呈现。其默认值为 flat,若要在元素上实现 3D 效果,必须将其设置为 preserve-3d,否则只会进行平面变换。
手把手带你玩转 CSS3 - 3D
第一步:HTML 结构
构建一个简单的 HTML 结构,使用一个容器包裹一个包含 6 个 piece 的 piece-box。
<div class="container">
<div class="piece-box">
<div class="piece piece-1"></div>
<div class="piece piece-2"></div>
<div class="piece piece-3"></div>
<div class="piece piece-4"></div>
<div class="piece piece-5"></div>
<div class="piece piece-6"></div>
</div>
</div>
第二步:添加必要的 3D 属性,进入 3D 世界
为容器和 piece-box 添加必要的 3D 属性。
/* 容器 */
.container {
-webkit-perspective: 1000px;
-moz-perspective: 1000px;
-ms-perspective: 1000px;
perspective: 1000px;
}
/* piece 盒子 */
.piece-box {
perspective-origin: 50% 50%;
-webkit-transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
-ms-transform-style: preserve-3d;
transform-style: preserve-3d;
}
第三步:加入必要的样式
为容器、piece-box 和 piece 添加样式。
/* 容器 */
.container {
-webkit-perspective: 1000px;
-moz-perspective: 1000px;
-ms-perspective: 1000px;
perspective: 1000px;
}
/* piece 盒子 */
.piece-box {
position: relative;
width: 200px;
height: 200px;
margin: 300px auto;
perspective-origin: 50% 50%;
-webkit-transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
-ms-transform-style: preserve-3d;
transform-style: preserve-3d;
}
/* piece 通用样式 */
.piece {
position: absolute;
width: 200px;
height: 200px;
background: red;
opacity: 0.5;
}
.piece-1 {
background: #FF6666;
}
.piece-2 {
background: #FFFF00;
}
.piece-3 {
background: #006699;
}
.piece-4 {
background: #009999;
}
.piece-5 {
background: #FF0033;
}
.piece-6 {
background: #FF6600;
}
完成这一步后,你可能只能看到一个正方形,即 piece-6,因为还未进行 3D 变换。
第四步:3D 变换来袭
实现走马灯的静态效果
要实现走马灯,首先让每个 piece 绕 Y 轴以递增 60 度的方式旋转。由于一个圆是 360 度,而我们有 6 个 piece,所以每个 piece 旋转 60 度。同时,为了将它们从中心拉开,需要改变 translateZ 的值。需要注意的是,当元素绕 Y 轴旋转后,X 轴和 Z 轴也会随之旋转,但正方体每个面的垂直线始终是 Z 轴。
.piece-1 {
background: #FF6666;
-webkit-transform: rotateY(0deg) translateZ(173.2px);
-ms-transform: rotateY(0deg) translateZ(173.2px);
-o-transform: rotateY(0deg) translateZ(173.2px);
transform: rotateY(0deg) translateZ(173.2px);
}
.piece-2 {
background: #FFFF00;
-webkit-transform: rotateY(60deg) translateZ(173.2px);
-ms-transform: rotateY(60deg) translateZ(173.2px);
-o-transform: rotateY(60deg) translateZ(173.2px);
transform: rotateY(60deg) translateZ(173.2px);
}
.piece-3 {
background: #006699;
-webkit-transform: rotateY(120deg) translateZ(173.2px);
-ms-transform: rotateY(120deg) translateZ(173.2px);
-o-transform: rotateY(120deg) translateZ(173.2px);
transform: rotateY(120deg) translateZ(173.2px);
}
.piece-4 {
background: #009999;
-webkit-transform: rotateY(180deg) translateZ(173.2px);
-ms-transform: rotateY(180deg) translateZ(173.2px);
-o-transform: rotateY(180deg) translateZ(173.2px);
transform: rotateY(180deg) translateZ(173.2px);
}
.piece-5 {
background: #FF0033;
-webkit-transform: rotateY(240deg) translateZ(173.2px);
-ms-transform: rotateY(240deg) translateZ(173.2px);
-o-transform: rotateY(240deg) translateZ(173.2px);
transform: rotateY(240deg) translateZ(173.2px);
}
.piece-6 {
background: #FF6600;
-webkit-transform: rotateY(300deg) translateZ(173.2px);
-ms-transform: rotateY(300deg) translateZ(173.2px);
-o-transform: rotateY(300deg) translateZ(173.2px);
transform: rotateY(300deg) translateZ(173.2px);
}
第五步:使用 animation 让 3D 动起来
要实现走马灯的动态效果,只需在 piece-box 上添加旋转动画,让其在 5 秒内从 0 度旋转到 360 度。
/* piece 盒子 */
.piece-box {
position: relative;
width: 200px;
height: 200px;
margin: 300px auto;
perspective-origin: 50% 50%;
-webkit-transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
-ms-transform-style: preserve-3d;
transform-style: preserve-3d;
animation: pieceRotate 5s;
-moz-animation: pieceRotate 5s; /* Firefox */
-webkit-animation: pieceRotate 5s; /* Safari and Chrome */
-o-animation: pieceRotate 5s; /* Opera */
}
/* 走马灯动画 */
@keyframes pieceRotate {
0% {
-webkit-transform: rotateY(0deg);
-ms-transform: rotateY(0deg);
-o-transform: rotateY(0deg);
transform: rotateY(0deg);
}
100% {
-webkit-transform: rotateY(360deg);
-ms-transform: rotateY(360deg);
-o-transform: rotateY(360deg);
transform: rotateY(360deg);
}
}
@-moz-keyframes pieceRotate {
0% {
-webkit-transform: rotateY(0deg);
-ms-transform: rotateY(0deg);
-o-transform: rotateY(0deg);
transform: rotateY(0deg);
}
100% {
-webkit-transform: rotateY(360deg);
-ms-transform: rotateY(360deg);
-o-transform: rotateY(360deg);
transform: rotateY(360deg);
}
}
@-webkit-keyframes pieceRotate {
0% {
-webkit-transform: rotateY(0deg);
-ms-transform: rotateY(0deg);
-o-transform: rotateY(0deg);
transform: rotateY(0deg);
}
100% {
-webkit-transform: rotateY(360deg);
-ms-transform: rotateY(360deg);
-o-transform: rotateY(360deg);
transform: rotateY(360deg);
}
}
@-o-keyframes pieceRotate {
0% {
-webkit-transform: rotateY(0deg);
-ms-transform: rotateY(0deg);
-o-transform: rotateY(0deg);
transform: rotateY(0deg);
}
100% {
-webkit-transform: rotateY(360deg);
-ms-transform: rotateY(360deg);
-o-transform: rotateY(360deg);
transform: rotateY(360deg);
}
}
正方体组装与旋转
正方体的实现思路
实现正方体并不复杂。可以先想象一个面,然后拓展其他面的实现方式。例如,将正方体的前面 translateZ(100px) 使其靠近我们 100 像素,后面 translateZ(-100px) 使其远离我们 100 像素;左边先 translateX(-100px) 再 rotateY(90deg),右边则是 translateX(100px) 再 rotateY(90deg);上面先 translateY(-100px) 再 rotateX(90deg),下面先 translateY(100px) 再 rotateX(90deg)。
CSS 代码示例(以 piece-1 为例)
.piece-1 {
background: #FF6666;
-webkit-transform: rotateY(0deg) translateZ(173.2px);
-ms-transform: rotateY(0deg) translateZ(173.2px);
-o-transform: rotateY(0deg) translateZ(173.2px);
transform: rotateY(0deg) translateZ(173.2px);
animation: piece1Rotate 5s 5s;
-moz-animation: piece1Rotate 5s 5s; /* Firefox */
-webkit-animation: piece1Rotate 5s 5s; /* Safari and Chrome */
-o-animation: piece1Rotate 5s 5s; /* Opera */
-webkit-animation-fill-mode: forwards; /* Chrome, Safari, Opera */
animation-fill-mode: forwards;
}
/* front */
@keyframes piece1Rotate {
0% {
-webkit-transform: rotateY(0deg) translateZ(173.2px);
-ms-transform: rotateY(0deg) translateZ(173.2px);
-o-transform: rotateY(0deg) translateZ(173.2px);
transform: rotateY(0deg) translateZ(173.2px);
}
100% {
-webkit-transform: rotateY(0deg) translateZ(100px);
-ms-transform: rotateY(0deg) translateZ(100px);
-o-transform: rotateY(0deg) translateZ(100px);
transform: rotateY(0deg) translateZ(100px);
}
}
@-moz-keyframes piece1Rotate {
0% {
-webkit-transform: rotateY(0deg) translateZ(173.2px);
-ms-transform: rotateY(0deg) translateZ(173.2px);
-o-transform: rotateY(0deg) translateZ(173.2px);
transform: rotateY(0deg) translateZ(173.2px);
}
100% {
-webkit-transform: rotateY(0deg) translateZ(100px);
-ms-transform: rotateY(0deg) translateZ(100px);
-o-transform: rotateY(0deg) translateZ(100px);
transform: rotateY(0deg) translateZ(100px);
}
}
@-webkit-keyframes piece1Rotate {
0% {
-webkit-transform: rotateY(0deg) translateZ(173.2px);
-ms-transform: rotateY(0deg) translateZ(173.2px);
-o-transform: rotateY(0deg) translateZ(173.2px);
transform: rotateY(0deg) translateZ(173.2px);
}
100% {
-webkit-transform: rotateY(0deg) translateZ(100px);
-ms-transform: rotateY(0deg) translateZ(100px);
-o-transform: rotateY(0deg) translateZ(100px);
transform: rotateY(0deg) translateZ(100px);
}
}
@-o-keyframes piece1Rotate {
0% {
-webkit-transform: rotateY(0deg) translateZ(173.2px);
-ms-transform: rotateY(0deg) translateZ(173.2px);
-o-transform: rotateY(0deg) translateZ(173.2px);
transform: rotateY(0deg) translateZ(173.2px);
}
100% {
-webkit-transform: rotateY(0deg) translateZ(100px);
-ms-transform: rotateY(0deg) translateZ(100px);
-o-transform: rotateY(0deg) translateZ(100px);
transform: rotateY(0deg) translateZ(100px);
}
}
这里使用了 animation-fill-mode: forwards; ,其作用是让 piece 保持动画最后的效果,即正方体的效果。若不添加该属性,动画结束后元素会恢复原样。
正方体的旋转
为了避免动画相互覆盖,在 HTML 结构中添加一个新的容器 piece-box2 包裹 piece。
<div class="container">
<div class="piece-box">
<div class="piece-box2">
<!-- 新加的容器 -->
<div class="piece piece-1"></div>
<div class="piece piece-2"></div>
<div class="piece piece-3"></div>
<div class="piece piece-4"></div>
<div class="piece piece-5"></div>
<div class="piece piece-6"></div>
</div>
</div>
</div>
在动画上,可以控制正方体动画的延时时间,即等到正方体组装完成后再开始旋转。
.piece-box2 {
-webkit-transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
-ms-transform-style: preserve-3d;
transform-style: preserve-3d;
animation: boxRotate 5s 10s infinite;
-moz-animation: boxRotate 5s 10s infinite; /* Firefox */
-webkit-animation: boxRotate 5s 10s infinite; /* Safari and Chrome */
-o-animation: boxRotate 5s 10s infinite; /* Opera */
}
/* 正方体旋转动画 */
@keyframes boxRotate {
0% {
-webkit-transform: rotateX(0deg) rotateY(0deg);
-ms-transform: rotateX(0deg) rotateY(0deg);
-o-transform: rotateX(0deg) rotateY(0deg);
transform: rotateX(0deg) rotateY(0deg);
}
100% {
-webkit-transform: rotateX(360deg) rotateY(360deg);
-ms-transform: rotateX(360deg) rotateY(360deg);
-o-transform: rotateX(360deg) rotateY(360deg);
transform: rotateX(360deg) rotateY(360deg);
}
}
@-moz-keyframes boxRotate {
0% {
-webkit-transform: rotateX(0deg) rotateY(0deg);
-ms-transform: rotateX(0deg) rotateY(0deg);
-o-transform: rotateX(0deg) rotateY(0deg);
transform: rotateX(0deg) rotateY(0deg);
}
100% {
-webkit-transform: rotateX(360deg) rotateY(360deg);
-ms-transform: rotateX(360deg) rotateY(360deg);
-o-transform: rotateX(360deg) rotateY(360deg);
transform: rotateX(360deg) rotateY(360deg);
}
}
@-webkit-keyframes boxRotate {
0% {
-webkit-transform: rotateX(0deg) rotateY(0deg);
-ms-transform: rotateX(0deg) rotateY(0deg);
-o-transform: rotateX(0deg) rotateY(0deg);
transform: rotateX(0deg) rotateY(0deg);
}
100% {
-webkit-transform: rotateX(360deg) rotateY(360deg);
-ms-transform: rotateX(360deg) rotateY(360deg);
-o-transform: rotateX(360deg) rotateY(360deg);
transform: rotateX(360deg) rotateY(360deg);
}
}
@-o-keyframes boxRotate {
0% {
-webkit-transform: rotateX(0deg) rotateY(0deg);
-ms-transform: rotateX(0deg) rotateY(0deg);
-o-transform: rotateX(0deg) rotateY(0deg);
transform: rotateX(0deg) rotateY(0deg);
}
100% {
-webkit-transform: rotateX(360deg) rotateY(360deg);
-ms-transform: rotateX(360deg) rotateY(360deg);
-o-transform: rotateX(360deg) rotateY(360deg);
transform: rotateX(360deg) rotateY(360deg);
}
}
最后,大功告成!你已经成功实现了酷炫的 CSS3 3D 效果。
关注“泰斗社区”,获取更多技术分享!