使用javascript/jQuery查找最接近鼠标位置的网格坐标

12
我想做的是在页面上制作一个由不可见坐标构成的网格,这些坐标等距离排列。当触发onclick事件时,我希望一个<div>被放置在最接近指针的网格坐标上。以下是大致的想法:

alt text

我已经跟踪了鼠标坐标和放置<div>的位置,现在遇到的问题是如何处理坐标网格问题。
首先,我应该将所有坐标放入数组中,然后将我的点击坐标与之比较吗?
或者,由于我的网格坐标遵循一定规则,我是否可以找出最接近点击坐标的是哪个坐标,它是我的间距是多少的倍数?
然后,我从哪里开始计算最接近的网格点坐标?最好的方法是什么?
谢谢!
3个回答

8
在确定最近的网格点方面 - 例如,每个块是10x10像素 - 要获取网格索引,您只需将它们除以 -
  1. 单击 [237; 112]
  2. 10x10块
  3. 网格索引 = [237/10; 112/10] = [23.7; 11.2]
  4. 四舍五入以获取“最近”的块索引为24,11
如果您需要存储数据,您可以在单击时将网格坐标推送到数组中以供以后参考。

好的,听起来棒极了!让我确认一下是否完全理解。基本上,每个网格点都有一个标识性的参考值[0->c, 0->r]( c=列数, r=行数)。然后我只需要将网格点参考值转换为实际坐标即可。xref=3; startxcoord=10; spacing=50; xcoord=(xref*spacing)+startxcoord; - Acorn
一切都应该像这样解释。谢谢! - Clark

7

我能否像查找哪个坐标是我的间距的倍数一样,找到最靠近单击坐标的坐标?

可以。网格的整个目的就是可以使用简单的算术计算,而不必携带一大堆任意点的数组。

我从何处开始计算最接近的网格点坐标?

每个轴都进行简单的四舍五入除法即可。

#canvas { position: relative; width: 100px; height: 100px; border: solid red 1px; }
#nearest { position: absolute; width: 10px; height: 10px; background: yellow; }

<div id="canvas"><div id="nearest"></div></div>

var gridspacing= 10;
$('#canvas').mousemove(function(event) {
    var pos= $(this).offset();
    var gridx= Math.round((event.pageX-pos.left)/gridspacing);
    var gridy= Math.round((event.pageY-pos.top)/gridspacing);
    $('#nearest').css('left', (gridx-0.5)*gridspacing+'px').css('top', (gridy-0.5)*gridspacing+'px');
});

漂亮的例子!在网页上它正在运行:http://acorn.host22.com/snappy.html - Acorn

5
我最初写的答案跟bobince的类似,但他比我写的更好。虽然他的版本有些问题(不过仍然是一个非常棒的回答)。
我假设你需要一个没有HTML标记的网格(也就是没有像表格一样的标记),bobince提供了解决方案。在这种情况下,代码可以被优化,以达到跨浏览器兼容性、可读性、错误处理和速度等要求。
因此,我建议代码应该更像这样:
#canvas { position: relative; width: 100px; height: 100px; border: solid red 1px; }
#nearest { position: absolute; width: 10px; height: 10px; background: yellow; }

<div id="canvas"><div id="nearest"></div></div>

var
    canvasOffset = $("div#canvas").offset(),
    // Assuming that the space between the points is 10 pixels. Correct this if necessary.
    cellSpacing = 10;

$("div#canvas").mousemove(function(event) {
    event = event || window.event;
    $("div#nearest").css({
        top: Math.round((mouseCoordinate(event, "X") - canvasOffset.left) / cellSpacing) * cellSpacing + "px",
        left: Math.round((mouseCoordinate(event, "Y") - canvasOffset.top) / cellSpacing) * cellSpacing + "px"
    });
});

// Returns the one half of the current mouse coordinates relative to the browser window.
// Assumes the axis parameter to be uppercase: Either "X" or "Y".
function mouseCoordinate(event, axis) {
    var property = (axis == "X") ? "scrollLeft" : "scrollTop";
    if (event.pageX) {
        return event["page"+axis];
    } else {
        return event["client"+axis] + (document.documentElement[property] ? document.documentElement[property] : document.body[property]);;
    }
};

mouseCoordinate()函数是这两个函数的简化版本:

function mouseAxisX(event) {
    if (event.pageX) {
        return event.pageX;
    } else if (event.clientX) {
        return event.clientX + (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft);
    }
};

function mouseAxisY(event) {
    if (event.pageY) {
        return event.pageY;
    } else if (event.clientY) {
        return event.clientY + (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop);
    }
};

我非常喜欢你的项目想法,也许我会自己做类似的东西:D


哦,对了,在获取鼠标位置时我忘记了浏览器兼容性的问题!如果你感兴趣,这是我目前想出来的东西:http://acorn.host22.com/tiles2.html非常丰富多彩! - Acorn
刚刚意识到还有另外一件事情。您需要考虑窗口的调整大小,这将需要通过添加以下内容来反映在canvasOffset中: $ (window) .resize(function(){canvasOffset = $(“#canvas”).offset()}); - Acorn
好的点子,完全正确。调整窗口大小将导致画布偏移混乱。不过有一件事让我想知道,你正在使用jQuery,但仍然在没有jQuery的情况下进行了很多可以使用jQuery优化的工作? - Sune Rasmussen
我对jQuery和javascript都是初学者,所以我的脚本中可能会出现一些愚蠢的问题并不感到意外。具体来说呢?评论可能不是讨论我的脚本最容易的地方,但我会非常感激您能给出的任何建议!我在我的个人资料中添加了一个电子邮件地址。 - Acorn
1
那我会写封邮件给你。我会把你的代码加上我的一些修改,这样你就能看到你哪里做错了 ;) - Sune Rasmussen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接