2010-08-19 11 views
8

Ho una tela con alcuni disegni di forma irregolare e vorrei avere un feedback quando qualcuno fa clic su uno specifico?html5 canvas facendo clic su rilevamento forma percorso bezier

Ho cercato ovunque e ho trovato solo soluzioni per il rettangolo.

Penso che possa avere a che fare con isPointInPath(), ma non ho ancora trovato una spiegazione concisa su come usarlo.

Qualsiasi aiuto benvenuto.

risposta

13

Ho creato un tutorial che utilizza una seconda tela invisibile per eseguire il test degli oggetti/hit test. Disegna tutte le forme, una alla volta, sulla seconda area di disegno fino a quando una di esse ha un pixel nero in cui si trova la posizione del mouse. Allora hai trovato il tuo oggetto!

Ecco un po 'dal tutorial che ho scritto sulla selezione di oggetti con la tela:

// 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; 
    } 

    } 

mio demo completa utilizza solo rettangoli, ma in una versione successiva che useranno cerchi/percorsi/testo.

Se si desidera vedere la demo e il mio codice completo è here.

+0

Grazie. Alla fine ho fatto qualcosa di simile, anche se sono rimasto sulla tela di salvataggio, non facendo alcun tratto o riempimento durante il ridisegno delle forme. – Brousselaine

+0

@Simon Sarris Ho usato il tuo tutorial per fare questo: http://edumax.org.ro/extra/new/mindmap/ (usa la griglia come mappa e tasto destro del mouse per il menu) Sto cercando di rendere i percorsi selezionabili anche usando il tuo metodo Capisco che tu abbia un tutorial su questo aspetto, ma c'è un modo in cui potresti darci un suggerimento su alcuni passaggi fondamentali che seguirai? (in particolare per la funzione path .contains()) –

+0

Mi spiace, quasi tutto il mio tempo libero in questo momento è dedicato alla scrittura di un libro, tornerò alla mia serie di tutorial web probabilmente verso la fine di quest'anno. La creazione di percorsi selezionabili può essere eseguita con la funzione 'isPointInPath' del contesto, ma è necessario salvare tutti i passaggi necessari per rendere ogni percorso e caricare il percorso corrente del contesto ogni volta che è necessario testare. –

0

È possibile utilizzare un Pathiterator, che trasforma tutte le forme in poligoni approssimati. Quindi utilizzare un algoritmo 'punto in poligono' per verificare se il punto è nella forma.

0

Questo può essere ottenuto utilizzando Path2D.

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>