Distorsión del lienzo HTML5

Estoy tratando de incluir un elemento de lienzo sobre un video de tamaño dinámico que se cargará de forma asincrónica. En el lienzo, el usuario podrá arrastrar y cambiar el tamaño de un cuadro de selección de rectángulo.

En mi archivo JS, tengo un oyente que mira la ventana y cambia el tamaño del lienzo a través de las propiedades .width y .height del elemento del lienzo para que sean exactamente el ancho y la altura del video.

Para el código de selección rectangular JS, estoy siguiendo el violín de la primera respuesta a esta pregunta de StackOverflow:dibujar un rectángulo con clic del mouse y arrastrar - javascriptSin embargo, por alguna razón,cuando el usuario se desplaza hacia abajo en la página el dibujo en el lienzo está completamente distorsionado y los rectángulos comienzan a dibujarse bastante lejos del mouse. Sin embargo, cuando el usuario está en la parte superior de la página, el rectángulo se dibuja en la posición correcta. ¿Por qué sucedería esto?

A continuación se muestra algunos de los códigos JS que estoy usando:

  
// Happens on mousedown event
  downCanvas: function(e) {
    $('.label-grid-canvas').css('cursor','crosshair');
    this.isDrawing = true
    this.startX = parseInt(e.clientX - this.offsetX);
    this.startY = parseInt(e.clientY - this.offsetY);
  },
  
// Happens on mouseup event
  upCanvas: function(e) {
    this.isDrawing = false;
    $('.label-grid-canvas').css('cursor','default');
  },
  // Happens on mousemove event
  moveCanvas: function(e) {
    if (this.isDrawing) {
      var mouseX = parseInt(e.clientX - this.offsetX);
      var mouseY = parseInt(e.clientY - this.offsetY);

      this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
      this.ctx.beginPath();
      this.ctx.rect(this.startX, this.startY, mouseX - this.startX, mouseY - this.startY);
      this.ctx.stroke();
    }
  },

  resizeCanvas: function() {
    this.canvas.width = $('#video-canvas')[0].offsetWidth;
    this.canvas.height = $('#video-canvas')[0].offsetHeight;

    this.canvasOffset = $('.label-grid-canvas').offset();
    this.offsetX = this.canvasOffset.left;
    this.offsetY = this.canvasOffset.top;

    this.redraw();
  },

  redraw: function() {
    this.ctx.strokeStyle = 'blue';
    this.ctx.lineWidth = '2';
    this.ctx.strokeRect(0, 0, $('#video-canvas')[0].offsetWidth,
        $('#video-canvas')[0].offsetHeight);
  },

// Happens after page-load
  initialize: function(options) {
    this.canvas = document.getElementById('label-grid-canvas');
    this.isDrawing = false;
    this.ctx = this.canvas.getContext('2d');
    this.startX;
    this.startY;
    this.canvasOffset = $('.label-grid-canvas').offset();
    this.offsetX = this.canvasOffset.left;
    this.offsetY = this.canvasOffset.top;
    $(window).on('resize', _.bind(this.resizeCanvas, this));
 ....
}

Por favor, ignore las ineficiencias, solo estoy tratando de hackear algo que funciona antes de limpiarlo.

Respuestas a la pregunta(1)

Su respuesta a la pregunta