JSFiddle - React, Tailwind, and code Playground
by Michael Prosser
HTML
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<div class="sphere">
<div class="sphere-inner">
<div class="sphere-inner-inner">
<div class="sphere-inner-top-10"></div>
<div class="sphere-inner-top-9"></div>
<div class="sphere-inner-top-8"></div>
<div class="sphere-inner-top-7"></div>
<div class="sphere-inner-top-6"></div>
<div class="sphere-inner-top-5"></div>
<div class="sphere-inner-top-4"></div>
<div class="sphere-inner-top-3"></div>
<div class="sphere-inner-top-2"></div>
<div class="sphere-inner-top-1"></div>
<div class="sphere-inner-middle"></div>
<div class="sphere-inner-bottom-1"></div>
<div class="sphere-inner-bottom-2"></div>
<div class="sphere-inner-bottom-3"></div>
<div class="sphere-inner-bottom-4"></div>
<div class="sphere-inner-bottom-5"></div>
<div class="sphere-inner-bottom-6"></div>
<div class="sphere-inner-bottom-7"></div>
<div class="sphere-inner-bottom-8"></div>
<div class="sphere-inner-bottom-9"></div>
<div class="sphere-inner-bottom-10"></div>
</div>
</div>
</div>
CSS
html{
height:100%;
}
body{
height:100%;
perspective:500px;
background-color:#000;
}
.sphere{
position:absolute;
top:50%;
left:50%;
width:0px;
height:0px;
transform-style:preserve-3d;
/*animation: rolling infinite linear 10s;*/
}
.sphere-inner{
position:absolute;
top:50%;
left:50%;
width:0px;
height:0px;
transform-style:preserve-3d;
/*animation: rolling infinite linear 10s;*/
}
.sphere-inner-inner{
position:absolute;
top:50%;
left:50%;
width:0px;
height:0px;
transform-style:preserve-3d;
/*animation: rolling infinite linear 10s;*/
}
@keyframes rolling{
0%{ transform: rotateX(30deg) rotateY(0deg); }
100%{ transform: rotateX(30deg) rotateY(360deg); }
}
.sphere-inner-inner>div{
position:absolute;
width:100px;
height:100px;
margin-top:-50px;
margin-left:-50px;
border-radius:50%;
background-color:rgba(255,0,0,0.1);
}
.sphere-inner-top-1{ transform:translateZ(5px) scale(.98); }
.sphere-inner-top-2{ transform:translateZ(10px) scale(.96); }
.sphere-inner-top-3{ transform:translateZ(15px) scale(.94); }
.sphere-inner-top-4{ transform:translateZ(20px) scale(.90); }
.sphere-inner-top-5{ transform:translateZ(25px) scale(.84); }
.sphere-inner-top-6{ transform:translateZ(30px) scale(.76); }
.sphere-inner-top-7{ transform:translateZ(35px) scale(.68); }
.sphere-inner-top-8{ transform:translateZ(40px) scale(.56); }
.sphere-inner-top-9{ transform:translateZ(45px) scale(.42); }
.sphere-inner-top-10{ transform:translateZ(50px) scale(.18); }
.sphere-inner-bottom-1{ transform:translateZ(-5px) scale(.98); }
.sphere-inner-bottom-2{ transform:translateZ(-10px) scale(.96); }
.sphere-inner-bottom-3{ transform:translateZ(-15px) scale(.94); }
.sphere-inner-bottom-4{ transform:translateZ(-20px) scale(.90); }
.sphere-inner-bottom-5{ transform:translateZ(-25px) scale(.84); }
.sphere-inner-bottom-6{ transform:translateZ(-30px) scale(.76); }
.sphere-inner-bottom-7{ transform:translateZ(-35px) scale(.68); }
.sphere-inner-bottom-8{...
JavaScript
var sphere = {
radius: 50,
circumfrance: 0,
rotation_to_pixels: 0,
element_left: $('.sphere'),
element_right: $('.sphere'),
element_left_inner: $('.sphere-inner'),
element_right_inner: $('.sphere-inner'),
element_left_inner_inner: $('.sphere-inner-inner'),
element_right_inner_inner: $('.sphere-inner-inner'),
direction_x: '',
direction_z: '',
speed: 4,
position: { rx:0, ry:0, rz:0, x:0, y:0, z:0 },
last_position: { rx:0, ry:0, rz:0, x:0, y:0, z:0 },
to_lowest_degree:function(num){
if(num < 0){
while(num < 0){
num+=360;
}
return num;
} else if(num > 0){
while(num > 360){
num-=360;
}
return num;
} else {
return 0;
}
},
nextPosition: function(x,y,z,rx,ry,rz,d){
var angle_rx_inradians = rx * Math.PI / 180;
var angle_ry_inradians = ry * Math.PI / 180;
var z2 = z + Math.cos(angle_ry_inradians) * (d*-1);
var x2 = x + Math.sin(angle_ry_inradians) * (d*-1);
var y2 = y + Math.tan(angle_rx_inradians) * (d*-1);
return { x: x2, y: y2, z: z2, rx: rx, ry: ry, rz: rz };
},
angleBetweenPoints: function(p1,p2){
return Math.atan2(p2.z - p1.z, p2.x - p1.x) * 180 / Math.PI;
},
render: function(){
sphere.position.rx = sphere.position.z*sphere.rotation_to_pixels*-1;
sphere.position.ry = sphere.position.x*sphere.rotation_to_pixels*-1;
switch(sphere.direction_z){
case 'forwards':
sphere.position.z-=sphere.speed;
break;
case 'backwards':
sphere.position.z+=sphere.speed;
break;
}
switch(sphere.direction_x){
case 'left':
sphere.position.x-=sphere.speed;
break;
case 'right':
sphere.position.x+=sphere.speed;
break;
}
sphere.element_left.css('transform','translateX(' + sphere.position.x + 'px) translateY(' +...