如何在画布上使用多个单击事件

时间:2017-09-01 04:53:30

标签: javascript jquery html5 canvas html5-canvas

我使用以下代码绘制了一个带canvas的圆圈。

<div class="abc"><canvas id="myCanvas">HTML5 canvas tag.</canvas></div>
<script>

    var c = document.getElementById("myCanvas");
    var ctx = c.getContext("2d");
    ctx.beginPath();
    ctx.arc(100,75,50,-0.1*Math.PI,1.7*Math.PI);
    ctx.lineWidth = 15;
    ctx.strokeStyle = "#c32020";
    ctx.stroke();

    var c2 = document.getElementById("myCanvas");
    var ctx2 = c2.getContext("2d");
    ctx2.beginPath();
    ctx2.arc(100,75,50,1.7*Math.PI,-0.1*Math.PI);
    ctx2.lineWidth = 15;
    ctx2.strokeStyle = "#a9a9a9";
    ctx2.stroke();

</script>

以下是网络浏览器的结果。

enter image description here

现在,当用户点击圈子的红色部分和灰色部分时,我需要拨打两个不同的javascript function

在红色部分的click,它应该调用function1,点击灰色部分,它应该调用function2

我已经尝试了很多但没有成功。我需要一些专家帮助来实现它。

2 个答案:

答案 0 :(得分:2)

让浏览器执行(大部分)工作

  

点击红色部分,它应该调用function1,点击灰色部分,它应该调用function2。

您可以使用可重用路径对象来存储要测试的不同路径,然后使用路径和坐标作为参数的isPointInPath()

通过检查命中的每个路径,您可以根据例如索引分配不同的呼叫。

没有必要这样做:

var c2 = document.getElementById("myCanvas");
var ctx2 = c2.getContext("2d");

这将简单地引用相同的上下文,因为画布只能有一个 - 如果请求的次数相同,则会给出相同的内容(如果不同,则为null)。

  

如何在画布上使用多次点击事件

您可以共享点击处理程序以执行您想要的操作,如下所示 -

对于现代浏览器,您可以使用两个Path2D对象来存储以后要使用的路径信息(我将在第二个示例中使用旧版浏览器)。

实施例

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var p1 = new Path2D();
var p2 = new Path2D();
var paths = [p1, p2];   // store paths in array for check later

// store arc parts to respective path objects
p1.arc(100, 75, 50, -0.1 * Math.PI, 1.7 * Math.PI);  // red part
p2.arc(100, 75, 50, 1.7 * Math.PI, -0.1 * Math.PI);  // grey part

// render the two path objects using a common context, but different style
ctx.lineWidth = 15;

ctx.strokeStyle = "#c32020";
ctx.stroke(p1);

ctx.strokeStyle = "#a9a9a9";
ctx.stroke(p2);

// check for clicks on common canvas
c.onclick = function(e) {
  var rect = this.getBoundingClientRect(),  // adjust click coordinates
      x = e.clientX - rect.left,
      y = e.clientY - rect.top;

  // iterate through path array to test each path for hits
  for(var i = 0; i < paths.length; i++) {
    if (ctx.isPointInStroke(paths[i], x, y)) {      // check which path
      console.log("Path " + (i+1) + " clicked");
      break;
    }
  }
};
<canvas id="myCanvas"></canvas>

浏览器兼容性

旧版浏览器不支持isPointInStroke(),例如IE11。

对于这种情况,您可以使用简单的数学来确定点击是否在弧的半径范围内:

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.lineWidth = 15;
ctx.arc(100, 75, 50, -0.1 * Math.PI, 1.7 * Math.PI);  // red part
ctx.strokeStyle = "#c32020";
ctx.stroke();

ctx.beginPath();
ctx.arc(100, 75, 50, 1.7 * Math.PI, -0.1 * Math.PI);  // grey part
ctx.strokeStyle = "#a9a9a9";
ctx.stroke();

// check for clicks on common canvas
c.onclick = function(e) {
  var rect = this.getBoundingClientRect(),  // adjust click coordinates
      x = e.clientX - rect.left,
      y = e.clientY - rect.top,
      diffX = 100 - x,
      diffY = 75 - y,
      len = diffX*diffX + diffY*diffY,     // we don't need to square-root it:
      r1 = 43*43,         // it's faster to scale up radius (50-50% of linewidth)
      r2 = 57*57;         // radius + 50% of linewidth

  // are we on the edge of the circle?
  if (len >= r1 && len <= r2) {
    // now find angle to see if we're in red or grey area
    var angle = Math.atan2(diffY, diffX);
    if (angle > 0.7 * Math.PI && angle < 0.9 * Math.PI) {
      console.log("Grey part");
    }
    else {
      console.log("Red part");
    }
  }
};
<canvas id="myCanvas"></canvas>

请注意,在后一个示例中的特殊情况,即当弧穿过0/360°点时,您将要分割检查[0,角度&gt;和[角度,360&gt;。

答案 1 :(得分:0)

您需要向canvas元素添加一个click事件,并计算是否单击了红色或灰色。 这里有一些代码可以帮助您入门,但您仍需要弄清楚您的圈子区域的坐标。

var elem = document.getElementById('myCanvas'),
elemLeft = elem.offsetLeft,
elemTop = elem.offsetTop;

// Add event listener for `click` events.
elem.addEventListener('click', function(event) {
var x = event.pageX,
    y = event.pageY;

// use x and y to determine if the colored regions are clicked and execute code accordingly

}, false);

代码来自此处:How do I add a simple onClick event handler to a canvas element?