Determining the precise mouse location within child elements regardless of zoom level, scrolling, or dimension changes

My goal is to accurately determine mouse coordinates within the page elements.

To see the code in action, please visit: http://jsfiddle.net/t8w9k6gu/

$('#p1, #p2, #p3').on('click mousemove touchmove', function(ev){
    var target = ev.originalEvent.currentTarget;
    var offset = $(target).offset();
    
    var x = ev.originalEvent.pageX;
    var y = ev.originalEvent.pageY;
    
    $(coords).html(x + ', ' + y);
    
    $(elm).html(target.id + ' {' + offset.left + ', ' + offset.top + '}');
    
});
 

var main = $('#main');
var content = $('#content');
var zoom = $('#zoom');
var coords = $('#coords');
var scroll = $('#scroll');
var zoomv = 0.5;
$(content).css({zoom: zoomv});
$('#headh').html($('#head').height());
$('#headsize').on('click', function(ev){
    $('#headbig').toggle();
    $('#headh').html($('#head').height());
});
$('#zoomin').on('click', function(){
    zoomv += .1;
    $(content).css({
        zoom: zoomv
    });
    $(zoom).html(zoomv);
});
$('#zoomout').on('click', function(){
    if(zoomv < .2){
        return;
    }
    zoomv -= .1;
    $(content).css({
        zoom: zoomv
    });
    $(zoom).html(zoomv);
});

$(main).on('scroll', function(ev){
    $(scroll).html($(main).scrollLeft() + ', ' + $(main).scrollTop());
});
html, body{
    margin:0;
    padding:0;
}
#head{
    border:2px #880 solid;
}
#headbig{
    border:2px #ccc dashed;
    height:50px;
    display: none;
}
#main{
    overflow:auto;
    height:186px;
    background-color:#f00;
}
#content{
    height:0;
    position:relative;
    overflow:visible;
    background-color: #00f;
}
#p1, #p2, #p3{
    background-color:#0ff;
    margin:10px;
    width:600px;
    height:800px;
    cursor:pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
   <div id="wrap">
       <div id="head">
           <input type="button" id="zoomin" value="Zoom in" />
           <input type="button" id="zoomout" value="Zoom Out" />
           <input type="button" id="headsize" value="Resize head" />
           <br />
           Mouse coords: <span id="coords">0, 0</span>
           <br />
           Element offset: <span id="elm">null, 0, 0</span>
           <br />
           Main scroll: <span id="scroll">0, 0</span>
           <br />
           Content zoom: <span id="zoom">0.5</span>
           <br />
           Head height: <span id="headh">0</span>
           <div id="headbig"></div>
       </div>
       <div id="main">
           <div id="content">
               <div id="p1">
                   <h1>Page 1</h1>
               </div>
               <div id="p2">
                   <h1>Page 2</h1>
               </div>
               <div id="p3">
                   <h1>Page 3</h1>
               </div>
           </div>
       </div>
   </div>

In this scenario, each page element measures 600x800 pixels. The objective is to obtain accurate mouse positions within any of the page elements regardless of zoom level, scrollbar positions, or head element size.

For instance, if the mouse cursor is at the bottom right corner of a page element, the coordinates should consistently be {600,800}. The top-left corner of the page should always read {0,0}, and the center of the page should yield {300,400}. This calculation must remain independent of zoom, scroll, or head size adjustments.

I've experimented with different methods involving mouse event values (pageX/pageY), page element offsets, scroll positions, zoom levels, but I'm yet to arrive at the most effective way to compute positions within the page elements correctly.

The structure of this layout cannot be modified as it's part of a more intricate application. As such, I am seeking guidance on how to calculate these positions precisely with the existing layout intact.

This functionality should work seamlessly on PC Chrome browser, as well as mobile iOS Safari and Android Chrome browsers.

Any assistance, recommendations, or suggested readings would be highly appreciated.

Edit:

The closest approximation I've achieved so far has been by utilizing getBoundingClientRect to calculate positions as follows:

var bb = target.getBoundingClientRect();    
var x = ev.originalEvent.pageX / zoomv - bb.left;
var y = ev.originalEvent.pageY / zoomv - bb.top;

See the updated Jsfiddle here: http://jsfiddle.net/t8w9k6gu/1/

While this approach meets my current requirements, there may still be room for improvement. Therefore, I welcome any suggestions for enhancement.

Answer №1

Enhance your rendering by avoiding zoom and utilizing transform scale instead. This way, the size adjustments will come after rendering, maintaining the integrity of the coordinate system.

Utilize ev.offsetX and ev.offsetY to retrieve the desired coordinates accurately. With this approach, you can ensure a range between 0,0 and 600,800 in Chrome across all zoom levels.

$('#zoomin').on('click', function(){
    zoomv += .1;
    $(content).css({
        'transform-origin': 'left top',
        transform: 'scale(' + zoomv + ')'
    });
    $(zoom).html(zoomv);
});

Explore a demo here

Answer №2

To ensure accuracy in determining the cursor value, it is important to consider the position of the div and adjust accordingly by excluding its left and top values.

In this scenario, I have employed two variables, 'a' and 'b', to capture the left and top positions of the current div, subsequently subtracting them from the x and y values.

For a visual representation and an updated version of the code, please refer to: http://jsfiddle.net/t8w9k6gu/8/

 function(ev){
    var target = ev.originalEvent.currentTarget;
    var offset = $(target).offset();
    var a = offset.left
    var b = offset.top
    var x = ev.originalEvent.pageX;
    var y = ev.originalEvent.pageY;

    $(coords).html((parseInt(x)-parseInt(a)) + ', ' + (parseInt(y)-parseInt(b)));

    $(elm).html(target.id + ' {' + offset.left + ', ' + offset.top + '}');  
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Encountered an issue loading a resource due to a lost network connection while using Safari 9 and JBoss WildFly 8.2

After successfully deploying my War file to the JBoss Wildfly 8.2 server, I attempted to access the application link from a remote MAC machine. The application opened correctly, but some functionalities were not working properly. An error message popped u ...

The feature of sorting appears to be malfunctioning within jQuery DataTables

I am having trouble implementing sorting in my data. Can you please help me understand why it is not working? What changes do I need to make so that the data can be displayed in order? <%@ page language="java" contentType="text/html; charset=ISO ...

Using the concept of method chaining in JavaScript, you can easily add multiple methods from

Hey there! I'm looking for some assistance with dynamically building a method chain. It seems like it should be pretty straightforward if you're familiar with how to do it... Currently, I am using mongoose and node.js to query a mongo database. ...

Step-by-step guide on displaying a window containing text when hovering over a CSS class

As a beginner in css, html, and js, I created an html page with a table of athletes. Each row is identified by the css class "athlete-name", like this: <div id="message-hide" style="display: none"> Hello world! </div> <t ...

combining HTML and CSS for perfect alignment

I'm having trouble trying to align an image and some text side by side. Below is the code that includes an image and text (Name and Age), but they are not aligning properly even after using float: left. Can anyone help me with this? Thank you. < ...

How important is a neglected parameter in the world of JavaScript?

Curious about the value of an ignored parameter in JS? Imagine a function that requires 2 values as parameters, but you only provide one during the call. What happens to the other parameter? You might think it's undefined, but the code below only show ...

What is the simplest method for moving cells between two tables using drag and drop?

Is there a way to select random cells from a table and move them to another table using drag and drop functionality? I'm looking for a library that can help achieve this with JavaScript and PHP. Additionally, I need to save the ID of the selected cel ...

What is the best way to configure the default selected value order in a jQuery select2 remote select box?

After customizing the select2 plugin to display default selected values, I encountered a problem when editing sessions. While creating a session and selecting multiple speakers from the dropdown, they were displayed as selected. However, when editing anoth ...

The content inside a Textbox cannot be clicked on. I am seeking help with implementing JavaScript to enable it to be

As a newcomer in the world of programming, I am sharing a snippet of my JavaScript and HTML code with you. I am facing an issue where I want to enable users to start typing in a text box upon clicking on the text "User Name", without deleting any existing ...

I am facing issues connecting my Express Node server to my MongoDB database using Mongoose

Starting my backend journey, I keep encountering the same error with my server.js --> // Step 1 - Create a folder named backend // Step 2 - Run npm init -y // Step 3 - Open in VS Code // Step 4 - Install express using npm i express // Step 5 - Create se ...

I am trying to layer 3 x 3 images on top of a background image, but the images are overlapping

I am in the process of creating a website using bootstrap 4. I have a background image that needs to have nine smaller images overlaid on top. However, the images are currently overlapping each other and need to be arranged properly. This layout also needs ...

Updating an AngularJS directive following a service method invocation

My goal is to set up a reusable alert service that can be easily called from anywhere in my application with just: alertService.showAlert('warning', 'something went wrong!'); One example of where I want to use this is after an AJAX ca ...

Issue with margin-bottom in flexbox causing layout problems

My design conundrum lies within a flexbox structure where I desire specific elements to have varying amounts of spacing, prompting me to experiment with margins. At the top of my box, there is a header that requires some distance between itself and the su ...

Contrast between pm.response.json() and parsing the responseBody using JSON.parse()

Can you explain the key distinction between const json_response = pm.response.json() and json_response = JSON.parse(responseBody) ...

"NextAuth encounters an issue while trying to fetch the API endpoint: req.body

Trying to implement authentication in my Next.js app using NextAuth.js, I've encountered an issue with the fetching process. Here's the code snippet from the documentation: authorize: async (credentials, req) => { const res = await fetch ...

jQuery blocking the Ajax response in IE

Currently attempting to make an API call using the $.ajax() function. The response is successful in Firefox, but encountering a blockage in IE due to jQuery. The debugger shows the error message: Permission denied - jquery-1.4.2.min.js line 127 charac ...

A guide to implementing VantaJS in SvelteKit

Can someone guide me on incorporating Vanta JS from a SvelteKit project? I've attempted to add it in +page.svelte, <script lang="ts"> import VANTA from "vanta"; import * as THREE from 'three'; VANTA. ...

Error: Attribute "th:replace" within element type "tr" is invalid because it contains the character '<'

<tr th:replace="textbox1 :: textbox1”></tr> Unfortunately, an error has occurred: org.xml.sax.SAXParseException: The value of attribute "th:replace" associated with an element type "tr" must not contain the '<' character. We n ...

Utilizing AJAX and PHP for seamless communication, retrieve and authenticate HTTPS SSL CERTIFICATE when interacting

Recently, I successfully created a node.js REST server located at . To develop the front-end, I am utilizing a combination of html, javascript, and php. However, when I attempted to implement an SSL certificate on the front-end, a problem arose: An issue ...

Exploring ways to dynamically adjust the video source URL based on the time in an HTML video player

I'm working on creating a custom video player that changes the video source based on specific times. For example, at "12 AM" I want to play "video1.mp4," at "1 AM" I want to switch to "video2.mp4," and at "5 PM" I want to play "video3.mp4." As a begi ...