Comment créer une sphère en css?

j'ai essayé de créer une sphère 3D en utilisant simplement du CSS pur, mais j'ai été incapable de générer la forme requise. J'ai vu un cylindre mais je ne trouve aucune référence à la création d'une véritable sphère .

mon code actuel ressemble à:

.red {
  background-color: red;
}
.green {
  background-color: green;
}
.blue {
  background-color: blue;
}
.yellow {
  background-color: yellow;
}
.sphere {
  height: 200px;
  width: 200px;
  border-radius: 50%;
  text-align: center;
  vertical-align: middle;
  font-size: 500%;
  position: relative;
  box-shadow: inset -10px -10px 100px #000, 10px 10px 20px black, inset 0px 0px 10px black;
  display: inline-block;
  margin: 5%;
}
.sphere::after {
  background-color: rgba(255, 255, 255, 0.3);
  content: '';
  height: 45%;
  width: 12%;
  position: absolute;
  top: 4%;
  left: 15%;
  border-radius: 50%;
  transform: rotate(40deg);
}
html lang-html prettyprint-override"><div class="sphere red"></div>
<div class="sphere green"></div>
<div class="sphere blue"></div>
<div class="sphere yellow"></div>
<div class="sphere"></div>

toutefois,

  • A: ce ne sont que des cercles 2D, pas des formes 3D
  • B: Je ne peux pas les faire tourner en 3d (je veux avoir une image tournante) similaire à celle d'un globe.

désolé si j'ai manqué quelque chose, mais je ne sais pas trop où je devrais aller pour demander ça.

7
demandé sur Max Payne 2015-06-17 15:40:17

5 réponses

Au-dessous de la réponse n'est pas une forme 3D à la . Il donne seulement une légère illusion D'être 3D, cependant, selon votre cas d'utilisation, vous pouvez être en mesure de "fake" il:

html,body{margin:0;padding:0;background:#222;}
div{
    height:300px;
    width:300px;
    background:url(http://lorempixel.com/300/300);
    border-radius:50%;
    animation:spin 3s linear infinite;
    transform:rotate(-15deg);
    position:relative;
}
div:before{
    content:"";
    position:absolute;
    bottom:-50px;
    border-radius:50%;
    left:0;
    height:10%;
    width:100%;
    transform:rotate(15deg);
    background:rgba(0,0,0,0.6);
    box-shadow: 0 0 10px 2px rgba(0,0,0,0.6);
    
}
div:after{
    content:"";
    position:absolute;z-index:12;
    top:0;left:0;height:100%;width:100%;border-radius:50%;
box-shadow:inset -20px -20px 20px 2px #222, inset 20px 20px 20px 5px rgba(200,200,200,0.4);    
}
@keyframes spin{
    to{background-position:-300px 0;}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div></div>

c'est animer le background-position de la div, et en utilisant des ombres de boîte, vous pourriez 'imiter' l'ombre d'une forme 3D.

6
répondu jbutler483 2015-06-29 10:36:13

vous pourriez vouloir utiliser 3D cercles tournés :

cela utilise des cercles rotatifs pour ressembler à une grille sphérique. le moindre pas. des éléments, meilleures sont les performances.

certains éléments ont été mis en rotation dans l'axe des abscisses et d'autres dans l'axe des ordonnées. J'ai rempli différentes couleurs pour montrer ceci:

#cont {
  perspective: 10000px;
  transform-style: preserve-3d;
  -webkit-animation: rotat 1s linear infinite;
  animation: rotat 10s linear infinite;
  transform-origin: 50% 50% 50%;
}
.circ {
  height: 200px;
  width: 200px;
  border: 2px solid black;
  border-radius: 50%;
  position: absolute;
  top: 50px;
  left: 50%;
  margin-left: -100px;
  transform-origin: 50%;
  transform-style: preserve-3d;
  background: orange;
}
.circ:nth-child(1) {
  transform: rotateX(0deg);
}
.circ:nth-child(2) {
  transform: rotateX(30deg);
}
.circ:nth-child(3) {
  transform: rotateX(60deg);
}
.circ:nth-child(4) {
  transform: rotateX(90deg);
}
.circ:nth-child(5) {
  transform: rotateX(120deg);
}
.circ:nth-child(6) {
  transform: rotateX(150deg);
}
.circ:nth-child(7) {
  transform: rotateX(180deg);
}
/*other side rotated*/

.circ:nth-child(8) {
  transform: rotateY(30deg);
}
.circ:nth-child(9) {
  transform: rotateY(60deg);
}
.circ:nth-child(10) {
  transform: rotateY(90deg);
}
.circ:nth-child(11) {
  transform: rotateY(120deg);
}
.circ:nth-child(12) {
  transform: rotateY(150deg);
}
.circ:nth-child(13) {
  transform: rotateY(180deg);
}
.oth {
  background: crimson;
}
@-webkit-keyframes rotat {
  0% {
    -webkit-transform: rotateY(0deg) translateX(0);
  }
  100% {
    -webkit-transform: rotateY(360deg);
  }
}
@keyframes rotat {
  0% {
    transform: rotateY(0deg);
  }
  100% {
    transform: rotateY(360deg);
  }
}
<div id="cont">
  <div class="circ"></div>
  <div class="circ"></div>
  <div class="circ"></div>
  <div class="circ"></div>
  <div class="circ"></div>
  <div class="circ"></div>
  <div class="circ"></div>
  <!--rotated other side-->
  <div class="circ oth"></div>
  <div class="circ oth"></div>
  <div class="circ oth"></div>
  <div class="circ oth"></div>
  <div class="circ oth"></div>
  <div class="circ oth"></div>
</div>

vous pouvez également tourner certains éléments dans la direction Z, mais cela le rendra encore plus buggé. Maintenant si vous remplissez les mêmes couleurs en cercles, il ressemble presque à une sphère :

#cont {
  perspective: 10000px;
  transform-style: preserve-3d;
  -webkit-animation: rotat 1s linear infinite;
  animation: rotat 10s linear infinite;
  transform-origin: 50% 50% 50%;
}
.circ {
  height: 200px;
  width: 200px;
  border: 2px solid black;
  border-radius: 50%;
  position: absolute;
  top: 50px;
  left: 50%;
  margin-left: -100px;
  transform-origin: 50%;
  transform-style: preserve-3d;
  background: crimson;
}
.circ:nth-child(1) {
  transform: rotateX(0deg);
}
.circ:nth-child(2) {
  transform: rotateX(30deg);
}
.circ:nth-child(3) {
  transform: rotateX(60deg);
}
.circ:nth-child(4) {
  transform: rotateX(90deg);
}
.circ:nth-child(5) {
  transform: rotateX(120deg);
}
.circ:nth-child(6) {
  transform: rotateX(150deg);
}
.circ:nth-child(7) {
  transform: rotateX(180deg);
}
/*other side rotated*/

.circ:nth-child(8) {
  transform: rotateY(30deg);
}
.circ:nth-child(9) {
  transform: rotateY(60deg);
}
.circ:nth-child(10) {
  transform: rotateY(90deg);
}
.circ:nth-child(11) {
  transform: rotateY(120deg);
}
.circ:nth-child(12) {
  transform: rotateY(150deg);
}
.circ:nth-child(13) {
  transform: rotateY(180deg);
}
.o {
  border: none;
}
@-webkit-keyframes rotat {
  0% {
    -webkit-transform: rotateY(0deg);
  }
  100% {
    -webkit-transform: rotateY(360deg);
  }
}
@keyframes rotat {
  0% {
    transform: rotateY(0deg);
  }
  100% {
    transform: rotateY(360deg);
  }
}
<div id="cont">
  <div class="circ"></div>
  <div class="circ"></div>
  <div class="circ"></div>
  <div class="circ"></div>
  <div class="circ"></div>
  <div class="circ"></div>
  <div class="circ"></div>
  <!--rotated other side-->
  <div class="circ o"></div>
  <div class="circ o"></div>
  <div class="circ o"></div>
  <div class="circ o"></div>
  <div class="circ o"></div>
  <div class="circ o"></div>
</div>
7
répondu Max Payne 2015-06-22 15:13:07

J'utilise JavaScript pour construire la sphère qui a formé par de nombreux éléments div. Pour maintenir la performance du navigateur, les éléments div sont faits aussi peu que possible.

var DIAMETER = 200;
var CELLS_PER_CIRCLE = 26;
var IMG_CELL = 'https://sites.google.com/site/zulnasibu/sphere/earth.png';
var NAME = 'sphere';
var WRAP = NAME + '-wrapper';
var _cssRules = '';
var _cellW;
var _cellAmount = 0;
var _imgW;
var _imgH;

function createFace(w, h, rx, ry, tz, ts, tsx, tsy, cname) {
	var face = document.createElement("div");
	var css;
	var cssText =
		'width: ' + w.toFixed(2) + 'px;' +
		'height: ' + h.toFixed(2) + 'px;' +
		'margin-left: ' + (-w / 2).toFixed(2) + 'px;' +
		'margin-top: ' + (-h / 2).toFixed(2) + 'px;' +
		'background: url("' + ts + '") ' + tsx.toFixed(2) + 'px ' + tsy.toFixed(2) + 'px;';
	css = 'transform: rotateY(' + ry.toFixed(2) + 'rad) rotateX(' + rx.toFixed(2) + 'rad) translateZ(' + tz.toFixed(2) + 'px);';
	cssText += addVendorPrefix(css);
	face.className = cname;
	face.style.cssText = cssText;
	return face;
}

function createModel() {
	var wrap = document.createElement("div");
	var model = document.createElement("div");
	wrap.className = WRAP;
	model.className = NAME;
	if (CELLS_PER_CIRCLE % 2 != 0) CELLS_PER_CIRCLE++;
	if (CELLS_PER_CIRCLE < 4) CELLS_PER_CIRCLE = 4;
	var baseAngle = Math.PI / CELLS_PER_CIRCLE;
	var cellAngle = 2 * baseAngle;
	_cellW = DIAMETER * Math.tan(baseAngle);
	_imgW = _cellW * CELLS_PER_CIRCLE;
	_imgH = CELLS_PER_CIRCLE / 2;
	if (CELLS_PER_CIRCLE % 4 == 0) _imgH++;
	_imgH *= _cellW;
	var xc = Math.ceil(CELLS_PER_CIRCLE / -4);
	var yc, rx, ry, tx, ty = -_imgH, tw, cang, cdia, cw;
	for (var x = xc; x <= -xc; x++) {
		rx = x * cellAngle;
		cw = _cellW;
		yc = CELLS_PER_CIRCLE;
		if (Math.abs(rx) == Math.PI / 2)
			yc = 1;
		else if (Math.abs(x) != 1) {
			cang = rx - Math.sign(x) * cellAngle / 2;
			cdia = DIAMETER * Math.cos(cang);
			cw = cdia * Math.tan(baseAngle);
		}
		_cellAmount += yc;
		tw = cw * yc;
		tx = (tw - _imgW) / 2;
		ty += _cellW;
		for (var y = 0; y < yc; y++) {
			ry = y * cellAngle;
			model.appendChild(createFace(cw + 1, _cellW + 1, rx, ry, DIAMETER / 2, IMG_CELL, tx, ty, 'cell' + x.toString() + y.toString()));
			tx -= cw;
		}
	}
	wrap.appendChild(model);
	var style = document.createElement('style');
	style.type = 'text/css';
	if (style.styleSheet)
		style.styleSheet.cssText = _cssRules;
	else
		style.innerHTML = _cssRules;
	document.head.appendChild(style);
	return wrap;
}

function addVendorPrefix(property) {
	return	'-webkit-' + property +
			'-moz-' + property +
			'-o-' + property +
			property;
}

function showGeometry(elm) {
	if (elm.checked)
		document.querySelector('.sphere').classList.add('show-geometry');
	else
		document.querySelector('.sphere').classList.remove('show-geometry');
}

document.body.appendChild(createModel());
.sphere-wrapper {
	position: absolute;
	top: 50%;
	left: 50%;
	-webkit-perspective: 1000px;
	-moz-perspective: 1000px;
	-o-perspective: 1000px;
	perspective: 1000px;
}
.sphere {
	position: absolute;
	-webkit-transform-style: preserve-3d;
	-moz-transform-style: preserve-3d;
	-o-transform-style: preserve-3d;
	transform-style: preserve-3d;
	-webkit-transform-origin: center center -100px;
	-moz-transform-origin: center center -100px;
	-o-transform-origin: center center -100px;
	transform-origin: center center -100px;
	-webkit-animation: spin 60s infinite linear;
	-moz-animation: spin 60s infinite linear;
	-o-animation: spin 60s infinite linear;
	animation: spin 60s infinite linear;
}
.sphere div {
	position: absolute;
	-webkit-backface-visibility: hidden;
	-moz-backface-visibility: hidden;
	-o-backface-visibility: hidden;
	backface-visibility: hidden;
}
@-webkit-keyframes spin {
	010.00% {-webkit-transform: rotateX(   0deg) rotateY( 360deg) rotateZ(   0deg);}
	020.00% {-webkit-transform: rotateX( 360deg) rotateY( 360deg) rotateZ(   0deg);}
	030.00% {-webkit-transform: rotateX( 720deg) rotateY( 720deg) rotateZ(   0deg);}
	100.00% {-webkit-transform: rotateX(2880deg) rotateY(3240deg) rotateZ(2520deg);}
}
@-moz-keyframes spin {
	010.00% {-moz-transform: rotateX(   0deg) rotateY( 360deg) rotateZ(   0deg);}
	020.00% {-moz-transform: rotateX( 360deg) rotateY( 360deg) rotateZ(   0deg);}
	030.00% {-moz-transform: rotateX( 720deg) rotateY( 720deg) rotateZ(   0deg);}
	100.00% {-moz-transform: rotateX(2880deg) rotateY(3240deg) rotateZ(2520deg);}
}
@-o-keyframes spin {
	010.00% {-o-transform: rotateX(   0deg) rotateY( 360deg) rotateZ(   0deg);}
	020.00% {-o-transform: rotateX( 360deg) rotateY( 360deg) rotateZ(   0deg);}
	030.00% {-o-transform: rotateX( 720deg) rotateY( 720deg) rotateZ(   0deg);}
	100.00% {-o-transform: rotateX(2880deg) rotateY(3240deg) rotateZ(2520deg);}
}
@keyframes spin {
	010.00% {transform: rotateX(   0deg) rotateY( 360deg) rotateZ(   0deg);}
	020.00% {transform: rotateX( 360deg) rotateY( 360deg) rotateZ(   0deg);}
	030.00% {transform: rotateX( 720deg) rotateY( 720deg) rotateZ(   0deg);}
	100.00% {transform: rotateX(2880deg) rotateY(3240deg) rotateZ(2520deg);}
}
input, input~ label {
	cursor: pointer;
}
input:checked~ label {
	color: #f77;
}
.show-geometry div {
	background: rgba(160, 160, 160, 0.5) !important;
	border: 1px solid #333;
	-webkit-backface-visibility: visible;
	-moz-backface-visibility: visible;
	-o-backface-visibility: visible;
	backface-visibility: visible;
}
<input id="show-geometry" type="checkbox" onchange="showGeometry(this);">
<label for="show-geometry">Show geometry</label>
6
répondu ZulNs 2015-12-24 22:40:17

forme de sphère

il n'y a pas de formes 3D réelles en html5

Mais vous pouvez empiler des formes 2D les unes sur les autres.

Avec ceci à l'Esprit, vous pouvez créer une représentation assez proche d'une sphère.

.container {
  perspective: 1000px;
  //transform-style: preserve-3d;
  width: 300px;
  height: 300px;
  border: 5px solid pink;
}
.circ {
  transform-style: preserve-3d;
  border: 5px solid firebrick;
  border-radius: 50%;
  position: absolute;
  top: 50%;
  left: 50%;
  transform-origin: center;
  transform: translateX(-50%) translateY(-50%);
  transition: transform 2s linear;
}
.circ:nth-of-type(1) {
  height: 10%;
  width: 10%;
  transform: translateX(-50%) translateY(-50%) rotateX(40deg) rotateY(40deg) translateZ(-55px);
}
.circ:nth-of-type(2) {
  height: 20%;
  width: 20%;
  transform: translatex(-50%) translateY(-50%) rotateX(40deg) rotateY(40deg) translateZ(-45px);
}
.circ:nth-of-type(3) {
  height: 30%;
  width: 30%;
  transform: translatex(-50%) translateY(-50%) rotateX(40deg) rotateY(40deg) translateZ(-25px);
}
.circ:nth-of-type(4) {
  height: 40%;
  width: 40%;
  transform: translatex(-50%) translateY(-50%) rotateX(40deg) rotateY(40deg) translateZ(-10px);
}
.circ:nth-of-type(5) {
  height: 40%;
  width: 40%;
  transform: translatex(-50%) translateY(-50%) rotateX(40deg) rotateY(40deg) translateZ(10px);
}
.circ:nth-of-type(6) {
  height: 30%;
  width: 30%;
  transform: translatex(-50%) translateY(-50%) rotateX(40deg) rotateY(40deg) translateZ(25px);
}
.circ:nth-of-type(7) {
  height: 20%;
  width: 20%;
  transform: translatex(-50%) translateY(-50%) rotateX(40deg) rotateY(40deg) translateZ(45px);
}
.circ:nth-of-type(8) {
  height: 10%;
  width: 10%;
  transform: translatex(calc(-50%)) translateY(-50%) rotateX(40deg) rotateY(40deg) translateZ(55px);
}
/*ANIMATION*/

.container:hover .circ:nth-of-type(1) {
  transform: translateX(-50%) translateY(-50%) rotateX(180deg) rotateY(40deg) translateZ(-60px);
}
.container:hover .circ:nth-of-type(2) {
  transform: translatex(-50%) translateY(-50%) rotateX(180deg) rotateY(40deg) translateZ(-40px);
}
.container:hover .circ:nth-of-type(3) {
  transform: translatex(-50%) translateY(-50%) rotateX(180deg) rotateY(40deg) translateZ(-20px);
}
.container:hover .circ:nth-of-type(4) {
  transform: translatex(-50%) translateY(-50%) rotateX(180deg) rotateY(40deg) translateZ(0px);
}
.container:hover .circ:nth-of-type(5) {
  transform: translatex(-50%) translateY(-50%) rotateX(180deg) rotateY(40deg) translateZ(20px);
}
.container:hover .circ:nth-of-type(6) {
  transform: translatex(-50%) translateY(-50%) rotateX(180deg) rotateY(40deg) translateZ(40px);
}
.container:hover .circ:nth-of-type(7) {
  transform: translatex(-50%) translateY(-50%) rotateX(180deg) rotateY(40deg) translateZ(60px);
}
.container:hover .circ:nth-of-type(8) {
  transform: translatex(-50%) translateY(-50%) rotateX(180deg) rotateY(40deg) translateZ(70px);
}
.container:hover {
  background-color: #f2f2f2;
}
<div class="container">
  <div class="circ"></div>
  <div class="circ"></div>
  <div class="circ"></div>
  <div class="circ"></div>
  <div class="circ"></div>
  <div class="circ"></div>
  <div class="circ"></div>
  <div class="circ"></div>
</div>
5
répondu Persijn 2015-06-17 15:34:20

#cont {
  perspective: 10000px;
  transform-style: preserve-3d;
  -webkit-animation: rotat 1s linear infinite;
  animation: rotat 10s linear infinite;
  transform-origin: 50% 50% 50%;
}
.circ {
  height: 200px;
  width: 200px;
  border: 2px solid black;
  border-radius: 50%;
  position: absolute;
  top: 50px;
  left: 50%;
  margin-left: -100px;
  transform-origin: 50%;
  transform-style: preserve-3d;
  background: orange;
}
.circ:nth-child(1) {
  transform: rotateX(0deg);
}
.circ:nth-child(2) {
  transform: rotateX(30deg);
}
.circ:nth-child(3) {
  transform: rotateX(60deg);
}
.circ:nth-child(4) {
  transform: rotateX(90deg);
}
.circ:nth-child(5) {
  transform: rotateX(120deg);
}
.circ:nth-child(6) {
  transform: rotateX(150deg);
}
.circ:nth-child(7) {
  transform: rotateX(180deg);
}
/*other side rotated*/

.circ:nth-child(8) {
  transform: rotateY(30deg);
}
.circ:nth-child(9) {
  transform: rotateY(60deg);
}
.circ:nth-child(10) {
  transform: rotateY(90deg);
}
.circ:nth-child(11) {
  transform: rotateY(120deg);
}
.circ:nth-child(12) {
  transform: rotateY(150deg);
}
.circ:nth-child(13) {
  transform: rotateY(180deg);
}
.oth {
  background: crimson;
}
@-webkit-keyframes rotat {
  0% {
    -webkit-transform: rotateY(0deg) translateX(0);
  }
  100% {
    -webkit-transform: rotateY(360deg);
  }
}
@keyframes rotat {
  0% {
    transform: rotateY(0deg);
  }
  100% {
    transform: rotateY(360deg);
  }
}
<div id="cont">
  <div class="circ"></div>
  <div class="circ"></div>
  <div class="circ"></div>
  <div class="circ"></div>
  <div class="circ"></div>
  <div class="circ"></div>
  <div class="circ"></div>
  <!--rotated other side-->
  <div class="circ oth"></div>
  <div class="circ oth"></div>
  <div class="circ oth"></div>
  <div class="circ oth"></div>
  <div class="circ oth"></div>
  <div class="circ oth"></div>
</div>
0
répondu EasterMedia 2018-08-21 21:43:17