简体   繁体   English

缩放后确定鼠标在 HTML5 画布上的位置

[英]Determining mouse position on an HTML5 canvas after zooming

I'm working on developing some software in HTML5 which involves the use of canvases.我正在开发一些涉及使用画布的 HTML5 软件。 There is one canvas in which I need to be able to zoom and allow the user to doodle on the canvas on mouse clicks.有一个画布,我需要能够在其中缩放并允许用户通过单击鼠标在画布上涂鸦。 So far, I have gotten the zoom to work, with help from some examples I found.到目前为止,在我找到的一些示例的帮助下,我已经使缩放工作了。 The problem is that after zooming, the mouse position on my drawing tool is out of whack.问题是缩放后,我的绘图工具上的鼠标位置不正常。 Before any zooming, I can draw just fine.在任何缩放之前,我可以画得很好。 Here is the code for the 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);
        }

Like I said, the zoom is not the actual problem, just the root of the problem.就像我说的,变焦不是实际问题,只是问题的根源。 Here is the code which determines 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 that the problem lies in the latter block of code, but I'm not sure out to fix it.我确定问题出在后面的代码块中,但我不确定要解决它。 Any help would be appreciated.任何帮助,将不胜感激。

I suspect this is a snippet of code that relies on some global variables like currentzoom我怀疑这是一段代码,它依赖于一些全局变量,如currentzoom

So, if I understand this question right, the problem lies in how you are using the canvas for both mouse control and zooming.所以,如果我理解这个问题是正确的,问题在于您如何使用画布进行鼠标控制和缩放。 I suspect that when you zoom, the DOM is placing the mouse cursor where it belongs on the picture as it was initially rendered.我怀疑当你缩放时,DOM 将鼠标光标放置在它最初呈现的图片上它所属的位置。 So if you zoom in 200% and place the mouse 100 pixels left of center of the canvas, the canvas will behave as though the mouse was 200 pixels to the left of center.因此,如果放大 200% 并将鼠标放置在画布中心左侧 100 像素处,画布将表现得好像鼠标位于中心左侧 200 像素处。

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

The / 1 is preserved in case future users want to set a non "1" value to currentzoom .保留/ 1以防将来用户想要将非“1”值设置为currentzoom

For Joomla site you can use Mouse Over Zoom - it's a Joomla Extension that enables you to view bigger versions of the thumbnails from your Joomla webpage.对于 Joomla 站点,您可以使用鼠标悬停缩放 - 它是一个 Joomla 扩展,可让您从 Joomla 网页查看更大版本的缩略图。 Now you can browse images galleries with ease: just move the mouse cursor over thumbnails to view images in their full size without loading a new page.现在您可以轻松浏览图片库:只需将鼠标光标移到缩略图上即可查看完整尺寸的图片,而无需加载新页面。 Download it here http://joomlaboat.com/mouse-over-zoom在这里下载http://joomlaboat.com/mouse-over-zoom

Pictures are automatically resized if they don't fit the window.如果图片不适合窗​​口,图片会自动调整大小。 You can customize the extension there are a lot of additional options.您可以自定义扩展,还有很多附加选项。 In order to load transparent images, without background just use .png images.为了加载没有背景的透明图像,只需使用 .png 图像。

Just try this out:试试这个:

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

Works perfect for me with mouse movement track.. Njoy!!!非常适合我的鼠标移动轨迹.. Njoy !!!

I got a better script to get 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 out, comment if any issues..试试看,如果有问题评论..

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM