tag style div bootstrap attribute html5 canvas mouse

html5 - style - Consigue clics a través de lienzo html



title tag html (8)

Así es como resolví este problema ...

Tengo un dispositivo de interfaz de usuario redondo (dibujado en un lienzo HTML5 simple, 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 de Kinetic JS.

Normalmente no se puede hacer clic en un lienzo.

Pero puede enviar el evento de clic a una forma cinética y activar a los oyentes de eventos dentro de esa forma de la siguiente manera:

$( ''#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 }; }

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

Aquí hay un ejemplo: con la imagen: http://www.1luckypixel.com/paranormal/canvas_test.html el enlace va a Google pero no se está registrando.

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


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

¡Pero la segunda respuesta más breve es que puedes hacer cualquier cosa 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 elemento detrás del lienzo, cree un elemento secreto similar frente al lienzo. Luego coloca el evento que quieras en el ítem 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 quieres ver ese código en acción haz click aquí.

Hay formas un poco más insanas pero más fáciles de mantener si tiene cien cosas detrás del lienzo en las que desea hacer clic, pero esta es probablemente la más fácil de hacer si solo tiene 1-3 cosas que quiere hacer clic detrás de un lona.


Creo que es mejor cambiar el índice z dinámicamente. Si necesita usar controles, establezca su índice z más alto que el lienzo. Si necesitas usar lienzo, establece que el índice z sea más alto que los controles. La forma exacta de cómo hacerlo depende de su situación. Puede escuchar los eventos de mouse / mouseup, o mousemove en algunas áreas.


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

Desafortunadamente mi otro método no funcionará en este caso. :( Sin embargo, aún podría meterse con las opacidades hasta que tenga algo parecido a lo que desea. Aquí hay un ejemplo de mapa transparente que muestra un lienzo detrás. Parece como si el cuadro verde estuviera en la parte superior, pero en realidad solo se muestra a través de: jsfiddle.net/un9yW/11 Por supuesto, hacer este método significa que no hay forma de hacer un cuadro verde para cubrir completamente una parte del mapa, y así sucesivamente, que es un poco escaso. Le haré saber si pienso de cualquier otra cosa que funcione para su situación. - Simon Sarris hace 7 horas


Pude lograr esto configurando el lienzo de esta manera:

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

Luego lo puse a lo 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 */ }

Se pudo hacer clic en el enlace dentro del div, independientemente de cualquier cosa que haya pintado en el lienzo en tiempo de ejecución.

¡Espero que esto ayude!


Si la funcionalidad de navegador cruzado no es un requisito, entonces hay una solución fácil. En los navegadores que lo admiten para elementos que no son SVG (webkit, Mozilla y quizás otros, pero en particular no para IE), puede utilizar la propiedad css denominada eventos de puntero . Desde el MDN:

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

Además de indicar que el elemento no es el objetivo de los eventos del mouse, el valor none indica al evento del mouse que pase "a través" del elemento y que el destino sea el 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 de la interfaz de usuario de CSS3, hay una discusión para posponerlo a CSS4. "

Como mínimo, puede usar Modernizr para detectar el soporte de eventos de puntero y hacer el truco de opacidad mencionado en la respuesta de Simon Sarris en los navegadores que no lo admiten.

Además, si su aplicación es específica de google maps, puede insertar su lienzo como una superposición de google maps, evitando así el problema.

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


Suponiendo que no puedas poner los enlaces sobre el lienzo ...

Para navegadores nuevos / decentes, simplemente use este CSS:

#canvas { pointer-events:none; }

Y una solución sucia para los navegadores IE + más antiguos (podría eliminar la dependencia de jQuery):

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

Obviamente, esto solo es compatible con los anclajes en su forma actual, y necesitas conocer el elemento específico debajo del lienzo (o puedes encontrarlo usando jQuery selector magic).


Tomando prestado de la respuesta de Simon Sarris, puede ser más simple en algunas situaciones tener el lienzo y los controles en el mismo plano. Dependiendo del control, no siempre permite que el lienzo se dibuje encima del 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 tengan un estilo con la palabra clave "posición" y que el HTML para los controles esté después de la declaración del 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>