Javascript 查找离单击点最近的元素
这里需要帮助。我是一个UI设计师,不擅长做实验性的web表单设计,我需要知道哪个输入元素最接近网页上的点击点。我知道如何用点做最近邻,但输入元素是矩形而不是点,所以我被卡住了 我正在使用jQuery。我只需要帮我做这个小算法。一旦我做完实验,我会告诉你们我在做什么 更新 我在想它是如何工作的。请看这个图表: 每个矩形有8个点(或者更确切地说是4个点和4条线),它们是有意义的。只有x值对水平点(红点)有效,只有y值对垂直点(绿点)有效。x和y对角都很重要 橙色十字是我的用例中鼠标点击的测量点。浅紫色线是橙色十字和可能最近点之间的距离 所以…对于任何给定的橙色十字,在每个矩形的8个点中循环,以找到每个矩形最接近橙色十字的最近边或角。值最小的矩形是最近的矩形Javascript 查找离单击点最近的元素,javascript,jquery,algorithm,math,nearest-neighbor,Javascript,Jquery,Algorithm,Math,Nearest Neighbor,这里需要帮助。我是一个UI设计师,不擅长做实验性的web表单设计,我需要知道哪个输入元素最接近网页上的点击点。我知道如何用点做最近邻,但输入元素是矩形而不是点,所以我被卡住了 我正在使用jQuery。我只需要帮我做这个小算法。一旦我做完实验,我会告诉你们我在做什么 更新 我在想它是如何工作的。请看这个图表: 每个矩形有8个点(或者更确切地说是4个点和4条线),它们是有意义的。只有x值对水平点(红点)有效,只有y值对垂直点(绿点)有效。x和y对角都很重要 橙色十字是我的用例中鼠标点击的测量点。浅
我可以将其概念化和可视化,但不能将其转化为代码。救命啊 您可以查找所有矩形中最近的角点。这在大多数情况下都有效,而且快速且易于实现。只要矩形在规则网格上对齐,此方法将为您提供最接近的矩形。我的方法不是使用数字,而是使用逻辑 我假设你想得到这样的结果,“如果x是最近的元素,那么当我点击其他地方时,做些什么,然后对x做些什么” 如果要处理的每个元素都位于简单的
容器中,该容器比要处理的元素大,但不超过它所包含的对象和它的下一个最近对象之间的一半,则可以执行此操作。实际上是一个网格
将所有容器设为同一类
然后,您可以说,“如果单击y,则对x执行某些操作”,您将已经知道每个容器中有哪个元素
我将编写代码,但我将离开工作…如果您想在二维网格上查找两点之间的距离,可以使用以下公式: (对于二维点A和B) 距离x=A.x-B.x 距离y=A.y-B.y 总距离=平方根((distX*distX)+(distY*distY))
一旦你可以检查两点之间的距离,你就可以很容易地找出你鼠标点击的哪个矩形角是最近的。你可以做很多事情来优化你想要的算法,但这应该给你一个好的开始。哈哈,问题是你为什么要考虑形状? 你的问题实际上是“如果我点击一个坐标,找到离我点击最近的节点/点”,这是一个遍历各个节点并计算距离的问题 如果X相同,则使用y差 如果y相同,则使用x差 否则使用抵押权 一旦找到最近的点,就可以得到正确的父图形?
这将起作用,因为您正在尝试捕捉到最近的点。因此,它甚至可以处理像星星这样的奇特形状。您的算法是正确的。因为您需要的是代码方面的帮助,而不是算法方面的帮助,下面是代码: 它可能不是最有效的。但它是有效的
// Define the click
var click = Array(-1, -2); // coodinates in x,y
// Define the buttons
// Assuming buttons do not overlap
var button0 = Array(
Array(0, 0), // bottom-left point (assuming x is horizontal and y is vertical)
Array(6, 6) // upper-right point
);
var button1 = Array(
Array(10, 11),
Array(17, 15)
);
var button2 = Array(
Array(-8, -5),
Array(-3, -1)
);
// Which button to trigger for a click
i = which(click, Array(button0, button1, button2));
alert(i);
function which(click, buttons){
// Check if click is inside any of the buttons
for (i in buttons){
var button = buttons[i];
var bl = button[0];
var tr = button[1];
if ( (click[0] >= bl[0] && click[0] <= tr[0]) &&
(click[1] >= bl[1] && click[1] <= tr[1]) ){
return i;
}
}
// Now calculate distances
var distances = Array();
for (i in buttons){
var button = buttons[i];
var bl = button[0];
var tr = button[1];
if ( (click[0] >= bl[0] && click[0] <= tr[0])) {
distances[i] = Math.min( Math.abs(click[1]-bl[1]), Math.abs(click[1]-tr[1]) );
}
else if ( (click[1] >= bl[1] && click[1] <= tr[1])) {
distances[i] = Math.min( Math.abs(click[0]-bl[0]), Math.abs(click[0]-tr[0]) );
}
else{
distances[i] = Math.sqrt(
(Math.pow(Math.min( Math.abs(click[0]-bl[0]), Math.abs(click[0]-tr[0]) ), 2)) +
(Math.pow(Math.min( Math.abs(click[1]-bl[1]), Math.abs(click[1]-tr[1]) ), 2))
);
}
}
var min_id = 0;
for (j in distances){
if (distances[j] < distances[min_id]){
min_id = j;
}
}
return min_id;
}
//定义单击
var click=Array(-1,-2);//x,y中的坐标
//定义按钮
//假设按钮不重叠
var button0=数组(
数组(0,0),//左下角点(假设x是水平的,y是垂直的)
数组(6,6)//右上角点
);
var button1=数组(
阵列(10,11),
阵列(17,15)
);
var button2=数组(
阵列(-8,-5),
数组(-3,-1)
);
//单击要触发哪个按钮
i=哪个(单击,数组(按钮0,按钮1,按钮2));
警报(一);
功能(单击、按钮){
//检查单击是否在任何按钮内
用于(按钮中的i){
var按钮=按钮[i];
var bl=按钮[0];
var tr=按钮[1];
如果((单击[0]>=bl[0]&&click[0]=bl[1]&&click[1]=bl[0]&&click[0]=bl[1]&&click[1]相对新的API的添加让我们可以采取另一种可能更轻的方法:我们可以围绕鼠标光标点击test,在更大的圆圈中进行,直到找到最近的元素
我在这里总结了一个快速的非生产性示例:(Chrome/Safari只是因为使用了WebKitMatcheSelector)。由于在可视化算法时使用了点,性能可能会变得滞后
除了轻型性能优化和事件绑定之外,代码的核心是:
function hitTest(x, y){
var element, i = 0;
while (!element){
i = i + 7; // Or some other threshold.
if (i > 250){ // We do want some safety belts on our while loop.
break;
}
var increment = i/Math.sqrt(2);
var points = [
[x-increment, y-increment], [x+increment, y-increment],
[x+increment, y+increment], [x-increment, y+increment]
];
// Pop additional points onto the stack as the value of i gets larger.
// ...
// Perhaps prematurely optimized: we're using Array.prototype.some to bail-out
// early once we've found a valid hit target.
points.some(function(coordinates){
var hit = document.elementFromPoint.apply(document, coordinates);
// isValidHit() could simply be a method that sees whether the current
// element matches the kinds of elements we'd like to see.
if (isValidHit(hit)){
element = hit;
return true;
}
});
}
在最近邻算法中使用表示矩形的4个点。或者使用矩形的中心点cx=(左+宽)/2,cy=(顶+高)/2.你有没有可能在jsfiddle.net中发布一些代码或做点什么?这都是假设的,否则…添加了一个说明来解释问题以及如何解决。太好了。这正是我需要的。我如何使代码适应任何宽度和高度?它适应任何宽度和高度。你只需要定义尺寸JavaScript顶部的按钮和点击坐标。