La posición del ratón

facebook-svg gplus-svg twitter-svg

Para obtener la posición del ratón encima del <canvas> hemos creado la función oMousePos() que devuelve un objeto con las coordenadas x e y del ratón.
Esta función utiliza el método getBoundingClientRect().

function oMousePos(canvas, evt) {
  var ClientRect = canvas.getBoundingClientRect();
	return { //objeto
	x: Math.round(evt.clientX - ClientRect.left),
	y: Math.round(evt.clientY - ClientRect.top)
}

También hemos escrito otras dos funciones:
marcarCoords() que da formato al <div id="output"> donde aparece el valor de las coordenadas y

function marcarCoords(output, x, y) {
  output.innerHTML = ("x: " + x + ", y: " + y);
  output.style.top = (y + 10) + "px";
  output.style.left = (x + 10) + "px";
  output.style.backgroundColor = "#FFF";
  output.style.border = "1px solid #d9d9d9"
  canvas.style.cursor = "pointer";
}

y limpiarCoords() que borra el contenido del <div id="output">.

function limpiarCoords(output) {
  output.innerHTML = "";
  output.style.top = 0 + "px";
  output.style.left = 0 + "px";
  output.style.backgroundColor = "transparent"
  output.style.border = "none";
  canvas.style.cursor = "default";
}

Utilizamos el método addEventListener() para detectar el movimiento del ratón ("mousemove") encima del canvas, y marcar las coordenadas con marcarCoords().
También utilizamos el método addEventListener() para registrar la salida del ratón ("mouseout") fuera del canvas, y borrar el valor del <div id="output"> con limpiarCoords().


Su navegador no soporta canvas :(

		var canvas = document.getElementById("lienzo");
		if (canvas && canvas.getContext) {
		  var ctx = canvas.getContext("2d");
		  if (ctx) {
		    var output = document.getElementById("output");

		    canvas.addEventListener("mousemove", function(evt) {
		      var mousePos = oMousePos(canvas, evt);
		      marcarCoords(output, mousePos.x, mousePos.y)
		    }, false);

		    canvas.addEventListener("mouseout", function(evt) {
		      limpiarCoords(output);
		    }, false);
		  }
		}

		function marcarCoords(output, x, y) {
		  output.innerHTML = ("x: " + x + ", y: " + y);
		  output.style.top = (y + 10) + "px";
		  output.style.left = (x + 10) + "px";
		  output.style.backgroundColor = "#FFF";
		  output.style.border = "1px solid #d9d9d9"
		  canvas.style.cursor = "pointer";
		}

		function limpiarCoords(output) {
		  output.innerHTML = "";
		  output.style.top = 0 + "px";
		  output.style.left = 0 + "px";
		  output.style.backgroundColor = "transparent"
		  output.style.border = "none";
		  canvas.style.cursor = "default";
		}

		function oMousePos(canvas, evt) {
		  var ClientRect = canvas.getBoundingClientRect();
		  return { //objeto
		    x: Math.round(evt.clientX - ClientRect.left),
		    y: Math.round(evt.clientY - ClientRect.top)
		  }
		}
Su navegador no soporta canvas :(

Pase por encima del canvas para obtener la posición actual del ratón.

La posición del ratón en un canvas redimensionado con CSS

Si redimensionamos un elemento canvas con css y después queremos utilizar eventos del ratón, tenemos la desagradable sorpresa de que las cosas ya no cuadran.  Supongamos que tenemos esta regla en el CSS:


canvas{
  transform: scale(2, 2);
}

Lo que pasa en este caso es que aunque el canvas es dos veces más grande la dimensión del contexto queda la misma, y si hacemos clic en el canvas a una distancia en x de 50px del origen, esto corresponde a una distancia de 25 en el context. Para que esto no pase tenemos que reescribir la función que detecta la posición del ratón teniendo en cuenta la deformación:


function oMousePosScaleCSS(canvas, evt) {
    var ClientRect = canvas.getBoundingClientRect(),
        let scaleX = canvas.width / ClientRect.width,
        let scaleY = canvas.height / ClientRect.height;
        return {
        x: (evt.clientX - ClientRect.left) * scaleX,
        y: (evt.clientY - ClientRect.top) * scaleY
    }
}

En el siguiente ejemplo el canvas fue redimensionado con CSS

See the Pen canvas scaled in CSS by Gabi (@enxaneta) on CodePen.

La posición del ratón en un canvas redimensionado utilizando el método scale()

También podemos redimensionar el contexto del canvas utilizando el método scale() del context. Si por ejemplo utilizamos ctx.scale(2,2)code> esto dobla el tamaño del contexto tanto en x como en y. El tamaño del canvas sigue igual pero el contexto es ya cuatro veces más grande. La misma posición del ratón que antes me daba 50 ahora me da 25. Podemos reescribir la función que detecta la posición del ratón teniendo en cuenta la deformación en x e y.


function oMousePosScale(canvas, evt) {
    var ClientRect = canvas.getBoundingClientRect(); 
        return {
        x: (evt.clientX - ClientRect.left) / scaleX,
        y: (evt.clientY - ClientRect.top) / scaleY
    }
  }

En el siguiente ejemplo el canvas fue redimensionado con scale(5,5). La línea que podemos dibujar siguie el ratón pero la línea es mucho mas gruesa.

See the Pen canvas ctx scaled***** by Gabi (@enxaneta) on CodePen.