Как получить координаты щелчка мышью на элементе canvas? - PullRequest
256 голосов
/ 11 сентября 2008

Какой самый простой способ добавить обработчик события щелчка к элементу холста, который будет возвращать координаты x и y клика (относительно элемента холста)?

Не требуется совместимость с устаревшими браузерами, подойдут Safari, Opera и Firefox.

Ответы [ 22 ]

0 голосов
/ 29 мая 2019

Я создавал приложение, имеющее canvas поверх pdf, которое включало в себя множество изменений размера canvas, таких как увеличение и уменьшение pdf и, в свою очередь, каждое увеличение / уменьшение PDF Мне нужно было изменить размер холста, чтобы адаптировать размер PDF, я просмотрел много ответов в stackOverflow и не нашел идеального решения, которое в конечном итоге решит проблему.

Я использовал rxjs и angular 6 и не нашел ответа, относящегося к самой новой версии.

Вот весь фрагмент кода, который будет полезен всем, кто использует rxjs для рисования поверх холста.

  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);
      });
  }

А вот фрагмент, который фиксирует координаты мыши относительно размера холста, независимо от того, как вы увеличиваете / уменьшаете холст.

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 )
};
0 голосов
/ 11 сентября 2008

Эй, это в додзё, просто потому, что у меня уже есть код для проекта.

Должно быть довольно очевидно, как преобразовать его обратно в не-додзё ванильный JavaScript.

  function onMouseClick(e) {
      var x = e.clientX;
      var y = e.clientY;
  }
  var canvas = dojo.byId(canvasId);
  dojo.connect(canvas,"click",onMouseClick);

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...