2010-09-01 20 views
16

Estoy viendo muchas preguntas sobre cómo obtener el elemento de lienzo html5 para recibir clics del mouse, estoy usando el lienzo como una superposición y los clics del mouse no están pasando por los elementos abajo. Estoy cargando una imagen en el lienzo, y pensé que ese podría ser el problema, pero también lo intenté con un lienzo vacío y obtuve el mismo resultado.obtener clics a través del lienzo html

Aquí se muestra un ejemplo: con la imagen: http://www.1luckypixel.com/paranormal/canvas_test.html el enlace va a Google, pero no es el registro.

Tengo entendido que el lienzo es transparente para el mouse por defecto?

+0

Aquí hay uno sin la imagen: sin: http://www.1luckypixel.com/paranormal/canvas_test2.html – JoeM05

+0

¿Es esto específico de LONA? ¿No tendrías el mismo problema si tuvieras un DIV o IMG del mismo tamaño que una superposición? – donohoe

+0

Esto no sería específico del lienzo, excepto por el hecho de que he tenido la impresión de que puede pasar clics a través de un lienzo, o más bien, es el comportamiento predeterminado (el mouse ignora el lienzo). Tengo esta idea en un taller html5 alojado en Google NYC. A menos que lo malinterprete. – JoeM05

Respuesta

7

Si la funcionalidad de navegador cruzado no es un requisito, entonces hay una solución fácil. En los navegadores que lo soportan para elementos que no son SVG (webkit, Mozilla y tal vez otros, pero notablemente no IE), puede usar la propiedad css llamada pointer-events. Desde el MDN:

"Los eventos de puntero de propiedad CSS permiten a los autores controlar bajo qué circunstancias (si existe) un elemento gráfico en particular puede convertirse en el objetivo de los eventos del mouse. Cuando esta propiedad no está especificada, las mismas características de visiblePainted el valor se aplica al contenido SVG.

Además de indicar que el elemento no es el objetivo de los eventos del mouse, el valor none indica que el evento del mouse "atraviese" el elemento y meta lo que está "debajo" de ese elemento.

Advertencia: El uso de eventos de puntero en CSS para elementos que no son SVG es experimental. Actualmente definido en el borrador de la especificación UI CSS3, hay discusión para posponerlo a CSS4. "

Por lo menos, se puede utilizar para detectar Modernizr apoyan puntero-eventos y hacer el truco opacidad mencionado en Simon Sarris's answer en los navegadores que no soportan.

Además, si su aplicación es específica a Google Maps, se puede insertar el lienzo como una superposición de los mapas de Google, evitando así el problema todos juntos

Ejemplo:. http://www.patrick-wied.at/static/heatmapjs/demo/maps_heatmap_layer/gmaps.php

+0

Esta función parece ser ampliamente compatible con los navegadores modernos ahora. Ver http://caniuse.com/#search=pointer -eventos – fzzfzzfzz

2

Bueno, la respuesta corta es que no se puede pasar el clic.

¡Pero la segunda respuesta más corta es que puedes hacer todo lo que tu corazón desee! Solo tienes que estar dispuesto a ponerte un poco extraño con la solución.

La primera forma en que puedo pensar es un poco enloquecedor pero fácil: para cada artículo detrás del lienzo, haga una pieza secreta similar similar delante del lienzo. A continuación, poner el evento que desea en el elemento secreto:

<!-- A visible button behind the canvas --> 
<button id="but" type="button" style="position: absolute; top: 100px; left: 100px;">Click Me!</button> 

<canvas id="can" width="500" height="500" style="position: absolute;"></canvas> 

<!-- A near copy of the visible button, but this one is invisible and in front of the canvas! --> 
<button id="but" type="button" onclick="alert('click!')" style="position: absolute; top: 100px; left: 100px; opacity: 0;">Click Me!</button> 

Si usted quiere ver ese código en la acción click here

Hay levemente maneras más-loco-aún-más-mantenibles si tiene cien detrás del lienzo en el que desea que se pueda hacer clic, pero probablemente sea el más fácil de hacer si solo tiene de 1 a 3 elementos sobre los que desea hacer clic detrás de un lienzo.

+0

Estoy usando esto como una superposición para un mapa de google ... así que esto no lo haría por desgracia. ¿Qué es este método más loco, pero más fácil de mantener? ¡Estoy intrigado! – JoeM05

+1

Desafortunadamente, mi otro método no funcionará en esta instancia. :( Sin embargo, todavía podría meterse con las opacidades hasta que tenga algo cerca de lo que desea. Aquí hay un ejemplo de un mapa transparente que muestra un lienzo detrás. Parece como si el cuadro verde estuviera en la parte superior, pero realmente solo muestra a través de: http://jsfiddle.net/un9yW/11/ Por supuesto, hacer este método significa que no hay forma de hacer que una caja verde cubra completamente parte del mapa, y así sucesivamente, lo cual es una especie de cojera Te lo haré saber si pienso en algo más que funcione para tu situación. –

0

no estoy seguro de cómo el procedimiento para ello va pero Simon Sarris realidad proporcionó la solución en los comentarios:

Desafortunadamente, mi otro método voluntad no trabajo en este caso. :(Sin embargo, todavía podría meterse con opacidades hasta usted tiene algo parecido a lo que falta. He aquí un ejemplo de transparencia mapa que muestra un lienzo detrás de él. Es aparece como si la caja verde está en la parte superior pero es realmente sólo muestra a través de: jsfiddle.net/un9yW/11 por supuesto, hacer este método significa que no hay manera de hacer una caja verde para cubrir por completo parte del mapa, y así sucesivamente, que es tipo de cojos te dejaré. usted sabe si yo pienso en cualquier otra cosa que funcione para su situación. - Simon Sarris 7 horas

1

endeudamiento de la respuesta de Simón Sarris, puede ser más sencillo de alguna situaciones para tener los controles canvas & en el mismo plano. Dependiendo del control, no siempre permite que el lienzo dibuje sobre el control, pero esto no parece ser necesario en la pregunta original de Joe. Lo importante es asegurarse de que el lienzo y los controles estén en el mismo plano Z, ambos tienen un estilo con la palabra clave "posición" y tienen el HTML para los controles después de la instrucción lienzo. El siguiente es un ejemplo de un lienzo combinado con controles que utilizan este método.

<canvas id="can" width="500" height="500" style="z-index:2; position: absolute;"></canvas> 
<!-- Put text and a link on the same plane as the canvas --> 
<div style="position: relative; z-index: 2;"> 
    <a href="http://www.google.com/">Click</a> this Google link. 
</div> 
5

Suponiendo que no se puede poner los enlaces de arriba del lienzo ...

Para los nuevos navegadores/decente, sólo tiene que utilizar este CSS:

#canvas { pointer-events:none; } 

Y una solución sucia para IE + navegadores antiguos (que podrían eliminar la dependencia en jQuery):

jQuery('#canvas').click(function(e) { 
    window.location = jQuery('#element-under-canvas').attr('href'); 
}); 

Obviamente, esto sólo es compatible con los anclajes tal y como está , y necesitas saber el elemento específico debajo del lienzo (o puedes encontrarlo usando la magia del selector jQuery).

0

Así es como he resuelto este problema ...

que tienen un dispositivo de interfaz de usuario y vuelta (dibujado en un lienzo HTML5 llano, que es un cuadrado). Solo el círculo está coloreado, el resto del lienzo es transparente y quiero hacer clic en él. Debajo de las esquinas del lienzo cuadrado, hay formas en un escenario Kinetic JS.

Normalmente no puede hacer clic a través de un lienzo.

Pero se puede enviar el evento de clic a través de una forma cinética, y activar los detectores de eventos dentro de esa forma como esto:

$('#myCanvasUserInterfaceLayer').on('click', function(e) { 

     var pos = getMousePos(e); 
     var obscuredKineticShape = kineticLayer.getIntersection(pos); 

    // (Note: console.log(obscuredKineticShape) and you find that 
    // 'getIntersection' returns an object with the topmost shape 
    // at the click point on the kinetic stage within it, called 'shape'). 

     obscuredKineticShape.shape.fire('mousedown'); 

    }); 

    function getMousePos(e) { 

     return { 
      x: e.pageX, 
      y: e.pageY 
     }; 
     } 
0

Creo que es mejor cambiar dinámicamente z-index. Si necesita usar controles, establezca su índice z más alto que el lienzo. Si necesita usar lienzo: configure su índice Z más alto que los controles. La forma exacta de hacerlo depende de su situación. Puede escuchar eventos mousedown/mouseup, o mousemove en algunas áreas.

2

que fue capaz de lograr esto mediante el establecimiento de la lona de la siguiente manera:

<div> 
    <a href='#'>my link</a> 
    <canvas></canvas> 
</div> 

Entonces me la pusieron al siguiente en CSS:

canvas { 
    display: block; 
    width: 100%; 
    height: 100%; 
    top: 0; 
    left: 0; 
    position: absolute; 
    z-index:-1; /* NOT SURE HOW SUPPORTED THIS IS, IT WORKED IN CHROME */ 
} 

el enlace dentro del div se puede hacer clic, sin tener en cuenta de cualquier cosa que pinté en el lienzo en tiempo de ejecución.

Espero que esto ayude!

Cuestiones relacionadas