2011-06-19 7 views
2

SVGで描かれたマップは、特定のマウスイベントに基づいて回転する行列変換を使用しています。マップの一部をクリックすると、(回転した画像とは別のグループ要素の)注釈が描画されます。画像全体を回転させることなく、JavaScriptでSVGグループ要素の位置を回転させます。

今、別のアクションとしてそのシフトを行うためにJavaScript関数にイベントを送信するだけで、マップを使ってアノテーションをマップに移動できます。基になるマップを回転して拡大/縮小するときは、同じようなことをしたいのですが、どのように処理するのかは分かりません。明らかに、注釈画像全体を回転させたくないのです。私はちょうど更新されたマップに一致するようにそれをシフトしたい。多分、単一点のX/Y座標に対するマップ変換の効果を計算し、その計算を注釈位置に適用する方法を理解する必要があるようです。私はどのようにそれを行うかを考え出すのに役立つリソースを見つけることができないようです。

ここで私は、私は基本的なマップを操作する方法について話して書いたブログ記事です:それは(私がJavaScriptファイルの場所を移動する)という記事でhttp://justindthomas.wordpress.com/category/flower-nfa/

ライブの例では、今は動作しませんが、私の質問にいくつかの有用な文脈を与えるべきです。

+0

あなた自身の解決策を見つけた場合は、それを回答として入力して受け入れる必要があります。 – Dan

+0

チップをありがとう! –

答えて

1

私は手で数学をやっていました。ここで私は後世のために使用する関数があります:

私はその後、使用回転操作について
getRadiusAngle: function(referenceX, referenceY, centerX, centerY) {     
    var width = centerX - referenceX; 
    var height = centerY - referenceY; 
    var angle, radius; 

    if(centerY > referenceY) { 
     if(centerX > referenceX) { 
      angle = Math.PI - Math.atan(Math.abs(height/width)); 
      radius = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2)); 
     } else if (centerX < referenceX) { 
      angle = Math.atan(Math.abs(height/width)); 
      radius = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2)); 
     } else if (centerX == referenceX) { 
      angle = Math.PI/2; 
      radius = height; 
     } 
    } else if(centerY < referenceY) { 
     if(centerX > referenceX) { 
      angle = Math.PI + Math.atan(Math.abs(height/width)); 
      radius = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2)); 
     } else if (centerX < referenceX) { 
      angle = (2 * Math.PI) - Math.atan(Math.abs(height/width)); 
      radius = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2)); 
     } else if (centerX == referenceX) { 
      angle = Math.PI * 1.5; 
      radius = Math.abs(height); 
     } 
    } else if(centerY == referenceY) { 
     if(centerX > referenceX) { 
      angle = Math.PI; 
      radius = width; 
     } else if (centerX < referenceX) { 
      angle = 0; 
      radius = Math.abs(width); 
     } else if(centerX == referenceX) { 
      angle = 0; 
      radius = 0; 
     } 
    } 

    return({ 
     "radius": radius, 
     "angle": angle 
    }) 
}, 

var calcwidth = annotations[i].getAttribute("calcwidth"); 
var matrix = annotations[i].getCTM(); 

var referenceX = (matrix.e + (calcwidth/2)); 
var referenceY = (matrix.f + 32); 

var ra = this.getRadiusAngle(referenceX, referenceY, pointerX, pointerY); 

var current_angle = ra.angle; 
var radius = ra.radius 

var newX, newY; 
if(radius == 0) { 
    newX = matrix.e; 
    newY = matrix.f; 
} else {  
    var new_angle = current_angle + -radians; 

    newX = (pointerX + (radius * Math.cos(new_angle))) - (calcwidth/2); 
    newY = (pointerY + -(radius * Math.sin(new_angle))) - 32; 
} 

annotations[i].setAttribute("transform", "translate(" 
    + newX + " " + newY + ")"); 

スケーリングのために、私は同様の戦略を使用していました。

関連する問題