CSS3 3D动画技术入门
先了解几个术语,透视(perspective)、旋转(rotate)和移动(translate)。
Perspective(透视)
透视即是以现实的视角来看屏幕上的2D事物,从而展现3D的效果。
在计算机世界怎么表达3D呢?
上方图可以辅助大家理解3D的透视perspective,黄色的是电脑或手机屏幕,红色是屏幕里的方块。CSS3 3D transform的透视点是在浏览器的前方。
3D坐标系
三维坐标系的旋转,包括X轴,Y轴,Z轴旋转。
3D Transform 中 rotate 有三种方法,rotateX(angle) X轴旋转,rotateY(angle) Y轴旋转,rotateZ(angle) Z轴旋转。参见下图:
理解平移起来就比较容易,就是在在X轴、Y轴、z轴移动。
CSS3中的变换函数(transform function)
CSS3中3D位移函数
CSS3中的3D位移主要包括translateZ()和translate3d()两个功能函数;
translate3d(tx,ty,tz)
ty:代表纵向坐标位移向量的长度;
tx:代表横向坐标位移向量的长度;
tz:代表Z轴位移向量的长度。此值不能是一个百分比值,如果取值为百分比值,将会认为无效值。
translateZ(t)
指的是Z轴的向量位移长度。
3D旋转函数
CSS3中的3D旋转主要包括rotateX()、rotateY()、rotateZ()和rotate3d()四个功能函数;
rotateX(a)
rotateX()函数指定一个元素围绕X轴旋转,旋转的量被定义为指定的角度;如果值为正值,元素围绕X轴顺时针旋转;反之,如果值为负值,元素围绕X轴逆时针旋转。
rotateY(a)
rotateY()函数指定一个元素围绕Y轴旋转,旋转的量被定义为指定的角度;如果值为正值,元素围绕Y轴顺时针旋转;反之,如果值为负值,元素围绕Y轴逆时针旋转。
rotateZ(a)
rotateZ()函数和其他两个函数功能一样的,区别在于rotateZ()函数指定一个元素围绕Z轴旋转
rotate3d(x,y,z,a)(建议取值0或1)
x:是一个0到1之间的数值,主要用来描述元素围绕X轴旋转的矢量值;
y:是一个0到1之间的数值,主要用来描述元素围绕Y轴旋转的矢量值;
z:是一个0到1之间的数值,主要用来描述元素围绕Z轴旋转的矢量值;
a:是一个角度值,主要用来指定元素在3D空间旋转的角度,如果其值为正值,元素顺时针旋转,反之元素逆时针旋转。
3D缩放函数
3D缩放:CSS3中的3D缩放主要包括scaleZ()和scale3d()两个功能函数;
简介: CSS3 3D变形中的缩放主要有scaleZ()和scale3d()两种函数,当scale3d()中X轴和Y轴同时为1,即scale3d(1,1,sz),其效果等同于scaleZ(sz)。通过使用3D缩放函数,可以让元素在Z轴上按比例缩放。默认值为1,当值大于1时,元素放大,反之小于1大于0.01时,元素缩小
scale3d()
sx:横向缩放比例;
sy:纵向缩放比例;
sz:Z轴缩放比例;
scaleZ(s)
s:指定元素每个点在Z轴的比例。
注:scaleZ()和scale3d()函数单独使用时没有任何效果,需要配合其他的变形函数一起使用才会有效果
【transform-function transform-function - CSS(层叠样式表) | MDN 】
CSS中与3D场景有关的属性(Properties)
perspective属性
指定了观察者与 z=0 平面的距离,使具有三维位置变换的元素产生透视效果。 z>0 的三维元素比正常大,而 z<0 时则比正常小,大小程度由该属性的值决定。
详见perspective - CSS(层叠样式表) | MDN
perspective-origin属性
指定了观察者的位置,用作 perspective 属性的消失点。观察3d元素的(位置)角度:
perspective-origin:center center (中心)
perspective-origin:left top (左上角)
perspective-origin:100% 100% (右下角)
详见perspective-origin - CSS(层叠样式表) | MDN
transform-style属性
transform-style属性是3D空间一个重要属性,指定嵌套元素如何在3D空间中呈现——3D 空间中还是平面中。主要有两个属性值:flat和preserve-3d
其中flat值为默认值,表示所有子元素在2D平面呈现。preserve-3d表示所有子元素在3D空间中呈现。
也就是说,如果对一个元素设置了transform-style的值为flat,则该元素的所有子元素都将被平展到该元素的2D平面中进行呈现。沿着X轴或Y轴方向旋转该元素将导致位于正或负Z轴位置的子元素显示在该元素的平面上,而不是它的前面或者后面。如果对一个元素设置了transform-style的值为preserve-3d,它表示不执行平展操作,他的所有子元素位于3D空间中。
详见transform-style - CSS(层叠样式表) | MDN
关键帧@keyframes是CSS的一种规则,可以用来定义CSS动画的一个周期的行为,创建简单的动画。
@keyframes参见 @keyframes - CSS(层叠样式表) | MDN
CSS @keyframes 规则 参见 CSS @keyframes 规则
CSS 动画属性(CSS Animation Properties)参见使用 CSS 动画 - CSS(层叠样式表) | MDN
有了前面的基础知识,下面给出示例
例1、源码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>CSS 3D示例</title>
<style>
ul { /*调整ul标签的样式,取消内边距、外边距,和“点”样式*/
padding: 0;
margin: 0;
list-style-type: none;
}
.stage { /*设置舞台元素在屏幕居中,设置合适的景深大小*/
position: relative;
width: 500px;
height: 400px;
margin: 100px auto;
perspective: 500px;
}
@keyframes move { /*设置动画关键帧*/
0% {
transform: rotateX(0deg);
}
25% {
transform: rotateX(180deg);
}
50% {
transform: rotateX(360deg) rotateY(0deg);
}
75% {
transform: rotateX(360deg) rotateY(180deg);
}
100% {
transform: rotateX(360deg) rotateY(360deg);
}
}
.stage .three-d-box { /*动画容器居中在舞台元素中间*/
width: 200px;
height: 200px;
position: absolute;
left: 50%;
top: 50%;
margin: -100px 0 0 -100px;
transform-style: preserve-3d; /*设置3D属性让子元素三维空间呈现*/
animation: move 3s linear infinite; /*设置动画*/
}
.stage .three-d-box>li { /*设置动画子元素公共属性*/
position: absolute;
width: 200px;
height: 200px;
left: 0;
top: 0;
font-size: 50px;
line-height: 200px;
text-align: center;
opacity: 0.5;
}
/*为了保证我们对立方体位置的控制,我们需要让动画容器在立方体的中间位置*/
.stage .three-d-box>li:nth-child(1) {
background-color: red;
transform: translateZ(-100px);
}
.stage .three-d-box>li:nth-child(2) {
background-color: greenyellow;
transform: translateZ(100px);
}
.stage .three-d-box>li:nth-child(3) {
background-color: cornflowerblue;
transform: rotateX(90deg) translateZ(100px);
}
.stage .three-d-box>li:nth-child(4) {
background-color: orangered;
transform: rotateX(-90deg) translateZ(100px);
}
.stage .three-d-box>li:nth-child(5) {
background-color: deeppink;
transform: rotateY(90deg) translateZ(100px);
}
.stage .three-d-box>li:nth-child(6) {
background-color: lightcoral;
transform: rotateY(-90deg) translateZ(100px);
}
</style>
</head>
<body>
<div class="stage"> <!--舞台元素,视角所在-->
<ul class="three-d-box"> <!--动画容器,通过它来控制整个立方体-->
<li>A</li> <!--动画元素,立方体的六个面-->
<li>B</li>
<li>C</li>
<li>D</li>
<li>E</li>
<li>F</li>
</ul>
</div>
<style>
#info {
position: fixed;
z-index: 999;
bottom: 20px;
left: 0px;
background: #222;
padding: 20px 30px;
color: #fff;
box-shadow: rgba(0, 0, 0, .5) 0 0 10px;
border-radius: 0 5px 5px 0;
font-size:16px;
}
#info a {
color: #0bf;
transition: .2s;
}
#info a:hover {
color: #6df;
}
</style>
</body>
</html>
保存文件名为:CSS_3D示例.html,运行效果如下:
下面再给出两个例子
例2、旋转的正四面体,源码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>CSS 3D - 正四面体</title>
<style>
.camera{
width:200px;
height:200px;
perspective-origin:50% 150%;
-moz-perspective-origin:50% 150%;
-webkit-perspective-origin:50% 150%;
perspective:500px;
-moz-perspective:500px;
-webkit-perspective:500px;
}
.space{
position:relative;
width:100%;
height:100%;
transform-style:preserve-3d;
-moz-transform-style:preserve-3d;
-webkit-transform-style:preserve-3d;
transform-origin:center center 29px;
-moz-transform-origin:center center 29px;
-webkit-transform-origin:center center 29px;
animation:s 4s linear infinite;
-moz-animation:s 4s linear infinite;
-webkit-animation:s 4s linear infinite;
}
@keyframes s{
0%{
transform:rotateY(0);
}
100%{
transform:rotateY(-359.9deg);
}
}
@-moz-keyframes s{
0%{
-moz-transform:rotateY(0);
}
100%{
-moz-transform:rotateY(-359.9deg);
}
}
@-webkit-keyframes s{
0%{
-webkit-transform:rotateY(0);
}
100%{
-webkit-transform:rotateY(-359.9deg);
}
}
.space div{
position:absolute;
width:0;
height:0;
border-width:0 50px 87px;
border-style:solid;
opacity:.4;
}
.box1{
border-color:transparent transparent #f00;
transform-origin:center bottom;
-moz-transform-origin:center bottom;
-webkit-transform-origin:center bottom;
transform:translateX(50px) translateY(50px) rotateX(-90deg);
-moz-transform:translateX(50px) translateY(50px) rotateX(-90deg);
-webkit-transform:translateX(50px) translateY(50px) rotateX(-90deg);
}
.box2{
border-color:transparent transparent #00f;
transform-origin:center bottom;
-moz-transform-origin:center bottom;
-webkit-transform-origin:center bottom;
transform:translateX(50px) translateY(50px) rotateX(-19.5deg);
-moz-transform:translateX(50px) translateY(50px) rotateX(-19.5deg);
-webkit-transform:translateX(50px) translateY(50px) rotateX(-19.5deg);
}
.box3{
border-color:transparent transparent #00f;
transform-origin:right bottom;
-moz-transform-origin:right bottom;
-webkit-transform-origin:right bottom;
transform:translateX(50px) translateY(50px) rotateY(60deg) rotateX(19.5deg);
-moz-transform:translateX(50px) translateY(50px) rotateY(60deg) rotateX(19.5deg);
-webkit-transform:translateX(50px) translateY(50px) rotateY(60deg) rotateX(19.5deg);
}
.box4{
border-color:transparent transparent #f0f;
transform-origin:left bottom;
-moz-transform-origin:left bottom;
-webkit-transform-origin:left bottom;
transform:translateX(50px) translateY(50px) rotateY(-60deg) rotateX(19.5deg);
-moz-transform:translateX(50px) translateY(50px) rotateY(-60deg) rotateX(19.5deg);
-webkit-transform:translateX(50px) translateY(50px) rotateY(-60deg) rotateX(19.5deg);
}
</style>
</head>
<body>
<div class="camera">
<div class="space">
<div class="box1"></div>
<div class="box2"></div>
<div class="box3"></div>
<div class="box4"></div>
</div>
</div>
<style>
#info {
position: fixed;
z-index: 999;
bottom: 20px;
left: 0px;
background: #222;
padding: 20px 30px;
color: #fff;
box-shadow: rgba(0, 0, 0, .5) 0 0 10px;
border-radius: 0 5px 5px 0;
font-size:16px;
}
#info a {
color: #0bf;
transition: .2s;
}
#info a:hover {
color: #6df;
}
</style>
</body>
</html>
保存文件名为:CSS_3D旋转的正四面体.html,运行效果如下:
例3、旋转的正方体(正六面体),源码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title> CSS 3D - 正六面体</title>
<style>
.camera{
width:200px;
height:200px;
perspective-origin:50% 150%;
-moz-perspective-origin:50% 150%;
-webkit-perspective-origin:50% 150%;
perspective:500px;
-moz-perspective:500px;
-webkit-perspective:500px;
}
.space{
position:relative;
width:100%;
height:100%;
transform-style:preserve-3d;
-moz-transform-style:preserve-3d;
-webkit-transform-style:preserve-3d;
transform-origin:center center -50px;
-moz-transform-origin:center center -50px;
-webkit-transform-origin:center center -50px;
animation:s 4s linear infinite;
-moz-animation:s 4s linear infinite;
-webkit-animation:s 4s linear infinite;
}
@keyframes s{
0%{
transform:rotateY(0);
}
100%{
transform:rotateY(-359.9deg);
}
}
@-moz-keyframes s{
0%{
-moz-transform:rotateY(0);
}
100%{
-moz-transform:rotateY(-359.9deg);
}
}
@-webkit-keyframes s{
0%{
-webkit-transform:rotateY(0);
}
100%{
-webkit-transform:rotateY(-359.9deg);
}
}
.space div{
position:absolute;
width:100px;
height:100px;
font-size:50px;
text-align:center;
line-height:100px;
}
.box1{
background:rgba(255,0,0,.2);
transform:translateX(50px) translateY(50px);
-moz-transform:translateX(50px) translateY(50px);
-webkit-transform:translateX(50px) translateY(50px);
}
.box2{
background:rgba(255,255,0,.2);
transform-origin:left top;
-moz-transform-origin:left top;
-webkit-transform-origin:left top;
transform:translateX(150px) translateY(50px) rotateY(90deg);
-moz-transform:translateX(150px) translateY(50px) rotateY(90deg);
-webkit-transform:translateX(150px) translateY(50px) rotateY(90deg);
}
.box3{
background:rgba(0,255,0,.2);
transform:translateX(50px) translateY(50px) translateZ(-100px) rotateY(180deg);
-moz-transform:translateX(50px) translateY(50px) translateZ(-100px) rotateY(180deg);
-webkit-transform:translateX(50px) translateY(50px) translateZ(-100px) rotateY(180deg);
}
.box4{
background:rgba(255,0,255,.2);
transform-origin:right top;
-moz-transform-origin:right top;
-webkit-transform-origin:right top;
transform:translateX(-50px) translateY(50px) rotateY(-90deg);
-moz-transform:translateX(-50px) translateY(50px) rotateY(-90deg);
-webkit-transform:translateX(-50px) translateY(50px) rotateY(-90deg);
}
.box5{
background:rgba(0,0,255,.2);
transform-origin:center bottom;
-moz-transform-origin:center bottom;
-webkit-transform-origin:center bottom;
transform:translateX(50px) translateY(-50px) rotateX(90deg);
-moz-transform:translateX(50px) translateY(-50px) rotateX(90deg);
-webkit-transform:translateX(50px) translateY(-50px) rotateX(90deg);
}
.box6{
background:rgba(0,255,255,.2);
transform-origin:center top;
-moz-transform-origin:center top;
-webkit-transform-origin:center top;
transform:translateX(50px) translateY(150px) rotateX(-90deg);
-moz-transform:translateX(50px) translateY(150px) rotateX(-90deg);
-webkit-transform:translateX(50px) translateY(150px) rotateX(-90deg);
}
</style>
</head>
<body>
<div class="camera">
<div class="space">
<div class="box1">1</div>
<div class="box2">2</div>
<div class="box3">3</div>
<div class="box4">4</div>
<div class="box5">5</div>
<div class="box6">6</div>
</div>
</div>
<style>
#info {
position: fixed;
z-index: 999;
bottom: 20px;
left: 0px;
background: #222;
padding: 20px 30px;
color: #fff;
box-shadow: rgba(0, 0, 0, .5) 0 0 10px;
border-radius: 0 5px 5px 0;
font-size:16px;
}
#info a {
color: #0bf;
transition: .2s;
}
#info a:hover {
color: #6df;
}
</style>
</body>
</html>
保存文件名为:CSS_3D旋转的正方体(正六面体).html,运行效果如下: