请看一下这个小例子。clickhandler 仅在您单击该行的中间时才起作用。该方法isPointInPath
似乎没有考虑线的宽度。有没有办法解决这个问题?
问问题
4426 次
1 回答
3
是的,你是对的。
新的 isPointInPath() 仅适用于“胖”线的中心线——而不是线的整个宽度。
它对大于 1 像素宽的封闭形状更加用户友好;)
针对您的确切问题的解决方法:不要画一条粗线,而是画一个 20px 宽的矩形。
这是代码和小提琴:http: //jsfiddle.net/m1erickson/QyWDY/
此代码使用基本三角法围绕一条线创建一个矩形。在 mousedown 事件处理程序中,它透明地重绘矩形,然后测试 isPointInPath()。
如果您需要测试折线,您可以使用这些相同的原则为折线的每一段制作矩形线。
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
// get canvas's relative position
var canvasOffset=$("#canvas").offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
// line specifications
var x1=50;
var y1=50;
var x2=300;
var y2=100;
// draw the lineRectangle
var lineRect=defineLineAsRect(x1,y1,x2,y2,20);
drawLineAsRect(lineRect,"black");
// overlay the line (just as visual proof)
drawLine(x1,y1,x2,y2,3,"red");
function drawLine(x1,y1,x2,y2,lineWidth,color){
ctx.fillStyle=color;
ctx.strokeStyle=color;
ctx.lineWidth=lineWidth;
ctx.save();
ctx.beginPath();
ctx.moveTo(x1,y1);
ctx.lineTo(x2,y2);
ctx.stroke();
ctx.restore();
}
function drawLineAsRect(lineAsRect,color){
var r=lineAsRect;
ctx.save();
ctx.beginPath();
ctx.translate(r.translateX,r.translateY);
ctx.rotate(r.rotation);
ctx.rect(r.rectX,r.rectY,r.rectWidth,r.rectHeight);
ctx.translate(-r.translateX,-r.translateY);
ctx.rotate(-r.rotation);
ctx.fillStyle=color;
ctx.strokeStyle=color;
ctx.fill();
ctx.stroke();
ctx.restore();
}
function defineLineAsRect(x1,y1,x2,y2,lineWidth){
var dx=x2-x1; // deltaX used in length and angle calculations
var dy=y2-y1; // deltaY used in length and angle calculations
var lineLength= Math.sqrt(dx*dx+dy*dy);
var lineRadianAngle=Math.atan2(dy,dx);
return({
translateX:x1,
translateY:y1,
rotation:lineRadianAngle,
rectX:0,
rectY:-lineWidth/2,
rectWidth:lineLength,
rectHeight:lineWidth
});
}
function handleMouseDown(e){
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
// draw our lineRect
drawLineAsRect(lineRect,"transparent");
// test if hit in the lineRect
if(ctx.isPointInPath(mouseX,mouseY)){
alert('Yes');
}
}
canvas.addEventListener("mousedown", handleMouseDown, false);
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=310 height=115></canvas>
</body>
</html>
于 2013-03-23T15:08:39.423 回答