ActinScript算法,拖拽、框选

需要涉及到的问题
1. 通过两个点获取到包含在两点之间的所有节点(框选)
2. 整体拖拽(框选后的整体拖拽)
3. 只允许节点在限定范围内拖拽(不让被框选的节点拖出限定范围外)

通过两点获取包含在两点之间的节点:
首先得到Canvas(简称ca)的两个点坐标即beginPoint,endPoint。通过节点(简称n)的x,y能够获取到该节点的中心点,即centerX,centerY。
代码:

public function setSelectionNodes(beginPoint:Point, endPoint:Point):void
{
for each (var n:GBaseNode in _allNodes)
{
if (beginPoint.x < endPoint.x && beginPoint.y < endPoint.y)
{
if (n.centerX > beginPoint.x && n.centerY > beginPoint.y && n.centerX < endPoint.x && n.centerY < endPoint.y)
{
n.select();
selectedNodes.push(n);
}
}
if (beginPoint.x > endPoint.x && beginPoint.y > endPoint.y)
{
if (n.centerX > endPoint.x && n.centerY > endPoint.y && n.centerX < beginPoint.x && n.centerY < beginPoint.y)
{
n.select();
selectedNodes.push(n);
}
}
if (beginPoint.x < endPoint.x && beginPoint.y > endPoint.y)
{
if (n.centerX > beginPoint.x && n.centerY < beginPoint.y && n.centerX < endPoint.x && n.centerY > endPoint.y)
{
n.select();
selectedNodes.push(n);
}
}
if (beginPoint.x > endPoint.x && beginPoint.y < endPoint.y)
{
if (n.centerX < beginPoint.x && n.centerY > beginPoint.y && n.centerY < endPoint.y && n.centerX > endPoint.x)
{
n.select();
selectedNodes.push(n);
}
}
}
}

代码中分别处理的四种情况,即由[b]左上角向右下角拖拽[/b]、[b]右下角向左上角拖拽[/b]、[b]左下角向右上角拖拽[/b]、[b]右上角向左下角拖拽[/b]。

整拖
每个节点都有两个属性用于判定当前坐标,即selectionXOffset和selectionYOffset,在选中节点后,点击一个被选中的节点,将此节点放入到一个新的变量_firstSelectedItem,通过此变量来判定其他节点的x,y坐标

var xOffset:Number=node.x;
var yOffset:Number=node.y;
for each (var baseNode:GBaseNode in this.selectedNodes)
{
if (baseNode == node)
{
continue;
}
else
{
baseNode.selectionXOffset=xOffset - baseNode.x;
baseNode.selectionYOffset=yOffset - baseNode.y;
}
}
view.addEventListener(Event.ENTER_FRAME, dragAllHandler);


在dragAllHandler中的处理函数如下:

private function dragAllHandler(e:Event):void
{
for each (var n:GBaseNode in this._selectedNodes)
{
if (n != _firstSelectedItem)
{
n.move(_firstSelectedItem.x - n.selectionXOffset, _firstSelectedItem.y - n.selectionYOffset);
}
}
}


限定范围内的拖拽,不仅仅是当选的节点的范围,还要考虑到整拖的时候不让其他节点也拖拽到边界外面去,因此,需要获得上下左右四个节点如图所示:
[img]http://dl.iteye.com/upload/attachment/462240/5db3cb78-e12b-3bc2-881c-0e5ccf3a579f.bmp[/img]
中间的节点是鼠标按下去的拖动节点,其他周边四个节点的移动则是参考了中间节点的坐标而移动的,为了不让节点在整体拖拽的时候被拖出工作区外,需要限定中间那个节点的拖拽范围。


if (view.isSelection && node.isSelected)
{
_firstSelectedItem=node;
//找到最左上角的节点
var leftNode:GBaseNode = findLeftNode();
trace("最左边的节点ID是:"+leftNode.itemId);
var topNode:GBaseNode = findTopNode();
trace("最上边的节点ID是:"+topNode.itemId);
var bottomNode:GBaseNode = findBottomNode();
trace("最下面的节点ID是:"+bottomNode.itemId);
var rightNode:GBaseNode = findRightNode();
trace("最右边的节点ID是:"+rightNode.itemId);
var lx:Number = node.x - leftNode.x;
var ly:Number = node.y - topNode.y;
var w:Number;
trace(_firstSelectedItem.itemId);
if(rightNode == _firstSelectedItem){
trace("1")
w = view.width - _firstSelectedItem.width - lx;
trace(_firstSelectedItem.itemId);
}else{
w = leftNode.x + (view.width - rightNode.x-rightNode.width);
}
var h:Number;
if(bottomNode == _firstSelectedItem){
trace("2");
h = view.height - _firstSelectedItem.height-ly;
}else{
h = topNode.y + (view.height - bottomNode.y - bottomNode.height);
}

trace(w,h);
node.startDrag(false, new Rectangle(lx,ly, w,h));
node.isDraging=true;

var xOffset:Number=node.x;
var yOffset:Number=node.y;
for each (var baseNode:GBaseNode in this.selectedNodes)
{
if (baseNode == node)
{
continue;
}
else
{
baseNode.selectionXOffset=xOffset - baseNode.x;
baseNode.selectionYOffset=yOffset - baseNode.y;
}
}
view.addEventListener(Event.ENTER_FRAME, dragAllHandler);
return;
}



其中findTopNode等类似函数,如下所示:

private function findTopNode():GBaseNode
{
var topNode:GBaseNode;
for each(var n:GBaseNode in _selectedNodes){
if(n == _firstSelectedItem){
continue;
}
var len:Number = _firstSelectedItem.y - n.y;
if(len >= 0)
{
if(topNode != null)
{
var len2:Number = _firstSelectedItem.y - topNode.y;
if(len2 >= 0)
{
if(len > len2)
{
topNode = n;
}
}
}else{
topNode = n;
}
}
}
if(topNode == null){
return _firstSelectedItem;
}
return topNode;
}

此处只是给出解决问题的方法,并没有指望您能看懂我写的代码,只希望你能看懂我的思路即可。也许你有更好的解决方案或者算法,还望赐教。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值