Wie füge ich einem Canvas-Element einen einfachen onClick-Ereignishandler hinzu?

Lesezeit: 9 Minuten

Wie fuge ich einem Canvas Element einen einfachen onClick Ereignishandler hinzu
Jer

Ich bin ein erfahrener Java-Programmierer, schaue mir aber zum ersten Mal seit etwa einem Jahrzehnt etwas mit JavaScript/HTML5 an. Ich bin völlig ratlos, was das Einfachste überhaupt sein sollte.

Als Beispiel wollte ich nur etwas zeichnen und einen Ereignishandler hinzufügen. Ich bin mir sicher, dass ich etwas Dummes mache, aber ich habe überall gesucht und nichts, was vorgeschlagen wird (z. B. die Antwort auf diese Frage: Onclick-Eigenschaft zur Eingabe mit JavaScript hinzufügen), funktioniert. Ich verwende Firefox 10.0.1. Mein Code folgt. Sie sehen mehrere kommentierte Zeilen und am Ende jeder Zeile steht eine Beschreibung dessen, was passiert (oder was nicht).

Wie ist hier die korrekte Syntax? Ich werde verrückt!

<html>
<body>
    <canvas id="myCanvas" width="300" height="150"/>
    <script language="JavaScript">
        var elem = document.getElementById('myCanvas');
        // elem.onClick = alert("hello world");  - displays alert without clicking
        // elem.onClick = alert('hello world');  - displays alert without clicking
        // elem.onClick = "alert('hello world!')";  - does nothing, even with clicking
        // elem.onClick = function() { alert('hello world!'); };  - does nothing
        // elem.onClick = function() { alert("hello world!"); };  - does nothing
        var context = elem.getContext('2d');
        context.fillStyle="#05EFFF";
        context.fillRect(0, 0, 150, 100);
    </script>

</body>

  • Verwenden onclick anstatt onClick

    – Anfänger

    26. März 2012 um 22:11 Uhr

  • Um näher darauf einzugehen, warum diese Versuche nicht funktionierten … Die ersten paar Kommentare zeigen sofort eine Warnung an, weil Sie anrufen alert() direkt hinein <script>anstatt eine aufrufende Funktion zu definieren alert(). Der Rest tut nichts wegen der Großschreibung von onclick.

    – LarsH

    15. Februar 2016 um 14:42 Uhr


  • Sie können diese Bibliothek verwenden jsfiddle.net/user/zlatnaspirala/fiddles sieht an bitbucket.org/nikola_l/visual-js . Sie erhalten viele Funktionen +

    – Nikola Lukic

    20. Dezember 2016 um 13:32 Uhr

Wie fuge ich einem Canvas Element einen einfachen onClick Ereignishandler hinzu
Alex

Wenn Sie zu a ziehen canvas -Element zeichnen Sie einfach eine Bitmap hinein Sofortmodus.

Die Elemente (Formen, Linien, Bilder), die gezeichnet werden, haben außer den Pixeln, die sie verwenden, und ihrer Farbe keine Repräsentation.

Um also eine zu bekommen klicken Veranstaltung an einem canvas Element (Form), müssen Sie Klickereignisse auf erfassen canvas HTML-Element und verwenden Sie etwas Mathematik, um zu bestimmen, auf welches Element geklickt wurde, vorausgesetzt, Sie speichern die Breite/Höhe und den x/y-Versatz der Elemente.

Hinzufügen eines click Veranstaltung zu Ihrer canvas Element, verwenden …

canvas.addEventListener('click', function() { }, false);

Um festzustellen welche Element wurde angeklickt…

var elem = document.getElementById('myCanvas'),
    elemLeft = elem.offsetLeft + elem.clientLeft,
    elemTop = elem.offsetTop + elem.clientTop,
    context = elem.getContext('2d'),
    elements = [];

// Add event listener for `click` events.
elem.addEventListener('click', function(event) {
    var x = event.pageX - elemLeft,
        y = event.pageY - elemTop;

    // Collision detection between clicked offset and element.
    elements.forEach(function(element) {
        if (y > element.top && y < element.top + element.height 
            && x > element.left && x < element.left + element.width) {
            alert('clicked an element');
        }
    });

}, false);

// Add element.
elements.push({
    colour: '#05EFFF',
    width: 150,
    height: 100,
    top: 20,
    left: 15
});

// Render elements.
elements.forEach(function(element) {
    context.fillStyle = element.colour;
    context.fillRect(element.left, element.top, element.width, element.height);
});​

jsFiddle.

Dieser Code hängt a click Veranstaltung zum canvas -Element und schiebt dann eine Form (als element in meinem Code) zu einem elements Reihe. Sie können hier beliebig viele hinzufügen.

Der Zweck der Erstellung eines Arrays von Objekten besteht darin, dass wir ihre Eigenschaften später abfragen können. Nachdem alle Elemente auf das Array geschoben wurden, durchlaufen wir sie und rendern sie basierend auf ihren Eigenschaften.

Wenn das click -Ereignis ausgelöst wird, durchläuft der Code die Elemente in einer Schleife und bestimmt, ob der Klick über einem der Elemente in der war elements Reihe. Wenn ja, feuert es eine alert()die leicht geändert werden könnte, um beispielsweise das Array-Element zu entfernen. In diesem Fall benötigen Sie ein separates machen Funktion zum Aktualisieren der canvas.


Der Vollständigkeit halber, warum Ihre Versuche nicht funktioniert haben …

elem.onClick = alert("hello world"); // displays alert without clicking

Dies weist den Rückgabewert von zu alert() zum onClick Eigentum von elem. Es ruft sofort die auf alert().

elem.onClick = alert('hello world');  // displays alert without clicking

In JavaScript ist die ' und " semantisch identisch sind, verwendet der Lexer wahrscheinlich ['"] für Zitate.

elem.onClick = "alert('hello world!')"; // does nothing, even with clicking

Sie weisen dem eine Zeichenfolge zu onClick Eigentum von elem.

elem.onClick = function() { alert('hello world!'); }; // does nothing

Bei JavaScript wird zwischen Groß- und Kleinschreibung unterschieden. Die onclick Eigenschaft ist die archaische Methode zum Anhängen von Event-Handlern. Es kann nur ein Ereignis an die Eigenschaft angehängt werden, und das Ereignis kann beim Serialisieren des HTML-Codes verloren gehen.

elem.onClick = function() { alert("hello world!"); }; // does nothing

Aufs Neue, ' === ".

  • Hmm … verzeihen Sie mir, wenn ich das falsch verstehe – aber erfasse ich nicht Klickereignisse auf dem Canvas-Element? Ich bin mir nicht sicher, was du meinst was Element wurde angeklickt. Es gibt nur ein Element auf dieser Seite, richtig?

    – Jer

    26. März 2012 um 21:48 Uhr

  • Er meinte “welches Element innerhalb der Leinwand” – also sozusagen welche “Form”.

    – Jovan Perović

    26. März 2012 um 21:53 Uhr

  • Vielen Dank – obwohl mir das letzte nicht ganz klar ist. Ich folge dem Beispiel hier: developer.mozilla.org/en/DOM/element.onclick (unter Verwendung der anonymen Funktion, die sie beschreiben) und es funktioniert, selbst wenn ich die Spanne in eine Leinwand ändere. Es wird mir also nicht schwer fallen, ihr Beispiel langsam in meins umzuwandeln, um zu sehen, was ich falsch mache. Vielen Dank für die ausführliche Antwort! Besonders hilfreich war die Erklärung, warum meine diversen Versuche falsch waren.

    – Jer

    26. März 2012 um 22:11 Uhr

  • @Jer Keine Sorge, wenn Sie weitere Fragen haben, können Sie mich gerne auf Twitter posten und anpingen. @alexdickson.

    – Alex

    26. März 2012 um 22:14 Uhr

  • @HashRocketSyntax Es sollte gut funktionieren, aktualisieren Sie einfach die Positionen Ihrer Objekte im Speicher und verwenden Sie diese Definitionen zum Rendern

    – Alex

    9. April 2018 um 14:02 Uhr

1646241730 589 Wie fuge ich einem Canvas Element einen einfachen onClick Ereignishandler hinzu
Le____

2021:

Um ein trackbares Element im HTML5-Canvas zu erstellen, sollten Sie die verwenden neuer Pfad2D() Methode.

Hören Sie zuerst auf Mausereignisse (onclick oder ondblclick oder oncontextmenu oder onmousemove oder etc.) auf Ihrer Leinwand, um die Punktkoordinaten (Mauskoordinaten) zu erhalten event.offsetX und event.offsetY dann benutze CanvasRenderingContext2D.isPointInPath() oder CanvasRenderingContext2D.isPointInStroke() um genau zu überprüfen, ob die Maus in diesem Fall über Ihrem Element schwebt.

IsPointInPath:

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

// Create circle
const circle = new Path2D();
circle.arc(150, 75, 50, 0, 2 * Math.PI);
ctx.fillStyle="red";
ctx.fill(circle);

// Listen for mouse moves
canvas.addEventListener('mousemove', function(event) {
  // Check whether point is inside circle
  if (ctx.isPointInPath(circle, event.offsetX, event.offsetY)) {
    ctx.fillStyle="green";
  }
  else {
    ctx.fillStyle="red";
  }

  // Draw circle
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.fill(circle);
});
<canvas id="canvas"></canvas>

IsPointInStroke:

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

// Create ellipse
const ellipse = new Path2D();
ellipse.ellipse(150, 75, 40, 60, Math.PI * .25, 0, 2 * Math.PI);
ctx.lineWidth = 25;
ctx.strokeStyle="red";
ctx.fill(ellipse);
ctx.stroke(ellipse);

// Listen for mouse moves
canvas.addEventListener('mousemove', function(event) {
  // Check whether point is inside ellipse's stroke
  if (ctx.isPointInStroke(ellipse, event.offsetX, event.offsetY)) {
    ctx.strokeStyle="green";
  }
  else {
    ctx.strokeStyle="red";
  }

  // Draw ellipse
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.fill(ellipse);
  ctx.stroke(ellipse);
});
<canvas id="canvas"></canvas>

Beispiel mit mehreren Elementen:

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

const circle = new Path2D();
circle.arc(50, 75, 50, 0, 2 * Math.PI);
ctx.fillStyle="red";
ctx.fill(circle);

const circletwo = new Path2D();
circletwo.arc(200, 75, 50, 0, 2 * Math.PI);
ctx.fillStyle="red";
ctx.fill(circletwo);

// Listen for mouse moves
canvas.addEventListener('mousemove', function(event) {
  // Check whether point is inside circle
  if (ctx.isPointInPath(circle, event.offsetX, event.offsetY)) {
    ctx.fillStyle="green";
    ctx.fill(circle);
  }
  else {
    ctx.fillStyle="red";
    ctx.fill(circle);
  }
  
    if (ctx.isPointInPath(circletwo, event.offsetX, event.offsetY)) {
    ctx.fillStyle="blue";
    ctx.fill(circletwo);
  }
  else {
    ctx.fillStyle="red";
    ctx.fill(circletwo);
  }
  
});
html {cursor: crosshair;}
<canvas id="canvas"></canvas>

Wenn Sie eine Liste mit dynamischen Elementen haben, die überprüft werden sollen, können Sie sie wie folgt in einer Schleife überprüfen:

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
var elementslist = []

const circle = new Path2D();
circle.arc(50, 75, 30, 0, 2 * Math.PI);
ctx.fillStyle="red";
ctx.fill(circle);

const circletwo = new Path2D();
circletwo.arc(150, 75, 30, 0, 2 * Math.PI);
ctx.fillStyle="red";
ctx.fill(circletwo);

const circlethree = new Path2D();
circlethree.arc(250, 75, 30, 0, 2 * Math.PI);
ctx.fillStyle="red";
ctx.fill(circlethree);

elementslist.push(circle,circletwo,circlethree)

document.getElementById("canvas").addEventListener('mousemove', function(event) {
event = event || window.event;
var ctx = document.getElementById("canvas").getContext("2d")

for (var i = elementslist.length - 1; i >= 0; i--){  

if (elementslist[i] && ctx.isPointInPath(elementslist[i], event.offsetX, event.offsetY)) {
document.getElementById("canvas").style.cursor="pointer";
    ctx.fillStyle="orange";
    ctx.fill(elementslist[i]);
return
} else {
document.getElementById("canvas").style.cursor="default";
    ctx.fillStyle="red";
    for (var d = elementslist.length - 1; d >= 0; d--){ 
    ctx.fill(elementslist[d]);
    }
}
}  

});
<canvas id="canvas"></canvas>

Quellen:

Wie fuge ich einem Canvas Element einen einfachen onClick Ereignishandler hinzu
Soham Dasgupta

Wahrscheinlich sehr spät zur Antwort, aber ich habe dies gerade gelesen, während ich mich auf meine vorbereitete 70-480 Prüfung, und festgestellt, dass dies funktioniert –

var elem = document.getElementById('myCanvas');
elem.onclick = function() { alert("hello world"); }

Beachten Sie das Ereignis als onclick anstatt onClick.

JS Bin Beispiel.

  • Das OP möchte hinzufügen onclick auf ein Element innerhalb der Leinwand, aber nicht auf die Leinwand selbst

    – Systemneustarter

    14. Januar 2021 um 19:02 Uhr


1646241730 628 Wie fuge ich einem Canvas Element einen einfachen onClick Ereignishandler hinzu
Goswin Rothenthal

Alternativ zur Antwort von Alex:

Sie könnten eine SVG-Zeichnung anstelle einer Canvas-Zeichnung verwenden. Dort können Sie Ereignisse direkt zu den gezeichneten DOM-Objekten hinzufügen.

siehe zum beispiel:

Ein SVG-Bildobjekt mit Onclick anklickbar machen, wobei eine absolute Positionierung vermieden wird

Ich empfehle folgenden Artikel: Trefferbereichserkennung für HTML5-Canvas und Anhören von Klickereignissen auf Canvas-Formen die verschiedene Situationen durchläuft.

Es deckt jedoch nicht die addHitRegion API, das muss der beste Weg sein (die Verwendung mathematischer Funktionen und/oder Vergleiche ist ziemlich fehleranfällig). Dieser Ansatz ist detailliert auf developer.mozilla

  • “[addHitRegion] ist obsolet. Obwohl es in einigen Browsern möglicherweise noch funktioniert, wird von seiner Verwendung abgeraten, da es jederzeit entfernt werden kann. Versuchen Sie, die Verwendung zu vermeiden.” – über den von Ihnen eingefügten dev.moz-Link, um anderen einen Klick zu ersparen.

    – Chris

    20. März 2020 um 17:21 Uhr

1646241731 106 Wie fuge ich einem Canvas Element einen einfachen onClick Ereignishandler hinzu
Sergej Bascharow

Sie können auch DOM-Elemente einfügen, wie z div auf der Leinwand, die Ihre Leinwandelemente darstellen und auf die gleiche Weise positioniert werden.

Jetzt können Sie Ereignis-Listener an diese Divs anhängen und die erforderlichen Aktionen ausführen.

  • “[addHitRegion] ist obsolet. Obwohl es in einigen Browsern möglicherweise noch funktioniert, wird von seiner Verwendung abgeraten, da es jederzeit entfernt werden kann. Versuchen Sie, die Verwendung zu vermeiden.” – über den von Ihnen eingefügten dev.moz-Link, um anderen einen Klick zu ersparen.

    – Chris

    20. März 2020 um 17:21 Uhr

1646241731 632 Wie fuge ich einem Canvas Element einen einfachen onClick Ereignishandler hinzu
TadLewis

Als weitere billige Alternative auf einer etwas statischen Leinwand ist die Verwendung eines überlagernden img-Elements mit einer Usemap-Definition schnell und schmutzig. Funktioniert besonders gut auf polygonbasierten Canvas-Elementen wie einem Tortendiagramm.

914380cookie-checkWie füge ich einem Canvas-Element einen einfachen onClick-Ereignishandler hinzu?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy