本文介绍了如何创建纯CSS 3维球体?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 tl; dr: 我想用CSS创建一个实际的3d球面-不仅仅是一种幻觉 使用纯CSS,您可以像这样创建和设置动画 3d立方体: #cube-wrapper {位置:绝对;左:50%;最高:50%;透视图:1500px;}。cube {位置:相对;转换样式:reserve-3d; animation-name:旋转;动画时间:30秒;动画定时功能:线性;动画迭代次数:无限;} @关键帧旋转{0%{变换:rotate3d(0,0,0,0); } 100%{变换:rotate3d(0,1,0,360deg); ; }}。face {position:absolute;宽度:200像素;高度:200px;边框:绿色3px;}#front_face {转换:translateX(-100px),translateY(-100px),translateZ(100px);背景:rgba(255,0,0,0.5);}#back_face {transform:translateX(-100px)translateY(-100px)translateZ(-100px);背景:rgba(255,0,255,0.5);}#right_face {转换:translateY(-100px)rotationY(90deg);背景:rgba(255、255、0、0.5);}#left_face {转换:translateY(-100px),translateX(-200px),rotateY(90deg);背景:rgba(0,255,0,0.5);}#top_face {转换:translateX(-100px),translateY(-200px),rotateX(90deg);背景:rgba(0、255、255、0.5);}#bottom_face {转换:translateX(-100px)rotationX(90deg);背景:rgba(255、255、255、0.5);}。cube {变换:rotateX(90deg)rotationY(90deg);} < div id = cube-wrapper> < div class = cube> < div id = front_face class = face>< / div> < div id = right_face class = face>< / div> < div id = back_face class = face>< / div> < div id = left_face class = face>< / div> < div id = top_face class = face>< / div> < div id = bottom_face class = face>< / div> < / div>< / div> 我想以相同的方式创建3D球体并为其设置动画。 所以...我得到的第一个想法是使用 border-radius 然后...嗯...不起作用。 #cube-wrapper {位置:绝对;左:50%;最高:50%;透视图:1500px;}。cube {位置:相对;转换样式:reserve-3d; animation-name:旋转;动画时间:30秒;动画定时功能:线性;动画迭代次数:无限;} @关键帧旋转{0%{变换:rotate3d(0,0,0,0); } 100%{变换:rotate3d(0,1,0,360deg); ; }}。face {position:absolute;宽度:200像素;高度:200px;边框:纯绿色3px; border-radius:100vw} #front_face {transform:translateX(-100px)translateY(-100px)translateZ(100px);背景:rgba(255,0,0,0.5);}#back_face {transform:translateX(-100px)translateY(-100px)translateZ(-100px);背景:rgba(255,0,255,0.5);}#right_face {转换:translateY(-100px)rotationY(90deg);背景:rgba(255、255、0、0.5);}#left_face {转换:translateY(-100px),translateX(-200px),rotateY(90deg);背景:rgba(0,255,0,0.5);}#top_face {转换:translateX(-100px),translateY(-200px),rotateX(90deg);背景:rgba(0、255、255、0.5);}#bottom_face {转换:translateX(-100px)rotationX(90deg);背景:rgba(255、255、255、0.5);}。cube {变换:rotateX(90deg)rotationY(90deg);} < div id = cube-wrapper> < div class = cube> < div id = front_face class = face>< / div> < div id = right_face class = face>< / div> < div id = back_face class = face>< / div> < div id = left_face class = face>< / div> < div id = top_face class = face>< / div> < div id = bottom_face class = face>< / div> < / div>< / div> 重新考虑了我的方法,并寻找了另一种方法。 我看过: 实施纯CSS Sphere进入网站-我该怎么做? 如何在CSS中创建球体? 显示使用CSS / Javascript cssanimation.rocks-CSS球形 MDN-圈 然后我再次尝试了……最好我太复杂了 3d对象幻觉。 就像这样: body {溢出:隐藏;背景:#333;}。wrapper {边距:1em; animation-duration:20s;}。planet,.planet:before,.planet:after {height:300px;宽度:300像素;边界半径:100vw;意志改变margin:0 auto;}。planet {box-shadow:inset 0px 0px 10px 10px rgba(0,0,0,0.4);位置:相对;}。包装器,.planet,.planet:之前{animation-name:myrotate; animation-duration:20s;}。wrapper,.planet,.planet:before,.planet:after {animation-timing-function:linear; animation-iteration-count:infinite;}。planet:before,.planet:after {content:’’;位置:绝对;最高:0; left:0;}。planet:before {box-shadow:inset 20px 20px 100px 00px rgba(0,0,0,.5),0px 0px 5px 3px rgba(0,0,0,.1);}。planet :after {filter:saturate(2.5);背景:线性渐变(rgba(0、0、0、1),透明),url( https://i.stack.imgur.com/eDYPN.jpg);不透明度:0.3; box-shadow:嵌入-20px -20px 14px 2px rgba(0,0,0,.2); animation-name:myopacity; animation-duration:5000000s;} @关键帧myrotate {0%{transform:rotationz(0deg); } 100%{变换:rotatez(360deg); }} @ keyframes myopacity {0%{背景位置:0像素;变换:rotatez(0deg); } 50%{背景位置:100000000px; } 100%{背景位置:0;变换:rotatez(-360deg); }} < div class = wrapper> < div class = planet>< / div>< / div> 这 body {background:#131418;}。wrapper {margin:1em;最大宽度:100%;位置:固定左:50%;最高:50%;转换:translate(-50%,-50%);}。planet,.planet:before,.planet:after {height:500px;宽度:500像素;最大高度:30vw;最大宽度:30vw;边界半径:100vw; will-change:transform;}。planet {box-shadow:inset 0px 0px 100px 10px rgba(0,0,0,.5);职位:相对向左飘浮; margin:0 2em;}。planet,.planet:before,.planet:after {animation-name:myrotate; animation-duration:10s;}。wrapper,.planet,.planet:before,.planet:after {animation-timing-function:linear; animation-iteration-count:infinite;}。planet:before,.planet:after {content:’’;位置:绝对;最高:0; left:0;}。planet:before {box-shadow:inset 50px 100px 50px 0 rgba(0,0,0,.5),0 0 50px 3px rgba(0,0,0,.25);背景图片:-webkit-radial-gradient(top,circle cover,#ffffff 0%,#000000 80%); opacity:.5;}。planet:after {opacity:.3;背景图片:-webkit-radial-gradient(bottom,circle,#ffffff 0%,#000000 -200%); box-shadow:inset 0px 0px 100px 50px rgba(0,0,0,.5);} @ keyframes myrotate {0%{transform:rotatez(0deg); } 100%{变换:rotatez(-360deg); }}。bg {背景:小麦;} < div class = wrapper> < div class = planet bg>< / div>< / div> 没关系,直到您尝试像我第一个示例中的立方体一样在 x轴或 y轴上实际旋转它们...然后发生以下情况:(简化示例) .sphere {背景:黑色;宽度:300像素;高度:300像素;边界半径:100vw;动画:myrotate 10s线性无限} @关键帧myrotate {0%{变换:rotate3d(0,0,0,0); } 100%{变换:rotate3d(0,1,0,360deg); }} < div class = sphere> < / div> $ p $ b 所得到的只是一个平面2d对象-考虑到元素是什么而被取消 我发现的最接近的东西是在教程 @-webkit-keyframes animateWorld {0%{-webkit-transform:rotationY(0deg)rotationX(0deg)rotationZ(0deg) ; } 50%{-webkit-transform:旋转Y(360deg)旋转X(180deg)旋转Z(180deg); } 100%{-webkit-transform:旋转Y(720度)旋转X(360度)旋转Z(360度); }} html {背景:#FFFFFF;}。 world {-webkit-perspective:1000px;}。cube {margin-left:auto;右边距:自动;职位:相对宽度:200像素;高度:200px; -webkit-transform-style:保留3d; -webkit-animation-name:animateWorld; -webkit-animation-duration:10秒; -webkit-animation-iteration-count:无限; -webkit-animation-timing-function:线性;}。circle {位置:绝对;宽度:100%;高度:100%;边框:2px虚线#009BC2;边界半径:50%;不透明度:0.8;背景:rgba(255、255、255、0);}。zero {-webkit-transform:rotateX(90deg);}。two {-webkit-transform:rotateY(45deg);}。three {-webkit-transform: rotationY(90deg);}。四个{-webkit-transform:rotateY(135deg);}。五{宽度:173px;高度:173px;边距:14px; -webkit-transform:rotateX(90deg)translationZ(50px);}。six {width:173px;高度:173px;边距:14px; -webkit-transform:rotateX(90deg)translateZ(-50px);} < div class = world> < div class = cube> < div class =圆零< / div> < div class = circle one>< / div> < div class =第二圈< / div < div class =圆圈三>< / div> < div class =圆圈四>< / div> < div class =圆圈5>< / div> < div class =圆圈六< / div> < / div>< / div> 所以这是我的 问题: 如何创建一个纯CSS的实际3维球体?更具体地说,一个被覆盖的对象-不只是一个框架-而且不涉及数百个html元素。 注释: 三维球体的高度,宽度和深度 -就像我的第一个示例片段中的立方体一样,只是 我不需要任何物理学,也不需要任何的用户交互。 其他资源: paulrhayes.com-球体 3d (2d幻觉),带有CSS旋转动画的地球 交互式CSS球体 解决方案严格来讲, any 3D在 flat 屏幕上的形状更像是3D对象的错觉。我们所看到的只是在屏幕平面上该形状的2D 投影,我们的大脑尽力猜测哪种形状可以给出我们所看到的投影。如果投影发生变化,我们的大脑会将其解释为改变其方向的3D对象,这有助于它更好地确定该对象的形状。 对于非对称物体和由多边形(例如,立方体)制成的物体,但是球体是一种非常特殊的情况:球体在平面上的投影始终只给出一个圆。静态球和旋转球具有相同的投影,相同的圆。即使在现实生活中,如果我们看一个表面均匀但没有任何痕迹的球体(例如抛光的金属球),也很难确定它是静止不动还是自转。我们的眼睛需要一些提示,一些细节根据球的几何形状沿着球的表面移动。这样的细节越多地从球形表面上的点移动到您期望的方式,就越清楚旋转球体的感知(很好,幻觉)。 这是制作CSS场景时会产生这种感觉的问题的关键:为了使这种错觉足够强烈,我们需要沿不同平面上的路径移动许多标记。在CSS中获得此标记的唯一方法是将每个标记作为单独的CSS框(元素或伪元素)。如果我们的领域仅由运动标记组成,那么我们真的需要其中的很多才能将其视为一个球形,因此在您所看到的大多数演示中都是数百个元素。 因此,如果要使球体看起来数量较少,则逼真的球体,则可能需要结合使静态基本球形形状(带有径向半径的圆)产生幻觉的效果渐变,内部阴影等),并带有一些相对较小的元素(以使其不太明显它们实际上是平坦的),使用3D变换沿球体的表面定向并进行动画处理-与该对象的面孔基本相同 下面是我自己尝试将这种方法付诸实践的尝试。我使用了20个圆形元素,这些元素的大致方向是常规二十面体的面(例如经典的白色六边形)足球)。为了方便起见,我将它们分为两组,每个半球都形成一个半球(这不是必需的,但是它使样式更简单)。整个3D场景由球体本身和背景框架(伪元素)组成,背景框架在球体的中心附近交叉(稍微靠近一点,以减少从近端到远端再到后退的圆的闪烁) ),并且始终面对屏幕。因此总共有24个元素(至少不是字面意义上的数百)。为了使圆看起来更鼓起(如球形段),我向每个圆添加了两个伪元素,然后将它们稍微升高了一个。在Chrome和Firefox 57+上效果最佳(在Firefox 56-和iOS Safari中,边缘附近仍然有些闪烁)。如果将鼠标悬停在圆圈上,则可以看到没有背景框(也没有闪烁)的场景。也可以在Codepen上 进行略微修改的版本。 .scene {视角:400vmin;转换样式:reserve-3d;位置:绝对;宽度:80vmin;高度:80vmin;最高:10vmin;左:10vmin;}。sphere {transform-style:preserve-3d;位置:绝对;动画:旋转20秒无限线性;宽度:100%;高度:100%;转换来源:50%50%;最高:0; left:0;}。scene :: before {content:’’;位置:绝对;宽度:100%;高度:100%;最高:0%;左:0%;背景:径向渐变(圆最远角为33%33%,rgba(240、240、220、0.85)0%,rgba(30、30、40、0.85)80%),径向渐变(圆最远-拐角处为45%45%,rgba(0,0,0,0)50%,#000000 80%);边界半径:50%;转换:translateZ(2vmin);}。scene:hover :: before {display:none;}。hemisphere {position:absolute;最高:0;左:0;宽度:100%;高度:100%;转换样式:reserve-3d;转换来源:50%50%;变换:rotateX(90deg);}。半球:nth-​​child(2){变换:rotateX(-90deg);}。face {位置:绝对;宽度:40vmin;高度:40vmin;背景:径向渐变(以50%的圆圈绘制50%,rgba(255、255、255、0.1),rgba(255、255、255、0.1)48%,#ff0000 49%,#ff0000 50%,rgba(0 ,0,0,0)51%);转换样式:reserve-3d;转换原点:50%0;最高:50%;左:20vmin;}。face :: before,.face :: after {content:’’;位置:绝对;边界半径:50%; box-sizing:border-box;}。face :: before {width:50%;高度:50%;最高:25%;左:25%;边框:2px实线#333;背景:rgba(255,255,255,0.3);转换:translateZ(1.6vmin);}。face :: after {width:20%;高度:20%;最高:40%;左:40%;背景:rgba(0,0,0,0.2);变换:translateZ(2.8vmin);}。face:nth-​​child(1){变换:translateZ(-41.6vmin)rotationZ(36deg)transformY(-6.8vmin)rotateX(143deg);}。face:nth-​​child( 2){变换:translateZ(-41.6vmin)rotateZ(108deg)translateY(-6.8vmin)rotateX(143deg);}。face:nth-​​child(3){变换:translateZ(-41.6vmin)rotateZ(180deg)transformY (-6.8vmin)rotateX(143deg);}。face:nth-​​child(4){变换:translateZ(-41.6vmin)rotateZ(252deg)translateY(-6.8vmin)rotateX(143deg);}。face:nth- child(5){变换:translateZ(-41.6vmin)rotateZ(-36deg)translateY(-6.8vmin)rotateX(143deg);}。face:nth-​​child(6){变换:translateZ(-26.8vmin)rotateZ( 36deg)translateY(-33.2vmin)rotateX(100deg);}。face:nth-​​child(7){transform:translateZ(-26.8vmin)rotateZ(108deg)translateY(-33.2vmin)rotateX(100deg);}。face :nth-​​child(8){变换:translateZ(-26.8vmin)rotateZ(180deg)translateY(-33.2vmin)rotateX(100deg);}。face:nth-​​child(9){变换:translateZ(-26.8vmin) rotationZ(252deg)平移Y(-33.2vmin)ro tateX(100deg);}。face:nth-​​child(10){变换:translateZ(-26.8vmin)rotateZ(-36deg)translateY(-33.2vmin)rotateX(100deg);}。face:nth-​​child(11) {transform:translateZ(-26.8vmin)rotateZ(36deg)translateY(-33.2vmin)rotateX(100deg);} @关键帧rotate {0%{transform:rotateZ(25deg)rotateX(20deg)rotateY(0deg); } 50%{transform:旋转Z(-25deg)旋转X(-20deg)旋转Y(180deg); } 100%{transform:旋转Z(25deg)旋转X(20deg)旋转Y(360deg); }} body {背景:#555;溢出:隐藏;} < div class = scene > < div class = sphere> < div class = hemisphere> < div class = face>< / div> < div class = face>< / div> < div class = face>< / div> < div class = face>< / div> < div class = face>< / div> < div class = face>< / div> < div class = face>< / div> < div class = face>< / div> < div class = face>< / div> < div class = face>< / div> < / div> < div class = hemisphere> < div class = face>< / div> < div class = face>< / div> < div class = face>< / div> < div class = face>< / div> < div class = face>< / div> < div class = face>< / div> < div class = face>< / div> < div class = face>< / div> < div class = face>< / div> < div class = face>< / div> < / div> < / div>< / div> tl;dr: I would like to create an actual 3d sphere with CSS - not just an illusionNote: some of the snippet examples are not responsive. Please use full screen. With pure CSS you can create and animate a 3d cube like so:#cube-wrapper { position: absolute; left: 50%; top: 50%; perspective: 1500px;}.cube { position: relative; transform-style: preserve-3d; animation-name: rotate; animation-duration: 30s; animation-timing-function: linear; animation-iteration-count: infinite;}@keyframes rotate { 0% { transform: rotate3d(0, 0, 0, 0); } 100% { transform: rotate3d(0, 1, 0, 360deg); ; }}.face { position: absolute; width: 200px; height: 200px; border: solid green 3px;}#front_face { transform: translateX(-100px) translateY(-100px) translateZ(100px); background: rgba(255, 0, 0, 0.5);}#back_face { transform: translateX(-100px) translateY(-100px) translateZ(-100px); background: rgba(255, 0, 255, 0.5);}#right_face { transform: translateY(-100px) rotateY(90deg); background: rgba(255, 255, 0, 0.5);}#left_face { transform: translateY(-100px) translateX(-200px) rotateY(90deg); background: rgba(0, 255, 0, 0.5);}#top_face { transform: translateX(-100px) translateY(-200px) rotateX(90deg); background: rgba(0, 255, 255, 0.5);}#bottom_face { transform: translateX(-100px) rotateX(90deg); background: rgba(255, 255, 255, 0.5);}.cube { transform: rotateX(90deg) rotateY(90deg);}<div id="cube-wrapper"> <div class="cube"> <div id="front_face" class="face"></div> <div id="right_face" class="face"></div> <div id="back_face" class="face"></div> <div id="left_face" class="face"></div> <div id="top_face" class="face"></div> <div id="bottom_face" class="face"></div> </div></div>I want to create and animate a 3d sphere in the same manner.So... the first idea I get is to use border-radius and...well... it doesn't work. #cube-wrapper { position: absolute; left: 50%; top: 50%; perspective: 1500px;}.cube { position: relative; transform-style: preserve-3d; animation-name: rotate; animation-duration: 30s; animation-timing-function: linear; animation-iteration-count: infinite;}@keyframes rotate { 0% { transform: rotate3d(0, 0, 0, 0); } 100% { transform: rotate3d(0, 1, 0, 360deg); ; }}.face { position: absolute; width: 200px; height: 200px; border: solid green 3px; border-radius: 100vw} #front_face { transform: translateX(-100px) translateY(-100px) translateZ(100px); background: rgba(255, 0, 0, 0.5);}#back_face { transform: translateX(-100px) translateY(-100px) translateZ(-100px); background: rgba(255, 0, 255, 0.5);}#right_face { transform: translateY(-100px) rotateY(90deg); background: rgba(255, 255, 0, 0.5);}#left_face { transform: translateY(-100px) translateX(-200px) rotateY(90deg); background: rgba(0, 255, 0, 0.5);}#top_face { transform: translateX(-100px) translateY(-200px) rotateX(90deg); background: rgba(0, 255, 255, 0.5);}#bottom_face { transform: translateX(-100px) rotateX(90deg); background: rgba(255, 255, 255, 0.5);}.cube { transform: rotateX(90deg) rotateY(90deg);}<div id="cube-wrapper"> <div class="cube"> <div id="front_face" class="face"></div> <div id="right_face" class="face"></div> <div id="back_face" class="face"></div> <div id="left_face" class="face"></div> <div id="top_face" class="face"></div> <div id="bottom_face" class="face"></div> </div></div>So, I reconsidered my approach and looked for a different method. I looked at:Implementing "Pure CSS Sphere" into website - how do I do it?How to create a sphere in css?Display an image wrapped around a sphere with CSS/Javascriptcssanimation.rocks - CSS spheresMDN -CircleThen I tried again...the best I got were overly complicated 3d object illusions. Like this:body { overflow: hidden; background: #333;}.wrapper { margin: 1em; animation-duration: 20s;}.planet,.planet:before,.planet:after { height: 300px; width: 300px; border-radius: 100vw; will-change: transform; margin: 0 auto;}.planet { box-shadow: inset 0px 0px 10px 10px rgba(0, 0, 0, 0.4); position: relative;}.wrapper,.planet,.planet:before { animation-name: myrotate; animation-duration: 20s;}.wrapper,.planet,.planet:before,.planet:after { animation-timing-function: linear; animation-iteration-count: infinite;}.planet:before,.planet:after { content: ''; position: absolute; top: 0; left: 0;}.planet:before { box-shadow: inset 20px 20px 100px 00px rgba(0, 0, 0, .5), 0px 0px 5px 3px rgba(0, 0, 0, .1);}.planet:after { filter: saturate(2.5); background: linear-gradient(rgba(0, 0, 0, 1), transparent), url("https://i.stack.imgur.com/eDYPN.jpg"); opacity: 0.3; box-shadow: inset -20px -20px 14px 2px rgba(0, 0, 0, .2); animation-name: myopacity; animation-duration: 5000000s;}@keyframes myrotate { 0% { transform: rotatez(0deg); } 100% { transform: rotatez(360deg); }}@keyframes myopacity { 0% { background-position: 0px; transform: rotatez(0deg); } 50% { background-position: 100000000px; } 100% { background-position: 0; transform: rotatez(-360deg); }}<div class="wrapper"> <div class="planet"></div></div>And this:body { background: #131418;}.wrapper { margin: 1em; max-width: 100%; position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%);}.planet,.planet:before,.planet:after { height: 500px; width: 500px; max-height: 30vw; max-width: 30vw; border-radius: 100vw; will-change: transform;}.planet { box-shadow: inset 0px 0px 100px 10px rgba(0, 0, 0, .5); position: relative; float: left; margin: 0 2em;}.planet,.planet:before,.planet:after { animation-name: myrotate; animation-duration: 10s;}.wrapper,.planet,.planet:before,.planet:after { animation-timing-function: linear; animation-iteration-count: infinite;}.planet:before,.planet:after { content: ''; position: absolute; top: 0; left: 0;}.planet:before { box-shadow: inset 50px 100px 50px 0 rgba(0, 0, 0, .5), 0 0 50px 3px rgba(0, 0, 0, .25); background-image: -webkit-radial-gradient( top, circle cover, #ffffff 0%, #000000 80%); opacity: .5;}.planet:after { opacity: .3; background-image: -webkit-radial-gradient( bottom, circle, #ffffff 0%, #000000 -200%); box-shadow: inset 0px 0px 100px 50px rgba(0, 0, 0, .5);}@keyframes myrotate { 0% { transform: rotatez(0deg); } 100% { transform: rotatez(-360deg); }}.bg { background: wheat;}<div class="wrapper"> <div class="planet bg"></div></div>Which are okay until you try to actually rotate them on either the x-axis or the y-axis like the cube in my first example...here's what happens then: (simplified example).sphere { background: black; width: 300px; height: 300px; border-radius: 100vw; animation: myrotate 10s linear infinite}@keyframes myrotate { 0% { transform: rotate3d(0, 0, 0, 0); } 100% { transform: rotate3d(0, 1, 0, 360deg); }}<div class="sphere"></div>All you get is a flat 2d object - which is expeceted considering that it's what the element isThe closest thing I found is the following shape created in a tutorial by Timo Korinth @-webkit-keyframes animateWorld { 0% { -webkit-transform: rotateY(0deg) rotateX(0deg) rotateZ(0deg); } 50% { -webkit-transform: rotateY(360deg) rotateX(180deg) rotateZ(180deg); } 100% { -webkit-transform: rotateY(720deg) rotateX(360deg) rotateZ(360deg); }}html { background: #FFFFFF;}. world { -webkit-perspective: 1000px;}.cube { margin-left: auto; margin-right: auto; position: relative; width: 200px; height: 200px; -webkit-transform-style: preserve-3d; -webkit-animation-name: animateWorld; -webkit-animation-duration: 10s; -webkit-animation-iteration-count: infinite; -webkit-animation-timing-function: linear;}.circle { position: absolute; width: 100%; height: 100%; border: 2px dashed #009BC2; border-radius: 50%; opacity: 0.8; background: rgba(255, 255, 255, 0);}.zero { -webkit-transform: rotateX(90deg);}.two { -webkit-transform: rotateY(45deg);}.three { -webkit-transform: rotateY(90deg);}.four { -webkit-transform: rotateY(135deg);}.five { width: 173px; height: 173px; margin: 14px; -webkit-transform: rotateX(90deg) translateZ(50px);}.six { width: 173px; height: 173px; margin: 14px; -webkit-transform: rotateX(90deg) translateZ(-50px);}<div class="world"> <div class="cube"> <div class="circle zero"></div> <div class="circle one"></div> <div class="circle two"></div> <div class="circle three"></div> <div class="circle four"></div> <div class="circle five"></div> <div class="circle six"></div> </div></div>So here's my Question:How do I create an actual 3 dimensional sphere with pure CSS? More specifically, one that is covered - not just a frame - and doesn't involve hundreds of html elements. Notes: Three dimensional spheres have height, width and depth - justlike the cube in my first example snippetI don't need any physics and there's no need for anyuser-interaction. Just an animated spinning sphere.Additional resources:paulrhayes.com - Spheres3d (2d illusion) Earth with Rotating Animation with CSSInteractive CSS sphere 解决方案 Strictly speaking, any "3D" shape on a flat screen is more an illusion of a 3D object. All we see is a 2D projection of that shape on the screen plane, and our brain does its best to guess which shape could give the projection we see. If the projection changes, our brain interprets it as a 3D object changing its orientation, which helps it to determine the shape of this object better.It works well with non-symmetric objects and objects made from polygons (e.g., cubes), but the sphere is a very special case: its projection on the plane always gives just a circle. The static sphere and the rotating one have the same projection, the same circle. Even in real life, if we look at a sphere with a uniform surface without any marks on it (e.g., a polished metal ball), it is hard to determine if it stands still or rotates. Our eyes need some hints, some details that are moving along the surface of the sphere according to its geometry. The more such details move the way you expect from points on the spherical surface to move, the clearer is the perception (well, illusion) of the rotating sphere.And here is the key to the problem in making a CSS scene that would give such perception: to make this illusion strong enough, we need many marks moving along the paths that lie in different planes. And the only way to get this in CSS is to have each mark as a separate CSS box (element or pseudo-element). If our sphere consists only of moving marks, we really need many of them to see it as a sphere — thus "hundreds of elements" in most demos you have seen.So if you want to make a sphere look realistic with a reasonably small number of elements, you would probably need to combine the effects that make an "illusion" of a static basic spherical shape (a circle with radial gradients, inner shadows etc.) with some elements that are relatively small (to make it less obvious that they are actually flat), oriented along the surface of the sphere with 3D transforms, and animated — basically the same way as the faces of the cube in your first demo.Below is my own attempt to put this approach into practice. I used 20 circular elements oriented roughly as the faces of the regular icosahedron (like white hexagons on the classic soccer ball). I grouped them into two groups each making one hemisphere for convenience (it was not necessary, but it made styling a bit simpler). The whole 3D scene consists of the sphere itself and the background frame (pseudo element) which crosses the sphere near its centre (a bit closer, to reduce "flickering" of the circles as they go from the near side to the far side and back) and always faces to the screen. So 24 elements in total (not literally "hundreds", at least:). To make the circles look more "bulging" (like spherical segments), I added two pseudo elements to each of them and elevated them slightly one above other. Works best in Chrome and Firefox 57+ (in Firefox 56- and iOS Safari there is still some "flickering" near the edges). If you hover the circle, you can see the scene without the background frame (and also without "flickering"). A slightly modified version is also available on Codepen. .scene { perspective: 400vmin; transform-style: preserve-3d; position: absolute; width: 80vmin; height: 80vmin; top: 10vmin; left: 10vmin;}.sphere { transform-style: preserve-3d; position: absolute; animation: rotate 20s infinite linear; width: 100%; height: 100%; transform-origin: 50% 50%; top: 0; left: 0;}.scene::before { content: ''; position: absolute; width: 100%; height: 100%; top: 0%; left: 0%; background: radial-gradient(circle farthest-corner at 33% 33%, rgba(240, 240, 220, 0.85) 0%, rgba(30, 30, 40, 0.85) 80%), radial-gradient(circle farthest-corner at 45% 45%, rgba(0, 0, 0, 0) 50%, #000000 80%); border-radius: 50%; transform: translateZ(2vmin);}.scene:hover::before { display: none;}.hemisphere { position: absolute; top: 0; left: 0; width: 100%; height: 100%; transform-style: preserve-3d; transform-origin: 50% 50%; transform: rotateX(90deg);}.hemisphere:nth-child(2) { transform: rotateX(-90deg);}.face { position: absolute; width: 40vmin; height: 40vmin; background: radial-gradient(circle at 50% 50%, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.1) 48%, #ff0000 49%, #ff0000 50%, rgba(0, 0, 0, 0) 51%); transform-style: preserve-3d; transform-origin: 50% 0; top: 50%; left: 20vmin;}.face::before, .face::after { content: ''; position: absolute; border-radius: 50%; box-sizing: border-box;}.face::before { width: 50%; height: 50%; top: 25%; left: 25%; border: 2px solid #333; background: rgba(255, 255, 255, 0.3); transform: translateZ(1.6vmin);}.face::after { width: 20%; height: 20%; top: 40%; left: 40%; background: rgba(0, 0, 0, 0.2); transform: translateZ(2.8vmin);}.face:nth-child(1) { transform: translateZ(-41.6vmin) rotateZ(36deg) translateY(-6.8vmin) rotateX(143deg);}.face:nth-child(2) { transform: translateZ(-41.6vmin) rotateZ(108deg) translateY(-6.8vmin) rotateX(143deg);}.face:nth-child(3) { transform: translateZ(-41.6vmin) rotateZ(180deg) translateY(-6.8vmin) rotateX(143deg);}.face:nth-child(4) { transform: translateZ(-41.6vmin) rotateZ(252deg) translateY(-6.8vmin) rotateX(143deg);}.face:nth-child(5) { transform: translateZ(-41.6vmin) rotateZ(-36deg) translateY(-6.8vmin) rotateX(143deg);}.face:nth-child(6) { transform: translateZ(-26.8vmin) rotateZ(36deg) translateY(-33.2vmin) rotateX(100deg);}.face:nth-child(7) { transform: translateZ(-26.8vmin) rotateZ(108deg) translateY(-33.2vmin) rotateX(100deg);}.face:nth-child(8) { transform: translateZ(-26.8vmin) rotateZ(180deg) translateY(-33.2vmin) rotateX(100deg);}.face:nth-child(9) { transform: translateZ(-26.8vmin) rotateZ(252deg) translateY(-33.2vmin) rotateX(100deg);}.face:nth-child(10) { transform: translateZ(-26.8vmin) rotateZ(-36deg) translateY(-33.2vmin) rotateX(100deg);}.face:nth-child(11) { transform: translateZ(-26.8vmin) rotateZ(36deg) translateY(-33.2vmin) rotateX(100deg);}@keyframes rotate { 0% {transform: rotateZ(25deg) rotateX(20deg) rotateY(0deg); } 50% {transform: rotateZ(-25deg) rotateX(-20deg) rotateY(180deg); } 100% {transform: rotateZ(25deg) rotateX(20deg) rotateY(360deg); }}body { background: #555; overflow: hidden;}<div class="scene"> <div class="sphere"> <div class="hemisphere"> <div class="face"></div> <div class="face"></div> <div class="face"></div> <div class="face"></div> <div class="face"></div> <div class="face"></div> <div class="face"></div> <div class="face"></div> <div class="face"></div> <div class="face"></div> </div> <div class="hemisphere"> <div class="face"></div> <div class="face"></div> <div class="face"></div> <div class="face"></div> <div class="face"></div> <div class="face"></div> <div class="face"></div> <div class="face"></div> <div class="face"></div> <div class="face"></div> </div> </div></div> 这篇关于如何创建纯CSS 3维球体?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
09-18 21:34