2009-07-10 27 views
31

का उपयोग कर एसवीजी ड्रैगगेबल मेरे पास एक HTML 5 पृष्ठ है जहां मैं एक svg सर्कल लोड करता हूं। जब मैं सर्कल पर क्लिक करता हूं तो मैं एक और छोटा सर्कल बनाता हूं जहां मैं क्लिक करता हूं। मैं दूसरे सर्कल को खींचने में सक्षम होना चाहता हूं लेकिन ऐसा लगता है कि jquery-ui .draggable() के साथ ऐसा नहीं लगता है;JQuery और Jquery-svg

मैं अपने सीएक्स और साइ गुणों तक पहुंचकर सर्कल को स्थानांतरित करने में सक्षम हूं, इसलिए इसे खींचने का एक तरीका होना चाहिए।

<!DOCTYPE HTML> 
<html > 
<head> 
<title></title> 
<link href="css/reset.css" rel="stylesheet" type="text/css"> 
<link href="css/layout.css" rel="stylesheet" type="text/css"> 
<link href="css/style.css" rel="stylesheet" type="text/css"> 
<script src="js/jquery.js" type="text/javascript" ></script> 
<script src="js/jquerysvg/jquery.svg.js" type="text/javascript" ></script> 
<script src="js/jquery-ui.js" type="text/javascript" ></script> 
<script type="text/javascript" > 
jQuery(document).ready(function(){ 
    $('#target').svg({onLoad: drawInitial}); 
    $('circle').click(function(e){ 
     drawShape(e); 
     var shape = this.id; 

    }); 

    $('.drag').mousedown(function(e){ 
     var shape = this.id; 
     this.setAttribute("cx", e.pageX); 
     this.setAttribute("cy", e.pageY); 
    }); 
}) 

function drawInitial(svg) { 
    svg.add($('#svginline')); 
} 

function drawShape(e) { 
    var svg = $("#target").svg('get'); 
    $('#result').text(e.clientX + ": " + e.pageX); 
    var dragme = svg.circle(e.clientX, e.clientY, 5, {fill: 'green', stroke: 'red', 'stroke-width': 3, class_: 'drag'});  
    //$(dragme).draggable(); 
} 
</script> 
</head> 
<body> 
    <div id="target" ></div> 
    <svg:svg id="svginline"> 
     <svg:circle id="circ11" class="area" cx="75" cy="75" r="50" stroke="black" stroke-width="2" fill="red"/> 
    </svg:svg> 
    <div id="result" >ffff</div> 
</body> 
</html> 

उत्तर

44

jQuery यूआई ड्रैगगेबल व्यवहार काम करता है, लेकिन आपको ड्रैग हैंडलर में मैन्युअल रूप से स्थिति को अद्यतन करने की आवश्यकता है, क्योंकि सापेक्ष सीएसएस स्थिति एसवीजी के अंदर काम नहीं करती है।

svg.rect(20,10,100,50, 10, 10, {fill:'#666'}); 
svg.rect(40,20,100,50, 10, 10, {fill:'#999'}); 
svg.rect(60,30,100,50, 10, 10, {fill:'#ccc'}); 

$('rect') 
    .draggable() 
    .bind('mousedown', function(event, ui){ 
    // bring target to front 
    $(event.target.parentElement).append(event.target); 
    }) 
    .bind('drag', function(event, ui){ 
    // update coordinates manually, since top/left style props don't work on SVG 
    event.target.setAttribute('x', ui.position.left); 
    event.target.setAttribute('y', ui.position.top); 
    }); 
+0

धन्यवाद, यह एक इलाज करता है। – skyfoot

1

मैंने अपने svg ऑब्जेक्ट्स को लक्षित करने के लिए एक मूल ड्रैग ड्रॉप फ़ंक्शन बनाया है। मेरे पास कोई रोकथाम या टक्कर का पता नहीं है। अगर मैं माउस को बहुत अच्छी तरह से ले जाता हूं तो एक मुद्दा है, मैं ड्रैगगेबल ऑब्जेक्ट को पीछे छोड़ दूंगा।

<!DOCTYPE HTML> 
<html > 
<head> 
<title></title> 
<link href="css/reset.css" rel="stylesheet" type="text/css"> 
<link href="css/layout.css" rel="stylesheet" type="text/css"> 
<link href="css/style.css" rel="stylesheet" type="text/css"> 
<script src="js/jquery.js" type="text/javascript" ></script> 
<script src="js/jquery-ui.js" type="text/javascript" ></script> 
<script src="js/jquerysvg/jquery.svg.js" type="text/javascript" ></script> 
<script src="js/jquerysvg/jquery.svgdom.js" type="text/javascript" ></script> 

<script type="text/javascript" > 
jQuery(document).ready(function(){ 
    $('#target').svg({onLoad: drawInitial}); 
    $('circle').click(function(e){ 
     drawShape(e); 
     var shape = this.id; 

    }); 
}) 

function drawInitial(svg) { 
    svg.add($('#svginline')); 
} 

function onMouseDown(evt){ 
     //var shape = this.id; 

     var target = evt.target;   
     target.onmousemove = onMouseMove; 

     return false; 
} 

function onMouseMove(evt){ 
    circle = evt.target 

    var cx = circle.getAttribute("cx"); 
    offsetX = $('#target').offset().left; 
    offsetY = $('#target').offset().top 
    circle.setAttribute("cx", evt.clientX -offsetX); 
    circle.setAttribute("cy", evt.clientY - offsetY); 

    circle.onmouseup = OnMouseUp; 
} 

function OnMouseUp(evt) { 
    var target = evt.target;   
    target.onmousemove = null; 
} 

function drawShape(e) { 
    var svg = $("#target").svg('get'); 
    offsetX = $('#target').offset().left; 
    offsetY = $('#target').offset().top; 
    $('#result').text(e.clientX + ": " + e.pageX); 
    var dragme = svg.circle(e.clientX - offsetX, e.clientY - offsetY, 5, {onmousedown: "onMouseDown(evt)",fill: 'green', stroke: 'red', 'stroke-width': 3});  
    $(dragme).addClass('drag'); 
} 
</script> 
</head> 
<body> 
    <div id="target" ></div> 
    <svg:svg id="svginline"> 
     <svg:circle id="circ11" class="area" cx="75" cy="75" r="50" stroke="black" stroke-width="2" fill="red"/> 
    </svg:svg> 
    <div id="result" >ffff</div> 
</body> 
</html> 
+0

मैं जो बनाया कीथ लकड़ी से एक प्रतिक्रिया थी jquerysvg http://keith-wood.name/svg.html "मैं jQuery एसवीजी डोम, जो थोड़ा करने के लिए अलग है के साथ काम करने के लिए हो रही पर काम कर रहा हूँ एचटीएमएल डोम जिसके लिए jQuery डिज़ाइन किया गया था। यह jQuery ईवेंट हैंडलर को एसवीजी तत्वों के अनुलग्नक की अनुमति देगा। यह स्पष्ट रूप से ड्रैग-एंड-ड्रॉप को लागू नहीं करेगा लेकिन यह ऐसा करने के लिए jQuery का उपयोग करने में सहायता करेगा। मैं ड्रैग- भावी रिलीज के लिए दिमाग में और ड्रॉप कार्यक्षमता।" – skyfoot

+0

विचारों की संख्या के कारण मैंने सोचा कि मैं इसे अपडेट कर दूंगा। मैंने चांदी की रोशनी में समान कार्यक्षमता बनाई और ड्रैग और ड्रॉप भी रोपी थी जब तक कि मैंने चांदी की रोशनी माउस कैप्चर का उपयोग नहीं किया। मुझे यकीन नहीं है कि माउस कैप्चर विधि में क्या होता है लेकिन अगर यह jquery में कार्यान्वित किया जा सकता है तो यह ड्रैग और ड्रॉप को हल करेगा। – skyfoot

+0

यह पूरी तरह से @skyfoot काम करता है। लेकिन उस रेखा के बारे में क्या है जिसमें निर्देशांक के दो जोड़े हैं, यानी (x1, y1) और (x2, y2) बल्कि एक समन्वय होना सर्कल (सीएक्स, साइ) की तरह? धन्यवाद। – Bakhtiyor

2

समाधान मैं को संवारता हूँ शामिल है (आपके मामले के लिए इसे टाई) एक नया div और svg, मूल आकार से अधिक उपयुक्त, लक्षित svg वस्तु के लिए संभाल के रूप में कार्य करने के लिए का निर्माण। हैंडल div draggable बनाओ और प्रारंभिक शीर्ष/बाएं ऑफसेट बाहरी रूप से स्टोर करें (छुपा div सोचें)। ड्रैगगेबल div के लिए "स्टॉप" ईवेंट निकाल दिए जाने के बाद, ऊपर और बाएं (stopX-startX = changeX) के लिए परिवर्तन की डिग्री जानें और मूल आकार निर्देशांक पर लागू करें। फिर .remove() अपने अस्थायी आकार।

2

This link (है, यानी JQuery की आवश्यकता के बिना) कैसे सामान्य रूप में समस्या को हल करने का एक बहुत अच्छा विवरण नहीं है, और कहा कि निश्चित रूप से सबसे अच्छा समाधान मैंने देखा है है। हालांकि, मैं JQuery के उत्कृष्ट ड्रैगगेबल एपीआई का उपयोग करना जारी रखना चाहता था।

मैंने हाल ही में इस समस्या पर कुछ दिन बिताए। उपरोक्त स्वीकृत उत्तर वह है जो मैंने पहले किया था, लेकिन मैं इसे फ़ायरफ़ॉक्स में सही काम नहीं कर सका। something about how browsers handle एसवीजी अलग-अलग निर्देशांक है।

मैं ऐसे समाधान के साथ आया जो क्रोम और फ़ायरफ़ॉक्स दोनों में मेरे लिए काफी अच्छा काम करता है, और मुझे JQuery UI का उपयोग करने देता है। मैंने इसे हर जगह परीक्षण नहीं किया है। यह निश्चित रूप से एक हैक है।

आप एक बेवकूफ़ here में किए गए कार्यों के त्वरित मॉक-अप देख सकते हैं। मुख्य विचार एक प्रॉक्सी div का उपयोग करना है जिसे आप खींचने के लिए इच्छित svg तत्व पर वास्तव में होवर करते रहते हैं। फिर जब आप प्रॉक्सी div खींचते हैं तो आप svg तत्व के x और y निर्देशांक बदलते हैं। कुछ इस तरह:

$('#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} 
       ); 
    }); 

मेरे मामले में एसवीजी तत्व मैं खींचें करने के लिए हमेशा के लिए स्क्रीन पर एक निश्चित वर्ग को भरना था चाहता था, इसलिए यह लक्ष्य से अधिक प्रॉक्सी div स्थिति बहुत आसान था। अन्य परिस्थितियों में यह और अधिक कठिन हो सकता है। यह सुनिश्चित करने के लिए 'रोकथाम' विकल्प का उपयोग करना भी मुश्किल नहीं है कि आप फ्रेम के बाहर पृष्ठभूमि को खींचें नहीं ... यह केवल कुछ सावधानीपूर्वक गणित लेता है और आपको प्रत्येक ड्रैग के बीच में रोकथाम को रीसेट करना होगा।

इसे अधिक एसवीजी तत्वों पर लागू करने के लिए, आप एक्स और वाई निर्देशांक के बजाय ट्रांसफॉर्म का उपयोग कर सकते हैं।