如何使用HTML5画布找出点击圈子的哪个部分?

时间:2016-06-30 03:45:43

标签: javascript jquery html5 canvas

我正在尝试使用HTML5 canvas和vanilla JavaScript创建Simon游戏。我对arc()方法中的坐标系感到困惑。我已将圆圈划分为4个象限,并想要提醒点击的象限数量。但是,我不知道如何找出圈子的哪个部分被点击。 https://jsfiddle.net/xawpLdys/1/

var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var x = canvas.width / 2;
var y = canvas.height / 2;

var pads = [];

var angle = 2 * Math.PI / 4;
var color = ["green","red","blue","yellow"];
var Pads = function(x, y, radius, start, end) {
   this.x = x;
   this.y = y;
   this.radius = radius;
   this.start = start;
   this.end = end;

};
function drawSimon(radius) {
for (var i = 0; i < 4; i++) {
    context.beginPath();
    context.moveTo(x, y);
    context.arc(x, y, radius, i*angle, (i+1)*angle, false);
    context.lineWidth = radius;
    context.fillStyle = color[i];
    context.fill();
    context.lineWidth = 2;
    context.strokeStyle = '#444';
    context.stroke();
    var pad = new Pads(x, y, radius, i*angle, (i+1)*angle);
    pads.push(pad);
}

}

 drawSimon(150);

  $('#myCanvas').click(function (e) {

  /*for (var i = 0; i < pads.length; i++) {
    if (//condition matches) {
        alert (i);
    }
   }*/
  });

2 个答案:

答案 0 :(得分:2)

试试这个

此示例只是将点击的e.pageXe.pageY转换为普通象限系统。在某些条件之后,您可以确定单击了哪个部分。

    $('#myCanvas').click(function (e) {
    var nx,ny;
    nx=-(x- e.pageX);
    ny=y- e.pageY;
        if (nx>0 && ny>0){
      alert('Yellow');
      }else if (nx<0 && ny>0){
      alert('Blue');
      }else if (nx>0 && ny<0){
      alert('Green');
      }else if (nx<0 && ny<0){
      alert('Red');
      }

    });

这是小提琴https://jsfiddle.net/xawpLdys/3/

<强>更新

John S是对的,(它会计算圈外的点击次数)。为了防止圆圈外的咔嗒声被考虑,我们需要找到距离圆心和点击点的距离。然后将距离与圆的半径进行比较,看它是否在半径范围内。

更新的代码:

    $('#myCanvas').click(function (e) {
    var nx,ny;
    nx=-(x- e.pageX);
    ny=y- e.pageY;
     var dx = Math.abs(Math.abs(x)-Math.abs(e.pageX));
     var dy = Math.abs(Math.abs(y)-Math.abs(e.pageY));
     var distance_clicked = Math.sqrt((dx*dx)+(dy*dy));
     if(distance_clicked <= radius){
        if (nx>0 && ny>0){
          alert('Yellow');
          }else if (nx<0 && ny>0){
          alert('Blue');
          }else if (nx>0 && ny<0){
          alert('Green');
          }else if (nx<0 && ny<0){
          alert('Red');
          }
    }
    });

这是更新的小提琴https://jsfiddle.net/xawpLdys/8/

它仍然有将圆圈划分超过4个切片的限制。

答案 1 :(得分:0)

接受的答案似乎有点受限。它会计算圈子外的点击次数。这可以很容易地修复,但它仍然只限于四个部分。

确定某个点是否在某个扇区中:

  1. 首先检查它是否在圆圈内。毕达哥拉斯定理在这里发挥作用。将x和y值平方,如果它们的总和小于或等于半径的平方,则该点在圆圈内。
  2. 如果该点位于圆圈中,则检查其角度是否在扇区的起始角度和结束角度之间。您可以使用三角函数的反正切函数获得点的角度。
  3. 试试这个jsfiddle

    以下是有助于实现此目的的类型:

    var Circle = function(center, radius) {
        this.center = center;
        this.radius = radius;
    
        this._radiusSquared = Math.pow(this.radius, 2);
    }
    
    $.extend(Circle.prototype, {
        containsPoint: function(point) {
            var relPoint = this.pointToRelPoint(point);
            return Math.pow(relPoint.x, 2) + Math.pow(relPoint.y, 2)
                    <= this._radiusSquared;
        },
    
        getAngleForPoint: function(point) {
            var relPoint = this.pointToRelPoint(point);
            return Math.atan2(-relPoint.y, -relPoint.x) + Math.PI;
        },
    
        pointToRelPoint: function(point) {
            return { x: point.x - this.center.x, y: point.y - this.center.y }
        }
    });
    
    var CircleSector = function(startAngle, endAngle) {
        this.startAngle = startAngle;
        this.endAngle = endAngle;
    };
    
    $.extend(CircleSector.prototype, {
        containsAngle: function(angle) {
            return (angle >= this.startAngle) && (angle < this.endAngle);
         },
    
        containsPoint: function(circle, point) {
            return circle.containsPoint(point)
                    && this.containsAngle(circle.getAngleForPoint(point));
        }
    });