¿Cuál es la forma más sencilla de agregar un controlador de eventos de clic a un elemento del lienzo que devolverá las coordenadas x e y del clic (en relación con el elemento del lienzo)?
No se requiere compatibilidad de navegador heredada, Safari, Opera y Firefox lo harán.
javascript
canvas
Tom
fuente
fuente
Respuestas:
Editar 2018: esta respuesta es bastante antigua y utiliza comprobaciones para navegadores antiguos que ya no son necesarios, ya que las propiedades
clientX
yclientY
funcionan en todos los navegadores actuales. Es posible que desee consultar Patriques Answer para obtener una solución más simple y más reciente.Respuesta original:
como se describe en un artículo que encontré en ese entonces pero ya no existe:
Funcionó perfectamente bien para mí.
fuente
Si le gusta la simplicidad pero aún desea la funcionalidad de navegador cruzado, encontré que esta solución funcionó mejor para mí. Esta es una simplificación de la solución de @ Aldekein pero sin jQuery .
fuente
getBoundingClientRect
devuelve posiciones relativas al puerto de visualización? Entonces mi suposición estaba equivocada. Nunca lo probé, ya que esto nunca fue un problema para mí, y amablemente quería advertir a otros lectores de un problema potencial que vi, pero gracias por su aclaración.var canvas = document.getElementById('canvasID'); canvas.addEventListener("mousedown", function (e) { getCursorPosition(canvas, e);});
Actualización (5/5/16): la respuesta de patriques debería usarse en su lugar, ya que es más simple y más confiable.
Dado que el lienzo no siempre tiene un estilo relativo a toda la página,
canvas.offsetLeft/Top
no siempre devuelve lo que necesita. Devolverá el número de píxeles que está desplazado en relación con su elemento offsetParent, que puede ser algo así como undiv
elemento que contiene el lienzo con unposition: relative
estilo aplicado. Para dar cuenta de esto, debe recorrer la cadena deoffsetParent
s, comenzando con el elemento de lienzo en sí. Este código funciona perfectamente para mí, probado en Firefox y Safari, pero debería funcionar para todos.La última línea facilita las cosas para obtener las coordenadas del mouse en relación con un elemento de lienzo. Todo lo que se necesita para obtener las coordenadas útiles es
fuente
event.offsetX
yevent.offsetY
atributos, por lo que modifiqué su solución agregandoif (event.offsetX !== undefined && event.offsetY !== undefined) { return {x:event.offsetX, y:event.offsetY}; }
. Parece que funciona.event.offsetX
yevent.offsetY
también funciona en IE9. Para Firefox (probado con v13) puede usarevent.layerX
yevent.layerY
.canvasX = event.pageX - totalOffsetX - document.body.scrollLeft; canvasY = event.pageY - totalOffsetY - document.body.scrollTop;
El navegador moderno ahora maneja esto por usted. Chrome, IE9 y Firefox admiten el offsetX / Y de esta manera, pasando el evento desde el controlador de clics.
La mayoría de los navegadores modernos también admiten layerX / Y, sin embargo, Chrome e IE usan layerX / Y para el desplazamiento absoluto del clic en la página, incluido el margen, el relleno, etc. En Firefox, layerX / Y y offsetX / Y son equivalentes, pero el offset no No existe previamente. Entonces, para compatibilidad con navegadores un poco más antiguos, puede usar:
fuente
Según el nuevo Quirksmode, los métodos
clientX
yclientY
son compatibles con todos los principales navegadores. Entonces, aquí va: el código bueno y funcional que funciona en un div de desplazamiento en una página con barras de desplazamiento:Esto también requiere jQuery para
$(canvas).offset()
.fuente
Hice una demostración completa que funciona en todos los navegadores con el código fuente completo de la solución de este problema: coordenadas de un clic del mouse en Canvas en Javascript . Para probar la demostración, copie el código y péguelo en un editor de texto. Luego guárdelo como example.html y, finalmente, abra el archivo con un navegador.
fuente
Aquí hay una pequeña modificación a la respuesta de Ryan Artecona para lienzos con un ancho variable (%):
fuente
Tenga cuidado al hacer la conversión de coordenadas; Hay varios valores que no son de navegador cruzado devueltos en un evento de clic. Usar clientX y clientY solo no son suficientes si se desplaza la ventana del navegador (verificado en Firefox 3.5 y Chrome 3.0).
Este modo peculiar artículo sobre el ofrece una función más correcta que puede usar pageX o pageY o una combinación de clientX con document.body.scrollLeft y clientY con document.body.scrollTop para calcular la coordenada de clic relativa al origen del documento.
ACTUALIZACIÓN: Además, offsetLeft y offsetTop son relativos al tamaño acolchado del elemento, no al tamaño interior. Un lienzo con el relleno: el estilo aplicado no informará la parte superior izquierda de su región de contenido como offsetLeft. Hay varias soluciones a este problema; el más simple puede ser borrar todos los estilos de borde, relleno, etc. en el lienzo y, en su lugar, aplicarlos a un cuadro que contiene el lienzo.
fuente
No estoy seguro de cuál es el punto de todas estas respuestas que recorren los elementos principales y hacen todo tipo de cosas raras .
El
HTMLElement.getBoundingClientRect
método está diseñado para manejar la posición real de la pantalla de cualquier elemento. Esto incluye el desplazamiento, por lo quescrollTop
no se necesitan cosas como :Imagen normal
El enfoque más simple ya se publicó aquí. Esto es correcto siempre que no existan reglas CSS salvajes .
Manejo de lienzo / imagen estirada
Cuando el ancho de píxel de la imagen no coincide con su ancho de CSS, deberá aplicar alguna proporción en los valores de píxel:
Mientras el lienzo no tenga borde, funciona para imágenes estiradas (jsFiddle) .
Manejo de bordes CSS
Si el lienzo tiene un borde grueso, las cosas se complican un poco . Literalmente, deberá restar el borde del rectángulo delimitador. Esto se puede hacer usando .getComputedStyle . Esta respuesta describe el proceso. .
La función luego crece un poco:
No se me ocurre nada que pueda confundir esta función final. Mírate en JsFiddle .
Notas
Si no le gusta modificar los
prototype
s nativos , simplemente cambie la función y llámela con(canvas, event)
(y reemplace cualquierathis
concanvas
).fuente
Aquí hay un tutorial muy bueno.
http://www.html5canvastutorials.com/advanced/html5-canvas-mouse-coordinates/
¡espero que esto ayude!
fuente
width
/height
anulación, pero sigue siendo una de las mejores soluciones.Usando jQuery en 2016, para obtener coordenadas de clic relativas al lienzo, hago:
Esto funciona ya que tanto el desplazamiento del lienzo () como jqEvent.pageX / Y son relativos al documento, independientemente de la posición de desplazamiento.
Tenga en cuenta que si su lienzo está escalado, estas coordenadas no son las mismas que las coordenadas lógicas del lienzo . Para obtenerlos, también harías:
fuente
Este es un tema simple pero un poco más complicado de lo que parece.
En primer lugar, generalmente hay preguntas combinadas aquí
Cómo obtener las coordenadas relativas del mouse del elemento
Cómo obtener coordenadas de mouse de píxeles de lienzo para la API de lienzo 2D o WebGL
entonces, respuestas
Cómo obtener las coordenadas relativas del mouse del elemento
Si el elemento es o no un lienzo que obtiene coordenadas relativas del mouse del elemento es el mismo para todos los elementos.
Hay 2 respuestas simples a la pregunta "Cómo obtener coordenadas relativas del mouse del lienzo"
Respuesta simple # 1 uso
offsetX
yoffsetY
Esta respuesta funciona en Chrome, Firefox y Safari. A diferencia de todos los demás valores de eventos
offsetX
yoffsetY
tener en cuenta las transformaciones CSS.El mayor problema con
offsetX
yoffsetY
es a partir de 2019/05 que no existen en eventos táctiles y, por lo tanto, no se pueden usar con iOS Safari. Existen en los eventos de puntero que existen en Chrome y Firefox pero no en Safari, aunque aparentemente Safari está trabajando en ello .Otro problema es que los eventos deben estar en el lienzo en sí. Si los coloca en otro elemento o en la ventana, no podrá elegir el lienzo como punto de referencia.
Respuesta simple # 2 uso
clientX
,clientY
ycanvas.getBoundingClientRect
Si no le importan las transformaciones CSS, la siguiente respuesta más simple es llamar
canvas. getBoundingClientRect()
y restar la izquierda declientX
ytop
declientY
como enEsto funcionará siempre que no haya transformaciones CSS. También funciona con eventos táctiles y funcionará con Safari iOS
Cómo obtener coordenadas de mouse de píxeles de lienzo para la API de lienzo 2D
Para esto, necesitamos tomar los valores que obtuvimos arriba y convertirlos del tamaño del lienzo que se muestra al número de píxeles en el lienzo mismo
con
canvas.getBoundingClientRect
yclientX
yclientY
o con
offsetX
yoffsetY
Nota: en todos los casos, no agregue relleno ni bordes al lienzo. Hacerlo complicará enormemente el código. En lugar de que desee un borde o relleno, rodee el lienzo en algún otro elemento y agregue el relleno o el borde al elemento exterior.
Ejemplo de trabajo usando
event.offsetX
,event.offsetY
Mostrar fragmento de código
Ejemplo de trabajo usando
canvas.getBoundingClientRect
yevent.clientX
yevent.clientY
Mostrar fragmento de código
fuente
Recomiendo este enlace: http://miloq.blogspot.in/2011/05/coordinates-mouse-click-canvas.html
fuente
x = new Number()
? El código a continuación que reasigna, lox
que significa que el Número asignado se descarta inmediatamenteEn Prototype, use cumulativeOffset () para hacer la suma recursiva como mencionó Ryan Artecona anteriormente.
http://www.prototypejs.org/api/element/cumulativeoffset
fuente
Podrías simplemente hacer:
Esto le dará la posición exacta del puntero del mouse.
fuente
Vea la demostración en http://jsbin.com/ApuJOSA/1/edit?html,output .
fuente
Aquí hay algunas modificaciones de la solución de Ryan Artecona anterior.
fuente
Primero, como han dicho otros, necesita una función para obtener la posición del elemento de lienzo . Aquí hay un método que es un poco más elegante que algunos de los otros en esta página (en mi humilde opinión). Puede pasarle cualquier elemento y obtener su posición en el documento:
Ahora calcule la posición actual del cursor con respecto a eso:
Tenga en cuenta que he separado la
findPos
función genérica del código de manejo de eventos. ( Como debería ser . Deberíamos tratar de mantener nuestras funciones en una tarea cada una).Los valores de
offsetLeft
yoffsetTop
son relativos aoffsetParent
, que podrían ser algúndiv
nodo contenedor (o cualquier otra cosa, para el caso). Cuando no hay ningún elemento que los envuelvacanvas
, son relativos albody
, por lo que no hay desplazamiento para restar. Es por eso que necesitamos determinar la posición del lienzo antes de poder hacer cualquier otra cosa.De forma similar,
e.pageX
ye.pageY
dar la posición del cursor con respecto al documento. Es por eso que restamos el desplazamiento del lienzo de esos valores para llegar a la posición verdadera.Una alternativa para los elementos posicionados es usar directamente los valores de
e.layerX
ye.layerY
. Esto es menos confiable que el método anterior por dos razones:fuente
ThreeJS r77
Después de probar muchas soluciones. Esto funcionó para mí. Podría ayudar a alguien más, por lo tanto, publicar. Lo tengo desde aqui
fuente
Aquí hay una solución simplificada (esto no funciona con bordes / desplazamiento):
fuente
Estaba creando una aplicación que tenía un lienzo sobre un pdf, que involucraba muchos cambios de tamaño del lienzo, como acercar y alejar el pdf, y a su vez en cada acercamiento / alejamiento del PDF tenía que cambiar el tamaño del lienzo para adaptar el tamaño del pdf, revisé muchas respuestas en stackOverflow, y no encontré una solución perfecta que eventualmente resuelva el problema.
Estaba usando rxjs y angular 6, y no encontré ninguna respuesta específica para la versión más nueva.
Aquí está el fragmento de código completo que sería útil, para cualquiera que aproveche los rxjs para dibujar sobre el lienzo.
Y aquí está el fragmento que arregla, las coordenadas del mouse en relación con el tamaño del lienzo, independientemente de cómo acerque / aleje el lienzo.
fuente
Oye, esto está en el dojo, solo porque es lo que ya tenía el código para un proyecto.
Debería ser bastante obvio cómo convertirlo de nuevo a JavaScript no dojo vanilla.
Espero que ayude.
fuente