【问题标题】:Canvas shape click removes more than one shape画布形状单击可删除多个形状
【发布时间】:2019-03-13 01:48:06
【问题描述】:

我正在尝试检测画布点击以及点击坐标是否与形状匹配。它工作正常,问题是当形状在画布上重叠时(一个形状可能比另一个小),那么两个形状都会被删除。有没有办法避免这种情况,一次只删除一个?

 addShape() {
    const randomNum = (min, max) => Math.round(Math.random() * (max - min) + min),
          randomRad = randomNum(10, 100),
          randomX = randomNum(randomRad, this.canvas.width - randomRad);

    let shape = new Shape(randomX, randomNum, randomRad);

    shape.drawShape();
    this.shapes.push(shape);
  }

canvasClick() {
    if(!this.paused) {
      const canvasRect = event.target.getBoundingClientRect(),
            clickedX = event.clientX - canvasRect.left,
            clickedY = event.clientY - canvasRect.top;

      for (let i = 0; i < this.shapes.length; i++) {

        if(Math.pow(clickedX - this.shapes[i].x, 2) + Math.pow(clickedY - this.shapes[i].y, 2) 
           < Math.pow(this.shapes[i].rad,2)) {

          this.shapes.splice(i, 1);
        }
      }
    }
  }

提前感谢您的帮助!

【问题讨论】:

    标签: javascript canvas


    【解决方案1】:

    如果我明白你的意思,那么解决方案非常简单。删除一个形状后只需break 循环。像这样的:

    for (let i = 0; i < this.shapes.length; i++) {
        if (
            Math.pow(clickedX - this.shapes[i].x, 2)
            + Math.pow(clickedY - this.shapes[i].y, 2)
            < Math.pow(this.shapes[i].rad, 2)
        ) {
            this.shapes.splice(i, 1);
            break; // <--
        }
    }
    

    您还可以存储形状的 z 位置,以便您可以首先按照 z 对它们进行排序,然后运行此循环,这样您就不会删除单击形状下方的形状。

    【讨论】:

    • @Corcs 不客气!一旦你检查它是否有效,也请接受我的回答:)
    【解决方案2】:

    我会这样做。请阅读代码中的 cmets。我正在使用ctx.isPointInPath 方法,但如果您愿意,可以使用公式。

    主要思想是找到并删除第一个圆圈后退出循环。 希望对你有帮助。

    let ctx = canvas.getContext("2d");
    canvas.width = 300;
    canvas.height = 300;
    ctx.fillStyle = "rgba(0,0,0,.5)";
    // the array of the circles
    let circles = []
    
    class Circle{
      
    constructor(){
      this.x = ~~(Math.random() * canvas.width);
      this.y = ~~(Math.random() * canvas.height); 
      this.r = ~~(Math.random() * (40 - 10 + 1) + 10); 
      
      this.draw();
    }
    draw(){
      ctx.beginPath();
      ctx.arc(this.x,this.y, this.r, 0,2*Math.PI) 
    }
    }
    
    // create 20 circles
    for(i=0;i<20;i++){
    let c = new Circle();
    ctx.fill()
    circles.push(c)    
    }
    
    canvas.addEventListener("click",(e)=>{
      // detect the position of the mouse
      let m = oMousePos(canvas, e)
      for(let i=0;i<circles.length;i++){
      // draw a circle but do not fill
      circles[i].draw();
        // check if the point is in path
        if(ctx.isPointInPath(m.x,m.y)){
          //remove the circle from the array
          circles.splice(i, 1);
          // clear the context
          ctx.clearRect(0,0,canvas.width,canvas.height)
          // redraw all the circles from the array
          for(let j=0;j<circles.length;j++){
          circles[j].draw();
          ctx.fill()
          }
          //exit the loop
          return;
        }
      }
    })
    
    
    // a function to detect the mouse position
    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}
    &lt;canvas id="canvas"&gt;&lt;/canvas&gt;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-19
      • 2017-03-08
      • 2011-02-04
      • 2019-04-08
      • 1970-01-01
      • 2019-04-08
      • 1970-01-01
      相关资源
      最近更新 更多