tadeuzagallo
9/12/2014 - 4:30 PM

HTML - Manual transform children

HTML - Manual transform children

<!DOCTYPE html>
<html>
<head>
  <title>Project name</title>
  <style>
  .container {
    display: block;
    border: 1px solid black;
    position: relative;
    height: 200px;
    width: 600px;
    padding: 100px 0 0 180px;
    transform: rotate3d(1, 1, 0, 45deg);
  }

  .preserve {
    transform-style: preserve-3d;
  }

  .one,
  .two,
  .three,
  .four {
    position: absolute;
    width: 200px;
    height: 200px;
  }

  .one {
    background: blue;
    transform-origin: center left;
    transform: rotateY(-90deg);
  }

  .two {
    background: red;
    transform-origin: top center;
    transform: rotateX(90deg);
  }

  .three {
    background: green;
    transform-origin: center right;
    transform: rotateY(90deg);
  }

  .four {
    background: black;
    transform-origin: bottom center;
    transform: rotateX(-90deg);
  }
    </style>
</head>
<body>
  <div class="container preserve">
    <div class="one"></div>
    <div class="two"></div>
    <div class="four"></div>
    <div class="three"></div>
  </div>

  <div class="container manual">
    <div class="one"></div>
    <div class="two"></div>
    <div class="four"></div>
    <div class="three"></div>
  </div-3d>

<script>
parseChildren(document.querySelector('.manual'));

function parseChildren(root, children) {
  var c = root.children;
  var l = c.length;

  if (!l) {
    return;
  }

  for (var i = 0; i < l; i++) {
    var x = c[i];
    multiply(root, x);
    parseChildren(x);
  }

  root.style.transform = 'none';
}

function multiply(a, b) {
  var ra = getCssTransform(a);
  var rb = getCssTransform(b);

  if (ra === 'none') {
    return;
  } else if (rb === 'none') {
    b.style.transform = ra;
    return;
  }

  var ma = getTransformMatrix(ra);
  var mb = getTransformMatrix(rb);

  var r = [];

  var l = 4;
  for (var i = 0; i < l; i++) {
    for (var j = 0; j < l; j++) {
      var sum = 0;
      for (var k = 0; k < l; k++) {
        sum += ma[i*l+k] * mb[k*l+j];
      }
      r.push(sum);
    }
  }

  b.style.transform = 'matrix3d(' + r.join(', ') + ')';
}

function getCssTransform(a) {
  return window.getComputedStyle(a)['transform'];
}

function getTransformMatrix(raw) {
  var match;
  if ((match = raw.match(/matrix3d\(([^)]+)\)/))) {
    return match[1].split(', ').map(function (a) {
      if (/e-/.test(a)) {
        return 0;
      }

      return parseFloat(a);
    });
  }
}</script>
</body>
</html>