clientX/clientY
Attempting to use clientX/clientY using root as the origin of coordinates.
by David Iglesias
HTML
<div id="transform">
<div id="root">
Root
<div id="wrapper">
<div id="content">
Content!<br />
300 x 300<br />
(after scale(1.5))<br/>
<br/>
<tt><tt>BREAKS!</tt></tt>
</div>
</div>
</div>
<div id="out"></div>
CSS
* {
box-sizing: border-box;
font-family: sans-serif;
}
body {
margin: 0;
padding: 0;
}
tt { font-family: monospace; font-style: italic; cursor: default; }
#transform {
transform-origin: 0 0;
transform: translate(60px, 130px) rotateX(60deg) rotateZ(-45deg);
}
#root {
width: 500px;
height: 300px;
border: 1px solid black;
background: #eee;
}
#wrapper {
background: rgba(255,127,0,.5);
pointer-events: none;
}
#content {
position: absolute;
top: 0;
left: 0;
pointer-events: auto;
transform-origin: 0 0;
transform: translate(60px, 130px) rotateX(60deg) rotateZ(-45deg);
background: #fabada;
border: 1px solid red;
width: 200px;
height: 200px;
}
#content tt {
display: block;
background: red;
transform: translate(60px, 130px) rotateX(60deg) rotateZ(-45deg);
}
#out {
/* margin: -10px 0 0 -10px; */
padding: 0;
position: absolute;
pointer-events: none;
width: 20px;
height: 20px;
background: #09f;
font-size: 20px;
/* border-radius: 20px; */
}
JavaScript
function log(n, x, y) {
out.style.left = `${x}px`;
out.style.top = `${y}px`;
}
let originEl = root; // origin of coordinates (glassPane).
root.addEventListener('pointermove', function(e) {
// const matrix = new DOMMatrix(window.getComputedStyle(e.target).transform);
const matrix = getElementTransformUpTo(e.target, originEl);
const transformedOffset = matrix.transformPoint(new DOMPoint(e.offsetX, e.offsetY));
console.log('target', getOpeningHtml(e.target));
console.log('matrix', matrix.toString());
console.log(transformedOffset.x, transformedOffset.y);
log(e.target.id, transformedOffset.x, transformedOffset.y);
});
const IDENTITY = new DOMMatrix([1, 0, 0, 1, 0, 0]);
function getElementTransformUpTo(element, upto) {
// Clone it because we are going to mutate it below.
let matrix = DOMMatrix.fromMatrix(IDENTITY);
while (element != null && element != upto) {
const currentMatrix = new DOMMatrix(window.getComputedStyle(element).transform);
matrix.preMultiplySelf(currentMatrix);
element = element.parentElement;
}
return matrix;
}
function getOpeningHtml(element) {
const outer = element.outerHTML;
const end = outer.indexOf('>');
// Use {} instead of <> because jsfiddle console escapes them into > and <
return '{' + outer.substring(1, end) + '}';
}