2012-01-20 24 views
9

svgポリゴンをマウスで動的にサイズ変更してドラッグする方法を見つけるのが苦労しています。残念ながら、jQueryUiはsvg要素では機能しません。私はRaphaelライブラリもチェックしましたが、これを実現するためのドキュメント/スニペットは見つかりません。SVGポリゴンを動的にサイズ変更してドラッグする

SVGを使用する以外に、ポリゴングラフィックを動的にサイズ変更してドラッグする方法はありますか?

答えて

13

自分でSVG要素を操作できます。特に、ポリゴンのポイントを見つけて、jQueryでドラッグ可能にしたHTML要素ハンドルを追加することができます。 (私は、あなたが持っている問題は、jQuery UIがSVG測位モデルでは動作しないことを前提としています)。ここで私が書いた完全な例があります(Safari 5とFirefox 9でテスト済み)。

(免責事項:私はjQueryのの通常のユーザーではないよ、このコードはすべてのためのjQueryを使用していないほかの方法でunidiomaticてもよい)

<!DOCTYPE html> 
 
<html><head> 
 
    <title>untitled</title> 
 

 
    <style type="text/css" media="screen"> 
 
    .handle { 
 
     position: absolute; 
 
     border: 0.1em solid black; 
 
     width: 1em; 
 
     height: 1em; 
 
    } 
 
    </style> 
 
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> 
 
    <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js"></script> 
 

 
    <script type="text/javascript"> 
 
    function draggablePolygon(polygon) { 
 
    var points = polygon.points; 
 
    var svgRoot = $(polygon).closest("svg"); 
 
    
 
    for (var i = 0; i < points.numberOfItems; i++) { 
 
     (function (i) { // close over variables for drag call back 
 
     var point = points.getItem(i); 
 

 
     var handle = document.createElement("div"); 
 
     handle.className = "handle"; 
 
     document.body.appendChild(handle); 
 

 
     var base = svgRoot.position(); 
 
     // center handles over polygon 
 
     var cs = window.getComputedStyle(handle, null); 
 
     base.left -= (parseInt(cs.width) + parseInt(cs.borderLeftWidth) + parseInt(cs.borderRightWidth))/2; 
 
     base.top -= (parseInt(cs.height) + parseInt(cs.borderTopWidth) + parseInt(cs.borderBottomWidth))/2; 
 

 
     handle.style.left = base.left + point.x + "px"; 
 
     handle.style.top = base.top + point.y + "px"; 
 

 
     $(handle).draggable({ 
 
      drag: function (event) { 
 
      setTimeout(function() { // jQuery apparently calls this *before* setting position, so defer 
 
       point.x = parseInt(handle.style.left) - base.left; 
 
       point.y = parseInt(handle.style.top) - base.top; 
 
      },0); 
 
      } 
 
     }); 
 
     }(i)); 
 
    } 
 
    } 
 
    </script> 
 
</head><body> 
 
    <p> 
 
    (Offset to test) 
 
    <svg id="theSVG" width="500" height="500" style="border: 2px inset #CCC;"> 
 
     <polygon id="x" points="200,200 100,100 100,1" fill="green" /> 
 
     <polygon id="y" points="200,200 100,100 1,100" fill="red" /> 
 
    </svg> 
 
    </p> 
 
    <script type="text/javascript"> 
 
    draggablePolygon(document.getElementById("x")); 
 
    draggablePolygon(document.getElementById("y")); 
 
    </script> 
 

 
</body></html>

ます。また、イベントを添付することができハンドラをSVGポリゴンにドラッグしてドラッグする(私はテストしたが、これはうまくいくかもしれない)が、非典型的なUIであり、おそらくトリッキーなポリゴンの現在の境界をクリックしてヒットテストを実装する必要がある。

このため、onmousedownハンドラをポリゴン要素に追加します。その後、そのポイントを取得し、クリック位置の範囲内にあるものを見つけ出し、マウスの最初の位置を保存してからonmousemoveハンドラにマウスの位置が変わるとポイントのxyを変更します。

+0

ありがとうございました!私は境界内でドラッグすることに取り組んでいます。まさに私が望むものです。 また、私はsvg-textでこれらのポリゴンにラベルを付けようとしていますが、ポリゴンのサイズを変更しながらテキストの位置を更新する方法を理解できませんでした。何かヒントを教えてもらえますか? – user1159545

+1

もちろん、私はヒントを追加しました。残念ながら、最初に書いたコードは保存しませんでした。 –

+0

ちょっと、私は問題を直面しています。ポリゴンのサイズを変更している間、ポリゴンの座標を更新する必要があります。 firebugでサイズ変更したポリゴン要素を調べると、サイズ変更されたにもかかわらず古い点が残っています。どのようにこれを解決するための任意のアイデア? – user1159545

関連する問題