JSFiddle - React, Tailwind, and code Playground

by Dawid Karwat

HTML

<div id="container">
    <div id="wrap">
        <div id="face1"></div>
        <div id="face2"></div>
        <div id="face3"></div>
    </div>
</div>

CSS

#container {
    width:180px;
    height:180px;
    perspective: 500px;
    margin:50px auto;
    transform-style: preserve-3d;
}
#wrap {
    width:180px;
    height:180px;
    transform-style: preserve-3d;
}
#wrap > div{
    width:180px;
    height:180px;
    position:absolute;
}
#face1 {
    background-color:rgba(63,0,127,.7);
}
#face2 {
    background-color:rgba(0,127,0,.7);
    transform: rotateY(90deg);
}
#face3 {
    background-color:rgba(0,127,127,.7);
    transform: rotateX(90deg);
}

JavaScript

//v4 what's new:
//- reverses rotateX direction if object is upside down
//- calculates degrees between 0 and 360
//- elements never reaches rotation values 90 and 270, so elements are always visible, so no bugs occur
var ct = document.getElementById('container');
var wr = document.getElementById('wrap');
var rX, rY;
var newX=0.25, newY=0.25;
function startDrag(e) {

    startPointX = e.clientX/2;
    startPointY = e.clientY/2;

    rX = newX;
    rY = newY;
    drag = true;

    document.onmousemove = dragging;
    return false;
}

function dragging(e) {
    if (!drag) return;
    if (rY<90||rY>270) newX = rX+e.clientX/2-startPointX;
    else newX = rX-e.clientX/2+startPointX;
    newY = rY-e.clientY/2+startPointY;
    wr.style.transform = "rotateX("+newY+"deg) rotateY("+newX+"deg)";
    return false;
}

function stopDrag() {
    drag = false;
    if(newX>=360 || newX<0) newX-=360*Math.floor(newX/360);
    if(newY>=360 || newY<0) newY-=360*Math.floor(newY/360);
	wr.style.transform = "rotateX("+newY+"deg) rotateY("+newX+"deg)";
}
wr.style.transform = "rotateX("+newY+"deg) rotateY("+newX+"deg)";
document.onmousedown = startDrag;
document.onmouseup = stopDrag;