2010-08-19 75 views
8

我有一個畫布,裏面有一些不規則形狀的圖畫,當有人點擊一個特定的圖形時,我想有一個反饋?html5 canvas點擊貝塞爾路徑形狀檢測

我一直在尋找這個,只找到矩形的解決方案。

我認爲它可能與isPointInPath()有關,但我還沒有找到關於如何使用它的簡明解釋。

任何幫助歡迎。

回答

13

我做了一個教程,使用第二個隱形畫布進行對象拾取/命中測試。將所有形狀逐一繪製到第二個畫布上,直到其中一個形狀的鼠標位置爲黑色像素。然後你找到了你的對象!

下面是我在用帆布選擇對象寫的教程位:

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

    } 

我的全演示只使用矩形,但在以後的版本我會用圓圈/路徑/文本。

如果你想看演示和我的完整代碼,它是here

+0

感謝。 我終於做了類似的事情,雖然我留在保存畫布上,在重繪圖形時沒有做任何筆觸或填充。 – Brousselaine 2010-08-26 21:41:45

+0

@Simon Sarris我已經使用你的教程來做到這一點:http://edumax.org.ro/extra/new/mindmap/(使用網格作爲地圖,右鍵單擊菜單)我想通過使用路徑選擇你的方法。我知道你有一個關於這個問題的教程,但是有沒有一種方法可以給我們提示你將遵循的一些基本步驟? (專門用於路徑.contains()函數) – 2012-08-05 11:33:06

+0

對不起,我現在幾乎所有的空閒時間都花在寫一本書,我可能會在今年年底左右回到我的網絡教程系列。可以使用上下文的「isPointInPath」函數完成路徑選擇,但是您必須保存每條路徑所需的所有步驟,並在每次需要測試時加載上下文的當前路徑。 – 2012-08-06 03:05:14

0

您可以使用pathiterator將所有形狀變成近似的多邊形。 然後使用'點多邊形'算法來檢查點是否在形狀中。

0

這可以通過使用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>