0

I push a element to an array so loop them. How I do a following. I want to click a circle area and then alert something. I found the answer be the rectangle so how the circle do?

<canvas id="myCanvas" width="500" height="500" style="border:1px solid #d3d3d3;"></canvas>

<script>

  var elements = [];
  elemLeft = canvas.offsetLeft,
  elemTop = canvas.offsetTop;


  var canvas = document.getElementById("myCanvas");
  var context = canvas.getContext("2d");

  elements.push({
      colour: '#112F41',
      x:200,
      y:240,
      r:100,
      sAngle:0,
      eAngle:2 * Math.PI
  });

  elements.forEach(function(element) {
      context.strokeStyle = element.colour;
      context.arc(element.x, element.y, element.r, element.sAngle, element.eAngle);
      context.lineWidth = 20;

      context.stroke();
  });

  canvas.addEventListener('click', function(event) {
    var x = event.pageX - elemLeft,
        y = event.pageY - elemTop;
    console.log(x, y);
    elements.forEach(function(element) {
        //??????
    });

}, false);

</script>
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Glufflix
  • 17
  • 2
  • 8
  • 1
    Possible duplicate of [How do I add a simple onClick event handler to a canvas element?](https://stackoverflow.com/questions/9880279/how-do-i-add-a-simple-onclick-event-handler-to-a-canvas-element) – EJK Dec 16 '18 at 16:31

2 Answers2

1

You need to redraw the shape before calling the method isPointInPath.

Ive added to your code a function to detect the mouse position and an other one that draws the element. I hope it helps.

var elements = [];
var canvas = document.getElementById("myCanvas");
canvas.width = "500";
canvas.height = "500";
var context = canvas.getContext("2d");

var mouse;

elements.push({
  colour: "#112F41",
  x: 200,
  y: 240,
  r: 100,
  sAngle: 0,
  eAngle: 2 * Math.PI
});

elements.forEach(element => {
  drawElement(element, context);
});

canvas.addEventListener(
  "click",
  function(event) {
    mouse = oMousePos(canvas, event)
    elements.forEach(function(element) {
      drawElement(element, context);
      if(context.isPointInPath(mouse.x, mouse.y)){console.log(mouse)}else{console.log("not in path")}
    });
  },
  false
);

function drawElement(element, context) {
  context.strokeStyle = element.colour;
  context.arc(element.x, element.y, element.r, element.sAngle, element.eAngle);
  context.lineWidth = 2;

  context.stroke();
}

function oMousePos(canvas, evt) {
  var ClientRect = canvas.getBoundingClientRect();
  return { //objeto
    x: Math.round(evt.clientX - ClientRect.left),
    y: Math.round(evt.clientY - ClientRect.top)
  }
}
canvas {
  border:1px solid;
}
<canvas id="myCanvas"></canvas>
enxaneta
  • 31,608
  • 5
  • 29
  • 42
0

You can also use trigonometry to calculate distance between the mouse and the circle. i added a pointInCircle method which return true if the mouse is inside the circle element other wise returns false.

Simple Pythagorean theorem

NOTE : This method also provides full browser support.

var elements = [];
var canvas = document.getElementById("myCanvas");
canvas.width = "500";
canvas.height = "500";
var context = canvas.getContext("2d");

var mouse;

elements.push({
  colour: "#112F41",
  x: 200,
  y: 240,
  r: 100,
  sAngle: 0,
  eAngle: 2 * Math.PI
});

elements.forEach(element => {
  drawElement(element, context);
});

canvas.addEventListener(
  "click",
  function(event) {
    mouse = oMousePos(canvas, event)
    elements.forEach(function(element) {
      drawElement(element, context);
      // method using point to circle collision detection
      if (pointInCircle(element, mouse)) {
        console.log(mouse)
      } else {
        console.log("not in path")
      }
    });
  },
  false
);

// pointInCircle
function pointInCircle(circle, mouse) {
   let dx = circle.x - mouse.x;
   let dy = circle.y - mouse.y;
   let dist = Math.sqrt(dx*dx + dy*dy);
   
   if (dist < circle.r) return true;
   return false
}

function drawElement(element, context) {
  context.strokeStyle = element.colour;
  context.arc(element.x, element.y, element.r, element.sAngle, element.eAngle);
  context.lineWidth = 2;

  context.stroke();
}

function oMousePos(canvas, evt) {
  var ClientRect = canvas.getBoundingClientRect();
  return {
    x: Math.round(evt.clientX - ClientRect.left),
    y: Math.round(evt.clientY - ClientRect.top)
  }
}
<canvas id="myCanvas"></canvas>
Anurag Hazra
  • 403
  • 1
  • 6
  • 14