0

I am trying to find where the mouse is on a canvas's 'grid' while maintaining resizability. I currently have the mouse coordinates for where it is on the screen (x and y).

The problem is, the 'scaling' between WebGL (which I am using to draw on the canvas) and the mouse coordinates is different. What WebGL considers to be 10 units to the right from origin is actually considered x number of units from the origin (different screen resolution changes this). This means that when my mouse is over what WebGL considers (10, 10), my mouse coordinates are (100, 100).

How would I convert the mouse coordinates on the screen to the 'WebGL coordinates' which are used to define a point?

This is similar to this question but I would like to do it without using Fabric.js.

Community
  • 1
  • 1
StillLearning
  • 97
  • 3
  • 12

2 Answers2

3

To convert canvas mouse coordinates to relative coordinates in the range of -1 to +1, one first needs to get the relative pixel coordinates within the canvas using offsetX/offsetY provided by the mouse event.

Then divide this by the actual width and height of the canvas using clientWidth/clientHeight.

Having the relative coordinates in a range from 0 to 1 we can now move them into the right range by multiplying by 2 and subtracting 1.

Note that in WebGL the up axis is positive 1 so one wants to invert the Y coordinate.

All put together:

var ndcX = (mouseEvent.offsetX / canvas.clientWidth) * 2 - 1;
var ndcY = (1 - (mouseEvent.offsetY / canvas.clientHeight)) * 2 - 1;
LJᛃ
  • 7,655
  • 2
  • 24
  • 35
  • [The full answer](http://stackoverflow.com/a/35741551/128511) is harder than it looks but for the normal case your solution works – gman Jun 15 '16 at 14:58
  • Small typo in the `ndcY` calculation. You should be deviding by `canvas.clientHeight` instead of `canvas.clientWidth`. – xoryouyou Oct 06 '16 at 09:31
-1

If your event listener is on the canvas element then the coordinates should already be on the canvas . Meaning mouse.x = 0 mouse.y = 0 would be at the top left corner of your canvas.

  • Looks like this might work. Let me do a bit more testing, but seems good. – StillLearning Jun 14 '16 at 22:08
  • This didn't work. 10 units wide in the canvas was more than 20 units reported by the onmousmove event listener even when on canvas element. – StillLearning Jun 14 '16 at 22:17
  • 1
    As mouse.x/y returns the same value as event.clientX/Y it means the coordinates will be relative to viewport not the element. x/y is not supported in all browsers. Ref: https://drafts.csswg.org/cssom-view/#dom-mouseevent-x –  Jun 14 '16 at 22:17