JSFiddle - React, Tailwind, and code Playground
HTML
<div id='log' style="position:fixed;right:0;top:0;"></div>
<br /><br /><br /><br /><br />
<br /><br /><br /><br /><br />
<br /><br /><br /><br /><br />
<div style="
-o-transform:translate(130px, -200px) skew(0deg, 0);
-webkit-transform:translate(130px, -100px) skew(0deg, 0);
-moz-transform:translate(130px, -200px) skew(60deg, 0);
-ms-transform:translate(130px, -200px) skew(60deg, 0);
">
<div id="clickMe" style="border:10px solid silver;
padding: 0px;
-moz-transform:rotate(25deg);
-ms-transform:rotate(25deg);
-o-transform:rotate(25deg);
-webkit-transform:rotate(490deg);
left:0;top:0;
width:100px;
height:50px;" > 120px x 70px</div>
</div>
JavaScript
/*
offsetXY(event, element) -> {x, y}
return coordinate in elements local coordinate system (css 2d transform supported)
getBoundingClientRectX(element)
return same result as element.getBoundingClientRect(),
fixes element.getBoundingClientRect() for Firefox
see https://bugzilla.mozilla.org/show_bug.cgi?id=591718
*/
(function () {
function multiply(a, b) {
var r = [], i, j, k, t;
for (i = 0; i < a.length; i++) {
for (j = 0; j < b[0].length; j++) {
t = 0;
for (k = 0; k < a[0].length; k++) {
t += a[i][k] * b[k][j];
}
r[i] = r[i] || [];
r[i][j] = t;
}
}
return r;
}
function matrixFromCssString(c) {
c = c.match(/matrix\(([^\)]+)\)/i)[1].split(',');
c = [
[+c[0], +c[2], parseFloat(c[4])],
[+c[1], +c[3], parseFloat(c[5])],
[0, 0, 1]
];
return c;
}
function translate(m, tx, ty) {
return [
[m[0][0], m[0][1], m[0][2] + tx],
[m[1][0], m[1][1], m[1][2] + ty],
[0, 0, 1]
];
}
function inverse(m) {// m - transform matrix only (2x3)
var det = m[0][0] * m[1][1] - m[0][1] * m[1][0];
// if det = 0 ?
return [
[ m[1][1] / det, -m[0][1] / det, (m[0][1] * m[1][2] - m[1][1] * m[0][2]) / det],
[-m[1][0] / det, m[0][0] / det, (m[0][2] * m[1][0] - m[0][0] * m[1][2]) / det],
[0, 0, 1]
];
}
function boundingClientRect(element, transformationMatrix) {
var points = [
multiply(transformationMatrix, [[0], [0], [1]]),
multiply(transformationMatrix, [[element.offsetWidth], [0], [1]]),
multiply(transformationMatrix, [[0], [element.offsetHeight], [1]]),
multiply(transformationMatrix, [[element.offsetWidth], [element.offsetHeight], [1]])
];
return {
left: Math.min(points[0][0][0], points[1][0][0], points[2][0][0], points[3][0][0]),
top: Math.min(points[0][1][0], points[1][1][0], points[2][1][0], points[3][1][0]),
right: ...