至此,一个 3D 立方体就完成了。写这篇文章的时候,本来到这里,这一块应该就结束了,但是写到这里的时候,突然突发奇想,既然正方体可以(正六面体),那么正四面体,正八面体甚至球体应该也能做出来吧?
嗯,没有按住躁动的心,立马动手尝试了一番,最后做出了下面的两个:
就不再详细讨论如何一步一步得到这两个了,有兴趣的可以去我的 github 上看看源码,或者直接和我讨论交流,简单的谈谈思路:
正四面体
和正方体一样,我们首先要准备 4 个三角形(下面会详细讲如何利用 CSS3 制作一个三角形 div),注意 4 个三角形应该是重叠在一起的,然后将其中三个分别沿着三条边的中心点旋转 70.5 度(正四面体临面夹角),就可以得到一个正四面体。
注意沿着三条边的中心点旋转 70.5 度这句话,意思是每个图形要定位一次旋转中心,也就是 transform-origin 属性,它允许我们设置旋转元素的基点位置。
球体
上面的 GIF 图因为添加了 animation 动画效果,看上去很像一个球体在运动,其实只用了 4 个 div,每个 div 利用 border-radius:100% 设置为圆形,然后以中心点为基准,每个圆形 div 绕 Y 轴旋转不同的角度,再让整个圆形容器绕 Y 轴动起来,就可以得到这样一个效果了。
perspective and perspective-origin 3D视距,透视/景深效果
继续说 3D ,接下来要说的属性是 persepective 和 perspective-origin 。
persepective
// 语法 perspective: number|none;
perspective 为一个元素设置三维透视的距离,仅作用于元素的后代,而不是其元素本身。
简单来说,当元素没有设置 perspective 时,也就是当 perspective:none/0 时所有后代元素被压缩在同一个二维平面上,不存在景深的效果。
而如果设置 perspective 后,将会看到三维的效果。
perspective-origin
perspective-origin 表示 3D 元素透视视角的基点位置,默认的透视视角中心在容器是 perspective 所在的元素,而不是他的后代元素的中点,也就是 perspective-origin: 50% 50%。
// 语法 perspective-origin: x-axis y-axis; // x-axis : 定义该视图在 x 轴上的位置。默认值:50% // y-axis : 定义该视图在 y 轴上的位置。默认值:50%
值得注意的是,CSS3 3D 变换中的透视的透视点是在浏览器的前方。
说总是很难理解,运用上面我们做出来的正方体试验一下,我设置了正方体的边长为 50 px ,这里设置正方体容器 cuber-inner 的 persepective 的为 100 px,而 perspective-origin 保持为默认值:
-webkit-perspective-origin: 50% 50%; perspective-origin: 50% 50%; -webkit-perspective: 100px; perspective: 100px;
上面这样设置,也就是相当于我站在 100px 的长度外去看这个立方体,效果如下:
通过调整 persepective 和 perspective-origin 的值,可以看到不一样的图形,这个很好理解,我们观测一个物体的角度和距离物体的距离不断发生改变,我们看的物体也是不一样的,嗯想象一下小学课文,杨桃和星星,就能容易明白了。
需要提出的是,我上面的几个正多面体图形和球形图形是没有加上 persepective 值的,感兴趣的可以加上试一下看看效果。
3D 透视照片墙回到文章一开始我贴的那个 3D 照片墙,运用 transform-style: preserve-3d 和 persepective ,可以做出效果很好的这种 3D 照片墙旋转效果。
代码就不贴了,本文已经很长了,只是简单的谈谈原理,感兴趣的去扒源码看看。
1、设立一个舞台,也就是包裹旋转的图片们的容器,给他设置一个 persepective 距离,以及 transform-style: preserve-3d 让后代可以进行 3D 变换;
2、准备 N 张图片置于容器内部,N 的大小看个人喜好了,图片的 3D 旋转木马效果是类似钢管舞旋转的运动,因此是绕 Y 轴的,我们关心的是 rotateY 的大小,根据我们添加的图片数量,用 360° 的圆周角将每个图片等分,也就是让每张图片绕 Y 轴旋转固定角度依次散开:(下面的图为示意效果,我调整了一下角度和透明度)
3、这个时候,N 张图肯定是重合叠在了一起,所以这里关键一步是运用 translateZ(length) 让图片沿 Z 轴平移,也就是运用 translateZ 可以让图片离我们更近或者更远,因为上一步设置了图片不同的 rotateY() 角度,所以 N 张图片设定一个 translateZ 后,图片就很自然以中点为圆心分散开了,也就是这样:
4、最后利用 animation ,我们让舞台,也就是包裹着图片的容器绕 Y 轴旋转起来(rotateY),那么一个类似旋转木马的 3D 照片墙效果就完成了!