1

I am currently implementing a functionality to place an canvas over pdf in pdf-reader so that we can draw on top of canvas, so the pdf in which canvas is placed can be zoomed-in and out to much extent, and I have to ensure that canvas should also resize as per the pdf, so that drawing on top of it remains intact, for resizing canvas I am using the canvas.style.width , drawing.style.height to resize it when pdf-resizes.

But now my concern is that on resizing mouse-pointer changes its position, for instance in the attached image my mouse is in bottom-right and it draws in top-left, due to shifting in mouse coordinates.

enter image description here

I am using RxJS for drawing, and capturing events, but I am not been able to figure out how to take care of mouse position in summary, I want coordinates to scale as per canvas resize.

  private captureEvents(canvasEl: HTMLCanvasElement) {
    // this will capture all mousedown events from the canvas element
    this.drawingSubscription = fromEvent(canvasEl, 'mousedown')
      .pipe(
        switchMap((e) => {

          // after a mouse down, we'll record all mouse moves
          return fromEvent(canvasEl, 'mousemove')
            .pipe(
              // we'll stop (and unsubscribe) once the user releases the mouse
              // this will trigger a 'mouseup' event
              takeUntil(fromEvent(canvasEl, 'mouseup').do((event: WheelEvent) => {
                console.log('e', e.type, e);
                const prevPos = {
                  x: null,
                  y: null
                };
                this.coordinatesArray[this.file.current_slide - 1].push(prevPos);
                console.log('coordinatesArray', this.coordinatesArray);
              })),
              // we'll also stop (and unsubscribe) once the mouse leaves the canvas (mouseleave event)
              takeUntil(fromEvent(canvasEl, 'mouseleave')),
              // pairwise lets us get the previous value to draw a line from
              // the previous point to the current point
              pairwise()
            )
        })
      )
      .subscribe((res: [MouseEvent, MouseEvent]) => {
        const rect = canvasEl.getBoundingClientRect();
        // previous and current position with the offset
        const prevPos = {
          x: res[0].clientX - rect.left,
          y: res[0].clientY - rect.top
        };

        const currentPos = {
          x: res[1].clientX - rect.left,
          y: res[1].clientY - rect.top
        };

        this.coordinatesArray[this.file.current_slide - 1].push(prevPos);
        // console.log('coordinatesArray', this.coordinatesArray);
        this.drawOnCanvas(prevPos, currentPos);
      });
  } 

Moreover, I am not generating the new canvas on every zoom-in/out, I am just modifying the it's height/width as per dimensions of page on top of which it is present.

enter image description here

Divyanshu Rawat
  • 4,421
  • 2
  • 37
  • 53

1 Answers1

0

I eventually solved it after spending a hell lot of time. I have posted the answer in relevant thread that will be helpful to others going through the similar problem.

https://stackoverflow.com/a/56363476/5763627

Divyanshu Rawat
  • 4,421
  • 2
  • 37
  • 53