2013-02-11 224 views
2

我一直在研究一个脚本,它将可拖动的div限制为一个圆(而不是矩形父div)。我发现这个线程:How to constrain movement within the area of a circle似乎解决了我的一些问题。我已经获得了适当的功能,当我在拖动功能中调用这些函数时,它将返回div的正确位置。我知道这一点,因为我可以在拖动功能中检查控制台日志,并检查div的位置。但是,我的问题是,我似乎无法在拖动事件期间设置实际位置。控制台报告正确的位置值,但div实际上不会受限于圆形边界。例如,如果我将div拖动到圆的中心,然后垂直移过圆的边界... div不会停在圆上,但控制台会将位置固定为[0,50]// 50是Y轴上X &中圆的中心。我读过其他一些线程,我可能不得不使用助手对象,但我似乎没有得到任何方法。我发布了一个简单的例子,希望有人能够提供帮助。谢谢。使用jquery draggable div拖动期间的设置位置

this.light = document.createElement("div"); 
this.light.style.position='absolute'; 
this.light.style.left="20px"; 
this.light.style.top="40px"; 
this.light.style.width="20px"; 
this.light.style.height="20px"; 

$(parentdiv).append(this.light); 

var circle_cenx = 50.0; 
var circle_ceny = 50.0; 
var circle_radius = 50.0; 

$(this.light).draggable({ 
    drag: function(event, ui){ 
     var position = $(that.light).position(); 
     var result = limit(position.left+10, position.top+10, circle_cenx, circle_ceny); 
     $(that.light).css({'top': result.y, 'left': result.x}); 
     position = $(that.light).position(); 
     console.log(position); 
    } 
}); 

function limit(x, y, cenx, ceny) { 
    var dist = distance([x, y], [cenx, ceny]); 
    if (dist <= circle_radius) { 
     return {x: x, y: y}; 
    } 
    else { 
     x = x - circle_cenx; 
     y = y - circle_ceny; 
     var radians = Math.atan2(y, x); 
     return { 
      x: Math.cos(radians) * circle_cenx + circle_radius, 
      y: Math.sin(radians) * circle_ceny + circle_radius 
     } 
    } 
} 

function distance(dot1, dot2) { 
    var x1 = dot1[0], 
     y1 = dot1[1], 
     x2 = dot2[0], 
     y2 = dot2[1]; 
    return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2)); 
} 
+0

我也是,我发现这个问题,运行到同一个问题后,今天。在拖动功能期间设置助手偏移或位置似乎没有任何作用。你有没有找到答案? – emrys57 2013-02-28 17:10:45

回答

5

是的,我终于搞清楚了。我曾认为.position是一个只读属性,但事实证明,您也可以使用它来设置位置。因此,在上面的代码中,我创建了一个名为result的变量,并存储了来自限制函数的返回值(它返回封闭圆圈内的鼠标的x和y值)。所以,在那之后你只需要调用这个:

ui.position={'top': result.y-10, 'left': result.x-10}; 

你需要删除行:

$(that.light).css({'top': result.y, 'left': result.x}); 

这应该是你所需要的。希望这可以帮助。

+0

jsFiddle演示? – softvar 2013-12-27 23:36:21

+0

@andyopayne感谢您指出这一点。完美的作品。我没有想过在'drag'事件处理函数中尝试修改'ui.position',直到我阅读这篇文章。 – 2016-10-23 22:05:12

0

检查是否包含可拖动元素。 希望,下面的链接可以帮助你

http://api.jqueryui.com/draggable/#option-containment

contaiment: [x1, y1, x2, y2]; 

你可以抓住光标位置和做数学题相应地设置X1,Y1,X2和Y2的值。

+0

谢谢你的澄清......尽管我可以说最好,提供一个[x1,y1,x2,y2]的数组只会指定边界框而不是圆。我之前使用包含选项将可拖动的div绑定到它的父容器...但我需要将div限制为一个圆而不是其父容器的矩形边界。此外,遏制选项不能设置(据我所知)内的其中一个可拖动的事件(可以)? – andyopayne 2013-02-12 12:52:27

1

由于我确信算法不完全正确,并且您提供的信息对我非常有帮助,因此我希望能够感激并创建一个jsfiddle演示,以供所有人查看算法的实际应用。我另外提供了一个默认的界面来玩。再次

http://jsfiddle.net/s7Uy2

感谢。

代码:

CSS:

.ui-controlpad { 
width:150px; 
height:150px; 
border:1px solid black; 
-moz-border-radius:75px; 
border-radius:75px; 
z-index:1000; 
} 
.ui-controlpad-pad { 
position:relative; 
width:75px; 
height:75px; 
top:37.5px; 
left:37.5px; 
border:1px solid black; 
-moz-border-radius:37.5px; 
border-radius:37.5px; 
z-index:1001; 
background-color:grey; 
} 

HTML:

<div id="Controlpad"></div> 

的Javascript:

jQuery.fn.extend({ 
    controlpad: function (options) { 
     $(this[0]).append('<div class="ui-controlpad"></div>'); 
     $(".ui-controlpad").append('<div class="ui-controlpad-pad"></div>'); 
     $(".ui-controlpad-pad").draggable({ 
      drag: options.ondrag, 
      revert: true 
     }); 
    } 
}); 
function limit(x, y, cenx, ceny, r) { 
    var dist = distance([x, y], [cenx, ceny]); 
    if (dist <= r) { 
     return { x: x, y: y }; 
    } 
    else { 
     x = x - cenx; 
     y = y - ceny; 
     var radians = Math.atan2(y, x); 
     return { 
      x: Math.cos(radians) * r + cenx, 
      y: Math.sin(radians) * r + ceny 
     } 
    } 
} 

function distance(dot1, dot2) { 
    var x1 = dot1[0], 
     y1 = dot1[1], 
     x2 = dot2[0], 
     y2 = dot2[1]; 
    return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2)); 
} 
$(document).ready(function(){ 
    var circle_cenx = 37.5; 
    var circle_ceny = 37.5; 
    var circle_radius = 37.5; 
    $("#Controlpad").controlpad({ 
     ondrag: function(event, ui){ 
      var result = limit(ui.position.left, ui.position.top, circle_cenx, circle_ceny, circle_radius); 
      ui.position = { 'top': result.y, 'left': result.x }; 
     } 
    }); 
});