views:

3887

answers:

4

I have an HTML 5 page where I load an svg circle. When I click on the circle I create another small circle where I click. I want to be able to drag the second circle but cant seem to do it with jquery-ui .draggable();

I am able to move the circle by accessing its cx and cy attributes so there must be a way to drag it.

    <!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>
A: 

Take a look at the SVG draggable jQuery plugin. I guess it was made to solve problems like your one:

http://keith-wood.name/svg.html

Also, jQuery UI draggable does not natively support the dragging of SVG objects, a ticket request this functionality was submitted 5 months ago:

http://dev.jqueryui.com/ticket/4211

The response from the jQuery guy was:

"Very unlikeley to happen, considering the extremely low adoption of SVG."

karim79
Thanks, I am using jquery-svg from the top link you posted but havent been able to fin any info on draggable. I have searched within all the js files included in the download but cant find any reference to being able to drag.
skyfoot
+1  A: 

I have created a basic drag drop function to target my svg objects. I dont have any containment or collistion detection. There is an issue if I move the mouse too quicly I will leave the draggable object behind.

<!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>
skyfoot
I had a response from Keith Wood who created jquerysvghttp://keith-wood.name/svg.html"I'm working on getting jQuery to work with the SVG DOM, which is slightly different to the HTML DOM for which jQuery was designed. This will allow the attachment of jQuery event handlers to SVG elements. It won't implement drag-and-drop explicitly but it will aid in using jQuery to do so. I'll keep drag-and-drop functionality in mind for a future release."
skyfoot
Because of the number of views I thought I would update this. I created similar functionality in silverlight and the drag and drop was also ropey until I used silverlights Mouse Capture. I am not sure what happens in the Mouse Capture method but if it can be implemented in jquery then this would solve the drag and drop.
skyfoot
A: 

Microsoft just announced they will provide deep SVG support in IE 9, which has spurred new interest. They have been holding out for a long time; this is why SVG adoption was low.

Bill
What has this got to do with the question?
fahadsadah
A: 

The solution I'm tinkering with involves (to tie it to your case) creating a new div and svg, positioned over the original shape, to act as the handle for the targeted svg object. Make the handle div draggable and store the starting top/left offset externally (think hidden div). Once the "stop" event for the draggable div is fired, figure out the degree of change for the top and left (stopX-startX=changeX) and apply that to the original shapes coordinates. Then .remove() your temporary shape.

Mike