1

I made a function that transforms mouse coordinates to canvas pixel coordinates:

/* Returns pixel coordinates according to the pixel that's under the mouse cursor**/
HTMLCanvasElement.prototype.relativeCoords = function(event) {
  var x,y;
  //This is the current screen rectangle of canvas
  var rect = this.getBoundingClientRect();

  //Recalculate mouse offsets to relative offsets
  x = event.clientX - rect.left;
  y = event.clientY - rect.top;
  //Also recalculate offsets of canvas is stretched
  var width = rect.right - rect.left;
  //I use this to reduce number of calculations for images that have normal size 
  if(this.width!=width) {
    var height = rect.bottom - rect.top;
    //changes coordinates by ratio
    x = x*(this.width/width);
    y = y*(this.height/height);
  } 
  //Return as an array
  return [x,y];
}

You can see demonstration of the pixel coordinate calculation. The problem is that the solutions fails for images having border property set.

How can I subtract the border width from rectangle? Performance does matter, as this calculation is often performed during mouse move events.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Tomáš Zato
  • 50,171
  • 52
  • 268
  • 778

1 Answers1

2

getComputedStyle contains the information you desire:

Fetch the border information once at the beginning of your app after the canvas border has been set.

// get a reference to the canvas element
var canvas=document.getElementById('yourCanvasId');

// get its computed style
var styling=getComputedStyle(canvas,null);

// fetch the 4 border width values
var topBorder=styling.getPropertyValue('border-top-width');
var rightBorder=styling.getPropertyValue('border-right-width');
var bottomBorder=styling.getPropertyValue('border-bottom-width');
var leftBorder=styling.getPropertyValue('border-left-width');

If you scope these border-width variables app-wide, you can use these prefetched variables in your HTMLCanvasElement.prototype.relativeCoords.

Good luck with your project!

markE
  • 102,905
  • 11
  • 164
  • 176
  • I'm not sure how is all the computed style geting and integer parsing fast, but [it definitelly works](http://jsfiddle.net/Darker/nrw7xu2r/2/), even for all kinds of weird border dimensions (`pt`, `em`...). – Tomáš Zato Nov 29 '14 at 17:07
  • @TomášZato gCS always calculates in pixels, in fact, everything in the browser is eventually ending up in pixels as this is the only unit the screen understands. So when using arbitrary units such as pt, em etc. these are converted to pixels internally before displaying anything which again becomes the basis for gCS when you request a dimension. –  Dec 02 '14 at 05:32
  • @TomášZato you would also need this for padding btw. –  Dec 02 '14 at 05:34