html5 canvas clicking on bezier path shape detection

前端 未结 3 1598
眼角桃花
眼角桃花 2021-02-15 13:51

I have a canvas with some irregular shape drawings in it, and I would like to have a feedback when someone clicks on a specific one?

I\'ve been looking everywhere for th

相关标签:
3条回答
  • 2021-02-15 14:22

    You can use a pathiterator, that turns all shapes into approximated polygons. Then use a 'point in polygon' algorithm to check if the point is in the shape.

    0 讨论(0)
  • 2021-02-15 14:23

    This can be achived by using Path2D.

    var div = document.getElementById("result");
    var canvas = document.getElementById("canvas");
    
    var ctx = canvas.getContext("2d");
    
    var path1 = new Path2D();
    path1.rect(10, 10, 100, 100);
    path1.closePath();
    ctx.stroke(path1);
    
    var path2 = new Path2D();
    path2.moveTo(220, 60);
    path2.arc(170, 60, 50, 0, 2 * Math.PI);
    path2.closePath();
    ctx.stroke(path2);
    
    var path3 = new Path2D("M230 10 h 80 v 80 h -80 Z");
    ctx.fill(path3);
    path3.closePath();
    
    $('canvas').click( function(event) 
    {
      div.innerHTML = "";
      
      var x = event.pageX;
      var y = event.pageY;
    
      if (ctx.isPointInPath(path1, x, y))
        div.innerHTML = "Path1 clicked";
    
      if (ctx.isPointInPath(path2, x, y))
        div.innerHTML = "Path2 clicked";
      
      if (ctx.isPointInPath(path3, x, y))
        div.innerHTML = "Path3 clicked";
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <body>
      <canvas id="canvas"></canvas>
      <div id="result"></div>
    </body>

    0 讨论(0)
  • 2021-02-15 14:36

    I made a tutorial that uses a second invisible canvas to do object picking/hit testing. Draw all your shapes, one by one, onto the second canvas until one of them has a black pixel where the mouse location is. Then you've found your object!

    Here's a bit from the tutorial I wrote on selecting objects with canvas:

      // gctx is ghost context, made from the second canvas
      // clear(gctx)
    
      // ...
    
      // run through all the boxes
      var l = boxes.length;
      for (var i = l-1; i >= 0; i--) {
        // draw shape onto ghost context
        drawshape(gctx, boxes[i], 'black', 'black');
    
        // get image data at the mouse x,y pixel
        var imageData = gctx.getImageData(mx, my, 1, 1);
        var index = (mx + my * imageData.width) * 4;
    
        // if the mouse pixel exists, select and break
        if (imageData.data[3] > 0) {
          mySel = boxes[i];
          offsetx = mx - mySel.x;
          offsety = my - mySel.y;
          mySel.x = mx - offsetx;
          mySel.y = my - offsety;
          isDrag = true;
          canvas.onmousemove = myMove;
          invalidate();
          clear(gctx);
          return;
        }
    
      }
    

    My full demo only uses rectangles but in a later version I will use circles/paths/text.

    If you want to see the demo and my full code it is here.

    0 讨论(0)
提交回复
热议问题