Determining mouse position on HTML5 canvas after scaling

So, I am working on developing some software in HTML5, which involves the use of canvases. There is one canvas in which I should be able to scale and allow the user to draw on the canvas with mouse clicks. So far, I got scaling for the job, with some examples that I found. The problem is that after scaling, the position of the mouse in my drawing tool is out of order. Before any scaling, I can draw just fine. Here is the code to enlarge:

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

As I said, scaling is not a real problem, but only the root of the problem. Here is the code that determines the mouse position for the drawing tool:

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

I'm sure the problem is in the last block of code, but I'm not sure how to fix it. Any help would be appreciated.

+4
source share
4 answers

I suspect this is a piece of code that relies on some global variables such as currentzoom

So, if I understand this question correctly, the problem is how you use the canvas to control the mouse and zoom. I suspect that when scaling, the DOM places the mouse cursor where it belongs in the picture, since it was originally rendered. Therefore, if you zoom in 200% and place the mouse 100 pixels to the left of the center of the canvas, the canvas will behave as if the mouse was 200 pixels to the left of the center.

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

/ 1 saved if future users want to set the value "1" in currentzoom .

0
source

For Joomla, you can use Mouse Over Zoom, a Joomla extension that lets you view large versions of thumbnails from your Joomla web page. Now you can easily browse image galleries: just move the mouse over thumbnails to view full size images without loading a new page. Download it here http://joomlaboat.com/mouse-over-zoom

Images are automatically resized if they do not fit the window. You can configure the extension, there are many additional options. To download transparent images without a background, simply use .png images.

0
source

Just try this:

 <!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> 

Great for me with a mouse movement. Njoy !!!

0
source

I got the best script to get the mouse position on the canvas:

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

Try it, comment if you have problems.

0
source

Source: https://habr.com/ru/post/1412865/


All Articles