0

I've been exploring the use of perspective in CSS to create a cube, with the hope that eventually I can animate it.

Currently, each individual square on every face is absolutely positioned CSS 3D transforms, but what I wondered was if it's possible to reduce the amount of code I've written by using transform: matrix3d()?

I can't find an explanation of transform: matrix3d() that makes sense to me, so I'm not sure how to use it, or whether it is in fact what I'm looking for.

Here's a CodePen of what I have so far - unfortunately its static at the moment so it doesn't rotate, but there are 6 sides.

2
  • Although a matrix can be really powerfull, it is not easy to use/maintain. Take a look at codepen.io/fta/pen/ifnqH to get a better understanding/feeling ;) Commented Jun 30, 2015 at 14:12
  • @BillyNate to be honest, even after looking at the codepen, I can't get my head around how it actually works! Commented Jul 2, 2015 at 6:21

1 Answer 1

1

Short answer: No, the amount of code won't be reduced much by using matrix3d.

Long answer: You can combine several transform properties (like translate, scale, rotation) into a matrix. But since the matrix3d() takes 16 parameters I won't be much shorter.

The easy way to get the paramers for matrix3d is to select the element in the inspector of your browser and look at the calculated value. The hard way is to calculate the values yourself.

To calculate the values, first get to know the meaning of each value. You could look them up at MDN for example. You'll notice that you'll need to adjust the following values on the matrix when using translate3d and rotationY (like cubie L8 in your Codepen):

cos(rot)    0   sin(rot)   tx
0           1   0          ty
-sin(rot)   0   cos(rot)   tz
0           0   0          1 

tx, ty, tz are translateZ, translateY and translateX.

rot is the rotationY in radians.

-90 degree / 180 * PI is -1.57079633 radians.

cos(1.57) = 0.00079632671

sin(1.57) = ~1

Resulting in

 0.00079632671   0   1                  0
 0               1   0                100
-1               0   0.00079632671   -100
 0               0   0                  1

Giving us matrix3d(0.00079632671, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0.00079632671, 0, 0, 100, -100, 1).

 

Your code with the L side in matrix3d (I also added a rotation animation):

	#wrapper {
	  width: 100%;
	  height: 100%;
	  position: relative;
	}
	
	#cube-container {
	  /*width: 100%;*/
	  
	  position: absolute;
	  top: 30%;
	  left: 30%;
	}
	
	#cube-viewport {
	  perspective: 600px;
	  perspective-origin: 150px 150px;
	  max-width: 600px;
	}
	
	#cube {
	  position: relative;
	  height: 300px;
	  width: 300px;
	  transform-style: preserve-3d;
	  transform-origin: 50% 50% -150px;
	  animation: rotate 10s infinite linear;
	  /* opacity: 1;
		 border: 1px black solid;*/
	}
	
	.row {
	  transform-style: preserve-3d;
	  transform-origin: 50% 50% -150px;
	  height: auto;
	}
	
	#cube .cubie {
	  position: absolute;
	  margin: 1px;
	  border: 1px solid black;
	  width: 98px;
	  height: 98px;
	  background-size: 100px;
	  opacity: 1;
	  z-index: -1;
	  text-align: center;
	  font-size: 30px;
	  transform-origin: 0 0;
	}
	
	#cube .cubie.front {
	  background-color: red;
	}
	
	#cube .cubie.back {
	  background-color: blue;
	}
	
	#cube .cubie.right {
	  background-color: green;
	}
	
	#cube .cubie.left {
	  background-color: orange;
	}
	
	#cube .cubie.down {
	  background-color: yellow;
	}
	
	#cube .cubie.top {
	  background-color: white;
	}
	
	.ftl {
	  transform: rotateX(0) translate3d(0, 0, 0);
	}
	
	.fcl {
	  transform: rotateX(0) translate3d(0, 100px, 0);
	}
	
	.fbl {
	  transform: rotateX(0) translate3d(0, 200px, 0);
	}
	
	.ftc {
	  transform: rotateX(0) translate3d(100px, 0, 0);
	}
	
	.fcc {
	  transform: rotateX(0) translate3d(100px, 100px, 0);
	}
	
	.fbc {
	  transform: rotateX(0) translate3d(100px, 200px, 0);
	}
	
	.ftr {
	  transform: rotateX(0) translate3d(200px, 0, 0);
	}
	
	.fcr {
	  transform: rotateX(0) translate3d(200px, 100px, 0);
	}
	
	.fbr {
	  transform: rotateX(0) translate3d(200px, 200px, 0);
	}
	
	.btl {
	  transform: rotateY(180deg) translate3d(-300px, 0, 300px);
	}
	
	.bcl {
	  transform: rotateY(180deg) translate3d(-300px, 100px, 300px);
	}
	
	.bbl {
	  transform: rotateY(180deg) translate3d(-300px, 200px, 300px);
	}
	
	.btc {
	  transform: rotateY(180deg) translate3d(-200px, 0, 300px);
	}
	
	.bcc {
	  transform: rotateY(180deg) translate3d(-200px, 100px, 300px);
	}
	
	.bbc {
	  transform: rotateY(180deg) translate3d(-200px, 200px, 300px);
	}
	
	.btr {
	  transform: rotateY(180deg) translate3d(-100px, 0, 300px);
	}
	
	.bcr {
	  transform: rotateY(180deg) translate3d(-100px, 100px, 300px);
	}
	
	.bbr {
	  transform: rotateY(180deg) translate3d(-100px, 200px, 300px);
	}
	
	.rtl {
	  transform: rotateY(90deg) translate3d(0, 0, 300px);
	}
	
	.rcl {
	  transform: rotateY(90deg) translate3d(0, 100px, 300px);
	}
	
	.rbl {
	  transform: rotateY(90deg) translate3d(0, 200px, 300px);
	}
	
	.rtc {
	  transform: rotateY(90deg) translate3d(100px, 0, 300px);
	}
	
	.rcc {
	  transform: rotateY(90deg) translate3d(100px, 100px, 300px);
	}
	
	.rbc {
	  transform: rotateY(90deg) translate3d(100px, 200px, 300px);
	}
	
	.rtr {
	  transform: rotateY(90deg) translate3d(200px, 0, 300px);
	}
	
	.rcr {
	  transform: rotateY(90deg) translate3d(200px, 100px, 300px);
	}
	
	.rbr {
	  transform: rotateY(90deg) translate3d(200px, 200px, 300px);
	}
	
	.ltl {
	  transform: matrix3d(0.00079632671, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0.00079632671, 0, 0, 0, -300, 1);
	}
	
	.lcl {
	  transform: matrix3d(0.00079632671, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0.00079632671, 0, 0, 100, -300, 1);
	}
	
	.lbl {
	  transform: matrix3d(0.00079632671, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0.00079632671, 0, 0, 200, -300, 1);
	}
	
	.ltc {
	  transform: matrix3d(0.00079632671, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0.00079632671, 0, 0, 0, -200, 1);
	}
	
	.lcc {
	  transform: matrix3d(0.00079632671, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0.00079632671, 0, 0, 100, -200, 1);
	}
	
	.lbc {
	  transform: matrix3d(0.00079632671, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0.00079632671, 0, 0, 200, -200, 1);
	}
	
	.ltr {
	  transform: matrix3d(0.00079632671, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0.00079632671, 0, 0, 0, -100, 1);
	}
	
	.lcr {
	  transform: matrix3d(0.00079632671, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0.00079632671, 0, 0, 100, -100, 1);
	}
	
	.lbr {
	  transform: matrix3d(0.00079632671, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0.00079632671, 0, 0, 200, -100, 1);
	}
	
	.utl {
	  transform: rotateX(90deg) translate3d(0, -300px, 0);
	}
	
	.ucl {
	  transform: rotateX(90deg) translate3d(0, -200px, 0);
	}
	
	.ubl {
	  transform: rotateX(90deg) translate3d(0, -100px, 0);
	}
	
	.utc {
	  transform: rotateX(90deg) translate3d(100px, -300px, 0);
	}
	
	.ucc {
	  transform: rotateX(90deg) translate3d(100px, -200px, 0);
	}
	
	.ubc {
	  transform: rotateX(90deg) translate3d(100px, -100px, 0);
	}
	
	.utr {
	  transform: rotateX(90deg) translate3d(200px, -300px, 0);
	}
	
	.ucr {
	  transform: rotateX(90deg) translate3d(200px, -200px, 0);
	}
	
	.ubr {
	  transform: rotateX(90deg) translate3d(200px, -100px, 0);
	}
	
	.dtl {
	  transform: rotateX(-90deg) translate3d(0, 0, 300px);
	}
	
	.dcl {
	  transform: rotateX(-90deg) translate3d(0, 100px, 300px);
	}
	
	.dbl {
	  transform: rotateX(-90deg) translate3d(0, 200px, 300px);
	}
	
	.dtc {
	  transform: rotateX(-90deg) translate3d(100px, 0, 300px);
	}
	
	.dcc {
	  transform: rotateX(-90deg) translate3d(100px, 100px, 300px);
	}
	
	.dbc {
	  transform: rotateX(-90deg) translate3d(100px, 200px, 300px);
	}
	
	.dtr {
	  transform: rotateX(-90deg) translate3d(200px, 0, 300px);
	}
	
	.dcr {
	  transform: rotateX(-90deg) translate3d(200px, 100px, 300px);
	}
	
	.dbr {
	  transform: rotateX(-90deg) translate3d(200px, 200px, 300px);
	}
	
	@keyframes rotate {
	  0% {
	    transform: rotateY(0deg) rotateX(0deg);
	  }
	  100% {
	    transform: rotateY(360deg) rotateX(360deg);
	  }
	}
<div id="wrapper">
  <div id="cube-container">
    <div id="cube-viewport">
      <div id="cube">
        <div class="ftl cubie front">F1</div>
        <div class="ftc cubie front">F4</div>
        <div class="ftr cubie front">F7</div>
        <div class="btl cubie back">B1</div>
        <div class="btc cubie back">B4</div>
        <div class="btr cubie back">B7</div>
        <div class="rtl cubie right">R1</div>
        <div class="rtc cubie right">R4</div>
        <div class="rtr cubie right">R7</div>
        <div class="ltl cubie left">L1</div>
        <div class="ltc cubie left">L4</div>
        <div class="ltr cubie left">L7</div>

        <!-- UP FACE -->
        <!-- LEFT COLUMN (L)  -->
        <div class="utl cubie top">U1</div>
        <div class="ucl cubie top">U2</div>
        <div class="ubl cubie top">U3</div>
        <!-- CENTER COLUMN (C)  -->
        <div class="utc cubie top">U4</div>
        <div class="ucc cubie top">U5</div>
        <div class="ubc cubie top">U6</div>
        <!-- RIGHT COLUMN (R)  -->
        <div class="utr cubie top">U7</div>
        <div class="ucr cubie top">U8</div>
        <div class="ubr cubie top">U9</div>
        <!-- END UP FACE -->

        <div class="fcl cubie front">F2</div>
        <div class="fcc cubie front">F5</div>
        <div class="fcr cubie front">F8</div>
        <div class="bcl cubie back">B2</div>
        <div class="bcc cubie back">B5</div>
        <div class="bcr cubie back">B8</div>
        <div class="rcl cubie right">R2</div>
        <div class="rcc cubie right">R5</div>
        <div class="rcr cubie right">R8</div>
        <div class="lcl cubie left">L2</div>
        <div class="lcc cubie left">L5</div>
        <div class="lcr cubie left">L8</div>

        <div class="fbl cubie front">F3</div>
        <div class="fbc cubie front">F6</div>
        <div class="fbr cubie front">F9</div>
        <div class="bbl cubie back">B3</div>
        <div class="bbc cubie back">B6</div>
        <div class="bbr cubie back">B9</div>
        <div class="rbl cubie right">R3</div>
        <div class="rbc cubie right">R6</div>
        <div class="rbr cubie right">R9</div>
        <div class="lbl cubie left">L3</div>
        <div class="lbc cubie left">L6</div>
        <div class="lbr cubie left">L9</div>

        <div class="dtl cubie down">D1</div>
        <div class="dcl cubie down">D2</div>
        <div class="dbl cubie down">D3</div>
        <div class="dtc cubie down">D4</div>
        <div class="dcc cubie down">D5</div>
        <div class="dbc cubie down">D6</div>
        <div class="dtr cubie down">D7</div>
        <div class="dcr cubie down">D8</div>
        <div class="dbr cubie down">D9</div>
      </div>
    </div>
  </div>
</div>

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.