Déterminer la position de la souris sur un canevas HTML5 après un zoom

Donc, je travaille sur le développement de certains logiciels en HTML5 qui implique l'utilisation de toiles. Il existe une toile dans laquelle je dois pouvoir zoomer et permettre à l'utilisateur de faire un tapis sur le canevas sur les clics de la souris. Jusqu'à présent, j'ai obtenu le zoom pour fonctionner, avec l'aide de quelques exemples que j'ai trouvés. Le problème est qu'après le zoom, la position de la souris sur mon outil de dessin est hors de portée. Avant tout zoom, je peux dessiner très bien. Voici le code du zoom:

//Zoom mainCanvas.onmousewheel = function(event) { var mousex = event.clientX - mainCanvas.offsetLeft; var mousey = event.clientY - mainCanvas.offsetTop; var wheel = event.wheelDelta / 120; //n or -n var zoom = 0; if(wheel < 0) { zoom = 1 / 2; if(currentzoom == 1) return; } else { mousex = event.clientX - mainCanvas.offsetLeft; mousey = event.clientY - mainCanvas.offsetTop; zoom = 2; if(currentzoom == 32) return; } currentzoom *= zoom; mainContext.translate(originx, originy); mainContext.scale(zoom, zoom); mainContext.translate(-(mousex / scale + originx - mousex / (scale * zoom ) ), -(mousey / scale + originy - mousey / (scale * zoom ) )); originx = (mousex / scale + originx - mousex / (scale * zoom ) ); originy = (mousey / scale + originy - mousey / (scale * zoom ) ); scale *= zoom; draw(mainContext, gridArray); } 

Comme je l'ai dit, le zoom n'est pas le problème réel, juste la racine du problème. Voici le code qui détermine la position de la souris pour l'outil de dessin:

 //this function determines the mouse position relative to the canvas element function ev_canvas(ev) { if(ev.layerX || ev.layerX == 0) {//Firefox, IE ev._x = ev.layerX; ev._y = ev.layerY; } else if(ev.offsetX || ev.offsetX == 0) {//Opera ev._x = ev.offsetX; ev._y = ev.offsetY; } var func = tool[ev.type]; if(func) { func(ev); } } 

Je suis sûr que le problème réside dans le dernier bloc de code, mais je ne suis pas sûr de le réparer. Toute aide serait appréciée.

Je soupçonne qu'il s'agit d'un extrait de code qui repose sur certaines variables globales comme currentzoom

Donc, si je comprends bien cette question, le problème réside dans la façon dont vous utilisez la toile pour le contrôle et le zoom de la souris. Je soupçonne que lorsque vous zoomez, le DOM place le curseur de la souris où il appartient sur l'image tel qu'il a été initialement rendu. Donc, si vous agrandissez 200% et placez la souris à 100 pixels à gauche du centre du canevas, la toile se comporte comme si la souris était de 200 pixels à gauche du centre.

 currentzoom = 1; originX = 0; originY = 0; function ev_canvas(ev) { if(ev.layerX || ev.layerX == 0) {//Firefox, IE ev._x = ev.layerX * currentzoom / 1 - originX; ev._y = ev.layerY * currentzoom / 1 - originY; } else if(ev.offsetX || ev.offsetX == 0) {//Opera ev._x = ev.offsetX * currentzoom / 1 - originX; ev._y = ev.offsetY * currentzoom / 1 - originY; } var func = tool[ev.type]; if(func) { func(ev); } } 

Le / 1 est conservé dans le cas où les futurs utilisateurs souhaitent définir une valeur non "1" pour currentzoom .

Pour le site Joomla, vous pouvez utiliser Mouse Over Zoom: c'est une extension Joomla qui vous permet de visualiser les plus grandes versions des vignettes depuis votre page Joomla. Maintenant, vous pouvez parcourir les galeries d'images avec facilité: il suffit de déplacer le curseur de la souris sur les vignettes pour afficher les images en pleine taille sans charger une nouvelle page. Téléchargez-le ici http://joomlaboat.com/mouse-over-zoom

Les images sont redimensionnées automatiquement si elles ne correspondent pas à la fenêtre. Vous pouvez personnaliser l'extension. Il existe beaucoup d'options supplémentaires. Pour charger des images transparentes, sans fond, utilisez simplement des images .png.

Essayez cela:

 <!DOCTYPE HTML> <html> <head> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js"></script> <style> body { margin: 0px; padding: 0px; } #wrapper { position: relative; border: 1px solid #9C9898; width: 578px; height: 200px; } #buttonWrapper { position: absolute; width: 30px; top: 2px; right: 2px; } input[type = "button"] { padding: 5px; width: 30px; margin: 0px 0px 2px 0px; } </style> <script> function draw(scale, translatePos){ var canvas = document.getElementById("myCanvas"); var context = canvas.getContext("2d"); // clear canvas context.clearRect(0, 0, canvas.width, canvas.height); context.save(); context.translate(translatePos.x, translatePos.y); context.scale(scale, scale); context.beginPath(); // begin custom shape context.moveTo(-119, -20); context.bezierCurveTo(-159, 0, -159, 50, -59, 50); context.bezierCurveTo(-39, 80, 31, 80, 51, 50); context.bezierCurveTo(131, 50, 131, 20, 101, 0); context.bezierCurveTo(141, -60, 81, -70, 51, -50); context.bezierCurveTo(31, -95, -39, -80, -39, -50); context.bezierCurveTo(-89, -95, -139, -80, -119, -20); context.closePath(); // complete custom shape var grd = context.createLinearGradient(-59, -100, 81, 100); grd.addColorStop(0, "#8ED6FF"); // light blue grd.addColorStop(1, "#004CB3"); // dark blue context.fillStyle = grd; context.fill(); context.lineWidth = 5; context.strokeStyle = "#0000ff"; context.stroke(); context.restore(); } window.onload = function(){ var canvas = document.getElementById("myCanvas"); var translatePos = { x: canvas.width / 2, y: canvas.height / 2 }; var scale = 1.0; var scaleMultiplier = 0.8; var startDragOffset = {}; var mouseDown = false; // add button event listeners document.getElementById("plus").addEventListener("click", function(){ scale /= scaleMultiplier; draw(scale, translatePos); }, false); document.getElementById("minus").addEventListener("click", function(){ scale *= scaleMultiplier; draw(scale, translatePos); }, false); // add event listeners to handle screen drag canvas.addEventListener("mousedown", function(evt){ mouseDown = true; startDragOffset.x = evt.clientX - translatePos.x; startDragOffset.y = evt.clientY - translatePos.y; }); canvas.addEventListener("mouseup", function(evt){ mouseDown = false; }); canvas.addEventListener("mouseover", function(evt){ mouseDown = false; }); canvas.addEventListener("mouseout", function(evt){ mouseDown = false; }); canvas.addEventListener("mousemove", function(evt){ if (mouseDown) { translatePos.x = evt.clientX - startDragOffset.x; translatePos.y = evt.clientY - startDragOffset.y; draw(scale, translatePos); } }); draw(scale, translatePos); }; jQuery(document).ready(function(){ $("#wrapper").mouseover(function(e){ $('#status').html(e.pageX +', '+ e.pageY); }); }) </script> </head> <body onmousedown="return false;"> <div id="wrapper"> <canvas id="myCanvas" width="578" height="200"> </canvas> <div id="buttonWrapper"> <input type="button" id="plus" value="+"><input type="button" id="minus" value="-"> </div> </div> <h2 id="status"> 0, 0 </h2> </body> </html> 

Fonctionne parfaitement pour moi avec la piste de mouvement de la souris. Njoy !!!

J'ai eu un meilleur script pour obtenir la position de la souris sur la toile:

 function writeMessage(canvas, message) { var context = canvas.getContext('2d'); context.clearRect(0, 0, canvas.width, canvas.height); context.font = '18pt Calibri'; context.fillStyle = 'black'; context.fillText(message, 10, 25); } function getMousePos(canvas, evt) { var rect = canvas.getBoundingClientRect(), root = document.documentElement; // return relative mouse position var mouseX = evt.clientX - rect.top - root.scrollTop; var mouseY = evt.clientY - rect.left - root.scrollLeft; return { x: mouseX, y: mouseY }; } window.onload = function() { var canvas = document.getElementById('myCanvas'); var context = canvas.getContext('2d'); canvas.addEventListener('mousemove', function(evt) { var mousePos = getMousePos(canvas, evt); var message = "Mouse position: " + mousePos.x + "," + mousePos.y; writeMessage(canvas, message); }, false); }; 

Essayez-le, commentez-vous s'il y a des problèmes …