想了解 rotate3d 是在给友链排版的时候——试了几种排版方案,最后决定把站点名/作品名和简短的描述放在悬停鼠标才能看到的位置,就想不妨做个小动画来表现层级关系吧(写「衬线字使用指北」时得到的提示)于是用 rotate3d 做了一个把文字「翻」到前面的动画。

参考 MDN 对于直观地理解 rotate3d 并没有太大的帮助。看过 demo 也还是似懂非懂,就有了这篇文章。文中示意图是使用 CSS 绘制的,点击它们可以切换不同的状态。

在介绍 rotate3d 之前回忆一下简单易懂的二维 rotate 变换,比如顺时针旋转 30 度:

.square {
    transform: rotate(30deg);
}

这个变换有一个等价的 rotate3d 版本——绕Z轴顺时针旋转 30 度:

.square {
    transform: rotate3d(0,0,1,30deg);
}

两张示意图是关联的。点击上一张示意图,可以改变图形旋转的角度。

.square {
  transform: rotate3d($x, $y, $z, $angel) ...;
}

不妨打开 Inspector 编辑这个图形的 transform 属性,观察三维座标系里图形发生的变化(你会看到两个函数的组合 transform,第一个函数是座标系变换,修改后面的 rotate3d 参数就可以了)

rotate3d 函数有四个参数,前三个参数 (x, y, z) 定义一个向量,(0, 0, 1) 表示在三维空间中的Z轴正方向上的单位向量、最后的 angel 参数用于指定「旋转」的角度,旋转正方向可以使用「右手定则」确定。rotate3d 函数是沿着指定向量,在旋转正方向上将「空间」旋转指定的角度的变换,我们会在接下来的例子里尽量通俗地解释这个概念。顺便一提,常见的 rotateX、rotateY、rotateZ 变换分别对应着使用 (1, 0, 0)、(0, 1, 0) 和 (0, 0, 1) 三个向量为轴的 rotate3d 变换。

所谓「空间」就是座标系所表示的位置的集合,为了方便说明,我们在原点附近把「空间」切出一小块,然后做一些可怕的事情:

和前面的例子一样,你可以在这里改变后面示意图展示的视角。

  1. 把图形固定到虚线的立方体里,也就是「切」出来的空间
  2. 从 (0, 0, 0) 到 (1, -1, 0) 的方向上画一个向量(注意!Y轴绿的正方向是朝下的所以 X-Y 平面上的点 (1, -1) 在右上方)
  3. 根据「右手定则」指示的正方向,往正方向旋转 -35 度(也就是往反方向转 35 度)

把上面三个步骤合并起来就是 rotate3d 函数的效果了,

.square {
  transform: rotate3d(1,-1,0,-35deg);
}

这样演示是不是能直观地理解「空间」了呢?如果对文章有疑问或者建议非常欢迎在评论区发表评论。

另一个重要的属性是 transform-origin,它可以改变「原点」和「图形」的相对位置,比如下面的例子把图形往「前方」移动了 40px(为什么这里第三个参数不是 -40px 呢)

.square {
  transform-origin: 50% 50% 40px;
}

使用 transform-origin 控制X和Y方向上的相对位置的情况和这类似,示例代码却会复杂得多,于是这里只演示Z方向平移的情况。

当图形和旋转的中心轴共面时,理解「空间」似乎并有什么用,对于理解类似 transform-origin 一起其他中心轴和图形不共面的情况是很有帮助的。

做个总结,

  • rotate3d 可以让「空间」绕着某个轴旋转特定的角度
  • transform-origin 改变「图形」和「原点」的相对位置
    • 图形固定移动原点(二维 transform 常用这种理解)
    • 原点固定移动图形(这样更容易理解 rotate3d 变换)

最终看到的是图形的正视图(上面的例子)文章中的示意图是使用多个 transform 函数组合出来的,感兴趣朋友请查看页面的代码,至于如何理解 transform 组合,有机会再继续填坑吧。