Pan Svg при перетаскивании элементов

Я хочу добиться «панорамирования» в svg при «перетаскивании» элемента в определенном направлении.

Скажем, я выбираю элемент и начинаю «перетаскивать» его вверх, пока он не достигнет верхней части экрана, теперь мой svg должен автоматически перемещаться вверх, не вызывая никаких проблем с перетаскиванием. как я могу этого добиться.?

Я сделал небольшой макет этого, где пользователь может выбирать и перетаскивать элементы. он также содержит две кнопки, которые заставляют svg перемещаться вверх и вниз. Я достигаю «Панорамирование», изменяя «ViewBox» svg. (я должен использовать эту логику, я не могу использовать другое решение);

вот ссылка на скрипку: 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/

ИЗМЕНИТЬ:- (ОБНОВИТЬ)

Я использую решение Яна, оно хорошо работает на образце, но когда я применил его к своему исходному приложению, оно не сработало. проверьте гифку ниже. Вы можете увидеть «зазор» между указателем мыши и элементом. как я могу удалить это? .

введите здесь описание изображения


person RashFlash    schedule 21.02.2014    source источник


Ответы (1)


Это один из способов, я только что сделал это с вертикалью Y/на данный момент...

Возможно, вы захотите настроить его так, чтобы, если курсор находится за пределами экрана, он также автоматически настраивал 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 здесь

person Ian    schedule 21.02.2014
comment
это здорово Ян, это работает хорошо, но это не сработало в моем приложении. Я загрузил гифку выше, пожалуйста, проверьте это. - person RashFlash; 22.02.2014
comment
Трудно сказать, не видя кода, с которым можно поиграть. Когда дело доходит до краев, потребуется некоторая настройка, в зависимости от того, что вы хотите делать с курсором при перетаскивании за края. - person Ian; 22.02.2014
comment
Ну, я хочу, чтобы svg продолжал панорамироваться, а курсор и элемент оставались на верхнем краю. Курсор не должен покидать элемент и элемент не должен исчезать. - person RashFlash; 23.02.2014