我有一个HTML 5页面,我加载了一个svg圈子。当我点击圆圈时,我会创建另一个小圆圈,然后单击。我希望能够拖动第二个圆圈,但似乎无法使用jquery-ui .draggable();
我可以通过访问它的cx和cy属性来移动圆圈,因此必须有一种方法来拖动它。
<!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>
答案 0 :(得分:46)
jQuery UI可拖动行为确实有效,但您需要在拖动处理程序中手动更新位置,因为相对CSS定位在SVG内部不起作用。
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);
});
答案 1 :(得分:2)
我正在修改的解决方案涉及(将其绑定到您的案例)创建一个新的div和svg,位于原始形状上,充当目标svg对象的句柄。使句柄div可拖动并在外部存储起始顶部/左侧偏移(想想隐藏的div)。一旦触发了可拖动div的“停止”事件,找出顶部和左侧的变化程度(stopX-startX = changeX)并将其应用于原始形状坐标。然后.remove()你的临时形状。
答案 2 :(得分:2)
This link有一个很好的描述如何一般地解决问题(即,不需要JQuery),这绝对是我见过的最好的解决方案。但是,我想继续使用JQuery优秀的Draggable API。
我最近花了几天时间来解决这个问题。上面接受的答案是我首先尝试的,但我无法让它在Firefox中正常工作。 something about how browsers handle SVG坐标不同。
我提出了一个在Chrome和Firefox中都能很好地运行的解决方案,让我继续使用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}
);
});
在我的情况下,我想要拖动的SVG元素将始终填充屏幕上的某个方块,因此很容易将代理div放在目标上。在其他情况下,可能会困难得多。使用'收容'选项确保不将框架拖到框架外也不是太难......只需要仔细考虑一下,你就必须在每次拖动之间重置收容。
为了使其适用于更多SVG元素,您可以使用变换而不是x和y坐标。
答案 3 :(得分: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>
答案 4 :(得分:0)
只需将svg放在可拖动的div中即可。
//*
$(document).ready(function(){
$('#mydiv').draggable();
});
//*/
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div id="mydiv">
<svg xml:lang="en"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<text class="main" x="10" transform="rotate(-28 0 0)" y="90">Sol min</text>
<text class="sous" x="4" y="110" transform="rotate(-28 0 20)">(SOUS DOM.)</text>
<line stroke="black" stroke-width="2" x1="10" y1="100" x2="110" y2="46" />
<line stroke="red" stroke-width=2 x1=10 y1=99 x2=10 y2=140 />
</svg>
</div>