How to create a sphere in css?

前端 未结 5 2121
臣服心动
臣服心动 2020-12-29 12:27

I have trying to create a 3D sphere using just pure css, but I\'ve been unable to generate the shape required. I\'ve seen a cylinder but I can\'t find any reference to creat

5条回答
  •  甜味超标
    2020-12-29 13:07

    I use JavaScript to build the sphere which formed by many div elements. To maintain the browser performance, the div elements are made as little as 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;
    }
    
    

提交回复
热议问题