canvas教程

Canvas: Click event on line

字号+ 作者:H5之家 来源:H5之家 2015-11-12 19:38 我要评论( )

Please take a look at this little a href=\http://jsfiddle.net/9V2Sq/\ rel=\nofollow\example/a. The clickhandler only works if you click in the middle

Yes, you are correct.

The new isPointInPath() works only on the centerline of a "fat" line--not the full width of the line.

It's more user friendly on closed shapes that are more than 1 pixel wide ;)

A Workaround for your exact question: Instead of drawing a fat line, draw a 20px wide rectangle.

Here is code and a Fiddle:

This code uses basic trigonometry to create a rectangle around a line. In the mousedown event handler, it redraws the rectangle transparently and then tests isPointInPath().

If you need to test a poly-line, you can use these same principles to make rectangle-lines for each segment of your poly-line.

<!doctype html> <html> <head> <link 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 width=310 height=115></canvas> </body> </html>

是的,你是正确的。

新的isPointInPath()只适用于中心线的“脂肪”,而不是完整的线的宽度。

更用户友好的封闭形状上超过1像素宽;)

一个解决方案为您的确切的问题:脂肪而不是画线,画一个20 px宽的矩形。

下面是代码和一个小提琴:

这段代码使用基本的三角线的创建一个矩形。在mousedown事件处理程序,它透明地重绘矩形,然后测试isPointInPath()。

如果您需要测试一个闸,您可以使用这些相同的原则为每一段rectangle-lines闸。

<!doctype html> <html> <head> <link 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 width=310 height=115></canvas> </body> </html>

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • html5canvas核心技术图形、动画与游戏开发源码

    html5canvas核心技术图形、动画与游戏开发源码

    2017-05-02 17:42

  • 打印html5中Canvas的方法

    打印html5中Canvas的方法

    2017-05-01 15:03

  • HTML样式CSS

    HTML样式CSS

    2017-05-01 10:03

  • HTML5+Canvas调用手机拍照功能实现图片上传(下)

    HTML5+Canvas调用手机拍照功能实现图片上传(下)

    2017-04-30 17:00

网友点评