Obtain the VW/VH coordinates from an onclick action in JavaScript

With this code snippet, you'll be able to retrieve the x and y coordinates of a click in pixels:

document.getElementById("game").addEventListener("click", function(event) {
   console.log(event.clientX, event.clientY);
});

However, I'm curious about how to retrieve the x and y values relative to VH (Viewport Height) and VW (Viewport Width) like you can in CSS with values such as 20vh [20% of viewport height] and so on.

Answer №1

To start, you will need to determine the Viewport Width (vw) using the window.innerWidth method, and the Viewport Height (vh) using the window.innerHeight method.

Next, you can calculate the X coordinate by dividing event.clientX by vw and then multiplying by 100 to obtain the percentage value. The same logic applies to the Y coordinate - divide event.clientY by vh and multiply by 100 to get the value in percentages.

Feel free to check out my demo below: (Simply click on the Game to view the coordinates)

let gameEl = document.getElementById("game"),
  eCXinVWEl = document.getElementById("eCXinVW"),
  eCYinVHEl = document.getElementById("eCYinVH");

gameEl.addEventListener("click", function(event) {
  let vw = window.innerWidth,
    vh = window.innerHeight,
    eCXinVW = event.clientX / vw * 100, // Multiplying by 100 to get percentage 
    eCYinVH = event.clientY / vh * 100; // Multiplying by 100 to get percentage 

  console.log(eCXinVW, eCYinVH);

  eCXinVWEl.innerHTML = eCXinVW;
  eCYinVHEl.innerHTML = eCYinVH;
});
.box {
  padding: 50px;
}

#game {
  padding: 20px;
  background: red;
}
<html>

  <head>
  </head>

  <body>
    <div class="box">
      <h6>Event coordinates X as a percentage of viewport width: <span id="eCXinVW">0</span>%</h6>
      <h6>Event coordinates Y as a percentage of viewport height: <span id="eCYinVH">0</span>%</h6>

      <div id="game">Game</div>
    </div>
  </body>

</html>

Answer №2

Did you have something similar in mind?

To achieve this, you simply need to retrieve the innerWidth and innerHeight values from the window object, then calculate the percentage using a cross product:

(elementX * 100) / viewport width
(elementY * 100) / viewport height

document.getElementById("game")
  .addEventListener("click", function(event) {
    const debug = document.getElementById('debug');
    const clickX = event.clientX;
    const clickY = event.clientY;
      
    const vh = window.innerHeight;
    const vw = window.innerWidth;
  
    const ratioX = (clickX * 100) / vw;
    const ratioY = (clickY * 100) / vh;
  
    debug.innerHTML = '';
    debug.append(`X:${clickX}  Y:${clickY}`);
    debug.append("\n");
    debug.append(`%X:${ratioX} %Y:${ratioY}`);

  });
body {
  background-color: lemon;
  display: flex;
  width: 100vw;
  height: 100vh;
  flex-flow: column;
  justify-content: center;
  align-items: center;
}

#game {
  background-color: cyan;
  width: 29.7vw;
  height: 21vh;
  box-shadow: 0px 0px 2px rgba(0,0,0,.6), 0px 0px 6px rgba(0,0,0,.3);
}
<div id=game></div>

<pre id=debug>
  X:   Y:
  %X: %Y: 
</pre>

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

Employing the findOne method repeatedly in a loop can significantly slow down operations in Node.js

Currently, I am working on a project using Node.js in conjunction with MongoDB, specifically utilizing Monk for database access. The code snippet I have is as follows: console.time("start"); collection.findOne({name: "jason"}, function(err, document) { ...

The headline is being improperly rendered inside a black box on Firefox

A while back, I inquired about creating a black box with padding around a two-line headline. The solution worked well, except for older versions of Internet Explorer. However, in Firefox, there are occasional issues with the display looking jagged. This oc ...

Changing MySQL Limit arguments into numerical values

I'm encountering an issue with my Rest call to a MySQL database. I'm using a JavaScript object and sending it through a REST GET call with a Java back-end. requestParams: { pageStart: 0, results: 10 } I have configured ...

Issues with the functionality of the Handlebars template are causing it to

Currently experimenting with Handlebars templates within my express/node.js application. I have created a template and corresponding .js files, but unfortunately, they are not functioning as expected. While the page correctly displays the unordered list&ap ...

Ways to align text within a table cell on a background using CSS

I'm attempting to print jukebox strips with designated corner markings. The code I have written generates the HTML page for displaying the strips, allowing users to then print them. Jukeboxes typically feature selection buttons labeled ABCDEFGHJK and ...

Real-time array filtering with ReactJS for nested arrays

I am currently working on implementing a real-time filtering search feature for a lengthy list of items. The items are structured in the form of an array containing arrays with a string and an object, as shown below: const items = [ ["cats", [ ...

Hitting a button causes Ajax.load to malfunction

Struggling to make ajax.load method work when clicking a button. The concept is simple: swap out the content of a div with something else using ajax.load. However, despite hours of research, I have yet to find a solution. Pressing the button does nothing. ...

What is the best way to create a board game layout inspired by Monopoly using HTML and CSS?

My goal is to create a square layout with smaller squares outlining it, similar to the tiles on a monopoly board. CSS isn't my forte, but I'm hoping to get the basic layout set up first and then play around to make it look nice. ...

What is the process of calculating the average of JSON data and looping through it multiple times using Javascript?

I've encountered a JSON data set that has the following structure: { name: "Evelyn", assignment: "SCRUM", difficulty: 3, fun: 4 } And so on. My goal is to calculate the average value of both difficulty and fun for e ...

Sending the user to their destination

There is a code in place that triggers when an email is sent to the user, containing a link that leads them to a specific endpoint upon opening. I am experiencing issues with redirection at the end of the function. The redirect does not seem to be working ...

Trouble with flex wrap in my design template using Material UI

How can I create a responsive template using flexbox wrapping method? <Box sx={{ padding: 0, margin: 0, listStyle: "none", display: "flex", flexFlow: ...

Starting service upon startup in Angularjs

I am looking to retrieve configuration data from the server and store it in the global scope within my AngularJS application. My app operates in multiple modes such as development and production, with different external services being used depending on the ...

Ensuring the authenticity of pubsubhubbub content signatures using Node.js and Express

Recently, I started working with Express and I'm currently in the process of setting up a middleware to handle a specific X-Hub-Signature based on the guidelines provided here: My goal is to create a middleware that can manage this task before the re ...

Adding a scroll bar to a fixed container: tips and tricks

I am looking to implement a scrollbar in a fixed container for the cart products. The goal is to enable easy navigation through a large number of products added to the cart by scrolling within the container. Below is the HTML code snippet representing the ...

Combining the power of Angular.js and Require.js

As I develop a local app on nw.js using angular.js, I'm starting to question my approach. In my controller, I often find myself writing code like this: .controller('UserSettingsCtrl', function($scope, $mdDialog, $translate) { var fs = ...

Remove duplicate elements from a JSON array

How can I add each item in an array for each duplicate? Transform: [ { "uuid":"EE877ABD-932F-4B4C-AB23-B324363B0B60", "planning":[ { "uuid":"6D680178-9B05-4744-A004-163D4B3E1E84", "star ...

increase the width of the side menu bar to accommodate more content on the Bootstrap

At the moment, the line that separates the content from the side menu stops at the side menu's content. However, the content is going to be longer than the side menu, causing the page to look uneven. I attempted to adjust the page-content d-flex but d ...

Preventing input in one textbox if another textbox has a filled value in HTML

Apologies for asking this question, but is there a way to disable one text box if another text box has a value? I've attempted using the following code, but it doesn't seem to work. Sorry for the inexperienced inquiry T_T function disableTextbox ...

Nodemailer contact form malfunctioning

I've been working on setting up a contact form in React and utilizing nodemailer to send messages to my email, but I seem to be encountering some issues. I have a server.js file located in the main folder along with Mailer.js which contains the form c ...

What is the best way to ensure that the state is updated only when the user begins typing in a text

I am currently working on a text editor-related code and my main focus is to update the state of the editor only when the user starts typing in the editor. The state should be updated under the following scenarios: 1. Update the state when the user begin ...