2010-08-19 15 views
8

Mam płótno z rysunkami o nieregularnych kształtach i chciałbym otrzymać informację zwrotną, gdy ktoś kliknie konkretny?Płótno html5 kliknięcie na detekcji kształtu ścieżki Beziera

Szukałem wszędzie tego i znalazłem tylko rozwiązania dla prostokąta.

Myślę, że może to mieć związek z isPointInPath(), ale jeszcze nie znalazłem zwięzłego wyjaśnienia, jak go używać.

Każda pomoc mile widziane.

Odpowiedz

13

Wykonałem samouczek, który wykorzystuje drugie niewidzialne płótno do wykonywania prób pobrania/trafienia. Narysuj wszystkie kształty, jeden po drugim, na drugim płótnie, aż jeden z nich będzie miał czarny piksel, w którym znajduje się położenie myszy. Wtedy znalazłeś swój obiekt!

Oto nieco z samouczka pisałem o wyborze przedmiotów z płótna:

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

    } 

Moje pełne demo używa tylko prostokąty, ale w nowszej wersji użyję okręgi/ścieżki/tekst.

Jeśli chcesz zobaczyć wersję demo i mój pełny kod, to jest to here.

+0

Dzięki. W końcu zrobiłem coś podobnego, chociaż pozostałem na płótnie zapisywania, nie robiąc żadnych pociągnięć i wypełnień podczas przerysowywania kształtów. – Brousselaine

+0

@Simon Sarris Skorzystałem z twojego tutorialu, aby to zrobić: http://edumax.org.ro/extra/new/mindmap/ (użyj siatki jako mapy i kliknij prawym przyciskiem myszy dla menu) Próbuję również wybrać ścieżki za pomocą twoja metoda. Rozumiem, że masz samouczek na ten temat, ale czy jest jakiś sposób, aby dać nam wskazówkę na temat kilku podstawowych kroków, które podążysz? (specjalnie dla funkcji path .contains()) –

+0

Niestety, prawie cały mój wolny czas spędzam właśnie na pisaniu książki. Wrócę do mojej serii samouczków prawdopodobnie pod koniec tego roku. Wybieranie ścieżek można wykonać za pomocą funkcji 'isPointInPath' kontekstu, ale należy zapisać wszystkie kroki potrzebne do utworzenia każdej ścieżki i załadować aktualną ścieżkę kontekstu za każdym razem, gdy trzeba przetestować. –

0

Można użyć ścieżki, która zamienia wszystkie kształty w przybliżone wielokąty. Następnie użyj algorytmu "punkt w wielokąt", aby sprawdzić, czy punkt ma kształt.

0

Można to osiągnąć za pomocą 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>

Powiązane problemy