rotate3d本质上是 rotateX、rotateY、rotateZ 的集合,不同的是语法结构及其导致的使用方式:rotate3d 更为抽象、难用,rotateX/Y/Z 更为直白、易用。
要理解 rotate3d,先得弄清楚 rotateX、rotateY 和 rotateZ 这三个 transform 转换下的函数。它们的具体功能是将对象在对应周上旋转多少个角度。假设你就是这个要旋转的对象,rotateX 就是你在单杠上做翻转运动——单杠的横条是X轴,你双手握着它不停地让身体绕X轴翻转着;rotateY 则是你在跳钢管舞——钢管是Y轴,你抱着它让身体性感地绕Y轴旋转着;rotateZ 就像你在表演耶稣钉在十字架上,十字架则像风车一样面向观者旋转着,并且摄影师还将镜头忽而拉近忽而拉远……此时你身体的旋转是绕Z轴进行,Z轴就是观者和被观察对象间的连接线。以下例子是 rotateX/Y/Z 的简易表演,它们没有你的表演待遇,不提供任何道具:
rotateX
rotateY
rotateZ
@keyframes rotX { to { transform: rotateX(360deg); } }
@keyframes rotY { to { transform: rotateY(360deg); } }
@keyframes rotZ { to { transform: rotateZ(360deg); } }
rotate3d 同时也是 transform 转换属性的函数,可以视为是 rotateX、rotateY、rotateZ 的语法糖。下面的例子,动画的设置等效于前例(可以点击“预览”按钮查看效果):
<style>
.sbox { margin: 20px auto; width: 1204px; height: 200px; display: grid; grid-template-columns: repeat(3, 1fr); place-items: center; border: 1px solid gray; }
.sbox span { font: bold 2em/1.5 sans-serif; text-shadow: 2px 2px 4px gray; }
.rotateX { color: red; animation: rotX linear 5s infinite; }
.rotateY { color: green; animation: rotY linear 5s infinite; }
.rotateZ { color: blue; animation: rotZ linear 5s infinite; }
@keyframes rotX { to { transform: rotate3d(1, 0, 0, 360deg); } }
@keyframes rotY { to { transform: rotate3d(0, 1, 0, 360deg); } }
@keyframes rotZ { to { transform: rotate3d(0, 0, 1, 360deg); } }
</style>
<div class="sbox">
<span class="rotateX">rotateX</span>
<span class="rotateY">rotateY</span>
<span class="rotateZ">rotateZ</span>
</div>
rotate3d 函数的语法共四个参数:
transform: rotate3d(X, Y, Z, 角度);
参数 X、Y、Z 决定旋转对象绕 X、Y、Z 三个轴中的哪一根轴或哪几根轴转,取值并没有严格规定,通常使用归一化矢量值,即 0~1 的范围,可以使用正、负数,正值时表示顺时针旋转、负值表示逆时针旋转,但这取决于第四个参数即角度参数的正负值,这里假设角度参数为正值。X、Y、Z 的绝对值大小可能不很重要,浏览器系统引擎关心的是它们之间的比例关系从而决定旋转对象在三个轴上如何旋转,它有自己的一整套处理机制,按照“X绝对值的平方+Y绝对值的平方+Z绝对值的平方=1”的原则做调整,因此实际对XYZ的赋值可以随意,我们关心的仅是正负、0或非0(0表示对应轴没有转动、非0表示转动);角度参数可以是 deg(角度)、turn(一圈)或 rad(弧度),可以是正、负值,正值时对象以顺时针旋转、负值时对象以逆时针旋转(这里假设XYZ矢量为正值)。关于对象的旋转方向,决定因素有两个:XYZ矢量取值的正负数和角度参数取值的正负数,二者的乘积为正则对象以顺时针方向旋转,为负逆时针旋转。
XYZ矢量设置容易令人困惑,所以很多人更倾向于使用 rotateX/Y/Z 去设置对象的旋转,不愿意使用 rotate3d 函数。实际上,rotate3d 函数也不复杂,总结来讲就是:XYZ三个参数的表示对象在哪一(些)轴上旋转、角度参数表示旋转多少个角度(或圈、弧度);XYZ三值以归一化取值,-1~1 范围,三者在系统内部按各自绝对值的平方和等于1的规范做调整,使用者可以不用管这个,只关心0或非0的意义以及它们之间的比例关系的意义即可;角度参数支持正负值。
不论是使用 rotateX/Y/Z 还是 rotate3d 函数来设置对象旋转,它们都可以用于 2d 旋转 和 3d 旋转。3d 旋转带来更强烈的立体感(近大远小),想让对象以3d形式渲染旋转效果,需要在对象的父级元素使用 perspective 属性设置场景的透视深度,并在对象CSS选择器或父元素(假设 perspective 景深设置在了祖父级元素)设置 transform-style 为 preserve-3d。下面的例子,父元素启用了 perspective 设置,左边子元素是2d旋转,右边子元素是3d旋转(设置有 transform0style: preserve-3d;):
<style>
.papa {
margin: 20px auto;
width: 1024px;
height: 300px;
border: 1px solid gray;
display: grid;
grid-template-columns: 1fr 1fr;
place-items: center;
perspective: 500px;
}
.son {
width: 200px;
height: 200px;
background: lightgreen;
transform: rotate3d(0, 1, 0, 30deg);
display: grid;
place-items: center;
font-size: 30px;
}
.son-3d { transform-origin: preserve-3d;}
</style>
<div class="papa">
<div class="son">2d旋转</div>
<div class="son son-3d">3d旋转</div>
</div>
理解 rotate3d 有些难度,希望本文对大家有所帮助。