/*THIS EXAMPLE WORKS IF THE MECHANISM OF TRANSFORMATION MATRICES
IN CSS DOM IS CLOSE ENOUGH TO SVG,
WHICH MEANS LIKE IN SVG, ROTATE SHOULD NOT
BE AROUND AN ELEMENTS CENTER (default) BUT TO
THE TOP LEFT CORNER OF THE ELEMENT.
IN SVG, ALL TRANFORMATIONS ARE RELATIVE TO THE TOP LEFT
CORNER OF THE VIEWBOX WHICH CANNOT
BE 100% TRANSPORTED TO CSS.
THE CLOSEST I COULD FIND WAS TO
SET TRANSFORM-ORIGIN: 0px 0px WHICH SEEMS TO WORK */
/*There is red parent square and blue child square
inside which both have cascading transformations.
The goal is to combine their transformation matrices
and make yellow (W) and magenta (U) squares
superimpose with the blue square*/
//get all the elements in variables
const [elX, elY, elU, elW] = [...document.getElementsByTagName("div")];
//make a regexp to extract the entries of the matrix, with match, it returns [a, b, c, d, e, f]
const rgx = /(-?[0-9]+(?:\.[0-9]+)?)/gi;
//DOMMatrices expect an array of 6 numbers for 2D transformations
//get the matrix of big red parent square
const matrix_elX = new DOMMatrix(getComputedStyle(elX).transform.match(rgx));
//get the matrix of the small blue child square
const matrix_elY = new DOMMatrix(getComputedStyle(elY).transform.match(rgx));
/*
'result' is MX * MY and 'result2' is MY * MX
magenta square U uses result,
yellow square W uses result2,
magenta square U correctly superimposes with blue square,
but yellow square W does NOT,
therefore MX * MY and MY * MX are not the same, as you can expect that matrice multiplication is NOT commutative
Below uses DOMMatrix.fromMatrix is create clones of the matrices because operations does mutate the matrix itself.
*/
let result = DOMMatrix.fromMatrix(matrix_elY).preMultiplySelf(DOMMatrix.fromMatrix(matrix_elX)),
result2 = DOMMatrix.fromMatrix(matrix_elX).preMultiplySelf(DOMMatrix.fromMatrix(matrix_elY));
elU.style.transform = result;
elW.style.transform = result2;
* {
margin: 0px;
box-sizing: border-box;
transform-origin: 0px 0px;
}
#x {
position: relative;
background: red;
width: 300px;
height: 300px;
transform: translate(-20px, -20px) rotate(-30deg) translate(150px, 100px) rotate(20deg);
}
#y {
position: relative;
background: blue;
width: 100px;
height: 100px;
transform: rotate(-5deg) rotate(10deg) translate(200px, 50px) rotate(75deg) translate(35px, 10px) rotate(-25deg);
}
#u {
position: absolute;
top: 0px;
width: 100px;
height: 100px;
background: magenta;
opacity: 0.5;
}
#w {
position: absolute;
top: 0px;
width: 100px;
height: 100px;
background: yellow;
opacity: 0.5;
}
<div id="x">
<div id="y">
</div>
</div>
<div id="u">U</div>
<div id="w">W</div>