-1

I'd like to create a 2dgrid with lets say xMax = 10, yMax = 6 to get something like this:

x 0 1 2 3 4 5 6 7 8 9
 _ _ _ _ _ _ _ _ _ _  y
|_|_|_|_|_|_|_|_|_|_| 0
|_|_|_|_|_|_|_|_|_|_| 1
|_|_|_|_|_|_|_|_|_|_| 2
|_|_|_|_|_|_|_|_|_|_| 3
|_|_|_|_|_|_|_|_|_|_| 4
|_|_|_|_|_|_|_|_|_|_| 5

Now I'd like to calculate on every mouse click in which of the fields (I will not add any real HTML-elements) I have clicked. As result I'd like to get the x&y position of the field from the grid (x, y).

Note: I do not want to add html-elements and listen for their click event, I'd like to calculate the result.


To make it a bit cleared I created this snippet to visualize where the coordinates start and end:

let sizeY = 6,
    sizeX = 10,
    fieldWidth = 40,
    fieldHeight = 40,
    paddingLeft = 60,
    paddingTop = 80;
    
for (let y=0; y<sizeY; y++) {
  for (let x=0; x<sizeX; x++) {
    let posX = x*fieldWidth + paddingLeft,
        posY = y*fieldHeight + paddingTop
    $(`<div class="field"></div>`).css({
      top: posY,
      left: posX,
      width: fieldWidth,
      height: fieldHeight,
      position: "absolute",
      background: `rgb(${parseInt(Math.random()*255)},
                      ${parseInt(Math.random()*255)},
                      ${parseInt(Math.random()*255)})`
    }).appendTo(document.body)
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

My question: Without adding any HTML "fields", how do I get the coordinates?:

let calculateField = function(event) {
  let sizeY = 6,
      sizeX = 10,
      fieldWidth = 40,
      fieldHeight = 40,
      paddingLeft = 60,
      paddingTop = 80,
      clickedX = event.clientX,
      clickedY = event.clientY;

   // ?
   console.log(clickedX, clickedY)
}

$(window).click(function(e) {
  calculateField(e)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Note: I'm pretty sure this is a task for the modulo operator but tbh I got no clue how to implement the code.

Cerbrus
  • 70,800
  • 18
  • 132
  • 147
  • 1
    So add click handler to the elements? – epascarello Sep 21 '18 at 14:16
  • No. There are **no real elements**. @epascarello Please read my question again. –  Sep 21 '18 at 14:16
  • 1
    And why _"I will not add any real HTML-elements"_ - that is just making it much harder for yourself – mplungjan Sep 21 '18 at 14:17
  • 1
    So $(`
    `) is not an element?
    – epascarello Sep 21 '18 at 14:17
  • 1
    That was an example. But why we did not get an example with pseudo elements I do not know - how about an image map? – mplungjan Sep 21 '18 at 14:18
  • 1
    So than you know the size of the element, get the x position of the click in the element, divide it by the width and you get the index. – epascarello Sep 21 '18 at 14:18
  • Of course this is an element. But as I said, have another look at my question! This is just hypothetic. There is no html needed because all I got is the property from the `calculateField()`.call. @epascarello –  Sep 21 '18 at 14:18
  • https://stackoverflow.com/questions/2159044/getting-the-x-y-coordinates-of-a-mouse-click-on-an-image-with-jquery than take the XY of that click and divide by the widths/heights to get the index.... – epascarello Sep 21 '18 at 14:21
  • You can also pre-compute (or just get statically) the boundries of each box, e.g., `a1 = {minX: 0, maxX: 100, minY: 0, maxY: 100}` . Get X/Y from click and see which elements it falls into by checking `minX <= x < maxX` and same with Y. – VLAZ Sep 21 '18 at 14:25

1 Answers1

2

Just calculate the pseudo-coordinates like this:

let calculateField = function(event) {
  let sizeY = 6,
      sizeX = 10,
      fieldWidth = 40,
      fieldHeight = 40,
      paddingLeft = 60,
      paddingTop = 80,
      clickedX = event.clientX,
      clickedY = event.clientY;

   const x = Math.floor((clickedX - paddingLeft) / fieldWidth);
   const y = Math.floor((clickedY - paddingTop) / fieldHeight);
   console.log("Coordinates clicked:", x, y)
}

$(window).click(function(e) {
  calculateField(e)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

And here's the example with the "demo" elements:

let sizeY = 6,
  sizeX = 10,
  fieldWidth = 40,
  fieldHeight = 40,
  paddingLeft = 60,
  paddingTop = 80;

for (let y = 0; y < sizeY; y++) {
  for (let x = 0; x < sizeX; x++) {
    let posX = x * fieldWidth + paddingLeft,
      posY = y * fieldHeight + paddingTop
    $(`<div class="field"></div>`).css({
      top: posY,
      left: posX,
      width: fieldWidth,
      height: fieldHeight,
      position: "absolute",
      background: `rgb(${parseInt(Math.random()*255)},
                      ${parseInt(Math.random()*255)},
                      ${parseInt(Math.random()*255)})`
    }).appendTo(document.body)
  }
}
let calculateField = function(event) {
  clickedX = event.clientX,
    clickedY = event.clientY;

  const x = Math.floor((clickedX - paddingLeft) / fieldWidth);
  const y = Math.floor((clickedY - paddingTop) / fieldHeight);
  console.log("Coordinates clicked:", x, y)
}

$(window).click(function(e) {
  calculateField(e)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Cerbrus
  • 70,800
  • 18
  • 132
  • 147
  • Note that, due to the padding, this will report "negative" coordinates. Just check for `x`/`y` being smaller than 0, if that's an issue. – Cerbrus Sep 21 '18 at 14:26
  • @mplungjan: I forgot the padding. See the [updated version](http://jsfiddle.net/Lg6f09uw/2/) – Cerbrus Sep 21 '18 at 14:27