2012-07-17 4 views
1

Я стучал головой о стену в течение нескольких дней и никуда не дену, поэтому просто хочу найти какое-то подтверждение того, что то, что я пытаюсь сделать, на самом деле действительно. ...JQuery & SVG drag and drop

У меня есть страница с SVG witin DIV. Я хочу иметь возможность щелкнуть компонент SVG и перетащить его. Простой в теории. У меня было это в грязной исходной версии javascript, но я пытаюсь сделать это в JQuery для обеспечения последовательности.

Я имел следующий, которым тащит весь контейнер DIV вокруг:

* вар svgName = "/mySvg.svg";

$(document).ready(function($) { 
    $('#svgDiv').svg(); 
    var svg = $('#svgDiv').svg('get'); 
    svg.load(svgName, 

    function() { 
     $('#svgDiv').draggable().bind('mousedown', function(event, ui) { 
      $(event.target.parentElement).append(event.target); 
     }).bind('drag', function(event, ui) { 
      event.target.setAttribute("transform", "translate("+event.clientX+","+event.clientY+")"); 
     }); 
    }); 
}); 

*

Я изменил это это это, что я думал получить элемент SVG по его ID, но это не делает ничего. Это похоже на то, что JQuery не видит «внутри» (не хочет лучшего слова) DIV. *

var svgSource = "/mySvg.svg"; 

$(document).ready(function($) { 
    $('#svgDiv').svg(); 
    var svgObj = $('#svgDiv').svg('get'); 
    svgObj.load(svgSource, 
     function() { 
      var svgObj2 = $('#svgDiv').svg('get'); 
      var svgElem = svgObj2.getElementById('pathIdOne'); 
      $(svgElem).draggable().bind('mousedown', function(event, ui) { 
       $(event.target.parentElement).append(event.target); 
      }).bind('drag', function(event, ui) { 
       //event.target.setAttribute("transform", "translate("+event.clientX+","+event.clientY+")"); 
       event.target.setAttribute('x', ui.position.left); 
       event.target.setAttribute('y', ui.position.top);      
      }); 
     }); 
}); 

*

Может кто-нибудь увидеть что-нибудь вопиюще очевидным, что нуждается в изменении, это может быть сделано, или это просто совершенно неправильно?

+0

Не так много элементов svg имеют атрибуты «x» и «y», вам может быть повезло с атрибутом «transform». –

ответ

1

Я недавно провел пару дней, забивая эту проблему, и я придумал решение, которое хорошо работало для меня. Это определенно взломать и не будет работать во всех ситуациях.

This link имеет отличное описание того, как решить проблему в целом, и это, безусловно, «лучшее» решение. Тем не менее, я хотел продолжать использовать превосходный API DragGable JQuery.

Вы можете увидеть быстрый макет того, что я сделал в скрипке here. Основная идея заключается в использовании прокси-div, который вы держите точно над элементом svg, который хотите перетащить. Затем вы меняете координаты x и y элемента svg при перетаскивании div-прокси. Что-то вроде этого:

$('#proxy').on('drag', function(e) 
    { 
     t = $('#background'); 
     prox = $('#proxy'); 
     t.attr('x', t.attr('x')*1 
        + prox.css('left').slice(0,-2)*1 
        - prox.data('position').left) 
      .attr('y', t.attr('y')*1 
         + prox.css('top').slice(0,-2)*1 
         - prox.data('position').top); 
     prox.data('position',{top : prox.css('top').slice(0,-2)*1, 
           left: prox.css('left').slice(0,-2)*1} 
       ); 
    }); 

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

Чтобы сделать это применимым к большему количеству элементов SVG, вы можете использовать преобразования, а не координаты x и y.