AS3 Clickable Button Inside a Draggable Movie Clip

A few years back I wrote a popular post that demonstrated an AS2 technique to have a clickable button inside of a draggable movie clip. Recently, I received a request to see how it would be accomplished in AS3.

I haven’t posted in a LONG time and I thought it was a great idea. Not only does it get me blogging again, but it’s a great, short introduction to a couple of the new features in AS3.

Download the sample

AS3 uses events to handle mouse click functionality. Rather than the AS2 method of adding an onRelease function to the clickable object, you now assign an event listener. While this is a pretty significant difference that may take a bit of getting used to, programmatically it makes a lot of sense.

AS3 used the DOM event model as a basis for its own event handling. So, instead of something that looks like this:

//AS2 button event
container_mc.drag_btn.onPress = function() {
	startDrag(this._parent);
};

The AS3 method looks like this:

//AS3 event handling
container_mc.addEventListener(MouseEvent.MOUSE_DOWN,mouseDownHandler_Drag);
function mouseDownHandler_Drag(mEvent:MouseEvent):void {
	mEvent.target.startDrag();
}

For a good introduction to AS3 Event Handlers, check out the Newton Flash 6 part series. Even though he uses the moniker of "Devigner", which I can't stand, the posts are pretty informative and to the point.

Another significant difference is that I no longer need an invisible button to allow me to drag the container around. AS3's event bubbling makes it possible to listen to both the container and the button within the container at the same time. Ruben Swieringa wrote a great post explaining AS3 bubbling which is definitely worth a look.

One addition to the code that may trip you up is the assignment of buttonMode to the Click Me button. AS3 does not assume that you want the hand cursor to appear over a movie clip just because you added a listener. Because of this, by default the cursor will remain an I-bar unless you set the clip's buttonMode to true:

container_mc.btn.buttonMode = true;

Another change to notice in the sample code is that there are no longer referrals to "_parent." (Though if there were, you would see that the new syntax drops the underscore so that it is simply "parent".) The reason it was required in the first place was because I needed to reference an object that was out of the clickable objects scope, and I didn't want to use _root. AS3's Event Handling method allows you to put the function code in the same scope as the outer container. This means that I can refer to it directly rather than having to navigate upwards:

//as2
this._parent._parent.text_txt.text="\rclick #"+counter;

//as3
text_txt.text="\rclick #"+counter;

One final piece that I'd like to point out is the reference to mEvent.target in my handler functions. mEvent is a reference to the mouse event pulled from the function's parms. mEvent.target is a reference to the object that the listener was attached to. So, when I want to start dragging the object that was clicked, I just refer to the target of the event:

mEvent.target.startDrag();

My apologies for such a long post about such a short sample. I just felt that this sample offered a great opportunity to address some of the early stumbling blocks when making the move to AS3.

-Glenn

NOTE: If you didn't notice the sample link above, here it is again.

13 thoughts on “AS3 Clickable Button Inside a Draggable Movie Clip

  1. That´s right. But I want the button to be a constant part of this mc. So the button should stick only with its movie. No dragging allowed for the button.
    Thanx again

  2. I noticed that startdrag and stop drag does not work correctly on osx 10.6.3 on firefox 3.6.3
    The dragger does not follow the mouse
    Instead it only moves when you let go and jumps to position

  3. Hi, i totally need this effect, however, i could not open up the fla file. Could you send it to my email??? thank you so much. 😀

  4. this example is great, but the yellow container_mc.btn movieclip is draggable too… to keep this from happening you have to use stop propagation OR stopImmediatePropagation.

    container_mc.btn.addEventListener(MouseEvent.MOUSE_DOWN,mouseDownHandler_BtnDrag);

    function mouseDownHandler_BtnDrag(mEvent:MouseEvent):void {
    mEvent.stopImmediatePropagation();

    }

  5. Hi Glenn,

    Nice tutorial, Im looking for something slightly different and would really appreciate some help.

    Basically what im after is a map of the UK, Each Region needs to be a button, which just makes a popup visible. However the map on the whole needs to be draggable, so that you can zoom in and out, drag the map around and then click the region button to open the popup.

    As it stands, i can drag the map around fine, but when i release the mouse it is acting as click and opening the popup. How can i differentiate between a click and a drag?

    Im in AS3 by the way.

    Here is simple code as it stands.

    import flash.display.MovieClip;
    import flash.events.MouseEvent;
    import flash.display.DisplayObject;
    import flash.events.Event;

    map.buttonMode = true;

    zoomin.addEventListener(MouseEvent.MOUSE_DOWN, zoomIn);
    zoomout.addEventListener(MouseEvent.MOUSE_DOWN, zoomOut);

    function zoomIn(e:MouseEvent) {
    //actions for zoom-in function
    map.scaleX += 1;
    map.scaleY += 1;
    map.x -= 303;
    map.y -= 317;
    }
    function zoomOut(e:MouseEvent) {
    //actions for zoom-out function
    map.scaleX -= 1;
    map.scaleY -= 1;
    map.x += 303;
    map.y += 317;
    }

    map.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
    map.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);

    function mouseDownHandler(evt:MouseEvent):void
    {
    var object = evt.currentTarget;
    object.startDrag();
    }

    function mouseUpHandler(evt:MouseEvent):void
    {
    var obj = evt.currentTarget;
    obj.stopDrag();
    }

    northumberlandPopup.visible = false;

    map.northumberland.addEventListener(MouseEvent.MOUSE_UP, shownorthumberlandPopup);
    function shownorthumberlandPopup(evt:MouseEvent):void
    {
    northumberlandPopup.visible = true;
    }

    Thanks in advance

    James

    1. Thanks for stopping by, James. At a glance it looks like it’s opening a popup when the button is released because of the shownorthumberlandPopup function which fires when the mouse is released anywhere over the northumberland object. If you’re still having a problem, try posting this on a forum like Stack Overflow where it will be seen by a large number of expert coders, all eager and willing to help out a struggling brethren.

      Glenn

Comments are closed.