JSFiddle - React, Tailwind, and code Playground

by kevin_dorion

HTML

<div id="el">

</div>
<div class="info">
  <div id="offset">move the mouse in the gray rectangle</div>
  <p>I need updated offset values even though the mouse is not moving.</p>
  <p>The resulting offset coordinates need to be relative to the transformed container, so it should be x:300 y:200 at the bottom right of the rectangle, even after the transformation, like it is on mousemove</p>
  <div id="pointInfo"></div>
  <div id="elInfo"></div>
</div>
<div id="point"></div>

CSS

body {
  display: flex;
}

#el {
  flex: 0 0 300px;
  background: #cccccc;
  width: 300px;
  height: 200px;
  transform-origin: 0 0 0;
  animation-duration: 15s;
  animation-name: animate;
  animation-iteration-count: infinite;
  animation-direction: alternate;
}
#point {
  position: absolute;
  width: 10px;
  height: 10px;
  background: red;
  margin-left: -5px;
  margin-top: -5px;
  pointer-events: none;
}

@keyframes animate {
  from {
    transform: rotate3d(1, 1, 1, 0deg) matrix3d(1, 1, 1);
  }
  to {
    transform: rotate3d(1, 1, 1, 30deg) matrix3d(0.393257, 0, 0, 0, 0, 0.391817, 0, 0, 0, 0, 1, 0, 40.1505, 50.782, 0, 1);
  }
}

JavaScript

const el = document.getElementById('el');
const offsetEl = document.getElementById('offset');
const pointEl = document.getElementById('point');
const pointInfoEl = document.getElementById('pointInfo');
const elInfoEl = document.getElementById('elInfo');
let lastMouseEvent;

function mousemove(evt) {
  // this is the value I need to update, even when the mouse is not moving
	offsetEl.innerHTML = `x: ${evt.offsetX} y: ${evt.offsetY}`;
  pointEl.style.left = `${evt.pageX}px`;
  pointEl.style.top = `${evt.pageY}px`;
  lastMouseEvent = evt;
}

function animate() {
  requestAnimationFrame(animate);
  // how do I manually calculate offsetX and offsetY of the mouse cursor relative to the "el" element when it's not moving?
  const pointRect = trimDecimals(pointEl.getBoundingClientRect());
  const elRect = trimDecimals(el.getBoundingClientRect());
  pointInfoEl.innerHTML = JSON.stringify(pointRect, null, 4);
  elInfoEl.innerHTML = JSON.stringify(elRect, null, 4);
}

function trimDecimals(obj) {
  const keys = Object.keys(obj.toJSON());
  return keys.reduce((acc, prop) => {
    const val = obj[prop];
    if (isFinite(val)) {
       acc[prop] = Math.round(val);
    }
  	return acc;
  }, {});
}

requestAnimationFrame(animate)
el.addEventListener('mousemove', mousemove);