How do I get the coordinates of a mouse click on a canvas element?

后端 未结 22 2838
忘掉有多难
忘掉有多难 2020-11-21 23:56

What\'s the simplest way to add a click event handler to a canvas element that will return the x and y coordinates of the click (relative to the canvas element)?

No

22条回答
  •  半阙折子戏
    2020-11-22 00:38

    I was creating an application having a canvas over a pdf, that involved a lot of resizes of canvas like Zooming the pdf-in and out, and in turn on every zoom-in/out of PDF I had to resize the canvas to adapt the size of the pdf, I went through lot of answers in stackOverflow, and didn't found a perfect solution that will eventually solve the problem.

    I was using rxjs and angular 6, and didn't found any answer specific to the newest version.

    Here is the entire code snippet that would be helpful, to anyone leveraging rxjs to draw on top of canvas.

      private captureEvents(canvasEl: HTMLCanvasElement) {
    
        this.drawingSubscription = fromEvent(canvasEl, 'mousedown')
          .pipe(
            switchMap((e: any) => {
    
              return fromEvent(canvasEl, 'mousemove')
                .pipe(
                  takeUntil(fromEvent(canvasEl, 'mouseup').do((event: WheelEvent) => {
                    const prevPos = {
                      x: null,
                      y: null
                    };
                  })),
    
                  takeUntil(fromEvent(canvasEl, 'mouseleave')),
                  pairwise()
                )
            })
          )
          .subscribe((res: [MouseEvent, MouseEvent]) => {
            const rect = this.cx.canvas.getBoundingClientRect();
            const prevPos = {
              x: Math.floor( ( res[0].clientX - rect.left ) / ( rect.right - rect.left ) * this.cx.canvas.width ),
              y:  Math.floor( ( res[0].clientY - rect.top ) / ( rect.bottom - rect.top ) * this.cx.canvas.height )
            };
            const currentPos = {
              x: Math.floor( ( res[1].clientX - rect.left ) / ( rect.right - rect.left ) * this.cx.canvas.width ),
              y: Math.floor( ( res[1].clientY - rect.top ) / ( rect.bottom - rect.top ) * this.cx.canvas.height )
            };
    
            this.coordinatesArray[this.file.current_slide - 1].push(prevPos);
            this.drawOnCanvas(prevPos, currentPos);
          });
      }
    

    And here is the snippet that fixes, mouse coordinates relative to size of the canvas, irrespective of how you zoom-in/out the canvas.

    const prevPos = {
      x: Math.floor( ( res[0].clientX - rect.left ) / ( rect.right - rect.left ) * this.cx.canvas.width ),
      y:  Math.floor( ( res[0].clientY - rect.top ) / ( rect.bottom - rect.top ) * this.cx.canvas.height )
    };
    const currentPos = {
      x: Math.floor( ( res[1].clientX - rect.left ) / ( rect.right - rect.left ) * this.cx.canvas.width ),
      y: Math.floor( ( res[1].clientY - rect.top ) / ( rect.bottom - rect.top ) * this.cx.canvas.height )
    };
    

提交回复
热议问题