4

表示領域の外にドロップする必要がある可能性のある svg 要素で d3 のドラッグ動作を使用しています。スクロールを有効にするためにオーバーフローを自動に設定して、2 つの div 内にセットアップしました。これは一部のブラウザでのみ機能しますが、すべてではありません。

問題は、一部のブラウザーではドラッグ中にスクロールできるが、他のブラウザーではドラッグ中にウィンドウがスクロールしないことです。私はまだこれを一貫して機能させる方法を見つけることができませんでした。

実際の例については、フィドルを参照してください: http://jsfiddle.net/glanotte/qd5Td/1/

これは期待どおりに機能しています:

クロム - mac/windows safari - mac

しかし、取り組んでいない

Firefox - Mac/Windows IE - Windows

html:

<div id="outerFrame">
    <div id="innerFrame">
        <svg width="600" height="600">
        </svg>
    </div>
</div>

CSS:

#outerFrame{
    width: 300px;
    height: 300px;
    border: 1px solid red;
    overflow: auto;
}

#innerFrame{
    width: 600px;
    height: 600px;
    background-color: lightgrey;
}

JavaScript:

var drag = d3.behavior.drag()
    .on("dragstart", dragstart)
    .on("drag", dragmove)
    .on("dragend", dragend);

function dragstart() {
  d3.select(this).style("border", "1px solid red");
}

function dragmove(d) {
    var coordinates = d3.mouse(d3.select("svg").node());
    d3.select(this).attr({
        x: coordinates[0] - 50,
        y: coordinates[1] - 25
    })

}

function dragend() {
  d3.select(this).style("border", null);
}

d3.select("svg")
    .append("rect")
    .attr({x: 100, y: 100, width: 100, height: 50})
    .call(drag);
4

1 に答える 1

4

残念ながら、mbostock によって以前に通知され、 WONT-FIX としてマークされFirefox のバグに遭遇しました。

バグレポートの提案に従って、コンテナを手動でスクロールすることによってのみ動作させることができます: http://jsfiddle.net/62CYD/

実装は非常にシンプルで、次の方法で改善できます。

  1. アニメーションの使用
  2. で行ったようにDOMUtilityServiceng-grid、スクロール バーの幅を考慮します
  3. 現在のマウス位置を考慮して、ドラッグされたアイテムのスナップを回避し、スクロールをスムーズにします。
  4. setTimeoutドラッグが停止してもスクロールを続けるために使用します
function dragmove(d) {
    var svg = d3.select("svg").node(),
        $parent = $('#outerFrame'),
        w = $parent.width(), h = $parent.height(),
        sL = $parent.scrollLeft(), sT = $parent.scrollTop();

    var coordinates = d3.mouse(svg),
        x = coordinates[0],
        y = coordinates[1];

    if (x > w + sL) {
        $parent.scrollLeft(x - w);  
    } else if (x < sL) {
        $parent.scrollLeft(x);
    }

    if (y > h + sT) {
        $parent.scrollTop(y - h);
    } else if (y < sT) {
        $parent.scrollTop(y);
    }

    d3.select(this).attr({
        x: x - 50,
        y: y - 25
    })
}
于 2013-11-02T00:11:27.990 に答える