Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

css3 transform-origin issue in 3D cube

I have created css-cube and its rotating on :hover.

But Its rotation is based on one side of cube!

I want to rotate it from its center, like in this example. I was trying transform-origin property but not got desired result.

I have also tried placing one middle plane inside cube but hover is not working in that situation!

.contain {
    width: 300px;
    height: 300px;
    -webkit-perspective: 500px;
    perspective: 500px;
    position: absolute;
}
.main {
    position:relative;
    width:100px;
    height:100px;
    margin:100px 100px;
    background:#07a;
    overflow:visible;
    transition: all linear,transform cubic-bezier(0.4, 0.25, 0.14, 1.5),background cubic-bezier(0.4, 0.25, 0.14, 1.5);
    transition-duration: 700ms;
    -moz-transform-style: preserve-3d;
    -webkit-transform-style: preserve-3d;
    transform-style: preserve-3d;
    transform-origin: center center;
}

.main:hover{
    transform:rotateY(180deg);
}

.top, .right, .left, .bottom,.lid{
    position:absolute;
    width:100px;
    height:100px;
    z-indexd:999;
    transition:  all 1s ease;
}
.top {
    background:crimson;
    top:-100px;
    transform-origin : 50% 100%;
    transform:rotateX(-90deg);
}
.bottom {
    background:crimson;
    bottom:-100px;
    transform-origin :100% 0%;
    transform:rotateX(90deg);
}
.left {
    background:#ccc;
    left:-100px;
    transform-origin :100% 0%;
    transform:rotateY(90deg);
}
.right {
    background:#ccc;
    right:-100px;
    transform-origin : 0% 0%;
    transform:rotateY(-90deg);
}
.lid {
    background:#07a;
    transform: translateZ(170px);
    transform-origin : 0% 0%;
    transform:translateZ(100px);
}
<div class="contain">
            <div class="main">
                <div class="lid"></div>
                <div class="top"></div>
                <div class="right"></div>
                <div class="left"></div>
                <div class="bottom"></div>
            </div>
        </div>
like image 654
Suresh Karia Avatar asked Dec 18 '14 11:12

Suresh Karia


People also ask

What is the default transform-origin?

By default, the origin of a transform is “50% 50%”, which is exactly in the center of any given element. Changing the origin to “top left” (as in the demo above) causes the element to use the top left corner of the element as a rotation point.

What is the use of transform-origin in CSS?

The transform-origin property allows you to change the position of transformed elements. 2D transformations can change the x- and y-axis of an element. 3D transformations can also change the z-axis of an element.

What does transform style preserve-3D do?

transform-style: preserve-3d tells the browser that the 3D transformed children of the element it's set on shouldn't be flattened into the plane of their parent (the element we set transform-style: preserve-3d on).


2 Answers

The problem is that you need to set the transform origin in the center of the cube, and the cube is a 3d element. You are missing the 3rd dimension !

So it should be

transform-origin: center center 50px;

since your cube side is 100px

.contain {
    width: 300px;
    height: 300px;
    -webkit-perspective: 500px;
    perspective: 500px;
    position: absolute;
}
.main {
    position:relative;
    width:100px;
    height:100px;
    margin:100px 100px;
    background:#07a;
    overflow:visible;
    transition: all linear,transform cubic-bezier(0.4, 0.25, 0.14, 1.5),background cubic-bezier(0.4, 0.25, 0.14, 1.5);
    transition-duration: 700ms;
    -moz-transform-style: preserve-3d;
    -webkit-transform-style: preserve-3d;
    transform-style: preserve-3d;
    transform-origin: center center 50px;
}

.main:hover{
    transform:rotateY(180deg);
}

.top, .right, .left, .bottom,.lid{
    position:absolute;
    width:100px;
    height:100px;
    z-indexd:999;
    transition:  all 1s ease;
}
.top {
    background:crimson;
    top:-100px;
    transform-origin : 50% 100%;
    transform:rotateX(-90deg);
}
.bottom {
    background:crimson;
    bottom:-100px;
    transform-origin :100% 0%;
    transform:rotateX(90deg);
}
.left {
    background:#ccc;
    left:-100px;
    transform-origin :100% 0%;
    transform:rotateY(90deg);
}
.right {
    background:#ccc;
    right:-100px;
    transform-origin : 0% 0%;
    transform:rotateY(-90deg);
}
.lid {
    background:#07a;
    transform: translateZ(170px);
    transform-origin : 0% 0%;
    transform:translateZ(100px);
}
<div class="contain">
            <div class="main">
                <div class="lid"></div>
                <div class="top"></div>
                <div class="right"></div>
                <div class="left"></div>
                <div class="bottom"></div>
            </div>
        </div>
like image 120
vals Avatar answered Oct 19 '22 15:10

vals


I added a translateZ to move the rotation axis, it looks a little more centered but still not like Desandro's ex.,

I read the documentation and I think you should checkout this! it explains a little bit about orgins and perspectives...

EDIT1: integrated translateZ instead of transform origin (now it's perfect!!)

.contain {
    width: 300px;
    height: 300px;
    -webkit-perspective:666px;
    perspective: 666px;
    position: absolute;
}
.main {
    position:relative;
    width:100px;
    height:100px;
    margin:100px 100px;
    background:#07a;
    overflow:visible;
    transition: all 1s ease;
    -moz-transform-style: preserve-3d;
    -webkit-transform-style: preserve-3d;
    transform-style: preserve-3d;
    transform:translateZ(-50px)
   
    
}

.main:hover{
    transform:  translateZ(-50px) rotateY(180deg);
    
    
}

.top, .right, .left, .bottom,.lid,.front{
    position:absolute;
    width:100px;
    height:100px;
    z-index:999;
    transition:  all 1s ease;
}
.front{
    background:yellow;
    transform:rotateY( 0deg ) translateZ( 50px );
}
.left {
    background:red;
    transform:rotateY(90deg) translateZ( 50px );
}
.right {
    background:purple;
    right:-100px;
    //transform-origin : 0% 0%;
    transform:rotateY(-90deg) translateZ( 150px );
}
.lid {
    background:green;
    transform:rotateY(180deg) translateZ( 50px );
   
}
<div class="contain">
            <div class="main">
                <div class="front"></div>
                <div class="lid"></div>
                <div class="right"></div>
                <div class="left"></div>
             </div>
        </div>

BTW CSS-transformations rock!!

like image 1
maioman Avatar answered Oct 19 '22 15:10

maioman