I have a mc which includes 5 dots that can be dragged in various ways.
each one needs to be limited to the stage area when it is being dragged.
The limit should only apply to the dot when being dragged. If a dot being dragged causes another to exit the stage area that is fine.
I have tried a few ways, none work too smoothly.
One issue is that a dot which stops dragging at the edge can be hard to pick again.
Another issue is that if you drag really fast you can drag a dot offstage. This is usually when the top or bottom dot is dragged quickly from where it has stopped at the edge and the mouse is released just outside the stage.
FLA is attached, any ideas VERY welcome, not just to fix the problems either, got a better way to code it let me know!
Its not a lot of code, please take a look.
thanks
Mark
I wasn't able to open your fla, is it CS4? From looking at your link, it is hard to tell exactly where things are going wrong. If you are using startDrag() to move your dot then you can set the bounds to the stage:
PHP Code:
var stageRect:Rectangle = new Rectangle( 0, 0, stage.stageWidth, stage.stageHeight );
dot.startDrag( false, stageRect );
StartDrag is super easy and I use it all the time, but it can be trouble with more complex projects and interactivity. For example, if you want to drag something and use a custom cursor at the same time. Also the bounds applies only to object's x/y and does not account for width/height so things can be partially dragged off stage.
Below is a basic example of a handling a custom drag. An easy way to limit values is with Math.min and Math.max. Assuming your dot is a circle and the registration point is centered, it will restrict the objects rect to the stage:
Thanks
that code is great.
how do I handle the fact that my dots are inside a mc?
I have been trying to use localToGlobal without getting it right.
Mark
Ok, I see your dots are children of the kite. Then what you can do is to take the stage topLeft and bottomRight down to the local coordinate system of the items parent:
PHP Code:
function onItemDragStart( e:MouseEvent ):void {
item = e.target as DisplayObject;
In the above, the mouseX, mouseY have also been changed to item.parent.mouseX, item.parent.mouseY so they are relative to the item's parent and not the sprite containing the script.
Hi,
thanks for the code
I finally got a chance to work with it.
my dot mc is actually 3 differently scaled and tinted versions of a circle mc.
So I was a bit surprised when I started dragging those independently ;-)
I changed to this
PHP Code:
var item:MovieClip;
item = e.target.parent as MovieClip;
Now I need to go and apply some of the different movement restrictions etc.
For example if the dots in kite pattern are numbered
PHP Code:
1
2 5 4
3
1 and 3 can be dragged in any direction.
when 1 is being dragged 3 mirrors its movement and the same for 3 to 1.
2 and 4 are restricted to movement on the x axis of kite (at y 0 in kite)
5 drags the whole kite anywhere (5 is at 0,0 in kite).
all are restricted to the stage area only when actually being dragged
sure I will be back with questions
Thanks again for the great code
Mark
Hi,
I got this far on my own, 80% working.
dots 1 to 4 drag as they should.
I can not seem to get dot5 to drag the whole kite_mc.
The other issue is performance. The lines do not seem to keep up with the dots.
I eventually want to calculate all the distances and angles too.
as I said I am a designer not a coder. I would be very interested to see how you would make this code more compact.
Thanks for your amazing help, I will also attach a CS3 fla again.
PHP Code:
var item:MovieClip; var dragOffsetX:int; var dragOffsetY:int; var itemOffsetXY:int;
//add event listeners to all dots kite_mc.dot1_mc.addEventListener(MouseEvent.MOUSE_DOWN, onItemDragStart); kite_mc.dot2_mc.addEventListener(MouseEvent.MOUSE_DOWN, onItemDragStart); kite_mc.dot3_mc.addEventListener(MouseEvent.MOUSE_DOWN, onItemDragStart); kite_mc.dot4_mc.addEventListener(MouseEvent.MOUSE_DOWN, onItemDragStart); kite_mc.dot5_mc.addEventListener(MouseEvent.MOUSE_DOWN, onItemDragStart);
function onItemDragStart( e:MouseEvent ):void { item = e.target.parent as MovieClip;
//copy position of dot1 to 3 and dot1.x to 5 function copyDragTo35():void{ kite_mc.dot3_mc.x = kite_mc.dot1_mc.x; kite_mc.dot3_mc.y = kite_mc.dot1_mc.y * -1; kite_mc.dot5_mc.x = kite_mc.dot1_mc.x; }
//copy position of dot3 to 1 and dot3.x to 5 function copyDragTo15():void{ kite_mc.dot1_mc.x = kite_mc.dot3_mc.x; kite_mc.dot1_mc.y = kite_mc.dot3_mc.y * -1; kite_mc.dot5_mc.x = kite_mc.dot3_mc.x; }
function loop():void{ //draw the lines and fill kite_mc.graphics.clear(); var a:Point = new Point(kite_mc.dot1_mc.x, kite_mc.dot1_mc.y); var b:Point = new Point(kite_mc.dot2_mc.x, kite_mc.dot2_mc.y); var c:Point = new Point(kite_mc.dot3_mc.x, kite_mc.dot3_mc.y); var d:Point = new Point(kite_mc.dot4_mc.x, kite_mc.dot4_mc.y); trace(kite_mc.dot4_mc.x + " 4X"); trace(kite_mc.dot2_mc.x + " 2X");
trace(b +" point B") var distance = Point.distance(a, b); trace(distance + " distance");
kite_mc.graphics.lineStyle(0); kite_mc.graphics.moveTo(a.x,a.y); ///This is where we start drawing kite_mc.graphics.beginFill(0x9DA8D0, .3); kite_mc.graphics.lineTo(b.x, b.y); kite_mc.graphics.lineTo(c.x, c.y); kite_mc.graphics.lineTo(d.x, d.y); kite_mc.graphics.lineTo(a.x, a.y); kite_mc.graphics.endFill() kite_mc.graphics.lineTo(c.x, c.y); kite_mc.graphics.moveTo(d.x,d.y); kite_mc.graphics.lineTo(b.x, b.y);
Hi again,
You can disregard my last post I thought about the issues and made some improvements. Even as a designer, who is not a real programmer, I finally realized that the case statement was having to execute every time MouseMove happened.
Moving that to the MouseDown obviously made a big difference.
I still need some help sorting out the code for dot5
if I haven't already exhausted your interest please take a look at my latest version.
Thanks Mark.
PHP Code:
var item:MovieClip;
var dragOffsetX:int;
var dragOffsetY:int;
var itemOffsetXY:int;
//add event listeners to all dots
kite_mc.dot1_mc.addEventListener(MouseEvent.MOUSE_DOWN, onItemDragStart);
kite_mc.dot2_mc.addEventListener(MouseEvent.MOUSE_DOWN, onItemDragStart);
kite_mc.dot3_mc.addEventListener(MouseEvent.MOUSE_DOWN, onItemDragStart);
kite_mc.dot4_mc.addEventListener(MouseEvent.MOUSE_DOWN, onItemDragStart);
kite_mc.dot5_mc.addEventListener(MouseEvent.MOUSE_DOWN, onItemDragStart);
function onItemDragStart( e:MouseEvent ):void {
item = e.target.parent as MovieClip;
//drag 1 mirror movement to 3 and x movement to 5
function dragItem1(e:MouseEvent):void{
var topLeft:Point = item.parent.globalToLocal( new Point( 0, 0 ) );
var bottomRight:Point = item.parent.globalToLocal( new Point( stage.stageWidth, stage.stageHeight ) );
item.x = Math.min( Math.max( item.parent.mouseX + dragOffsetX, topLeft.x + itemOffsetXY ), bottomRight.x - itemOffsetXY );
item.y = Math.min( Math.max( item.parent.mouseY + dragOffsetY, topLeft.y + itemOffsetXY ), bottomRight.y - itemOffsetXY );
kite_mc.dot3_mc.x = item.x;
kite_mc.dot3_mc.y = item.y * -1;
kite_mc.dot5_mc.x = item.x;
loop();
}
//drag 2 or 4 restrict movement to X plane
function dragItem24(e:MouseEvent):void{
var topLeft:Point = item.parent.globalToLocal( new Point( 0, 0 ) );
var bottomRight:Point = item.parent.globalToLocal( new Point( stage.stageWidth, stage.stageHeight ) );
item.x = Math.min( Math.max( item.parent.mouseX + dragOffsetX, topLeft.x + itemOffsetXY ), bottomRight.x - itemOffsetXY );
loop();
}
//drag 3 mirror movement to 1 and x movement to 5
function dragItem3(e:MouseEvent):void{
var topLeft:Point = item.parent.globalToLocal( new Point( 0, 0 ) );
var bottomRight:Point = item.parent.globalToLocal( new Point( stage.stageWidth, stage.stageHeight ) );
item.x = Math.min( Math.max( item.parent.mouseX + dragOffsetX, topLeft.x + itemOffsetXY ), bottomRight.x - itemOffsetXY );
item.y = Math.min( Math.max( item.parent.mouseY + dragOffsetY, topLeft.y + itemOffsetXY ), bottomRight.y - itemOffsetXY );
kite_mc.dot1_mc.x = item.x;
kite_mc.dot1_mc.y = item.y * -1;
kite_mc.dot5_mc.x = item.x;
loop();
}
//drag 5 move the whole kite? not working
function dragItem5(e:MouseEvent):void{
var topLeft:Point = item.parent.globalToLocal( new Point( 0, 0 ) );
var bottomRight:Point = item.parent.globalToLocal( new Point( stage.stageWidth, stage.stageHeight ) );
item.x = Math.min( Math.max( item.parent.mouseX + dragOffsetX, topLeft.x + itemOffsetXY ), bottomRight.x - itemOffsetXY );
item.y = Math.min( Math.max( item.parent.mouseY + dragOffsetY, topLeft.y + itemOffsetXY ), bottomRight.y - itemOffsetXY );
loop();
}
//draw kite one last time just in case fast mouse movement gets dot ahead of line
//remove all possible mouse move listeners
function onItemDragStop( e:MouseEvent ):void {
loop();
stage.removeEventListener( MouseEvent.MOUSE_MOVE, dragItem1 );
stage.removeEventListener( MouseEvent.MOUSE_MOVE, dragItem24 );
stage.removeEventListener( MouseEvent.MOUSE_MOVE, dragItem3 );
stage.removeEventListener( MouseEvent.MOUSE_MOVE, dragItem5 );
stage.removeEventListener( MouseEvent.MOUSE_UP, onItemDragStop );
}
//draw and fill the kite
//calculate all distances and angles (eventually)
function loop():void{
//draw the lines and fill
kite_mc.graphics.clear();
var a:Point = new Point(kite_mc.dot1_mc.x, kite_mc.dot1_mc.y);
var b:Point = new Point(kite_mc.dot2_mc.x, kite_mc.dot2_mc.y);
var c:Point = new Point(kite_mc.dot3_mc.x, kite_mc.dot3_mc.y);
var d:Point = new Point(kite_mc.dot4_mc.x, kite_mc.dot4_mc.y);
var distance = Point.distance(a, b);
trace(distance + " distance");
kite_mc.graphics.lineStyle(0);
kite_mc.graphics.moveTo(a.x,a.y); ///This is where we start drawing
kite_mc.graphics.beginFill(0x9DA8D0, .3);
kite_mc.graphics.lineTo(b.x, b.y);
kite_mc.graphics.lineTo(c.x, c.y);
kite_mc.graphics.lineTo(d.x, d.y);
kite_mc.graphics.lineTo(a.x, a.y);
kite_mc.graphics.endFill()
kite_mc.graphics.lineTo(c.x, c.y);
kite_mc.graphics.moveTo(d.x,d.y);
kite_mc.graphics.lineTo(b.x, b.y);