Search code examples
javascriptcsscss-transitions

Javascript event.offset alternative for final value during CSS scale & transition


I have an HTML image that I want to pan & zoom programatically. In order to improve the experience, I added a CSS transition for smoothness.

When I click on the image, I need to determine the mouse position within the image. Currently, event.offsetX gives me the mouse position within the image at the current frame of the animation.

I would like to know the mouse position as if the animation finished already (even though it hadn't).

Here is another way of explaining the problem. I created below an example where an image zooms in after we click on the button. The zoom takes 5 seconds. During the zoom, if I keep my mouse fixed and keep clicking, the offset value changes as the image moves on the screen and then it stabilizes after 5 seconds and returns the same offset value. I would like to know that final offset value before the animation finishes if possible.

<button onclick="onButton()">Zoom</button>
<br>
<img
    id='img'
    onclick="onImage(event)"
    src="https://picsum.photos/id/237/200"
    style="transition: 5s ease"
>

<script>
function onButton() {
    const img = document.querySelector('#img')
    img.style.scale = 5.0
}
function onImage(event) {
    console.log(event.offsetX, event.offsetY)
}
</script>


Solution

  • If you don't mind adding some additional HTML and CSS:

    function onButton() {
      const img = document.querySelector("#img");
      img.style.scale = 5.0;
      const target = document.querySelector("#target");
      target.style.scale = 5.0;// make sure target's style matches img's style
    }
    function onImage(event) {
      console.log(event.offsetX, event.offsetY);
    }
    #wrapper {
      display: inline-block;
      position:relative;
      font-size:0;
    }
    #target{
      position:absolute;
      width:100%;
      height:100%;
    }
    #img {
      transition: 5s ease;
      z-index:2;
      pointer-events:none;
    }
    <button onclick="onButton()">Zoom</button>
    <br>
    <div id="wrapper">
      <div id="target" onclick="onImage(event)"></div>
      <img id="img" src="https://picsum.photos/id/237/200">
    </div>

    This work by zooming an invisible div behind the image without transition, and transfer the click event to that div instead of the image itself