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>