2017-05-16 6 views
1

svg.jsを使用してドラッグアンドドロップを実装し、グラフィック要素の外観を操作したいと思います。主に動作しますが、なぜ私は完全に理解できません。svg.js svg.draggable.jsと外観の操作

私は自分のアプリの状況を説明するために私のアプリから重要な部分を抽出しました。そこを遊び、その効果を見ることは可能です。

https://jsfiddle.net/bwl21/ex8dcxtm/12/

SVGは自分のアプリケーションによって文字列として生成されます。 jsfiddleのHTMLペインにSVGを追加することでこれをシミュレートします。

私は、SVG要素のIDを取得し、ドラッグハンドラをアタッチ機能「set_draggable(ID)を持っている

function set_draggable(svg_element) { 

    var xx = SVG.get(svg_element); 
    xx.addClass("zn_draggable"); 

    xx.draggable(function(x, y) { 
    return { 
     x: Math.floor(x), 
     y: Math.floor(y) 
    } 
    }); 

    var sx = 0, 
    sy = 0; 
    xx.on('dragstart', function(e) { 
    sx = e.detail.p.x; 
    sy = e.detail.p.y; 
    this.fill("red"); 
    }); 

    // todo: don't know why 'this' is the only way to change the filling ... 
    xx.on('dragend', function(e) { 
    this.fill("green"); 
    var result = { 
     delta: [ e.detail.p.x - sx, e.detail.p.y - sy], 
     element: svg_element 
    }; 
    alert(JSON.stringify(result)); 
    }) 
} 


set_draggable("ZN_18"); 
set_draggable("ZN_19"); 
set_draggable("ZN_20"); 
set_draggable("ZN_21"); 

私の質問:ドラッグ可能なイベントハンドラで

  1. なぜ、これはドラッグされたオブジェクトを参照しているのですか? fill()をエフェクトで適用する唯一の方法です。xxはdomノードdraggableを接続します。また、e.target.fill("red")で試しました。

  2. Fermata - Character(パス)をドラッグすると、色は変わりません。テキストをドラッグするときに機能します。 何が原因でしょうか?

    回答:bwl21:そのグループの属性が子の属性を上書きしないことがわかりました。だから私はストロークを削除し、パスからいっぱいにしなければならなかった。

    でも、私は子供たちに移動してそこの属性を変更することはできませんでした。 ZN_19をドラッグすると、私はドラッグ可能に作られたよう

  3. それはだけ垂直を移動することができます。私がグループ(ZN_20のような)にそれをラップし、これに対してdraggable()を呼び出すと、私は望む通りにそれを動かすことができます。

  4. ドラッグの結果としてデルタを取得するより良い方法はありますか? xとyを 'dragstart'ハンドラに格納し、 'dragend'ハンドラのデルタを計算します。 draggable()に渡された関数によって丸められるので、デルタが整数であることを期待しています。

  5. 私は多くのオブジェクトを持っている場合(私のアプリケーションは約300です)、私は多くのハンドラを作成するので、パフォーマンスの問題に直面しますか?これを行うより良い方法はありますか?

助けてください。

答えて

1

質問はたくさんあります。私はそれらを通して仕事をしようとします。

1.なぜ「this」はドラッグされたオブジェクトを参照していますか?

これは一般的にsvg.jsの機能です。すべてのイベントハンドラは、要素のコンテキストで実行されます。 要素をクリックしたときにこれはtrueを出力します。

el.on('click', function() { console.log(this == el) }) 

はそうです、あなたは代わりxxを使用することができ、そのはあなたの例ではうまく働きます。 thisxxに置き換えてください。

どこかredeclearedされる可能性があります外側の変数(典型的な例:ループ内のイベントハンドラをアタッチ)を使用しているときに、変数のスコープとのトラブルに実行することができますので、しかし、this保存方法です

2.なぜフェルマーの塗りつぶしは変わりません

これはすでに正しく答えられています。一般的なヒントとして、私は言うことができます:彼らは1つの図形を保持する場合は、グループを使用しないでください。そうする必要はありません。

domのナビゲートに関する後続の質問については、svg.jsに素晴らしいドキュメントがあります。検索結果にchildrenと入力してhttp://svgjs.com/に入力してください。

el.children() // array 
el.get(index) // element at index 
el.first() // first element 
el.last() // last element 

3.なぜテキストのドラッグされた唯一のあなたのSVGをsvg.js.を使用して生成されなかった

垂直作業:

あなたは複数の可能性を持っていますSvg.jsはすべての第1レベルのtspanを新しい行として扱いますIF svg.jsで作成されました。そうでなければ、それは特別なことは何もしません。あなたの場合は意味:テキスト移動(domを見てください - それを見ることができます)。しかし、あなたのsvgコードでは、x座標をtspanの80にリセットするので、それは永遠にそこにとどまります。あなたがそれを望まないなら、を使用するのではなく、代わりにdxを使用するか、テキストx座標が変更されたときのx座標の変更を含む特別な処理を可能にするtspanでnewLine()を呼び出します。

これに関するメモ:テキストを消したあなたの例のフィドルでこれを行いました。それはテキストそのものが画面外のx 189を持っているので、まずそれを80に調整する必要があります

4.ドラッグの結果としてデルタを得る良い方法はありますか?

いいえありません。

要素に設定する直前の座標に丸めが適用されます。しかし:多くの要素

を使用した場合、真実のそのソース

5.そこにパフォーマンスの問題ですので、orginalポイントは、イベントオブジェクトに与えられている要素の多くは、DOMの操作が遅くなります。だから、何百もの要素を一緒に動かしてはいけません。それらにハンドラを適用するだけで問題にはならないはずです。

ただし、パフォーマンスはブラウザによっても異なります。演技コードを書くようにしてください。 (el.draggable(nameOfFunc))を定義してdraggable-constraint関数を再利用し、ハンドラの外側変数(xxなど)にアクセスしないようにしてください。クローズが生成される必要はないので、ドラッグで重い作業をしないでください。

希望する場合は

+0

お返事ありがとうございました。それは本当に多くの助けになります。 – Bernhard

+0

WRT 2.グループ内でラップすることなく、カーソルと共に移動するように管理していませんでした。パスデータは最終座標にないので、変換する必要があります。私はナビゲーション方法を見たが、属性を変更することはできなかった。私はもう一度やり直します。一方、私はパスからアトリビュートを削除することによって、実用的な解決策を持っています。また、マウスで簡単に把握できるように、グループにもハンドルがあります。 – Bernhard

+0

WRT 3:svgはsvg.jsの外部で生成されています。私はライブラリを早期に見つけられなかったからです。私は、SVGジェネレータをDOMにアクセスできないWebワーカーに移行する予定です。 SVGを文字列として生成するのはかなり簡単でした。 SVGはjspdfで作成したPDFと同じに見える必要があるという問題もあります。だから私はテキストのすべての行を制御する必要があります。私はそれを試みた。しかしそれはうまくいかなかった。 dxは前の行の末尾にaddesです。それを動作させる唯一の方法は、それをグループにまとめてグループをドラッグすることでした。 – Bernhard

関連する問題