我有一个包含可拖动/可拖放元素的页面,该元素一旦被拖放,就需要计算它们可能接触的其他可拖动元素的左侧位置和宽度。
它本身并不太难,但是我真正遇到麻烦的地方是让他们填补空白。如何使可拖动对象填充空白区域而又不加倍叠加?
// $t is the element being added/dropped.
// nd refers to New Dimensions, IE, the new dimensions for $t
// existingDivs gets any DIV's that have already been added to the dom
var $t = $(this), nd = {t:$t.position().top, h:$t.height(), l: 0, w: 95},
existingDivs = $('#container .subContainer .draggable'), intersectArr = [],
nonIntersectArr = [], finalArr = [];
// If there are no DIV's in the DOM you dont need to check if they intersect.
if (existingDivs.length > 0) {
// Find the DIV's that Intersect with the one being added
intersectArr = $.grep(existingDivs, function(val,num){
// xd is Existing Dimensions, for the current item being checked
// verse the one being added.
var $t2 = $(val), xd = {h:$t2.height(), w:parseFloat($t2.css('width')),
l:parseFloat($t2.css('left')), t:$t2.position().top};
// If they intersect add it to this array
return ((xd.t <= nd.t && xd.t+xd.h > nd.t) ||
(nd.t <= xd.t && nd.t+nd.h > xd.t));
});
// Find the DIV's that DO NOT Intersect with the one being added
nonIntersectArr = $.grep(existingDivs, function(val,num){
// xd is Existing Dimensions, for the current item being checked
// verse the one being added.
var $t2 = $(val), xd = {h:$t2.height(), w:parseFloat($t2.css('width')),
l:parseFloat($t2.css('left')), t:$t2.position().top};
// If they DO NOT intersect add it to this array
return ((xd.t > nd.t && xd.t > nd.t+nd.h) ||
(nd.t > xd.t && nd.t > xd.t+xd.h));
});
// For every element that does not intersect, check it verse the ones that do
$(nonIntersectArr).each(function(){
// nid is Non Intersecting Dimensions
var $t2 = $(this), c = 0, nid = {h:$t2.height(),
w:parseFloat($t2.css('width')),
l:parseFloat($t2.css('left')), t:$t2.position().top};
$(intersectArr).each(function(){
// id is Intersecting Dimensions
var $t3 = $(this), id = {h:$t3.height(), w:parseFloat($t3.css('width')),
l:parseFloat($t3.css('left')), t:$t3.position().top};
// if the non intersecting hits one that is intersecting, then there is no space
// beneath/near it, so we add it to the final intersecting array then increment c
if((id.t <= nid.t && id.t+id.h > nid.t) ||
(nid.t <= id.t && nid.t+nid.h > id.t)){ finalArr.push(this); c++; }
else { finalArr.push(this); }
});
// if c has been incremented, we cant use this nonIntersect, so add it to the final
if(c > 0) { finalArr.push(this); }
});
// make sure all items in the final Array are unique
finalArr = $.unique(finalArr);
// iterate over the final array, processing the dimensions of each element in the
// array layering them so you can see each one
$(finalArr).each(function(num){
// xd is Existing Dimensions, for the current item being checked
// verse the one being added.
var $t2 = $(this), xd = {h:$t2.height(), w:parseFloat($t2.css('width')),
l:parseFloat($t2.css('left')), t:$t2.position().top};
if(((xd.t <= nd.t && xd.t+xd.h > nd.t) ||
(nd.t <= xd.t && nd.t+nd.h > xd.t))) {
if(nd.l == xd.l){
nd.w = ((95/(finalArr.length+1))*1.5);
xd.l = ((nd.w)*(num));
$(finalArr).each(function(ci){
$(this).css({left:((nd.w*ci)*0.58)+'%',
width:((95/(finalArr.length+1))*1.5)+'%'});
nd.l = ((nd.w*ci)*0.58);
});
}
}
});
}
// Add the New Element to the container and position accordingly.
nd.l = ((nd.l/finalArr.length)*(finalArr.length+1))+'%';
nd.w = nd.w+'%';
$('#container .subContainer').append('<div style="top:'+nd.t+'px;left:'+nd.l+
';width:'+nd.w+';height:'+nd.h+'px;" class="dragId_'+$t.attr('id')+
' draggable"><div class="title">'+$t.attr('title')+'</div></div>');
任何建议/帮助将不胜感激。谢谢。
最佳答案
这是您需要执行的算法:
当有形状触摸时,找出最右边的形状(具有最大右x坐标的形状)正在触摸另一个形状。移动它,使其左边缘位于刚接触的最右边的形状的右边。
尽管有些形状不位于其左侧的某物旁边,但应找出其最小x坐标位于其左侧某物旁边的形状。移动它,使其左边缘恰好位于形状的右边,最大x坐标位于对象的y范围内。
很简单?好吧,这是简化版:
当形状彼此接触时,请移动最右边的形状,以使它不接触其他任何形状。
当某些形状彼此不依up在一起时,请移动最左边的形状,使其依ugg到最接近的形状。
编辑:例如...
假设我取了第3平方,并将其放在第1平方和第2平方的顶部:
1111 44
1111 44
1133333
1133333
33333
3333322
3333322
2222
2222
步骤1.找到最相交的形状。在这种情况下,形状为2。将其移到相交的位置右边。
1111 44
1111 44
1133333
1133333
33333
333332222
333332222
2222
2222
现在有形状在碰吗?是的,最右边的是形状3。将它移到要触摸的形状的右边,形状1:
1111 44
1111 44
111133333
111133333
33333
3333322
3333322
2222
2222
现在有形状在碰吗?是的,最右边的是形状2。将它移到要触摸的形状的右边,形状3:
1111 44
1111 44
111133333
111133333
33333
333332222
333332222
2222
2222
现在有形状在碰吗?否。所以我们完成了步骤1。
第2步:找到最左边的形状,该形状不会紧贴任何东西。在这种情况下,没有依not在任何东西上的最左边的一个是形状4。将它向左移动,使其恰好位于它最左边的形状的右边,该形状与它的y坐标相同:
111144
111144
111133333
111133333
33333
333332222
333332222
2222
2222
有什么不依依不舍的吗?不!这样就完成了!
如您所见,基本上有一个扩展阶段和一个收缩阶段。您从右到左执行扩展阶段,因此没有任何东西可以通过其他方式进行扩展。您从左到右执行收缩阶段,因此没有其他事物收缩。