web-dev-qa-db-ja.com

JQueryを使用して2つの要素の間に線を引き、その線を更新するにはどうすればよいですか?

JQuery-UIのドラッグ可能オブジェクトとドロップ可能オブジェクトを使用して、要素をdivに複製しています。 JQueryを使用してページ上の要素間に線を引くための最良の方法は何ですか。

ページの行を更新する最良の方法は何ですか?ページに複数の行があり、すべての行を更新するのではなく、特定の行のみを更新したいと思います。

15
StuperUser

私は今これを機能させています。

私の経験では、jquery.svgを使用しないでください。別のプラグインを回避する方法を学習せずに解決する必要があったかもしれませんが、それが価値があるよりも面倒であり、互換性の問題を引き起こしました。

HTML5キャンバスと excanvas互換性スクリプト 、および 素晴らしいhtml5ウォークスルー を使用して解決することは可能ですが、HTML5キャンバスの動作方法のため、すべてのlinseが必要です。線を削除する必要がある場合、またはその位置を更新する必要がある場合、キャンバスは破棄されて再描画されます。

間に線を引く要素は、関係を表す親要素の内部にあります。子要素は開始と終了を表すため、たとえばを使用して親のコレクションを取得することで、これらの関係をすべて再描画できます。 $('.relationshipClass')そして、セットの要素の子に問い合わせて、線のポイントを取得します。
このコードを使用するには、ラインポイントを簡単に再描画できるようにする方法を考え出す必要があります。

マークアップ:
素晴らしくシンプルな、間に描画される要素(おそらくJQuery UIドラッグ可能)を保持するhtml <div>と、同じ位置にある<canvas>

 <div id="divCanvasId" class="divCanvasClass"></div>
 <canvas id="html5CanvasId"></canvas>

CSS:
CSSで<canvas>要素の幅を制御しないでください。 キャンバスストレッチに関する質問 を参照してください。 <canvas><div>と同じ位置に配置し、その後ろ(z-indexを使用)に配置します。これにより、<div>の後ろに線が表示され、<canvas>が防止されます。 <div>の子とのドラッグアンドドロップの相互作用をブロックしないようにします。

canvas
{
    background-color: #FFFFFF;
    position: absolute;
    z-index: -10;
    /* control height and width in code to prevent stretching */
}

Javascriptアプローチ:
ユーティリティメソッドの作成:サンプルコードは JQueryプラグイン 内にあります。

  • キャンバスをリセットするヘルパー関数(幅を変更すると、すべてが削除されます)
  • 2つの要素の間に線を引くヘルパー関数
  • 1つを必要とするすべての要素の間に線を引く関数

新しい線を追加したり、線の位置を調整したりすると、既存の線が破棄され、すべての線が描画されます。以下のコードを従来の関数に入れるか、プラグインのままにしておくことができます。

Javascriptコード:
N.B。匿名化後はテストされていません。

$(document).ready(function () {
    $.fn.yourExt = {

        _readjustHTML5CanvasHeight: function () {
            //clear the canvas by readjusting the width/height
            var html5Canvas = $('#html5CanvasId');
            var canvasDiv = $('#divCanvasId');

            if (html5Canvas.length > 0) {
                html5Canvas[0].width = canvasDiv.width();
                html5Canvas[0].height = canvasDiv.height();
            }
        }
        ,
        //uses HTML5 <canvas> to draw line representing relationship
        //IE support with excanvas.js
        _drawLineBetweenElements: function (sourceElement, targetElement) {

            //draw from/to the centre, not the top left
            //don't use .position()
            //that will be relative to the parent div and not the page
            var sourceX = sourceElement.offset().left + sourceElement.width() / 2;
            var sourceY = sourceElement.offset().top + sourceElement.height() / 2;

            var targetX = targetElement.offset().left + sourceElement.width() / 2;
            var targetY = targetElement.offset().top + sourceElement.height() / 2;

            var canvas = $('#html5CanvasId');

            //you need to draw relative to the canvas not the page
            var canvasOffsetX = canvas.offset().left;
            var canvasOffsetY = canvas.offset().top;

            var context = canvas[0].getContext('2d');

            //draw line
            context.beginPath();
            context.moveTo(sourceX - canvasOffsetX, sourceY - canvasOffsetY);
            context.lineTo(targetX - canvasOffsetX, targetY - canvasOffsetY);
            context.closePath();
            //ink line
            context.lineWidth = 2;
            context.strokeStyle = "#000"; //black
            context.stroke();
        }
        ,

        drawLines: function () {
        //reset the canvas
        $().yourExt._readjustHTML5CanvasHeight();

        var elementsToDrawLinesBetween;
        //you must create an object that holds the start and end of the line
        //and populate a collection of them to iterate through
        elementsToDrawLinesBetween.each(function (i, startEndPair) {
            //dot notation used, you will probably have a different method
            //to access these elements
            var start = startEndPair.start;
            var end = startEndPair.end;

            $().yourExt._drawLineBetweenElements(start, end);
        });
    }

これらの関数をイベントハンドラー(例: JQuery UIのドラッグイベント )から呼び出して線を描画できるようになりました。

14
StuperUser