Al obtener la ubicación del ratón en el lienzo [Duplicar]
-
12-09-2019 - |
Pregunta
Esta pregunta ya tiene una respuesta aquí:
¿Hay una manera de conseguir el ratón ubicación dentro de una etiqueta <canvas>
? Quiero que la ubicación con respecto a la esquina superior derecha de la <canvas>
, no toda la página.
Solución
La manera más fácil es probablemente añadir un detector de eventos onmousemove al elemento de tela, y entonces se puede obtener las coordenadas relativas a la lona del evento en sí.
Esto es trivial de lograr si sólo tiene que soportar los navegadores específicos, pero hay diferencias entre f.ex. Opera y Firefox.
Algo como esto debería funcionar para los dos:
function mouseMove(e)
{
var mouseX, mouseY;
if(e.offsetX) {
mouseX = e.offsetX;
mouseY = e.offsetY;
}
else if(e.layerX) {
mouseX = e.layerX;
mouseY = e.layerY;
}
/* do something with mouseX/mouseY */
}
Otros consejos
La respuesta aceptada no funcionará cada vez. Si no se utiliza la posición relativa de los atributos offsetX y offsetY pueden ser engañosos.
Se debe utilizar la función:. canvas.getBoundingClientRect()
de la API de canvas
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
canvas.addEventListener('mousemove', function(evt) {
var mousePos = getMousePos(canvas, evt);
console.log('Mouse position: ' + mousePos.x + ',' + mousePos.y);
}, false);
También tenga en cuenta que necesitará CSS:
Posición: relative;
set de su etiqueta de tela, con el fin de obtener la posición relativa del ratón dentro del lienzo.
Y los cambios de desplazamiento si hay un borde
Voy a compartir el código más a prueba de balas ratón que he creado hasta el momento. Funciona en todos los navegadores que tengan todo tipo de relleno, margen, borde y complementos (como la barra superior StumbleUpon)
// Creates an object with x and y defined,
// set to the mouse position relative to the state's canvas
// If you wanna be super-correct this can be tricky,
// we have to worry about padding and borders
// takes an event and a reference to the canvas
function getMouse = function(e, canvas) {
var element = canvas, offsetX = 0, offsetY = 0, mx, my;
// Compute the total offset. It's possible to cache this if you want
if (element.offsetParent !== undefined) {
do {
offsetX += element.offsetLeft;
offsetY += element.offsetTop;
} while ((element = element.offsetParent));
}
// Add padding and border style widths to offset
// Also add the <html> offsets in case there's a position:fixed bar (like the stumbleupon bar)
// This part is not strictly necessary, it depends on your styling
offsetX += stylePaddingLeft + styleBorderLeft + htmlLeft;
offsetY += stylePaddingTop + styleBorderTop + htmlTop;
mx = e.pageX - offsetX;
my = e.pageY - offsetY;
// We return a simple javascript object with x and y defined
return {x: mx, y: my};
}
Se dará cuenta de que yo uso algunos (opcional) variables que no definidos en la función. Ellos son:
stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(canvas, null)['paddingLeft'], 10) || 0;
stylePaddingTop = parseInt(document.defaultView.getComputedStyle(canvas, null)['paddingTop'], 10) || 0;
styleBorderLeft = parseInt(document.defaultView.getComputedStyle(canvas, null)['borderLeftWidth'], 10) || 0;
styleBorderTop = parseInt(document.defaultView.getComputedStyle(canvas, null)['borderTopWidth'], 10) || 0;
// Some pages have fixed-position bars (like the stumbleupon bar) at the top or left of the page
// They will mess up mouse coordinates and this fixes that
var html = document.body.parentNode;
htmlTop = html.offsetTop;
htmlLeft = html.offsetLeft;
Me gustaría recomendar solamente el cálculo de los una vez, por lo que no están en la función getMouse
.
Para la posición del ratón, que suelen utilizar jQuery ya que normaliza algunos de los atributos de evento.
function getPosition(e) {
//this section is from http://www.quirksmode.org/js/events_properties.html
var targ;
if (!e)
e = window.event;
if (e.target)
targ = e.target;
else if (e.srcElement)
targ = e.srcElement;
if (targ.nodeType == 3) // defeat Safari bug
targ = targ.parentNode;
// jQuery normalizes the pageX and pageY
// pageX,Y are the mouse positions relative to the document
// offset() returns the position of the element relative to the document
var x = e.pageX - $(targ).offset().left;
var y = e.pageY - $(targ).offset().top;
return {"x": x, "y": y};
};
// now just make sure you use this with jQuery
// obviously you can use other events other than click
$(elm).click(function(event) {
// jQuery would normalize the event
position = getPosition(event);
//now you can use the x and y positions
alert("X: " + position.x + " Y: " + position.y);
});
Esto funciona para mí en todos los navegadores.
EDIT:
He copiado el código de una de mis clases que estaba usando, por lo que la llamada jQuery para this.canvas
estaba mal. La función de actualización se da cuenta de que elemento de DOM (targ
) causó el evento y luego utiliza ese elemento está compensado para averiguar la posición correcta.
GEE es una biblioteca sin fin útil para suavizar los problemas con lienzo, incluyendo la ubicación del ratón.
enfoque simple utilizando las propiedades de eventos de ratón y de lona:
jsFiddle demostración de la funcionalidad http://jsfiddle.net/Dwqy7/5/
(Nota: Las fronteras no se tienen en cuenta, lo que resulta en off-by-one):
-
Añadir un evento de ratón para el lienzo
canvas.addEventListener("mousemove", mouseMoved);
-
Ajuste
event.clientX
yevent.clientY
basado en:
canvas.offsetLeft
window.pageXOffset
window.pageYOffset
canvas.offsetTop
Así:canvasMouseX = event.clientX - (canvas.offsetLeft - window.pageXOffset); canvasMouseY = event.clientY - (canvas.offsetTop - window.pageYOffset);
La pregunta original pedido coordenadas de la esquina superior derecha (segunda función). Estas funciones tendrán que estar dentro de un ámbito en el que puedan acceder al elemento canvas.
0,0 en la parte superior izquierda:
function mouseMoved(event){
var canvasMouseX = event.clientX - (canvas.offsetLeft - window.pageXOffset);
var canvasMouseY = event.clientY - (canvas.offsetTop - window.pageYOffset);
}
0,0 en la parte superior derecha:
function mouseMoved(event){
var canvasMouseX = canvas.width - (event.clientX - canvas.offsetLeft)- window.pageXOffset;
var canvasMouseY = event.clientY - (canvas.offsetTop - window.pageYOffset);
}
que haría uso de jQuery.
$(document).ready(function() {
$("#canvas_id").bind( "mousedown", function(e){ canvasClick(e); } );
}
function canvasClick( e ){
var x = e.offsetX;
var y = e.offsetY;
}
De esta manera sus lona puede estar en cualquier lugar en su página, relativa o absoluta.
Resta los X e Y desplazamientos del elemento de DOM de la lona de la posición del ratón para obtener la posición local dentro de la lona.