Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS cubes, trouble aligning to grid

Tags:

css

transform

3d

So my goal is to have these cubes on a grid and have them line up, draggable and snappable. I got the cubes working well based on this example, but I'm not fully comprehending some of the mechanics and as such am having some problems.

  1. The cube starts out larger than it is after it rotates. To see this, simply click "1" which applies the "show-front" class, while you're still on the front face. It will immediately shrink. fixed

  2. The cube axis is not centered, so when it rotates it ends up at different xy coordinates.

  3. In the CSS I'm setting the size to 200x200 (or any factor of 25) but due to the Z transform it's not exactly right. This one is mostly fixed, see update at bottom.

How can I fix these three things?

Here is the fiddle: http://jsfiddle.net/scottbeeson/phJpS/

Here is the CSS which is the important part:

    .itemView {
      width: 200px;
      height: 200px;
      /*position: relative;*/
      /*margin: 0 auto 40px;*/
      /*border: 1px solid #CCC;*/
      -webkit-perspective: 1000px;
         -moz-perspective: 1000px;
           -o-perspective: 1000px;
              perspective: 1000px;
        -webkit-margin-start: 0 !important;
        -webkit-margin-before: 0 !important;
        -webkit-margin-end: 0 !important;
        -webkit-margin-after: 0 !important;
    }

    .cube {
      width: 100%;
      height: 100%;
      position: absolute;
      -webkit-transform-style: preserve-3d;
         -moz-transform-style: preserve-3d;
           -o-transform-style: preserve-3d;
              transform-style: preserve-3d;
      -webkit-transition: -webkit-transform 1s;
         -moz-transition: -moz-transform 1s;
           -o-transition: -o-transform 1s;
              transition: transform 1s;
    }

    .cube figure {
      display: block;
      position: absolute;
      width: 196px;
      height: 196px;
      border: 2px solid black;
      color: white;
    }

    .cube.panels-backface-invisible figure {
      -webkit-backface-visibility: hidden;
         -moz-backface-visibility: hidden;
           -o-backface-visibility: hidden;
              backface-visibility: hidden;
    }

    .cube .front  {     
        background-color: #555;
        border: 1px solid #ccc; 
    }
    .cube .back   {
        background-color: #555;
        border: 1px solid #ccc; 
    }
    .cube .right  { 
        background-color: #555;
        border: 1px solid #ccc; 
    }
    .cube .left   { 
        background-color: #555;
        border: 1px solid #ccc; 
     }
    .cube .top    {
        background-color: cornflowerblue;
        border: 1px solid #ccc; 
     }
    .cube .bottom { 
        background-color: #555;
        border: 1px solid #ccc; 
     }

    .cube .front  {
      -webkit-transform: translateZ( 99px );
    }
    .cube .back   {
      -webkit-transform: rotateX( -180deg ) translateZ( 99px );
    }
    .cube .right {
      -webkit-transform: rotateY(   90deg ) translateZ( 99px );
    }
    .cube .left {
      -webkit-transform: rotateY(  -90deg ) translateZ( 99px );
    }
    .cube .top {
      -webkit-transform: rotateX(   90deg ) translateZ( 99px );
    }
    .cube .bottom {
      -webkit-transform: rotateX(  -90deg ) translateZ( 99px );
    }

    .cube.show-front {
      -webkit-transform: translateZ( -99px );
    }
    .cube.show-back {
      -webkit-transform: translateZ( -99px ) rotateX( -180deg );
    }
    .cube.show-right {
      -webkit-transform: translateZ( -99px ) rotateY(  -90deg );
    }
    .cube.show-left {
      -webkit-transform: translateZ( -99px ) rotateY(   90deg );
    }
    .cube.show-top {
      -webkit-transform: translateZ( -99px ) rotateX(  -90deg );
    }
    .cube.show-bottom {
      -webkit-transform: translateZ( -99px ) rotateX(   90deg );
    }

.itemHandle {
    position: absolute;
    top: 0px;
    left: 0px;
    right: 0px;
    cursor: move;
    white-space: nowrap;
    background-color: cornflowerblue;
    text-align: left;
    /*border-top-right-radius: 15px;*/
}

Also, if anyone feels like these should be separate questions, that's fine. I just figured they're all part of the same "problem" and it would be easier than posting the same fiddle 3 times.

update on #1, #3 (updated fiddle)

I was able to change transformZ of the front face to 0 and adjust the rest of the transforms to basically make the front face of the cube on the same plane as the "workArea". This is much better, but the perspective is a little off, as if you're not looking head-on towards the cube. Not noticeable though unless the faces are translucent. Here is the updated CSS:

.cube .front  {
  -webkit-transform: translateZ( 0px );
}
.cube .back   {
  -webkit-transform: rotateX( -180deg ) translateZ( 200px );
}
.cube .right {
  -webkit-transform: rotateY(   90deg ) translateZ( 100px ) translateX(100px);
}
.cube .left {
  -webkit-transform: rotateY(  -90deg ) translateZ( 100px ) translateX(-100px);
}
.cube .top {
  -webkit-transform: rotateX(   90deg ) translateZ( 100px ) translateY(-100px);
}
.cube .bottom {
  -webkit-transform: rotateX(  -90deg ) translateZ( 100px ) translateY(100px);
}

1 Answers

The figures are off because of margin and padding.

Try :

.cube figure {
     display: block;
    position: absolute;
    width: 200px;
    height: 200px;
    border: 0px solid black;
    color: white;
    margin: 0px;
    padding: 0px;
  }

Added margin and padding = 0

demo

I have now changed the whole coordinate system. It is easier if you make the cube center be at 0 0 coordinates. Now all the rotating stuff only needs rotation, and that is much easier to figure out.

If you really wnat the front face to be on the z=0 plane, set an global offset at the base level.

like image 173
vals Avatar answered Jan 26 '26 01:01

vals



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!