2

要素を特定の方向に「ドラッグ」しながら、svg で「パン」を実現したいと考えています。

要素を選択し、画面の上部に到達するまで「ドラッグ」を開始すると、ドラッグで問題が発生することなく、svg が自動的に上にパンするはずです。どうすればこれを達成できますか。

ユーザーが要素を選択してドラッグできる、これの小さなモックアップを作成しました。また、svg を上下にパンさせる 2 つのボタンも含まれています。svgの「ViewBox」を変更して「パン」を実現しています。(このロジックを使用する必要があります。他のソリューションは使用できません);

ここにフィドルのリンクがあります: http://jsfiddle.net/9J25r/

完全なコード:-

addEventListener('mousedown', mousedown, false);
            var mx, my;
            var dx, dy;
            var mainsvg = document.getElementById('svg');
            var selectedElement;
            var eleTx, eleTy;

            function getSvgCordinates(event) {

                var m = mainsvg.getScreenCTM();
                var p = mainsvg.createSVGPoint();

                var x, y;

                x = event.pageX;
                y = event.pageY;

                p.x = x;
                p.y = y;
                p = p.matrixTransform(m.inverse());

                x = p.x;
                y = p.y;

                x = parseFloat(x.toFixed(3));
                y = parseFloat(y.toFixed(3));

                return {x: x, y: y};
            }

            function mousedown(event) {
                if (event.target.id === 'arrow_t') {
                    panning('up');
                }
                else if (event.target.id === 'arrow_b') {
                    panning('down');
                }
                else  if (event.target.id.split('_')[0] === 'rect') {

                    selectedElement = event.target;
                    var translatexy = selectedElement.getAttribute('transform');
                    translatexy = translatexy.split('(');
                    translatexy = translatexy[1].split(',');

                    eleTx = translatexy[0];
                    translatexy = translatexy[1].split(')');
                    eleTy = translatexy[0];

                    eleTx = parseFloat(eleTx);
                    eleTy = parseFloat(eleTy);

                    var xy = getSvgCordinates(event);

                    mx = xy.x;
                    my = xy.y;

                    mx = parseFloat(mx);
                    my = parseFloat(my);

                    addEventListener('mousemove', drag, false);
                    addEventListener('mouseup', mouseup, false);
                }
            }

            function drag(event) {
                var xy = getSvgCordinates(event);
                dx = xy.x - mx;
                dy = xy.y - my;

                selectedElement.setAttribute('transform', 'translate(' + (eleTx + dx) + ',' + (eleTy + dy) + ')');
            }
            function mouseup(event) {


                removeEventListener('mousemove', drag, false);
                removeEventListener('mouseup', mouseup, false);

            }

            function panning(direction) {
                var viewBox = svg.getAttribute('viewBox');
                viewBox = viewBox.split(' ');
                var y = parseFloat(viewBox[1]);
                if (direction === 'up')
                {
                    y+=5;
                }
                else if (direction === 'down')
                {
                    y-=5;
                }

                viewBox=viewBox[0]+' '+y+' '+viewBox[2]+' '+viewBox[3];
                svg.setAttribute('viewBox',viewBox);
            }

ここに画像の説明を入力

ここに画像の説明を入力

ここにフィドルのリンクがあります: http://jsfiddle.net/9J25r/

編集:-(更新)

私は Ian のソリューションを使用していますが、サンプルではうまく機能しますが、元のアプリケーションに適用すると機能しませんでした。下のgifをチェックしてください。マウス ポインタと要素の間に「ギャップ」が見られます。どうすればそれを削除できますか? .

ここに画像の説明を入力

4

1 に答える 1

1

これは 1 つの方法です。今のところ、Y/vertical で実行しました...

カーソルが画面から外れている場合は、viewBox も自動的に調整されるように調整することをお勧めします。

var viewBox = svg.getAttribute('viewBox');
viewBoxSplit = viewBox.split(' ');

if( ely < viewBoxSplit[1] ) {
      panning('down');
} else if( ely + +event.target.getAttribute('height')> +viewBoxSplit[1] + 300 ) {
      panning('up');
}

ここでjsfiddle

于 2014-02-21T09:33:07.560 に答える