简体   繁体   中英

Click listener incorrect data after resizing window with canvas in angular 6

I am using a canvas with clickable elements that was added using for loop, I added a resizing event that redrawing the canvas after user window was resized, When the window is loading for the first time the canvas and click listeners works great, My problem starts after the window resizing, I getting wrong click coordinates and bad behavior, It looks the click event have sort of a backlog for all the times that the screen was resized

Here is the full code on stackblitz

The resize function

   @HostListener('window:resize', ['$event'])
    onResize(event) {
      this.innerWidth = window.innerWidth;
      this.innerHeight = window.innerHeight;
      this.canvas.width = this.innerWidth;
      this.canvas.height = this.innerHeight 
      this.cleardraw()
      this.draw()         
    }

      cleardraw(){
    var ctx = this.canvas.getContext('2d');
    ctx.clearRect(0, 0, this.innerWidth, this.innerHeight);

   }

The draw function

draw() {

  var ctx = this.canvas.getContext('2d');
  ctx.font = "15px Arial";
  var seats = []                               
  var tempOrderArrey = []                        
  var orderSeatsClinet = []                        
  var selectedSeatsClient = []                      
  var numberOfSeats = 10
  var numberOfRows = 10
  var canvasWidth = this.innerWidth
  var canvasHight = this.innerHeight


  function Seat(x, y, w, h, id, line, seatNum, color) {
      this.x = x - 160
      this.y = y ;
      this.w = w;
      this.h = h;
      this.id = id;
      this.line = line
      this.seatNo = seatNum + 1 ;
      this.color = color
  }


  Seat.prototype.draw = function () {
      ctx.fillStyle = this.color
      ctx.fillRect(this.x, this.y, this.w, this.h)


  }



  function drawAll() {
      for (var i = 0; i < seats.length; i++) {
          seats[i].draw();
      }
  }

    var id = 1;
    var xPad = canvasWidth / 30


    function addSeats(value, ch) {
        for (let i = 0; i <= 15; i++)
            seats.push(new Seat( (canvasWidth / 3) + (i * xPad), value, canvasWidth/ 37, canvasWidth/ 37, id++, ch, i, "#998515"));
    }

    var start = 60, diff = canvasWidth/30, ch = 0;
    for (let i = 0; i < 2; i++) {
        //60 + (40 * i)
        addSeats(start + (diff * i), ch++);
    }     

  drawAll()

The click event function

 this.renderer.listen(this.canvasRef.nativeElement, 'click', (event) => {
    let cX = event.layerX;
    let cY = event.layerY;

    const offsetLeft = this.canvasRef.nativeElement.offsetLeft;
    const offsetTop = this.canvasRef.nativeElement.offsetTop;

    this.cX = cX - offsetLeft;
    this.cY = cY - offsetTop;

      for (var i = 0; i < seats.length; i++) {
          var s = seats[i];
          if (cX >= s.x && cX < s.x + s.w && cY >= s.y && cY < s.y + s.h) {
              if (s.color == '#998515') {      // If green
                  tempOrderArrey.push({ "id": s.id, "seatNum": s.seatNo, "rowNum": s.line })
                  s.color = '#ff0000'
                  ctx.fillStyle = '#ff0000'
                  ctx.fillRect(s.x, s.y, s.w, s.h)

              }
              else if (s.color == '#ff0000') {  // If red
                  tempOrderArrey = tempOrderArrey.filter(seat => seat.id != s.id);
                  ctx.fillStyle = '#998515'
                  s.color = '#998515'
                  ctx.fillRect(s.x, s.y, s.w, s.h)                                   
              }

          }
          this.tempOrderArrey =   tempOrderArrey
      }})



}

The reason is that each time you resize, renderer.listen is called again, so for one click there are many events being fired.

You need to make sure that you clear the listener before creating a new one

// Check if the reference exists
if (this.reference != null) {
    this.reference; // Clear the listener
}

// Store a reference to the listener
this.reference = this.renderer.listen(this.canvasRef.nativeElement, 'click', (event) => {

Here is a fork of the StackBlitz

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM