Flash Drag and Drop Tutorial | startDrag Actionscript

I find that Drag and Drop is the most intuitive form of user interaction (at least using a mouse). Actionscript has some of this functionality built in, with the interactive functions startDrag and stopDrag, these can help make our coding pretty easy. If you are transitioning from as2, the code was incredibly simple:

Actionscript2

on (press) {
    startDrag (this);
}
on (release, releaseOutside) {
    stopDrag ();
}

On the movie clip action panel you’d just put that script, which is actually pretty readable even if you don’t know code. The releaseOutside is to keep from the clip missing the release event, because sometimes if a user released the mouse button but was not currently over the clip being dragged for whatever reason, it will not stop dragging.

Actionscript 3

drag-drap-as3-ballSome things have changed with as3, other than the actual coding structure, the biggest change for me doing drag and drop in the new actionscript was that the mouse events have changed. There is no more a press or release. They were replaced with, MOUSE_DOWN and MOUSE_UP. There is no more releaseOutside either and this one is a little more complicated to find among the new MouseEvent list.
Leaving it out works, but we still have the same problem. Check out the working example below and try dragging the red ball to the green or yellow one and drop it there. Since the green is above the red in the layer sequence, the mouse is over the green and when the MouseEvent.MOUSE_UP fires, it’s not on the red ball but on the green, so we don’t get to the code that drops the red ball. So the red ball code basically has times when the dragging sticks even after we release the mouse button. Not to mention the dragging is very jumpy!

ballRed.addEventListener(MouseEvent.MOUSE_DOWN, dragRed);
ballRed.addEventListener(MouseEvent.MOUSE_UP, dropRed);
function dragRed(e:MouseEvent):void{
    ballRed.startDrag();
}
function dropRed(e:MouseEvent):void{
    ballRed.stopDrag();
}

Using the Mouse Move event will help us to customize our behavior a bit more. Plus I wanted to get a more abstract level to it, so I could apply the event listeners to any display object and use the event properties to target the right clips. We begin the drag with the Mouse Down, and the create some other eventListeners for the stage that will watch the Mouse Move and Up events. So clicking on the green or yellow ball, fires the grabMe function which sets the me variable (which will hold any object) to the current target of the event, which should always be the object that you click. So we are using the same code for both the green and yellow ball. I’m a big fan of code consolidation and reuse, it takes a little more effort, but the code is much more clean and portable even. Then we add the event listeners for the stage on MOUSE_MOVE and MOUSE_UP. So first, mthe dragMe function, just says to update after event. This makes the animation smoother cause it only updates the display after the event completes it’s process. Then the drop me function is attached to the stage, so anywhere you release the mouse, the object will stop dragging, plus we remove the stage event listeners and add back the listener for the original object (me). Note the buttonMode property as well, this will make the cursor turn to a hand when you hover that object.

ballYellow.addEventListener(MouseEvent.MOUSE_DOWN, grabMe);
ballYellow.buttonMode = true;
ballGreen.addEventListener(MouseEvent.MOUSE_DOWN, grabMe);
ballGreen.buttonMode = true;

var me:Object;
function grabMe(e:MouseEvent):void{
    me = e.currentTarget;
    me.removeEventListener(MouseEvent.MOUSE_DOWN, grabMe);
    me.startDrag();
    stage.addEventListener(MouseEvent.MOUSE_MOVE, dragMe);
    stage.addEventListener(MouseEvent.MOUSE_UP, dropMe);
}
function dropMe(e:MouseEvent):void {
    stage.removeEventListener(MouseEvent.MOUSE_UP, dropMe);
    stage.removeEventListener(MouseEvent.MOUSE_MOVE, dragMe);
    me.stopDrag();
    me.addEventListener(MouseEvent.MOUSE_DOWN, grabMe);
}
function dragMe(e:MouseEvent):void {
    e.updateAfterEvent();
}

This functionality is much smoother and then when I want to add more code to the dragging or dropping, I have a place to do it already!

Example

Get Adobe Flash player

Source

as3dragdrop-ball.fla

This entry was posted in tutorial and tagged , , , , , , , , . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

11 Comments

  1. samBrown
    Posted April 27, 2009 at 9:56 am | Permalink

    interesting example, I’ve run into this as well and had to use a work-around. Thanks for the tip

  2. Posted April 30, 2009 at 4:06 pm | Permalink

    Nice tutorial, I as well had to do a work around because I wasn’t happy with the performance, but your code was a little better.

  3. André
    Posted August 28, 2009 at 8:47 am | Permalink

    What i´ve made to correct this issue??

    I´ve made a class extending the Sprite or MovieClip with the function Drag, that automatically add the listener to the stage when the mouse is down over the object, and remove when the stage has a mouseup… also all you need to do is “myInstance.draggable=true;” to create a draggable object, and you have another parameters like: lockCenter, bounds, smoothDrag (e.updateAfterEvent), topLevel (when mouse is down and topLevel is true the object becomes the top level of the container)

  4. fedoo
    Posted December 1, 2009 at 5:26 pm | Permalink

    Hi,

    Is there neccessary to use “me” variable? Could we use just “this” instead?
    like -> this.startDrag(); etc.

    thanks

  5. Morgan
    Posted December 6, 2009 at 12:40 pm | Permalink

    Worked great for me. Thanks for the tutorial.

  6. Posted December 7, 2009 at 10:09 am | Permalink

    @fedoo – the “me” isn’t required I’ve had to use it a couple times to specify the object that is being dragged in different ways in the past, and I guess it just stuck. using this is chancy though because at different times this can mean different things… I try to at least always use event.currentTarget or something of the sort.
    Thanks!

  7. Best Flash Stock
    Posted July 6, 2010 at 11:24 am | Permalink

    Thanks for the tip, very useful, i was using different approach, but it is similar.

  8. Rakesh
    Posted August 26, 2011 at 11:06 am | Permalink

    i need circle will delete when i right click on cirlce. how it will be.

  9. Anand Meena
    Posted September 8, 2011 at 7:36 am | Permalink

    Hi, I tried in flash builder and it is working fine.
    Below is the code :-
    just copy and paste this code in .mxml component.

    //Import classes so you don’t have to use full names.
    public function start():void
    {
    a3.addEventListener(MouseEvent.MOUSE_DOWN,grabME);
    a3.buttonMode = true;

    a4.addEventListener(MouseEvent.MOUSE_DOWN,grabME);
    a4.buttonMode = true;

    a5.addEventListener(MouseEvent.MOUSE_DOWN,grabME);
    a5.buttonMode = true;

    a6.addEventListener(MouseEvent.MOUSE_DOWN,grabME);
    a6.buttonMode = true;

    a2.addEventListener(MouseEvent.MOUSE_DOWN,grabME);
    a2.buttonMode = true;

    }

    private var me:Object;
    public function grabME(e:MouseEvent):void
    {
    me = e.currentTarget;
    me.removeEventListener(MouseEvent.MOUSE_DOWN, grabME);
    me.startDrag();
    stage.addEventListener(MouseEvent.MOUSE_MOVE,dragMe);
    stage.addEventListener(MouseEvent.MOUSE_UP, dropMe);
    }

    public function dropMe(e:MouseEvent):void {
    stage.removeEventListener(MouseEvent.MOUSE_UP, dropMe);
    stage.removeEventListener(MouseEvent.MOUSE_MOVE, dragMe);
    me.stopDrag();
    me.addEventListener(MouseEvent.MOUSE_DOWN, grabME);
    }

    public function dragMe(e:MouseEvent):void
    {
    e.updateAfterEvent();
    }

    Thanks for this nice tutorial :-)
    Best of luck for your next tutorial.

  10. Kylie
    Posted October 7, 2011 at 12:32 pm | Permalink

    Hi, I am doing a puzzle game. MOUSE_DOWN is to startDrag(); and MOUSE_UP is to stopDrag();. I also used x and y coordinates to snap and hold the puzzle piece into place once the piece goes over the invisible movie clip. It works for the first puzzle piece which snaps into place but when I want to move my other puzzle pieces it doesn’t allow it.

    Do I add removeEventListenr():? Because when I do it says “Incorrect number of arguements? Thanks for the help.

  11. Posted November 14, 2011 at 10:33 am | Permalink

    Dude

    Cheers for this, I’ve been getting strange interference to my keyboard events caused by a slider and this appears to have fixed the issue and makes for far smoother dragging.

One Trackback

  1. By Video | Enjolt.com | Innovate for Success on April 25, 2009 at 2:17 pm

    [...] strong class=keywordFlex/strong optimization techniques and practices Open Enterprise 2009: Dion Flash Drag and Drop Tutorial | startDrag Actionscript – circlecube.com 04/24/2009 I find that Drag and Drop is the most intuitive form of user [...]

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

  • Recent Posts

    Developing for old browsers is (almost) a thing of the past – (37signals)

    Basecamp announces that it’s new version will not support old browsers! They will of course continue to support them in their “classic” version. But this is good news and as more implement this type of policy the internet will be happy. It used to be one of the biggest pains of web development. Juggling different [...]

    Screen shot 2012-02-10 at 12.59.33 PM

    Vendor Prefixes – about to go south

    What are “standards” coming to? Who’s guilty? Apple and Chrome: They’re supporting vendor prefixed properties like they’re a standard part of development. Firefox, Opera and Internet Explorer: They should have been on the ball more. Need to push their evangelism further. Teach developers that it’s not exclusively -webkit to style elements. All the browsers: experimental [...]

    bio

    An Event Apart Notes: Ethan Marcotte, Responsive Web Design

    Ethan Marcotte has become the father of Responsive Web Design and spent this whole day focused on principles, techniques, gotchas, examples, … all about building and how to build responsive sites. With a sprinkle of mobile first. For Ethan, it all started with this article: http://www.alistapart.com/articles/dao/ Think of architecture, the whole design phase is established [...]

    Webcomm_Montreal

    An Event Apart Notes: Jared Spool, The Curious Properties of Intuitive Web Pages

    Senseless waste of asterisks… Avis used an asterisk to denote optional fields. This means that there is a lot of baggage that comes with an asterixk. Somewhere this symbol got meaning, it’s not in the bible! We can control when something goes from unintuitive to intuitive. A design is intuitive (although technically and grammatically speaking [...]

    untitled-158-2

    An Event Apart Notes: Marco Arment, Bridging the App Gap

    The iPhone changed our industry in 2007: first mobile to have a desktop class web browser and it made people start using their mobile phones as computers! All apps other than apple provided ones were web browser apps. Most of the first apps were branded web browsers. No real difference between using mobile site or [...]

    lukew_space

    An Event Apart Notes: Luke Wroblewski, Mobile to the Future

    MASS MEDIA (in waves) Print, Recordings, Cinema, Radio, Television, Internet, Mobile Mobile is the new Mass Media It certainly is mass and massive. More mobile devices (by far) every day than babies born on the planet. Mobile devices are eating into our personal computing shares. New waves of mobile media eat all previous media waves. [...]

    IMG_4500

    An Event Apart Notes: Josh Clark, Buttons are a Hack

    Mobile and touch should be revolutionizing design and user experience. We don’t want to touch a tiny link or button. Back button is just stupid. Fitz’s Law, make things fat proximal targets for easy touching. People are lazy, let’s as designers LET people be lazy! Maybe even use the whole screen as your control. Eliminate [...]

    nicole_pink_bkg_2012

    An Event Apart Notes: Nicole Sullivan, Our Best Practices are Killing Us

    Grep to for analyze css. CSS duplication is a web-wide problem. Started helping facebook optimize thier site and they had 1.9MB of css loading. The same color showing up hundreds of times. Many many color statements and declarations. !important declarations get dangerous. Sites found to have over 500 !important declarations! float is a serious problem [...]

    ericmeyer

    An Event Apart Notes: Eric Meyer, The Future of CSS

    Cormorant trained to fish for the fishermen. The fishermen tie bands around the birds necks that are. Fishermen fish at night, using lamps they attract bugs, which attract fish, and the cormorant get to fish but cant swallow them and the fishermen take the fish. Browser vendors are promising us new CSS tools, but don’t [...]

    sammyj

    An Event Apart Notes: Ethan Marcotte, Rolling Up Our Responsive Sleeves

    Henry Adams (Descendant of 2 presidents: great-grandson to John Adams and grandson to John Quincy Adams). He lived between the civil war and world war 1. He witnessed the industrial revolution. Chaos was the law of nature, Order was the dream of man Samuel Johnson – funniest man in the 17th Century… Responsive Design: 1. [...]

  • Recent Comments

    me-gamer

    me-gamer

    this is really nice. this made many of my task simple.
    Lori Newman

    Lori Newman

    Just wanted to thank you for your presentation. It was extremely informative and just what I...
    Karl

    Karl

    I have been using for some time this nice Banner, from developer FX. They have a really nice Live...
    Karl

    Karl

    Thank you for this wonderful link… recommend it! Fast, simple, easy… :-)
    Gabriel

    Gabriel

    Hi Valerie, I don’t know if you are still following this post, but I tried seeing if it is...
    avinash

    avinash

    Hi Evan, I am using the same code and trying it on chrome/firefox it is not working on neither...