当前位置: 首页 > 科技观察

进阶CSS:尝试炫酷的3D视角

时间:2023-03-21 22:48:05 科技观察

之所以写这篇文章是因为看到了这个页面:https://shakeduang.nuomi.com/campus/index.html?from=timeline&isappinstalled=1(Mobile端页面,用模拟器看)用CSS3完成的3D透视,虽然3D有点晕,但是让人置身其中的交互体验感觉非常好,在移动端做一些H5页面还是很养眼的.而且掌握了原理之后,做出来也不费力气。好好学习之后,我将一些学习过程分享给大家。在下方输入文字:(部分Gif图片较大,需要稍等)3D效果说明看的比看的好。.io/Chokcoco/pen/mAyRGv),这里我以一个带背景色的div为例,我们的视角是在一个立方体中,立方体的旋转动画给我们一种3D的感觉。那么原图是什么样子的呢?我们把距离拉远看看:http://codepen.io/Chokcoco/pen/KgwqRd看起来是这样的:与第一个效果相比,实际上做了什么它只是把我们的视角推入了立方体,给我们一种感觉在那里。而合理利用CSS3提供的一些3D属性,可以轻松实现上述效果。制作这样的3D图形,我在之前的文章中已经详细描述了过程。有兴趣的可以戳进去看看:【CSS3进阶】超酷的3D旋转透视transform-styleandperspective。它使用了两个CSS属性:transform-style要使用CSS3实现3D效果,最重要的是使用transform-style属性。transform-style只有两个值://语法:transform-style:flat|preserve-3d;transform-style:flat;//默认情况下,子元素不会保留其3D位置transform-style:保留3d;//子元素将保留其3D位置。当父元素设置transform-style:preserve-3d时,可以对子元素进行3D变形操作。3D变形与2D变形相同。可以使用transform属性来设置,也可以使用指定的函数或三维矩阵。元素的变形:当我们指定一个容器的transform-style属性值为preserve-3d时,该容器的后代元素将具有3D效果。这个有点抽象,就是当前父容器设置了preserve-3d值后,它的子元素就可以相对于父元素所在的平面进行3D变形操作。使用translateX(length)、translateY(length)、translateZ(length)执行3D位移操作。和2D操作一样,元素位移操作也可以组合成translate3d(x,y,z);使用scaleX()、scaleY()、scaleY()进行3D缩放操作,也可以组合成scale3d(number,number,number);使用rotateX(angle)、rotateY(angle)、rotateZ(angle)进行3D旋转操作,也可以组合成rotate3d(Xangle,Yangle,Zangle)的格式。perspective//语法perspective:number|none;简单的说,当元素没有设置perspective,即当perspective:none/0时,所有的后代元素都被压缩在同一个二维平面上,没有景深的影响。perspective设置元素的三维透视距离,只作用于元素的后代,不作用于元素本身。如果你设置透视,你会看到三维效果。我们之所以能在立方体之外看到立方体,深入到立方体内部,就是因为透视属性。它让我们可以选择将视角推入或远离它,因此它具有3D的感觉。3D视图页面的布局结构为了达到这样的效果,需要灵活的布局来控制整个3D效果的显示。下面是我认为比较好的方法:

最外层的容器控制图形的位置和整个页面的布局;stagelayer,舞台层,从这里设置3D景深效果,添加透视视图距离;control层,动画控制层,通过该层可以在移动端添加旋转动画或者触摸动画,也可以通过改变translateZ属性来放大透视;imgWrap层,图片层,加载我们要拼接的图片,下面会讲到。图像拼接图像拼接实际上是一项需要大量计算的技术工作。以上面Demo中的立方体为例,class为img的div块的高和宽为400px*400px。然后,要使用4个这样的div拼接一个立方体,需要将4个div绕Y轴旋转[90°、180°、270°、360°],然后平移Y(200px)。值得注意的是一定要先旋转角度,再旋转偏移距离。这个顺序非常重要。看俯视图,就是这个意思:这是最简单的情况,都是直角。如果一张图片需要分成八份,假设每张图片的高和宽都是400400,需要对8张图片做的操作就是依次绕Y轴旋转[45°,90°,135°,180°,225°,270°,315°,360°],偏移距离为translateY(482.84px),即(200+200√2)。看一下顶视图:效果图(http://codepen.io/Chokcoco/pen/WGbERo):图像分割上面的例子都是用了带背景色的div块,现在我们选择一张真实的图像拼接成一个圆柱。下图是3480px*2000px大小:我们把它分成20份,拼成一个规则的20边形。当然,我们不需要把图片一块一块切下来,可以使用background-position来完成。而且划分的数量越多,最终效果越像圆柱体,效果越逼真。一个普通的20边形需要20个div。假设容器为.img-bg1~.img-bg20,每张图片的宽度为174px,增量角度为18°,我们需要计算偏移距离为translateZ(543px)。您可以使用一些CSS预处理器来处理此代码。下面是Sass的写法://Sass的写法$imgCount:20!default;@for$ifrom1through$imgCount{.img-bg#{$i}{background-position:($i*-174px+174px)0;transform:rotateY($i*18deg)translateZ(543px);}}看效果:Demo(http://sbco.cc/demo/3dview/html/3dView2.html)可以看出图片中的近景是一个圆柱体,但是有一些小问题:所选图片必须左右首尾相接,否则圆柱体的接缝处会出现明显的不协调,这就需要用这种方法制作的时候H5页面,美工制作的设计图必须左右相连,不能有违和感。另一点是分割的块技术。图片分成的块越多,图像越接近圆柱体,效果越好。控制控制层,输入圆柱形图像,即可实现这一步。剩下的唯一一步是推进我们的视角并进入圆柱体内部以创建3D视图的感觉。我们通过class为control的div来控制这个效果,但是这里控制我们进入圆柱体内部的属性并不是调整修改perspective属性,而是调整translateZ属性。控制translateZ得到的画面更逼真。大家可以试试分别控制perspective和translateZ的效果,会有深有感触。最佳效果:Demo(http://sbco.cc/demo/3dview/html/index.html),因为是移动端效果,最好打开模拟器看,整体效果图太大,只有部分制作截取程GIF:还有一个小问题,就是进入到圆柱体内部之后,整个画面是颠倒的,所以我们可能需要用PS把原图左右翻转一下,这样之后进入室内,看到的是原图效果。至此,整个页面就完成了,接下来就是添加一些触摸事件,添加一些细节。在写作过程中可能遗漏了一些细节。如果有什么难以理解的地方,可以在评论中留言。本文的示例demo已经上传到我的Github:Css33DView(https://github.com/chokcoco/Css33DView)