2013-03-23 61 views
1

请看看这个小example。点击处理程序只在点击行的中间时才起作用。看起来方法isPointInPath不考虑线的宽度。有没有办法解决这个问题?帆布:线上点击活动

回答

3

是的,你是对的。

新的isPointInPath()仅适用于“胖”行的中心线 - 不是行的全部宽度。

它更人性化的封闭图形是超过1个像素宽;)

用于您的具体问题解决办法:不要画脂肪线,绘制一个20像素宽的矩形。

这里是代码和一个小提琴: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> 
+0

您是否有绘制矩形而不是线条的示例?如果你想通过mousemoves创建线条并且你不知道线条位置,我认为这很难做到。 – Maxii 2013-03-23 20:43:15

+0

编辑我的答案,为你包括一个例子:) – markE 2013-03-26 18:12:05