2016-07-17 7 views
2

私の問題は、私は要素をドラッグすると、要素はカーソルの後ろにあるので、潜在的に比率の問題のように見える?インタラクトJS、ビューボックス内のsvg要素をドラッグしますか?

screen grab of the weird movement

コード:

interact('.element', { 
     context: '.lipstick__plane' 
    }) 
     .draggable({ 
      snap: { 
       targets: [ 
        interact.createSnapGrid({x: 10, y: 10}) 
       ], 
       range: Infinity 
      }, 
      inertia: true, 
      restrict: { 
       restriction: '#lipstick__plane__main', 
       elementRect: {top: 0, left: 0, bottom: 1, right: 1}, 
       endOnly: true 
      } 
     }) 
     .on('dragmove', function (event) { 
      $scope.$apply(function() { 
       var target = event.target, 
        x = (parseFloat(target.getAttribute('x')) || 0) + ((1020/window.outerWidth) * event.dx), 
        y = (parseFloat(target.getAttribute('y')) || 0) + ((1020/window.outerHeight) * event.dy); 

       var indx = event.target.getAttribute('data-index'); 

       _.set($scope.stage.elements[indx], 'meta.XCord', x); 
       _.set($scope.stage.elements[indx], 'meta.YCord', y); 
      }); 
     }); 

私は、カーソルにそれが近い得ている、そこにダイビングですが、私は一日中番号をしようとすることができ...

マイSVG初期化ブロック:私は思います

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1024 1024" width="1024px" height="1024px" xml:space="preserve" id="lipstick__plane__main"> 

一つのことが問題かもしれないが、私は疑います新しくxy属性を取得するために、クエリーの後にAngularダイジェストが発生するのでしょうか?

+0

svg内に変換が適用されているかどうか確認しましたか?翻訳が拡大縮小されているかのように見えます。変換を行っているラッピンググループによって何が起こるかわかります.... – philipp

+0

ラッパーdivに適用される 'width:calc(100vw - 200px)'と 'display:block ;幅:100%; height:auto; 'をsvg要素自体に追加します。 –

+0

それはスケーリングの問題です。それは1024ピクセルのサイズで表示されるsvgで試してみてください。うまくいくはずです。その場合、画面変換行列を使用して翻訳ベクトルをスケーリングする必要があります – philipp

答えて

2

この問題は、SVGの内部設定が1024ピクセルの幅と高さに設定されているが、異なるサイズで表示されているために発生します。この場合は小さいので、ドラッグからの変換が縮小され、要素がカーソルより遅いようです。

これに対処するには、それに応じて翻訳ベクトルを拡大縮小する必要があります。

  1. クエリSVGの結果バウンディングボックスbbgetClientBoudingRect
  2. sx = bb.width/1024 // (original size), same for sy

か、によってあなたがsvg elementにアクセスすることができた場合:スケーリングはsxsyは可能性が要因獲得に向かう途中で道.getScreenCTM()を使用して変換行列を取得できます。これは次のようになります。sxdsyを表すべき

​​

a

編集は、私は、セットアップの基本的なアプローチを示して少しいじるhere持っています。全体として、解はベクトルの行列変換であり、解くパズルは正しい行列を見つけることです。すべてのSVG要素は、独自のを持っているかもしれないので、変換、またはグループの子として、その親から変換し得るかもしれ、それは使用するのに十分ではないルート<svg>C urrent T ransformation M ATRIX。各SVGElementSVGLocatableインターフェイスを実装している理由は、ルート<svg>からSVGElement(getCTM)への変換、またはSVGElement(getScreenCTM())への変換を可能にするものです。反対の方向は、それらの行列の逆数によって記述される。 (explanation on SO

let svg = document.querySelector('svg'), 
    e  = svg.querySelector('.myelement'), 
    ctm = e.getScreenCTM(), 
    point = svg.createSVGPoint(), 
    point2; 

point.x = …; 
point.y = …; 

point2 = point.matrixTransform(ctm); 

結論する:それは(少なくともべきで)回転ように、CSSでSVGに適用することができた、アカウントにすべての変換を取るので、変換行列を使用して、好適な方法であるべきです、 3D変換などがあります。より具体的にすると、変換したい要素が分かっているほど精度が高くなります。

+0

このスケーリングベクトルが得られたら、マウスを動かすときの 'x + = sx'と' y + = sy'座標としてこれを使いますか? –

1

SVGがスケーリングされているため、マウス座標はSVG座標で1:1ではありません。ドラッグされたオブジェクトの正しい位置を取得するには、マウス/スクリーン座標をSVG座標に変換する必要があります。

変換の方法については、この質問を参照してください。

How do you convert screen coordinates to document space in a scaled SVG?

関連する問題