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
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;
}