2013-02-11 101 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 }; 
     } 
    }); 
});