Search code examples
htmlcss3dcss-transformsrotatetransform

Cube spinning on its corner


I have a 3D cube made from pure HTML-cum-CSS which is supposed to spin on one of its corners without the corner moving around the screen. Unfortunately, it doesn't quite do so, it rather wobbles along a line (2D) or around a circle (3D). What am I doing wrong?

#cube {
    position: relative;
    margin: 100px auto;
    height: 100px;
    width: 100px;
    animation: 4s rotateforever infinite linear;
    transform-style: preserve-3d;
}

.face {
    position: absolute;
    height: 78px;
    width: 78px;
    padding: 10px;
    border: black 2px solid;
}

.one {
    transform: rotateX(-45deg) rotateY(45deg) translateZ(50px);
}

.two {
    transform: rotateX(-45deg) rotateY(135deg) translateZ(50px);
}

.three {
    transform: rotateX(-45deg) rotateY(225deg) translateZ(50px);
}

.four {
    transform: rotateX(-45deg) rotateY(315deg) translateZ(50px);
}

.five {
    transform: rotateX(45deg) rotateZ(-45deg) translateZ(50px);
}

.six {
    transform: rotateX(45deg) rotateY(180deg) rotateZ(-45deg) translateZ(50px);
}

@keyframes rotateforever {
    to {
        transform: rotateY(360deg);
    }
}
<body>
    <div id="cube">
        <div class="face one">one</div>
        <div class="face two">two</div>
        <div class="face three">three</div>
        <div class="face four">four</div>
        <div class="face five">five</div>
        <div class="face six">six</div>
    </div>
</body>

JSFiddle


Solution

  • Found the answer:

    According to a post on Blender the left and right angle between the horizontal and the cube in its original position is not 45deg (as I assumed), but only 35.2644deg.

    Therefore in my CSS, I had to change the values of each occurrence of a transform: rotateX(...) to 35.2644deg where I used to have 45deg and to 54.7356deg (90 - 35.2644) where I used to have -45deg.

    Like so:

    .one {
        transform: rotateX(-54.7356deg) rotateY(45deg) translateZ(50px);
    }
    
    .two {
        transform: rotateX(-54.7356deg) rotateY(135deg) translateZ(50px);
    }
    
    .three {
        transform: rotateX(-54.7356deg) rotateY(225deg) translateZ(50px);
    }
    
    .four {
        transform: rotateX(-54.7356deg) rotateY(315deg) translateZ(50px);
    }
    
    .five {
        transform: rotateX(35.2644deg) rotateZ(-45deg) translateZ(50px);
    }
    
    .six {
        transform: rotateX(35.2644deg) rotateY(180deg) rotateZ(-45deg) translateZ(50px);
    }
    

    I updated the JSFiddle.