2011-09-06 38 views
8

Cần trợ giúp ở đây. Tôi là một nhà thiết kế giao diện người dùng không giỏi về số lượng thiết kế biểu mẫu web thử nghiệm và tôi cần biết yếu tố đầu vào nào gần nhất với điểm được nhấp trên trang web. Tôi biết làm thế nào để làm hàng xóm gần nhất với điểm nhưng các yếu tố đầu vào là hình chữ nhật không điểm vì vậy tôi bị mắc kẹt.Tìm phần tử gần điểm nhấn nhất

Tôi đang sử dụng jQuery. Tôi chỉ cần giúp đỡ với bản ngã nhỏ này. Khi tôi hoàn thành xong thử nghiệm của mình, tôi sẽ cho các bạn thấy những gì tôi đang làm.

CẬP NHẬT

Tôi nghĩ về nó như thế nào có thể làm việc. Nhìn vào sơ đồ này:

Nearest

Mỗi hình chữ nhật có 8 điểm (hay đúng hơn là 4 điểm và 4 dòng) mà là rất lớn. Chỉ giá trị x là đáng kể cho các điểm ngang (dấu chấm màu đỏ) và chỉ giá trị y là đáng kể cho các điểm dọc (chấm màu xanh lá cây). Cả x và y đều đáng kể cho các góc.

Vượt cam là các điểm cần đo lường - số lần nhấp chuột trong trường hợp sử dụng của tôi. Các đường màu tím nhạt là khoảng cách giữa chữ thập màu cam và có thể là điểm gần nhất.

Vì vậy… đối với bất kỳ đường chéo cam nào, hãy lặp qua từng điểm trong 8 điểm của mỗi hình chữ nhật để tìm cạnh hoặc góc gần nhất của mỗi hình chữ nhật với đường chéo màu cam. Hình chữ nhật có giá trị thấp nhất là hình chữ nhật gần nhất.

Tôi có thể khái niệm hóa và trực quan hóa nó nhưng không thể đưa nó vào mã. Cứu giúp!

+0

Sử dụng 4 điểm đại diện cho một hình chữ nhật trong thuật toán láng giềng gần nhất của bạn. Hoặc sử dụng điểm trung tâm của hình chữ nhật cx = (left + width)/2, cy = (top + height)/2. –

+0

bất kỳ cơ hội nào bạn có thể đăng một số mã hoặc làm điều gì đó trong jsfiddle.net? đó là tất cả một chút giả định nếu không ... – T9b

+0

Thêm một minh họa để giải thích vấn đề và làm thế nào nó có thể được giải quyết. –

Trả lời

3

Thuật toán của bạn là chính xác. Vì bạn cần trợ giúp về mã và không có trong thuật toán, đây là mã:

Nó có thể không hiệu quả nhất. Nhưng nó đã có tác dụng.

// 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; 
} 
+0

Tuyệt vời. Chỉ cần những gì tôi cần. Làm cách nào để làm cho mã có thể thích ứng với bất kỳ chiều rộng và chiều cao nào? –

+1

Có thể thích ứng với bất kỳ chiều rộng và chiều cao nào. Bạn sẽ chỉ phải xác định kích thước của các nút và tọa độ của nhấp chuột ở phần trên cùng của JavaScript. – uzyn

+0

Cảm ơn người đàn ông tuyệt vời. –

2

Bạn có thể tìm điểm góc gần nhất của tất cả các hình chữ nhật. Điều này làm việc trong hầu hết các trường hợp, là nhanh chóng và dễ thực hiện. Miễn là hình chữ nhật của bạn được căn chỉnh trên lưới thường xuyên, phương pháp này cung cấp cho bạn hình chữ nhật gần nhất.

0

Cách tôi làm điều đó không phải là số, nhưng với logic.

Tôi giả định rằng bạn muốn kết thúc với cái gì mà nói, "nếu x là yếu tố gần nhất sau đó làm điều gì đó khi tôi nhấp vào nơi khác sau đó làm điều gì đó để x"

Bạn có thể làm điều này nếu mỗi người trong số các phần tử bạn muốn làm gì đó ở trong các vùng chứa đơn giản là <div> lớn hơn phần tử bạn muốn xử lý, nhưng không lớn hơn nửa chừng giữa đối tượng chứa và đối tượng gần nhất tiếp theo. Một mạng lưới trong thực tế.

cung cấp tất cả các vùng chứa cùng một lớp.

Sau đó, bạn có thể nói, "nếu y được nhấp vào, hãy làm điều gì đó với x", bạn đã biết phần tử nào nằm trong mỗi vùng chứa.

Tôi muốn viết mã nhưng tôi rời khỏi công việc ...

+0

Tôi không muốn đánh dấu thêm. –

0

Nếu bạn muốn tìm khoảng cách giữa hai điểm trên một mạng lưới 2D, bạn có thể sử dụng công thức sau:

(cho điểm 2D Một & B)

distanceX = Axe - Bx

distanceY = Ay - B.y

totalDistance = căn bậc hai ((distX * distX) + (distY * distY))

Một khi bạn có thể kiểm tra khoảng cách giữa hai điểm bạn có thể khá dễ dàng tìm ra những hình chữ nhật góc click chuột của bạn là gần quá. Có rất nhiều điều bạn có thể làm để tối ưu hóa thuật toán dự định của mình, nhưng điều này sẽ cho bạn một khởi đầu tốt.

0

lol, câu hỏi đặt ra là tại sao bạn lại nghĩ đến hình dạng? câu hỏi của bạn thực sự là "nếu tôi nhấp vào một tọa độ, hãy tìm cho tôi nút/điểm gần nhất với nhấp chuột của tôi", đó là vấn đề đi qua các nút khác nhau và tính khoảng cách.

Nếu cùng X, sử dụng y chênh lệch

Nếu cùng kỳ năm trước, sử dụng sự khác biệt x

nếu không sử dụng hypotheneuse

khi bạn tìm thấy điểm gần nhất bạn có thể lấy hình dạng cha mẹ phải không? Điều này sẽ hoạt động vì bạn đang cố gắng chụp nhanh điểm gần nhất. Vì vậy, nó thậm chí sẽ làm việc với các hình dạng lạ mắt như sao.

2

Việc bổ sung một cách tiếp cận mới, có khả năng nhẹ hơn: chúng tôi có thể thử nghiệm xung quanh con trỏ chuột, đi theo vòng tròn lớn hơn cho đến khi tìm được phần tử gần nhất.

Tôi kết hợp một ví dụ nhanh, không sản xuất tại đây: http://jsfiddle.net/yRhhs/ (Chrome/Safari chỉ do sử dụng webkitMatchesSelector). Hiệu suất có thể bị lag do các dấu chấm được sử dụng trong việc hình dung thuật toán.

Cốt lõi của mã này, ngoài việc tối ưu hiệu suất ánh sáng và gán sự kiện, là bit này:

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; 
      } 
     }); 
} 
Các vấn đề liên quan