2010-08-19 3 views
8

Ich habe eine Leinwand mit einigen unregelmäßigen Formzeichnungen darin, und ich hätte gerne ein Feedback, wenn jemand auf einen bestimmten klickt?html5 canvas clicking auf bézier path shape detection

Ich habe überall nach diesem gesucht und habe nur Lösungen für Rechteck gefunden.

Ich denke, es kann mit isPointInPath() zu tun haben, aber ich habe noch eine kurze Erklärung zu finden, wie man es benutzt.

Jede Hilfe willkommen.

Antwort

13

Ich habe ein Tutorial erstellt, das eine zweite unsichtbare Leinwand verwendet, um Objektauswahl/Treffertests durchzuführen. Zeichnen Sie alle Ihre Formen nacheinander auf die zweite Leinwand, bis eine von ihnen ein schwarzes Pixel hat, an dem sich die Maus befindet. Dann hast du dein Objekt gefunden!

Hier ist ein bisschen aus dem Tutorial ich auf der Auswahl von Objekten mit Leinwand geschrieben:

// gctx is ghost context, made from the second canvas 
    // clear(gctx) 

    // ... 

    // run through all the boxes 
    var l = boxes.length; 
    for (var i = l-1; i >= 0; i--) { 
    // draw shape onto ghost context 
    drawshape(gctx, boxes[i], 'black', 'black'); 

    // get image data at the mouse x,y pixel 
    var imageData = gctx.getImageData(mx, my, 1, 1); 
    var index = (mx + my * imageData.width) * 4; 

    // if the mouse pixel exists, select and break 
    if (imageData.data[3] > 0) { 
     mySel = boxes[i]; 
     offsetx = mx - mySel.x; 
     offsety = my - mySel.y; 
     mySel.x = mx - offsetx; 
     mySel.y = my - offsety; 
     isDrag = true; 
     canvas.onmousemove = myMove; 
     invalidate(); 
     clear(gctx); 
     return; 
    } 

    } 

Meine volle Demo verwendet nur Rechtecke, aber in einer späteren Version werde ich Kreise/Pfade/Text verwenden.

Wenn Sie die Demo und meinen vollständigen Code sehen möchten, ist es here.

+0

Dank. Ich habe endlich etwas Ähnliches gemacht, obwohl ich auf der sicheren Leinwand blieb, keine Striche oder Füllungen machte, während ich die Formen neu zeichnete. – Brousselaine

+0

@Simon Sarris Ich habe dein Tutorial verwendet, um dies zu machen: http://edumax.org.ro/extra/new/mindmap/ (benutze Gitter als Karte und rechter Mausklick für das Menü) Ich versuche Pfade auch mit Hilfe von auswählbar zu machen deine Methode. Ich verstehe, dass Sie ein Tutorial zu diesem Thema haben, aber geben Sie uns einen Hinweis auf einige grundlegende Schritte, die Sie befolgen werden? (speziell für den Pfad .contains() Funktion) –

+0

Entschuldigung, fast meine ganze Freizeit verbringt ich gerade damit, ein Buch zu schreiben, ich werde wahrscheinlich gegen Ende dieses Jahres zu meiner Web Tutorial Serie zurückkehren. Die Auswahl von Pfaden kann mit der 'isPointInPath'-Funktion des Kontexts erfolgen, aber Sie müssen alle Schritte speichern, die für jeden Pfad erforderlich sind, und den aktuellen Pfad des Kontexts bei jedem Test neu laden. –

0

Sie können einen Pathiterator verwenden, der alle Formen in angenäherte Polygone verwandelt. Verwenden Sie dann einen "Punkt in Polygon" -Algorithmus, um zu überprüfen, ob der Punkt in der Form ist.

0

Dies kann mit Path2D erreicht werden.

var div = document.getElementById("result"); 
 
var canvas = document.getElementById("canvas"); 
 

 
var ctx = canvas.getContext("2d"); 
 

 
var path1 = new Path2D(); 
 
path1.rect(10, 10, 100, 100); 
 
path1.closePath(); 
 
ctx.stroke(path1); 
 

 
var path2 = new Path2D(); 
 
path2.moveTo(220, 60); 
 
path2.arc(170, 60, 50, 0, 2 * Math.PI); 
 
path2.closePath(); 
 
ctx.stroke(path2); 
 

 
var path3 = new Path2D("M230 10 h 80 v 80 h -80 Z"); 
 
ctx.fill(path3); 
 
path3.closePath(); 
 

 
$('canvas').click(function(event) 
 
{ 
 
    div.innerHTML = ""; 
 
    
 
    var x = event.pageX; 
 
    var y = event.pageY; 
 

 
    if (ctx.isPointInPath(path1, x, y)) 
 
    div.innerHTML = "Path1 clicked"; 
 

 
    if (ctx.isPointInPath(path2, x, y)) 
 
    div.innerHTML = "Path2 clicked"; 
 
    
 
    if (ctx.isPointInPath(path3, x, y)) 
 
    div.innerHTML = "Path3 clicked"; 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<body> 
 
    <canvas id="canvas"></canvas> 
 
    <div id="result"></div> 
 
</body>