DOM ist ein sehr wichtiger Teil des Web-Frontend-Bereichs und wird nicht nur bei der Verarbeitung von HTML-Elementen, sondern auch in der grafischen Programmierung verwendet. Beispielsweise werden beim SVG-Zeichnen verschiedene Grafiken in Form von DOM-Knoten in die Seite eingefügt, was bedeutet, dass Grafiken mithilfe von DOM-Methoden manipuliert werden können. Wenn beispielsweise ein -Element vorhanden ist, können Sie direkt mit jquery ein Klickereignis $('#p1').click(function(){…})" hinzufügen. Diese DOM-Verarbeitungsmethode ist für HTML5 nicht mehr anwendbar. Canvas verwendet einen anderen Satz von Mechanismen, egal wie viele Grafiken auf Canvas gezeichnet werden. Die Grafiken selbst sind tatsächlich Teil von Canvas Separat erhältlich, daher kann es nicht direkt an jemanden weitergegeben werden. JavaScript-Ereignisse zu Grafiken hinzugefügt
.
Einschränkungen von Canvas
In Canvas werden alle Grafiken auf dem Rahmen gezeichnet. Die Zeichenmethode gibt die gezeichneten Grafikelemente nicht als Rückgabewert aus und js kann die gezeichneten Grafikelemente nicht abrufen. Zum Beispiel:
cvs = document.getElementById( 'mycanvas' );
ctx = canvas.getContext('2d');
theRect = ctx.rect(10, 10, 100, 100);
ctx.Stroke();
Konsole .log( theRect); //undefiniert
Dieser Code zeichnet ein Rechteck im Canvas-Tag. Zunächst können Sie sehen, dass die Methode rect zum Zeichnen von Grafiken keinen Rückgabewert hat. Wenn Sie die Entwicklertools des Browsers öffnen, können Sie auch sehen, dass innerhalb des Canvas-Tags kein Inhalt hinzugefügt wurde und das Canvas-Element und der in js erhaltene aktuelle Kontext keinen Inhalt haben, der auf die neuen Grafiken hinweist.
Daher sind die üblicherweise im Frontend verwendeten DOM-Methoden im Canvas nicht anwendbar. Wenn Sie beispielsweise auf das Rechteck im Canvas oben klicken, klicken Sie tatsächlich auf das gesamte Canvas-Element.
Ereignisse an das Canvas-Element binden
Da das Ereignis nur die Ebene des Canvas-Elements erreichen kann, müssen Sie Code zur Verarbeitung hinzufügen, wenn Sie weiter gehen und ermitteln möchten, auf welche Grafik im Canvas der Klick erfolgt ist. Die Grundidee besteht darin, ein Ereignis an das Canvas-Element zu binden. Wenn das Ereignis auftritt, überprüfen Sie die Position des Ereignisobjekts und prüfen Sie dann, welche Grafiken diese Position abdecken. Im obigen Beispiel wurde beispielsweise ein Rechteck gezeichnet, das den Bereich von 10-110 auf der x-Achse und 10-110 auf der y-Achse abdeckt. Solange die Maus innerhalb dieses Bereichs klickt, kann dies als Klicken auf das Rechteck betrachtet werden und das vom Rechteck zu verarbeitende Klickereignis kann manuell ausgelöst werden. Die Idee ist eigentlich relativ einfach, die Umsetzung ist allerdings noch etwas kompliziert. Es muss nicht nur die Effizienz dieses Beurteilungsprozesses berücksichtigt werden, sondern auch die Ereignistypen müssen an einigen Stellen neu beurteilt werden und der Erfassungs- und Bubbling-Mechanismus in Canvas muss neu definiert werden.
Als Erstes müssen Sie ein Ereignis an das Canvas-Element binden. Wenn Sie beispielsweise ein Klickereignis an eine Grafik innerhalb des Canvas binden möchten, müssen Sie das Ereignis über das Canvas-Element weiterleiten:
cvs = document.getElementById( 'mycanvas' );
cvs.addEventListener('click', function(e){
//...
}, false);
Als nächstes müssen Sie den Ort bestimmen, an dem das Ereignisobjekt auftritt. Die Attribute „layerX“ und „layerY“ des Ereignisobjekts repräsentieren die Koordinaten im internen Koordinatensystem von Canvas. Allerdings unterstützt Opera dieses Attribut nicht und Safari plant, es zu entfernen, daher müssen wir einige kompatible Schreibmethoden erstellen:
Funktion 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};
}
//Hinweis: Um die obige Funktion verwenden zu können, müssen Sie die Position des Canvas-Elements auf absolut setzen.
Da wir nun die Koordinatenposition des Ereignisobjekts haben, müssen wir bestimmen, welche Grafiken im Canvas diese Koordinate abdecken.
isPointInPath-Methode
Die isPointInPath-Methode von Canvas kann bestimmen, ob die aktuelle Kontextgrafik eine bestimmte Koordinate abdeckt, wie zum Beispiel:
cvs = document.getElementById( 'mycanvas' );
ctx = canvas.getContext('2d');
ctx.rect(10, 10, 100, 100);
ctx.Stroke();
ctx.isPointInPath (50, 50); //true
ctx.isPointInPath(5, 5); //false
Fügen Sie als Nächstes eine Ereignisbeurteilung hinzu, um zu bestimmen, ob ein Klickereignis auf dem Rechteck auftritt:
cvs.addEventListener('click ', function (e){
p = getEventPosition(e);
if(ctx.isPointInPath(p.x, p.y)){
//Auf das Rechteck geklickt
}
}, false );
Das Obige ist die grundlegende Methode zur Behandlung von Canvas-Ereignissen, der obige Code weist jedoch Einschränkungen auf, da die isPointInPath-Methode nur den Pfad im aktuellen Kontext bestimmt, wenn mehrere Grafiken in gezeichnet wurden Nur Leinwand Das Ereignis kann anhand des Kontexts der letzten Grafik beurteilt werden, zum Beispiel:
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
Wie Sie dem obigen Code entnehmen können, kann die isPointInPath-Methode nur den Grafikpfad im aktuellen Kontext identifizieren und der zuvor gezeichnete Pfad kann nicht im Nachhinein beurteilt werden. Die Lösung für dieses Problem lautet: Wenn ein Klickereignis auftritt, zeichnen Sie alle Grafiken neu und verwenden Sie für jede gezeichnete Grafik die Methode isPointInPath, um zu bestimmen, ob die Ereigniskoordinaten innerhalb der Abdeckung der Grafiken liegen.
Loop-Neulackierung und Event-Sprudeln
Um ein zyklisches Neuzeichnen zu erreichen, müssen die Grundparameter der Grafiken im Voraus gespeichert werden:
arr = [
{x:10, y:10, width:100, height:100},
{x:110, y: 110, Breite: 100, Höhe: 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();
});
}
Der obige Code speichert die Grundparameter der beiden Rechtecke im Voraus. Bei jedem Aufruf der Zeichenmethode werden diese Grundparameter in einer Schleife aufgerufen, um die beiden Rechtecke zu zeichnen. Die Methode „clearRect“ wird hier auch verwendet, um die Leinwand beim Neuzeichnen zu leeren. Als Nächstes müssen Sie Ereignisdelegierte hinzufügen und beim Neuzeichnen für jeden Kontext die Methode isPointInPath verwenden:
cvs.addEventListener('click ', function (e){
p = getEventPosition(e);
draw(p);
}, false);
Wenn das Ereignis eintritt, übergeben Sie die Koordinaten des Ereignisobjekts, um die Methodenverarbeitung zu zeichnen. Hier müssen einige kleine Änderungen an der Zeichenmethode vorgenommen werden:
Funktion 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)){
// Wenn Ereigniskoordinaten übergeben werden, verwenden Sie isPointInPath, um zu bestimmen
//Wenn die aktuelle Umgebung die Koordinaten abdeckt, geben Sie den Indexwert der aktuellen Umgebung in das Array
who.push(i); }
});
// Entsprechend dem Indexwert im Array kann das entsprechende Element im arr-Array gefunden werden.
zurückgeben, wer;
}
Wenn im obigen Code das Klickereignis auftritt, führt die Zeichenmethode eine Neuzeichnung durch und prüft während des Neuzeichnungsprozesses, ob jede Grafik die Ereigniskoordinaten abdeckt. Wenn die Beurteilung wahr ist, gilt die Grafik als angeklickt , und Fügen Sie den Indexwert der Grafik in das Array ein und verwenden Sie schließlich das Array als Rückgabewert der Zeichenmethode. Wenn bei diesem Verarbeitungsmechanismus N Grafiken im Canvas vorhanden sind, sich ein Teil davon überlappt und das Klickereignis zufällig in diesem überlappenden Bereich auftritt, enthält das Rückgabearray der Zeichenmethode N Mitglieder. Zu diesem Zeitpunkt ist es ein bisschen ähnlich wie bei der Ereignissprudelung. Das letzte Mitglied des Arrays befindet sich oben im Canvas und das erste Mitglied befindet sich unten. Wir können uns vorstellen, dass das oberste Mitglied e.target ist und die anderen Mitglieder sind e.target Der Knoten, an den während des Blasenprozesses übergeben wird. Dies ist natürlich nur die einfachste Verarbeitungsmethode. Wenn Sie die DOM-Verarbeitung wirklich simulieren möchten, müssen Sie eine Eltern-Kind-Beziehung für die Grafiken festlegen.
Das Obige ist die grundlegende Methode zur Verarbeitung von Canvas-Ereignissen. In der tatsächlichen Anwendung muss entsprechend der tatsächlichen Situation geklärt werden, wie Grafikparameter zwischengespeichert werden, wie eine Schleifenneuzeichnung durchgeführt wird und wie mit Ereignisblasen umgegangen wird. Darüber hinaus ist Click ein relativ einfach zu handhabendes Ereignis. Die relativ problematischen Ereignisse sind Mouseover, Mouseout und Mousemove. Denn sobald die Maus das Canvas-Element betritt, tritt das Mousemove-Ereignis immer auf, wenn Sie also Mouseover oder Mouseout separat festlegen möchten Für eine bestimmte Grafik müssen Sie außerdem den Weg der Mausbewegung aufzeichnen und den Ein- und Ausstiegsstatus für die Grafik festlegen. Da die Verarbeitungsschritte komplexer werden, muss den Leistungsaspekten mehr Aufmerksamkeit geschenkt werden.