Pour garder une trace de ce qui est dessiné, de nombreuses applications, telles que les applications de dessin, les systèmes de conception assistée par ordinateur (systèmes de CAO) et les jeux, conservent une liste des objets actuellement affichés. Généralement, ces applications permettent aux utilisateurs de manipuler des objets actuellement affichés à l'écran. Par exemple, dans une application de CAO, nous pouvons sélectionner, déplacer, zoomer, etc. des éléments de la conception
-"Technologie de base du canevas HTML5"
Il en va de même 实现拖拽
dans Canvas. Canvas fournit une API appelée isPointInPath(x, y)
pour déterminer si 点(x, y)
se trouve dans le chemin. Renvoie vrai s'il se trouve dans le chemin. On peut donc avoir les idées suivantes :
Conservez un 数组
qui peut décrire chaque chemin et utilisez ispointInPath(x, y)
pour déterminer si la position cliquée se trouve dans un certain chemin. Si elle se trouve dans ce chemin, sélectionnez ce chemin, effectuez des opérations (déplacement, zoom, etc.). , puis dessinez les graphiques
Dans cet article, j'utilise 多边形拖拽为例进行说明
. La démo est la suivante (la raison derrière l'empreinte est le logiciel d'enregistrement d'écran : japan_ogre :) :
CodePen s'ouvre
Comment dessiner des polygones dans la démo a déjà été résumé, je n'entrerai donc pas dans les détails : ghost:: Canvas polygon draw
Explication des idéesLa figure ci-dessous donne une description approximative et un pseudo-code. L'idée n'est pas difficile, mais certains détails doivent être traités.
La structure du code est répertoriée ici et ses idées sont marquées. Des commentaires de code plus détaillés se trouvent dans CodePen.
Cet article se concentrant sur la traînée, il y aura moins de description de la partie dessin.
//Dessiner la fonction de chemin de polygone, fonction drawPolygonPath//Classe de définition de classe Polygone Polygon{ ...}//Renvoyer la position dans le canevas en fonction de l'événement de clic, fonction positoinInCanvas//Obtenir la distance en ligne droite entre deux points, fonction getDistance// Au début, enregistrez le glisser. Faites glisser l'objet canvas.onmousedown//Phase de déplacement, tracez le chemin, tracez canvas.onmousemove//Phase de fin, mettez à jour la position de l'objet de déplacement canvas.onmouseupDescription des éléments clés
Ensuite, commencez à traiter les éléments clés et les détails du code
Comment conserver un tableau d'objets glisserLors de l'initialisation du programme, nous définissons un tableau polygonArray
polygonArray = []
Chaque fois qu'un nouveau polygone est dessiné, un nouvel objet polygone sera inséré dans le tableau pour maintenance.
const polygon = new Polygon(mouseStart.get('x'), mouseStart.get('y'), sideNum, radius);polygonArray.push(polygon);//Objet de chemin d'enregistrement
Lors des opérations de clic ultérieures, il est nécessaire de déterminer si la position du clic se trouve dans le chemin en fonction des informations correspondantes.
Comment sélectionner l'objet à faire glisser en cliquant Tout d'abord, obtenez la position correspondante canvas中
lorsque vous cliquez dessus. Mon code utilise mouseStart
pour enregistrer x
et y
Parcourez ensuite polygon
dans polygonArray
, appelez polygon.createPath()
pendant le parcours et utilisez isPointInPath()
pour déterminer s'il existe un chemin à la position cliquée. Si tel est le cas, draggingPolygon = polygon
termine la fonction.
const pos = positionInCanvas(e, canvasLeft, canvasTop);//Obtenir la position du pixel dans canvas//Enregistrer le point de départ de la souris smouseStart.set('x', pos.x);mouseStart.set('y', pos. y);...for (laisser le polygone de polygonArray) { polygon.createPath(); (ctx.isPointInPath(mouseStart.get('x'), mouseStart.get('y'))) { draggingPolygon = polygone } }Calcul en glissant
Cette partie doit être parfaitement comprise. Il est recommandé de déboguer en fonction des deux console.log(draggingPolygon)
et du code dans la démo, car nous sommes dans la phase mousemove
et les fonctions sont déclenchées très fréquemment à ce stade.
J'essaie de l'exprimer clairement avec des mots
Tout d'abord, calculez la distance depuis mouseStart
lors move
, qui est enregistrée comme diff. Il y a offsetX
sur l'axe des x et offsetY
sur l'axe des y.
const pos = positionInCanvas(e, canvasLeft, canvasTop), diff = new Map([ ['offsetX', pos.x - mouseStart.get('x')], ['offsetY', pos.y - mouseStart.get( 'y')] ]);
Enregistrez ensuite centerX
et centerY
de l'objet de glissement actuel, enregistrés en tant que temp
laissez tempCenterX = draggingPolygon.centerX, tempCenterY = draggingPolygon.centerY;
C’est le point difficile à comprendre. Pourquoi devrions-nous l’enregistrer ? Continuez à lire, vous l'utiliserez plus tard.
Définir la nouvelle position centrale de draggingPolygon en fonction du décalage dans diff
draggingPolygon.centerX += diff.get('offsetX'); draggingPolygon.centerY += diff.get('offsetY');
Ensuite, effacez la toile et dessinez de nouveaux chemins et traits
ctx.clearRect(0, 0, canvas.width, canvas.height);for (laisser le polygone de polygonArray) { drawPolygonPath(polygon.sideNum, polygon.radius, polygon.centerX, polygon.centerY, ctx.stroke(); );}
Enfin, tempCenterX
et tempCenterY
mentionnés ci-dessus sont utilisés :
draggingPolygon.centerX = tempCenterX; draggingPolygon.centerY = tempCenterY;
Pourquoi devons-nous faire cela ?
Parce que notre glissement est 基于多边形的原位置
et que mousemove
不能确定函数的最终位置
. S'il n'y a pas de récupération à ce moment-là, 漂移
se produira. l'effet est le suivant :
Si je n'ai pas été clair, je recommande à tout le monde de modifier et de déboguer le code.
Traitement après glisser Une fois le glissement terminé, nous sommes à l'étape mouseup
. À ce stade, nous avons déterminé la position finale de dragginPolygon, il suffit de le mettre à jour et enfin de le définir sur null pour exclure 在没有拖拽多边形情况下,鼠标在画布上移动触发对应代码
const pos = positionInCanvas(e, canvasLeft, canvasTop), offsetMap = new Map([ ['offsetX', pos.x - mouseStart.get('x')], ['offsetY', pos.y - mouseStart.get( 'y')] ]); draggingPolygon.centerX += offsetMap.get('offsetX'); offsetMap.get('offsetY'); draggingPolygon = null;Conclusion
En fait, il n'est pas difficile de mettre en œuvre cette fonction. La clé est de comprendre un concept : le suivi est obtenu en maintenant une liste des objets actuellement affichés et en faisant des jugements avec isPointInPath.
Enfin, bienvenue à tous pour échanger et apprendre
Références"Technologie de base du canevas HTML5"
Ce qui précède représente l’intégralité du contenu de cet article. J’espère qu’il sera utile à l’étude de chacun. J’espère également que tout le monde soutiendra le réseau VeVb Wulin.