Distorsion de toile HTML5

J'essaie d'inclure un élément de toile sur une vidéo de taille dynamique qui se chargera de manière asynchrone. Sur la toile, l'utilisateur pourra faire glisser et redimensionner une boîte de sélection de rectangle.

Dans mon fichier JS, j'ai un auditeur en regardant la fenêtre et redimensionner le canevas via les propriétés .width et .height de l'élément de toile pour être la largeur et la hauteur exactes de la vidéo.

Pour le code de sélection rectangulaire JS, je suis en train de suivre la première réponse à cette question StackOverflow: dessiner un rectangle avec le clic de la souris et le jeter-javascript , pour une raison quelconque, lorsque l'utilisateur est défilé sur le dessin de la page sur le La toile est totalement déformée, et les rectangles commencent à être dessinés assez loin de la souris. Lorsque l'utilisateur est en haut de la page, cependant, le rectangle s'inspire de la position correcte. Pourquoi cela arriverait-il?

Voici un code JS que j'utilise:

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

Veuillez négliger les inefficacités, je tente tout d'abord de pirater une entreprise avant de la nettoyer.

Voici le squelette montrant comment comptabiliser le redimensionnement et le défilement lors du calcul de la position de la souris.

 var canvas=document.getElementById("canvas"); var ctx=canvas.getContext("2d"); var cw=canvas.width; var ch=canvas.height; function reOffset(){ var BB=canvas.getBoundingClientRect(); offsetX=BB.left; offsetY=BB.top; } var offsetX,offsetY; reOffset(); window.onscroll=function(e){ reOffset(); } window.onresize=function(e){ reOffset(); } var isDown=false; var startX,startY,mouseX,mouseY; var $mouse=$('#mouse'); $("#canvas").mousemove(function(e){handleMouseMove(e);}); function handleMouseMove(e){ // tell the browser we're handling this event e.preventDefault(); e.stopPropagation(); // calc the current mouse position mouseX=parseInt(e.clientX-offsetX); mouseY=parseInt(e.clientY-offsetY); // report the mouse position $mouse.text('Mouse position: '+mouseX+' / '+mouseY); } 
 body{ background-color: ivory; } #canvas{border:1px solid red; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <h4 id=mouse>Move the mouse around the canvas.</h4> <canvas id="canvas" width=300 height=300></canvas>