tl;dr: 我想用 CSS 创建一个实际的 3d 球体——而不仅仅是幻觉
注意:一些片段示例没有响应。请使用全屏。
使用纯 CSS,您可以像这样 创建 3d 立方体并为其设置动画:
#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>
我想以相同的方式创建一个 3d 球体并为其设置动画。
所以……我得到的第一个想法是使用 border-radius
并且……好吧……它不起作用。
#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>
所以,我重新考虑了我的方法,并寻找了一种不同的方法。
我看着:
- 在网站中实现“纯 CSS Sphere”——我该怎么做?
- 如何在css中创建一个球体?
- 使用 CSS/Javascript 显示环绕球体的图像
- cssanimation.rocks - CSS 球体
- MDN - 圈子
然后我又试了一次……我得到的最好的结果是过于 复杂 的 3d 对象 幻觉。
像这样:
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>
和这个:
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>
在您尝试像我的第一个示例中的立方体一样在 x 轴 或 y 轴上 实际旋转它们之前,这是可以的……接下来会发生什么:(简化示例)
.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>
你得到的只是一个平面的 2d 对象 - 考虑到它就是元素,这是可以预期的
我发现的最接近的是 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>
所以这是我的
问题:
如何使用纯 CSS 创建一个实际的 3 维球体?更具体地说,一个被覆盖的——不仅仅是一个框架——并且不涉及数百个 html 元素。
笔记:
- 三维球体具有 高度、宽度和深度——就像我的第一个示例片段中的立方体一样
- 我不需要任何物理,也不需要任何用户交互。只是一个动画旋转球体。
其他资源:
原文由 I haz kode 发布,翻译遵循 CC BY-SA 4.0 许可协议
在没有 JavaScript+WebGL 的情况下我能看到的唯一方法是使用自定义过滤器编写一个顶点着色器,将 6 个立方体面的顶点映射到一个球体。您获取顶点法线并将它们乘以球体半径。会有一些拉伸,但它和 CSS 一样好
https://developers.google.com/web/updates/2013/03/Introduction-to-Custom-Filters-aka-CSS-Shaders