Maison >interface Web >Tutoriel H5 >Introduction à la gestion des événements des compétences du didacticiel HTML5 Canvas_html5

Introduction à la gestion des événements des compétences du didacticiel HTML5 Canvas_html5

WBOY
WBOYoriginal
2016-05-16 15:46:531303parcourir

DOM est une partie très importante du domaine du front-end Web. Il est utilisé non seulement lors du traitement des éléments HTML, mais également dans la programmation graphique. Par exemple, dans le dessin SVG, divers graphiques sont insérés dans la page sous forme de nœuds DOM, ce qui signifie que les graphiques peuvent être manipulés à l'aide des méthodes DOM. Par exemple, s'il existe un élément , vous pouvez directement utiliser jquery pour ajouter un événement de clic $('#p1').click(function(){…})". Cependant, cette méthode de traitement DOM n'est pas adaptée au HTML5. Elle n'est plus applicable dans Canvas. Canvas utilise un autre ensemble de mécanismes. Quel que soit le nombre de graphiques dessinés sur Canvas, Canvas est un tout. Les graphiques eux-mêmes font en fait partie de Canvas et ne peuvent pas l'être. obtenu séparément, il ne peut donc pas être directement donné à quelqu'un. Ajout d'événements JavaScript aux graphiques

.

Limitations de Canvas

Dans Canvas, tous les graphiques sont dessinés sur le cadre. La méthode de dessin ne générera pas les éléments graphiques dessinés comme valeur de retour, et js ne peut pas obtenir les éléments graphiques dessinés. Par exemple :


Copier le code
Le code est le suivant :

cvs = document.getElementById( 'mycanvas' );
ctx = canvas.getContext('2d');
theRect = ctx.rect(10, 10, 100, 100);
ctx.Stroke();
console .log(theRect); //non défini

Ce code dessine un rectangle dans la balise canvas. Tout d'abord, vous pouvez voir que la méthode rect pour dessiner des graphiques n'a pas de valeur de retour. Si vous ouvrez les outils de développement du navigateur, vous pouvez également voir qu'aucun contenu n'a été ajouté à l'intérieur de la balise canvas, et que l'élément canvas et le contexte actuel obtenu dans js n'ont aucun contenu indiquant les nouveaux graphiques.

Ainsi, les méthodes DOM couramment utilisées sur le front-end ne sont pas applicables dans Canvas. Par exemple, si vous cliquez sur le rectangle dans le Canvas ci-dessus, vous cliquerez en fait sur l'intégralité de l'élément Canvas.

Lier les événements à l'élément Canvas

Étant donné que l'événement ne peut atteindre que le niveau de l'élément Canvas, si vous souhaitez aller plus loin et identifier sur quel graphique à l'intérieur du Canvas le clic a eu lieu, vous devez ajouter du code pour le traitement. L'idée de base est la suivante : lier un événement à l'élément Canvas. Lorsque l'événement se produit, vérifiez la position de l'objet événement, puis vérifiez quels graphiques couvrent cette position. Par exemple, dans l'exemple ci-dessus, un rectangle a été dessiné, qui couvre la plage de 10 à 110 sur l'axe des x et de 10 à 110 sur l'axe des y. Tant que l'on clique sur la souris dans cette plage, cela peut être considéré comme un clic sur le rectangle, et l'événement de clic qui doit être traité par le rectangle peut être déclenché manuellement. L’idée est en fait relativement simple, mais la mise en œuvre reste quand même un peu compliquée. Non seulement l'efficacité de ce processus de jugement doit être prise en compte, mais les types d'événements doivent également être réévalués à certains endroits, et le mécanisme de capture et de bouillonnement à l'intérieur de Canvas doit être redéfini.

La première chose à faire est de lier un événement à l'élément Canvas. Par exemple, si vous souhaitez lier un événement de clic à un graphique à l'intérieur du Canvas, vous devez proxy l'événement via l'élément Canvas :


Copier le code
Le code est le suivant :

cvs = document.getElementById( 'mycanvas' );
cvs.addEventListener('click', function(e){
//...
}, false);

Ensuite, vous devez déterminer l'emplacement où l'objet événement se produit. Les attributs layerX et layerY de l'objet événement e représentent les coordonnées dans le système de coordonnées interne du Canvas. Cependant, Opera ne prend pas en charge cet attribut et Safari prévoit de le supprimer. Nous devons donc créer des méthodes d'écriture compatibles :


Copier le code
Le code est le suivant :

fonction getEventPosition(ev){
var x, y;
if (ev.layerX || ev.layerX == 0) {
x = ev.layerX;
y = ev.layerY;
} else if (ev. offsetX || ev.offsetX == 0) { // Opera
x = ev.offsetX;
y = ev.offsetY;
}
return {x : x, y : y};
}
//Remarque : Pour utiliser la fonction ci-dessus, vous devez définir la position de l'élément Canvas sur absolue.

Maintenant que nous avons la position des coordonnées de l'objet événement, nous devons déterminer quels graphiques dans le canevas couvrent cette coordonnée.

Méthode isPointInPath

La méthode isPointInPath de Canvas peut déterminer si le graphique de contexte actuel couvre une certaine coordonnée, telle que :


Copier le code
Le code est le suivant :

cvs = document.getElementById( 'mycanvas' );
ctx = canvas.getContext('2d');
ctx.rect(10, 10, 100, 100);
ctx.Stroke();
ctx.isPointInPath (50, 50); //vrai
ctx.isPointInPath(5, 5); //faux

Ensuite, ajoutez un jugement d'événement pour déterminer si un événement de clic se produit sur le rectangle :


Copier le code
Le code est le suivant :

cvs.addEventListener('cliquez ', function (e){
p = getEventPosition(e);
if(ctx.isPointInPath(p.x, p.y)){
// J'ai cliqué sur le rectangle
}
}, false );

Ce qui précède est la méthode de base de gestion des événements Canvas, mais le code ci-dessus a des limites puisque la méthode isPointInPath ne détermine le chemin que dans le contexte actuel, lorsque plusieurs graphiques ont été dessinés dans le contexte. Toile, uniquement L'événement peut être jugé en fonction du contexte du dernier graphique, par exemple :

Copier le code
Le code est le suivant :

cvs = document.getElementById('mycanvas');
ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.rect(10, 10, 100, 100);
ctx.stroke();
ctx.isPointInPath(20, 20); //true
ctx.beginPath();
ctx.rect(110, 110, 100 , 100);
ctx.stroke();
ctx.isPointInPath(150, 150); //true
ctx.isPointInPath(20, 20); //false

Comme vous pouvez le voir dans le code ci-dessus, la méthode isPointInPath ne peut identifier le chemin graphique que dans le contexte actuel, et le chemin précédemment tracé ne peut pas être jugé rétrospectivement. La solution à ce problème est la suivante : lorsqu'un événement de clic se produit, redessinez tous les graphiques et utilisez la méthode isPointInPath pour chacun dessiné afin de déterminer si les coordonnées de l'événement se trouvent dans la couverture des graphiques.

Repeinture de boucle et bouillonnement d'événement

Afin de réaliser un redessinage cyclique, les paramètres de base du graphique doivent être enregistrés au préalable :

Copier le code
Le code est le suivant :

arr = [
{x:10, y:10, width:100, height:100},
{x:110, y : 110, largeur : 100, hauteur :100}
];

cvs = document.getElementById('mycanvas');
ctx = canvas.getContext('2d');

draw( );

function draw(){
ctx.clearRech(0, 0, cvs.width, cvs.height);
arr.forEach(function(v){
ctx.beginPath();
ctx.rect(v.x, v.y, v.width, v.height);
ctx.Stroke();
});
}

Le code ci-dessus enregistre à l'avance les paramètres de base des deux rectangles. Chaque fois que la méthode draw est appelée, ces paramètres de base seront appelés en boucle pour dessiner les deux rectangles. La méthode clearRect est également utilisée ici pour effacer le canevas lors du redessin. La prochaine chose à faire est d'ajouter des délégués d'événement et d'utiliser la méthode isPointInPath sur chaque contexte lors du redessin :


Copier le code
Le code est le suivant :

cvs.addEventListener('cliquez ', function (e){
p = getEventPosition(e);
draw(p);
}, false);

Lorsque l'événement se produit, transmettez les coordonnées de l'objet événement pour dessiner le traitement de la méthode. Quelques petits changements doivent être apportés à la méthode de tirage ici :


Copier le code
Le code est le suivant :

fonction draw(p){
var who = [];
ctx.clearRech(0, 0, cvs.width, cvs.height);
arr.forEach(function(v, i){
ctx.beginPath( );
ctx.rect(v.x, v.y, v.width, v.height);
ctx.Stroke();
if(p && ctx.isPointInPath(p.x, p.y)){
// Si les coordonnées de l'événement sont transmises, utilisez isPointInPath pour déterminer
// Si l'environnement actuel couvre les coordonnées, placez la valeur d'index de l'environnement actuel dans le tableau
who.push(i);
}
});
//Selon la valeur de l'index dans le tableau, l'élément correspondant peut être trouvé dans le tableau arr.
renvoyer qui ;
}

Dans le code ci-dessus, lorsque l'événement de clic se produit, la méthode de dessin effectuera un redessin et, pendant le processus de redessin, vérifiera si chaque graphique couvre les coordonnées de l'événement. Si le jugement est vrai, le graphique est considéré comme ayant été cliqué. , et placez la valeur d'index du graphique dans le tableau, et enfin utilisez le tableau comme valeur de retour de la méthode draw. Sous ce mécanisme de traitement, s'il y a N graphiques dans le canevas, dont une partie se chevauche et que l'événement de clic se produit dans cette zone de chevauchement, alors il y aura N membres dans le tableau de retour de la méthode draw. À l'heure actuelle, c'est un peu similaire à la situation de bouillonnement d'événements. Le dernier membre du tableau est en haut du canevas, et le premier membre est en bas. On peut penser que le membre supérieur est e.target. , et les autres membres sont e.target Le nœud transmis pendant le processus de bulle. Bien sûr, il ne s'agit que de la méthode de traitement la plus simple. Si vous souhaitez réellement simuler le traitement DOM, vous devez définir une relation parent-enfant pour les graphiques.

Ce qui précède est la méthode de base de gestion des événements Canvas. Dans l'application réelle, comment mettre en cache les paramètres graphiques, comment effectuer un redessinage de boucle et comment gérer le bouillonnement d'événements doivent tous être traités en fonction de la situation réelle. De plus, click est un événement relativement facile à gérer. Les événements relativement gênants sont mouseover, mouseout et mousemove, car une fois que la souris entre dans l'élément Canvas, l'événement mousemove se produit toujours, donc si vous souhaitez définir mouseover ou mouseout séparément. pour un certain graphique, vous devez également enregistrer l'itinéraire du mouvement de la souris et définir l'état d'entrée et de sortie du graphique. À mesure que les étapes de traitement deviennent plus complexes, une attention accrue doit être accordée aux problèmes de performances.

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn