tl;dr : J'aimerais créer une véritable sphère en 3D avec CSS, et pas seulement une illusion.
Note : certains des exemples de snippets ne sont pas responsive. Veuillez utiliser le plein écran.
Avec le CSS pur, vous pouvez créer et animer un cube 3d comme ceci :
#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>
Je veux créer et animer une sphère 3d de la même manière.
Donc... la première idée qui me vient est d'utiliser border-radius
et... eh bien... ça ne marche pas.
#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>
J'ai donc reconsidéré mon approche et cherché une autre méthode.
J'ai regardé :
- Mise en œuvre de "Pure CSS Sphere" dans un site web - comment faire ?
- Comment créer une sphère en css ?
- Afficher une image enroulée autour d'une sphère avec CSS/Javascript
- cssanimation.rocks - Sphères CSS
- MDN - Cercle
Puis j'ai réessayé... les meilleurs résultats que j'ai obtenus étaient trop... compliqué Objet 3d illusions .
Comme ça :
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>
Et ceci :
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>
Ce qui ne pose aucun problème jusqu'à ce que vous essayiez de les faire tourner sur l'un ou l'autre des systèmes suivants Axe x ou le axe y comme le cube de mon premier exemple... voici ce qui se passe alors : (exemple simplifié)
.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>
Tout ce que vous obtenez, c'est un objet plat en 2D, ce qui est normal puisque c'est ce qu'est l'élément.
La chose la plus proche que j'ai trouvée est la forme suivante créée dans une tutoriel par 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>
Alors voici mon
Question :
Comment créer une sphère tridimensionnelle réelle avec du pur CSS ? Plus précisément, une sphère qui soit couverte - pas seulement un cadre - et qui n'implique pas des centaines d'éléments html.
Notes :
- Les sphères tridimensionnelles ont hauteur, largeur et profondeur - juste comme le cube de mon premier exemple.
- Je n'ai pas besoin de physique et il n'y a pas besoin d'une quelconque d'interaction avec l'utilisateur. Juste une sphère animée qui tourne.
Ressources supplémentaires :