obtenez des clics à travers la toile html

je vois beaucoup de questions sur la façon d'obtenir l'élément canvas html5 pour recevoir des clics de souris, j'utilise la toile comme superposition et les clics de souris ne passent pas par les éléments ci-dessous. Je suis de chargement d'une image dans la toile, et j'ai pensé que peut-être le problème, mais j'ai aussi essayé avec une toile vierge et j'obtiens le même résultat.

Voici un exemple: avec l'image: http://www.1luckypixel.com/paranormal/canvas_test.html le lien est pour google, mais ce n'est pas de l'inscription.

je crois comprendre que la toile est transparente à la souris par défaut?

17
demandé sur JoeM05 2010-09-01 10:32:55

8 réponses

si la fonctionnalité de cross browser n'est pas une exigence, alors il y a une solution facile. Sur les navigateurs qui le supportent pour des éléments non SVG(webkit, Mozilla et peut-être d'autres, mais pas IE notamment), vous pouvez utiliser la propriété css appelée pointeur-événements. De la SOCIÉTÉ:

" le pointeur de propriété CSS-events permet aux auteurs de contrôler dans quelles circonstances (s'il y en a) un élément graphique particulier peut devenir la cible des événements de la souris. Lorsque cette propriété est indéterminée, la les mêmes caractéristiques de la valeur visiblepaint s'appliquent au contenu SVG.

en plus d'indiquer que l'élément n'est pas la cible des événements de la souris, la valeur none indique à l'événement de la souris d'aller "à travers" l'élément et de cibler ce qui est "sous" cet élément à la place.

avertissement: L'utilisation d'événements pointeurs dans CSS pour les éléments non SVG est expérimentale. Actuellement défini dans le projet de spécification de L'IU CSS3, il est question de le reporter. à CSS4."

a tout le moins, vous pouvez utiliser Modernizr pour détecter le support pointer-events et faire le truc d'opacité mentionné dans réponse de Simon Sarris sur les navigateurs qui ne le supportent pas.

en outre, si votre application est spécifique à google maps, vous pouvez insérer votre toile comme une superposition de Google maps, évitant ainsi le problème tous ensemble.

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

9
répondu Bojin Li 2018-09-05 16:53:41

en supposant que vous ne pouvez pas placer les liens au-dessus de la toile...

pour les nouveaux navigateurs, utilisez simplement ce CSS:

#canvas { pointer-events:none; }

Et un sale solution de contournement pour IE + les navigateurs plus anciens (vous pouvez supprimer la dépendance sur jQuery):

jQuery('#canvas').click(function(e) {
    window.location = jQuery('#element-under-canvas').attr('href');
});
5
répondu Dunc 2013-11-19 17:25:27

la réponse courte est que vous ne pouvez pas passer le clic.

mais la deuxième réponse la plus courte est que vous pouvez en effet faire tout ce que votre cœur désire! Tu dois juste être prêt à devenir un peu étrange avec la solution.

la première façon dont je peux penser est légèrement exaspérant mais facile: pour chaque élément derrière la toile, faire un similaire secret de l'élément devant la toile. Alors mettez l'événement que vous voulez sur le secret élément:

<!-- 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 vous voulez voir ce code en action cliquez ici

Il y a des moyens un peu plus insensés mais plus maintenables si vous avez une centaine de choses derrière la toile que vous voulez être cliquable, mais c'est probablement le plus facile à faire si vous avez juste 1-3 choses que vous voulez cliquer derrière une toile.

2
répondu Simon Sarris 2010-09-01 19:37:16

j'ai pu accomplir ceci en plaçant la toile comme ceci:

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

Puis je l'ai mis à la suite dans le 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 */
}

le lien à l'intérieur de la div était cliquable, indépendamment de tout ce que j'ai peint sur la toile à l'exécution.

Espérons que cette aide!

2
répondu Steve Woods 2014-11-29 19:40:16

en empruntant la réponse de Simon Sarris, il peut être plus simple dans certaines situations d'avoir la toile et les commandes sur le même plan. Selon la commande, cela ne permet pas toujours à la toile de dessiner au-dessus de la commande, mais cela ne semble pas nécessaire dans la question originale de Joe. La chose importante est de s'assurer que la toile et les contrôles sont sur le même plan Z, les deux ont un style en utilisant le mot-clé "position", et ont le HTML pour les contrôles être après la déclaration de toile. Le voici un exemple d'une toile combinée avec des commandes utilisant cette méthode.

<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>
1
répondu Frank 2013-04-09 21:04:51

Je ne suis pas sûr de la façon dont la procédure pour cela va, mais Simon Sarris réellement fourni la solution dans les commentaires:

Malheureusement, mon autre méthode ne les travaux de cette instance. :( Cependant, vous on peut toujours jouer avec les opacitésjusqu'à vous avez quelque chose de proche de ce que vous vouloir. Voici un exemple de transparence carte montrant une toile derrière elle. Il apparaît comme si la boîte verte est en haut mais c'est vraiment juste montrer à travers: jsfiddle.net/un9yW/11 Bien sûr, faire cette méthode signifie qu'il n'existe aucun moyen de faire une boîte verte pour couvrir complètement partie de la carte, et ainsi de suite, ce qui est type de lame. Je vais vous laisser savoir si je pensez à quelque chose d'autre qui le fera le travail pour votre situation. - Simon Sarris 7 heures

0
répondu JoeM05 2011-12-01 13:43:47

Voici comment j'ai résolu ce problème...

j'ai un périphérique d'interface utilisateur rond (dessiné sur une toile HTML5, qui est un carré). Seul le cercle est coloré, le reste de la toile est transparent, et je veux cliquer à travers elle. Sous les coins de la toile carrée, il y a des formes sur une scène cinétique JS.

Normalement vous ne pouvez pas cliquer sur une toile.

mais vous pouvez envoyer l'événement de clic à travers à une forme cinétique, et activer les écouteurs d'événement à l'intérieur de cette forme comme ceci:

    $( '#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
répondu JSdc 2014-01-24 02:39:31

je pense que c'est mieux de changer le z-index de façon dynamique. Si vous avez besoin d'utiliser les commandes, définissez leur index z plus élevé que canvas. Si vous avez besoin d'utiliser canvas - set c'est Z-index plus élevé que les contrôles. Exact façon de le faire dépend de votre situation. Vous pouvez écouter les événements de mousedown/mouseup, ou de mousemove sur certaines zones.

0
répondu Олег Всильдеревьев 2014-05-24 02:44:22