2011-09-06 19 views
8

ここで助けが必要です。私は、実験的なWebフォームデザインを行っている数字にうまく対応していないUIデザイナーです。どの入力要素がWebページ上のクリックされたポイントに最も近いかを知る必要があります。私は点で最も近い隣人をする方法を知っていますが、入力要素は点ではない矩形ですので、私は立ち往生しています。クリックしたポイントに最も近い項目を見つける

私はjQueryを使用しています。私はちょっとこの小さな仲間に助けが必要です。実験を終えたら、私がしていることを皆さんにお伝えします。

UPDATE

私はそれが動作する方法を考えました。この図を見て:

Nearest

各矩形は有意である(むしろ又は4点と4線)8点を有しています。 x値のみが水平ポイント(赤い点)で有意であり、y値のみが垂直ポイント(緑色の点)で有意です。 xとyの両方がコーナーで重要です。

オレンジ色の十字は、私のユースケースではマウスのクリックに対して測定される点です。薄い紫色の線は、オレンジ色の十字線とそれが可能な最も近い点の間の距離です。

だから...どのオレンジ色の十字線についても、すべての四角形の8つの点のそれぞれをループして、各矩形の最も近い辺または角をオレンジ色の十字線に近づけることができます。最も小さい値の矩形が最も近い矩形です。

私はそれを概念化して視覚化することはできますが、コードに入れることはできません。助けて!

+0

あなたの最近傍アルゴリズムで矩形を表す4点を使用します。または、cx =(left + width)/ 2、cy =(top + height)/ 2の矩形の中心点を使用します。 –

+0

jsfiddle.netで何かコードを投稿したり、何かすることができますか?そうでなければ少し仮説です... – T9b

+0

問題を説明するイラストを追加し、それがどのように解決されるかを説明しました。 –

答えて

3

あなたのアルゴリズムは正しいです。アルゴリズムではなくコードで助けが必要なので、ここにコードがあります:

これは最も効率的ではありません。しかし、それは動作します。

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

ちょうど私が必要なもの。コードをどのような幅と高さに適応させるには? –

+1

任意の幅と高さに適応可能です。 JavaScriptの上部にボタンのサイズとクリックの座標を定義するだけで済みます。 – uzyn

+0

クール感謝の男。 –

2

すべての長方形の最も近いコーナーポイントを検索できます。これはほとんどの場合に機能し、実装が迅速かつ容易です。長方形が規則的なグリッド上に配置されている限り、この方法は最も近い長方形を与えます。

0

私はそれを行う方法は数字ではなく、論理を持っています。

私はそれぞれの場合は、この操作を行うことができ、「xが最も近い要素であるならば、私は他の場所でクリックしたときに何かをした後のxに何かをする」、あなたが言う何かで終わるしたいこと

を想定していますあなたが何かしたい要素は、単純な<div>のコンテナで扱いたい要素よりも大きかったが、それに含まれるオブジェクトとそれに最も近い次のオブジェクトの中間よりも大きくはなかった。実際にはグリッド。

すべてのコンテナに同じクラスを割り当てます。

次に、「yをクリックするとxに何かする」と言うと、各コンテナにどの要素があるのか​​はすでに分かっているはずです。

あなたは2Dグリッド上の2点間の距離を見つけたい場合は、次の式を使用することができます...

+0

余分なマークアップは必要ありません。 –

0

を私はコードを書くと思いますが、私は仕事を残している:

( B. -

distanceY = AyのBxを - 2次元点& B)

distanceX =アックス用Y

totalDistance =平方根((distX * distX)+(distY * distY))

あなたは2点間の距離を確認することができたら、あなたはかなり簡単にあなたのマウスクリックがあまりにも最も近くなる長方形の角を把握することができます。あなたの目的のアルゴリズムを最適化するためにあなたができることはたくさんありますが、これはあなたに良いスタートを与えるはずです。

0

笑、質問はなぜ形を考えているのですか? あなたの質問は本当に「私が座標をクリックすると、私に最も近いノードを見つける/私のクリックを指す」ということです。これは様々なノードを通って距離を計算する問題です。あなたは親形状権を得ることができる最も近い点を見つけたら

同じX、利用yの差

もし同じY、使用X差

の場合は、そうでない場合は

をhypotheneuseでしょうか? これは、最も近いポイントにスナップしようとしているために機能します。だから、星のような空想的な形でも動作します。

2

比較的新しいelementFromPoint() APIの追加は、私たちは、潜在的に軽いアプローチを代替手段を取ることができます:我々は、我々が最も近い要素を見つけるまで大きなサークルで行く、マウスカーソルを中心にテストを打つことができます。

ここでは、非生産のクイックサンプルをhttp://jsfiddle.net/yRhhs/(Chrome/SafariはwebkitMatchesSelectorを使用しているためのみ)にまとめました。アルゴリズムを視覚化する際に使用されるドットのため、パフォーマンスが遅くなることがあります。

コードのコアは、光パフォーマンスの最適化とイベントバインディングの外側に、このビットは次のとおり

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; 
      } 
     }); 
} 
関連する問題