2010-08-19 41 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>