最新的方法在本机JavaScript中的一个画布中获取鼠标位置 [英] Most modern method of getting mouse position within a canvas in native JavaScript

查看:178
本文介绍了最新的方法在本机JavaScript中的一个画布中获取鼠标位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,我知道这个问题已经被问过很多次了。然而,所提供的答案不一致,并且使用各种方法来获得鼠标位置。几个示例:



方法1:

  canvas.onmousemove = function(event){//此对象引用canvas对象
Mouse = {
x:event.pageX - this.offsetLeft,
y:event.pageY - this.offsetTop
}方法2:












$ b

  function getMousePos(canvas,evt){
var rect = canvas.getBoundingClientRect();
return {
x:evt.clientX - rect.left,
y:evt.clientY - rect.top
};方法3:












$ b

  var findPos = function(obj){
var curleft = curtop = 0;
if(obj.offsetParent){
do {
curleft + = obj.offsetLeft;
curtop + = obj.offsetTop;
} while(obj = obj.offsetParent);
}
return {x:curleft,y:curtop};
};方法4:

 


var x;
var y;
if(e.pageX || e.pageY)
{
x = e.pageX;
y = e.pageY;
}
else {
x = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
y = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
}
x - = gCanvasElement.offsetLeft;
y - = gCanvasElement.offsetTop;

等等。



好奇的是哪种方法是最现代的在浏览器支持和方便在画布中获取鼠标位置。或者是那些具有边际影响的事情,上述任何一个是一个好的选择? (是的,我意识到上面的代码是不完全一样的)

解决方案

你的目标画布,所以你只针对最近的浏览器。 br>
所以你可以忘记方法4的pageX的内容。

方法1在嵌套canvas的情况下失败。

方法3就像方法2,但是慢,因为你用手做。



- >>走路的选择是选择2.



不想在每次鼠标移动时调用DOM
:在某些var /属性中缓存boundingRect左边和顶部。



如果 您的网页允许滚动,请不要忘记处理'scroll'事件



坐标以css像素提供: 如果 带有css的画布,
确保其边框为0,并使用offsetWidth和offsetHeight计算正确的
位置。因为你想缓存这些值的性能和避免太多的全局变量,代码如下:

  var mouse = { x:0,y:0,down:false}; 

function setupMouse(){

var rect = cv.getBoundingClientRect();
var rectLeft = rect.left;
var rectTop = rect.top;

var cssScaleX = cv.width / cv.offsetWidth;
var cssScaleY = cv.height / cv.offsetHeight;

function handleMouseEvent(e){
mouse.x =(e.clientX - rectLeft)* cssScaleX;
mouse.y =(e.clientY - rectTop)* cssScaleY;
}

window.addEventListener('mousedown',function(e){
mouse.down = true;
handleMouseEvent(e);
} );

window.addEventListener('mouseup',function(e){
mouse.down = false;
handleMouseEvent(e);
}

window.addEventListener('mouseout',function(e){
mouse.down = false;
handleMouseEvent(e);
}

window.addEventListener('mousemove',handleMouseEvent);
};

最后一个词:性能测试一个事件处理程序,至少,可疑,除非你能确保在每次测试期间执行完全相同的移动/点击。没有办法比上面的代码更快地处理事情。好吧,如果你确定canvas不是css缩放,你可以保存2 muls,但无论如何,现在浏览器的输入处理开销是如此之大,它不会改变一个东西。


First, I know this question has been asked many times. However, the answers provided are not consistent and a variety of methods are used to get the mouse position. A few examples:

Method 1:

canvas.onmousemove = function (event) { // this  object refers to canvas object  
Mouse = {
    x: event.pageX - this.offsetLeft,
    y: event.pageY - this.offsetTop
}
}

Method 2:

function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
  x: evt.clientX - rect.left,
  y: evt.clientY - rect.top
};
}

Method 3:

var findPos = function(obj) {
var curleft = curtop = 0;
if (obj.offsetParent) { 
    do {
       curleft += obj.offsetLeft;
       curtop += obj.offsetTop; 
    } while (obj = obj.offsetParent);
}
return { x : curleft, y : curtop };
};

Method 4:

var x;
var y;
if (e.pageX || e.pageY)
{
    x = e.pageX;
    y = e.pageY;
}
else {
    x = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
    y = e.clientY + document.body.scrollTop + document.documentElement.scrollTop; 
} 
x -= gCanvasElement.offsetLeft;
y -= gCanvasElement.offsetTop;

and so on.

What I am curious is which method is the most modern in terms of browser support and convenience in getting the mouse position in a canvas. Or is it those kind of things that have marginal impact and any of the above is a good choice? (Yes I realize the codes above are not exactly the same)

解决方案

You target canvas, so you target only recent browsers.
So you can forget about the pageX stuff of Method 4.
Method 1 fails in case of nested canvas.
Method 3 is just like Method 2, but slower since you do it by hand.

-->> The way to go is option 2.

Now since you worry about performances, you don't want to call to the DOM on each mouse move : cache the boundingRect left and top inside some var/property.

If your page allows scrolling, do not forget to handle the 'scroll' event and to re-compute the bounding rect on scroll.

The coordinates are provided in css pixels : If you scale the Canvas with css, be sure its border is 0 and use offsetWidth and offsetHeight to compute correct position. Since you will want to cache also those values for performances and avoid too many globals, code will look like :

var mouse = { x:0, y:0, down:false };

function setupMouse() {

    var rect = cv.getBoundingClientRect();
    var rectLeft = rect.left;
    var rectTop = rect.top;

    var cssScaleX = cv.width / cv.offsetWidth;
    var cssScaleY = cv.height / cv.offsetHeight;

    function handleMouseEvent(e) {
        mouse.x = (e.clientX - rectLeft) * cssScaleX;
        mouse.y = (e.clientY - rectTop) * cssScaleY;
    }

    window.addEventListener('mousedown', function (e) {
        mouse.down = true;
        handleMouseEvent(e);
    });

    window.addEventListener('mouseup', function (e) {
        mouse.down = false;
        handleMouseEvent(e);
    });

    window.addEventListener('mouseout', function (e) {
        mouse.down = false;
        handleMouseEvent(e);
    });

    window.addEventListener('mousemove',  handleMouseEvent );
};

Last word : performance testing an event handler is, to say the least, questionable, unless you can ensure that the very same moves/clicks are performed during each test. There no way to handle things faster than in the code above. Well, you might save 2 muls if you are sure canvas isn't css scaled, but anyway as of now the browser overhead for input handling is so big that it won't change a thing.

这篇关于最新的方法在本机JavaScript中的一个画布中获取鼠标位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆