Clickable Button Inside a Draggable Movie Clip

I’ve noticed postings in a few different places asking “How do I get a button to work inside a draggable movie clip?” The answer, of course, is that you can’t. Once you attach an event handler that listens for the mouse, the movie clip will receive mouse activity rather than any button contained within. But there is a way to achieve the desired effect, and it’s easily done.

The trick is that you don’t place the code on the movie clip itself. Instead, create a button the same size as the movie clip and place it inside the clip on a layer below your buttons. If you don’t want to see the button, make it invisible by populating only the hit frame. Attach your movie clip’s drag code to the button and then place any other buttons you want inside the movie clip on a layer above your drag button.

This way, the user will be able to drag your movie clip when they hold the mouse button down anywhere on the mc except for over the other buttons. Check out the sample below or download it here to see how easy it is.

This is all the code that it takes:


container_mc.drag_btn.onPress = function() {
	startDrag(this._parent);
};

container_mc.drag_btn.onRelease = function() {
	stopDrag();
};

container_mc.btn.onRelease = function() {
	counter++;
	this._parent._parent.text_txt.text="\rclick #"+counter;
};

-rG

46 thoughts on “Clickable Button Inside a Draggable Movie Clip

  1. Hi there, i’m trying to achieve something slightly similar and wondered if you could offer me anything in the way of help/advice. I have a sliding tile game working, but I want each tile of the game to have its own sound attached to it. I also want to be able to control these sounds with stop/start functions…failing that, extreme volume control from 0-100 to allow the music clips to play continuously even when not heard.

    If you could offer me any help i’d really really appreciate it. I’m currently studying for an MA in Audio Tech and Flash is very new to me…the project has to be in within the next few weeks and i’m really scared that i’m not going to get it done…

    Kind Regards,
    Jamie.

  2. Hi Jamie,

    There doesn’t seem to be anything in your question that relates to the post. There is a lot of useful information in the Flash help files on the use of sound. Look up Actionscript Classes > Sound.

    As an example, to play a sound using AS, you would write something like this:

    var theSound:Sound = new Sound();
    theSound.attachSound(“gameover”);
    theSound.start();

    gameover, in this example, refers to a sound in your library that’s been given the linkage name ‘gameover’.

    Glenn

  3. I was wondering if you’d help me also with an animating movieclip of images, inside the MC, is buttons(images), what’s suppose to happen is on mouseOver the MC should slow/stop, click on button inside MC, button takes you to another scene,frame label or external link

    Fidel

  4. Hi fidel,

    That can be done pretty easily using the example. You just need to add an onRollOver function for the movie clip:

    container_mc.drag_btn.onRollOver = function() {
    _root.stopMoving();
    /*stopMoving being a reference
    to a function you’ve written
    on the main timeline to stop
    the clips movement. */
    };

    Then change the button’s code to a goto or a getURL, something like this:

    container_mc.btn.onRelease = function() {
    _root.gotoAndPlay(“frameLabel”);
    //or
    getURL(“http://www.yahoo.com”);
    };

  5. also, I prefer to use a hit test for such situations so that you can test when the mouse is over any clip you want, completely independently of other movie clips, and thus have two different functions run without effecting each other. The above method overrides the startDrag() when the user is over the inner button, which would not happen with multiple hit tests…

  6. is it possible to do this, with 10 different containers with 10 different buttons?
    Im doing a project with 10 buttons that each lead to their own scene..I would like all 10 buttons draggable as well..is this possible to have more than one like your example
    ?

  7. @ryan: I wouldn’t want the user to be able to drag the clip around by pressing on one of the buttons. If they press on a button, I want the button functionality to kick in.

    @usualsuspekt: You can place as many of these containers on the stage as you want. They will all function independently.

  8. Geat! So what would i change to the script to have the button go to the scene instead of a counter? Sorry to trouble you im just a noob 🙁

  9. I would discourage you from using scenes. I prefer to use frame labels on the same timeline.

    scenes + actionscript = wacky results

    Read “About Scenes” in the Flash help for several reasons to avoid scenes.

    That being said, all scenes are supposed to form one timeline when the swf is compiled so you *should* be able to label a frame in your scene and use code like this:

    container_mc.btn.onRelease = function() {
    _root.gotoAndPlay(“framelabel”);
    };

  10. i got the drag function working but the whole goto marker is not working…i have the container on layer one frame one and frame 10 as well
    on layer 2 frame 1 i have a stop action
    on layer 2 frame 1 i have your script
    now when i test the scene the drag works and when i try and drag from the button(movie clip) it doesnt so it leads me to believe its almost right but it does not go to the marker thats in the script, it just stays at frame 1..
    Can you help?

  11. here is the script:

    stop();
    container_mc.drag_btn.onPress = function() {
    startDrag(this._parent);
    };

    container_mc.drag_btn.onRelease = function() {
    stopDrag();
    };

    container_mc.btn.onRelease = function() {
    _root.gotoAndStop(num1marketing);
    };

  12. You… are… a GOD!!!
    OMG No one on the freakin web knew the solution and you came up with the most simple and enginious idea EVER!
    when I make some code complement on my creations, I’ll be sure to spot your name there

  13. Thanks for the compliments, Daniel. Glad I could help. If there’s one thing I found while coding it’s that oftentimes the challenges that seem so difficult have the simplest solutions. It can just take so damn long to arrive at them!

    Glenn

  14. I’m trying to get this to work but I keep getting the same error. I’ve applied the code to a btn inside of the mc that I want to be draggable. I am getting an error that tells me the code has to be ‘within on handler’ when I attach it to the btn. Any suggestions?

    I can’t open the sample file in version MX. It would be a great help to see the sample. Thank you in advance!

  15. @Phil

    Sounds like you might be putting your button code on the timeline rather than on your button. In my example, I put all of the code on the main timeline. The button code is contained in the container_mc.btn.onRelease function.

    I uploaded an mx version for you here.

  16. I owe you my life and, perhaps, an unborn child or two! I’ve been going crazy trying to get this to work or find something/someone to point me in the right direction. With your help I found it was just one little change that makes all the difference. Your code works like a charm! Thanks for donating your knowledge to the world and helping out a poor plagued soul.

  17. Maaaaan you are my AS hero! Saved my day!
    If you need something to draw freehand, please contact me, I wanna return the favoure you did! 😀 have a nice holiday!

  18. hello rabidGadfly , thank you very much

    It is working in actionscript 2 but I have been trying to do it from along time in my project that is used actionscript 3

    I’ev tried to do it like this

    mc.addEventListener(MouseEvent.MOUSE_DOWN,dragmc);
    mc.addEventListener(MouseEvent.MOUSE_UP,dropmc);
    mc.btn.addEventListener(MouseEvent.CLICK,clickbtn);

    function dragmc(event:MouseEvent):void
    {
    event.target.startDrag();
    }

    function dropmc(event:MouseEvent):void
    {
    event.target.stopDrag();
    }

    function clickbtn(event:MouseEvent):void
    {
    trace(“clicked”);
    }

    the drag and drop is working fine but the click is’nt

    the error for the click code

    mc.btn.addEventListener(MouseEvent.CLICK,clickbtn);

    TypeError: Error #1010: A term is undefined and has no properties.
    at main_fla::MainTimeline/main_fla::frame1()

    I know the article is posted in along time but I realy need this cause I could’nt find an answer

    thanks

  19. Thanks rabidGadfly!

    Safe to say I would NEVER have figured this out on my own. One question: How do I get my “buttons” to animate on rollOver. I want the buttons to scale to 120% when you rollOver. I’m using the TweenLite class to animate, but I imagine the concepts are the same.

    Here is a sample of my code:

    onMouseMove = function () {
    updateAfterEvent();
    };

    map.mapDrag_btn.onPress = function() {
    startDrag(this._parent, false, 300, 920, 600, -300);
    };

    map.mapDrag_btn.onRelease = function() {
    stopDrag();
    };

    map.mapDrag_btn.onReleaseOutside = function() {
    stopDrag();
    };

    map.info_btn.onRelease = function() {
    this._parent._parent.gotoAndStop(2);
    };

    map.info_btn.onRollover = function() {
    import gs.TweenLite;
    import mx.transitions.easing.*;
    TweenLite.to(info_btn,1,{_xscale:120, _yscale:120});

    };

    stop();

    I can drag the map, I can click the buttons, but I can’t get that rollover state to work on the buttons.

    Thanks for any advice you might have.

  20. Hi RabidGadfly,

    I desperately need your help. I am fairly new to flash which will explain why I can’t figure this whole button in a movie clip thing.

    I’m using scence (UGH… I know) and I purchased a slide out navigation menu from a flash site. The buttons on the slide out menu have this code:

    on (rollOver)
    {
    active = true;
    }
    on (rollOut)
    {
    active = false;
    }
    on(release){
    _root.centerPAGES.mytext.text = “NAVIGATION ONE”;
    loadMovie(“one.swf”, “_root.centerPAGES.myloadmc”)
    }

    I’ve tried loading my own .swf files and tried targeting the scenes with no luck. Any help you can give me is greatly appreciated. I’m stuck and don’t know what to do.

    Thanks!!!

  21. Hello, you uploaded a MX-version of your sample. But I can’t open it (unexpected file-format). Do you have another one? I need your solution desperately!

    Jos Morren,
    Holland

  22. Hi Jos,

    Which version of Flash are you using? The fla in the zip will open in any version MX and above.

    It can also be easily recreated. All of the code is in the post. You just have to create a dynamic text field with an instance name text_txt. Use _sans as the font to make things easier for the example (you’ll have to export the characters of the font you pick otherwise). Next, create a movie clip with an instance name of “container_mc”. Then, inside the clip, create a button with an instance name of drag_btn. The code itself goes into its own frame on the main timeline.

    Glenn

  23. Hi,
    i have a draggable movie clip. Inside i have various buttons such as home, contact etc.. i want to load a external .swf file when i click on any of those buttons. How would i achieve that.

  24. hello
    there is the option to add a easing function to this script
    for have an mc draggable with inercia on release button?
    thank you

  25. Danae,
    This is just intended to be a simple example demonstrating a way to place a button inside a draggable movie clip. You can certainly add tweening or transitions to your own app if you like.

    Glenn

  26. I drew what should look like a desk from above. There are desk handles which when mouse down starts drag. Once the user stops playing around with the drag what I want to do is have a button within this “drawer” leading to a url page. I thought the post could be what I needed but I can’t seem to work it out, i don’t normally use Flash. Help.
    to see what i mean see: http://www.lizmicallef.co.uk

  27. THANKS A LOT BUDDY, ACTUALLY PAST ONE WEEK I M REALLY SO CONFUSED WORKING ON MY PROJECT (MAP DRAG AND ZOOM WITH LINK POPUP). IF I DRAG THE MAP THE INSIDE LINK IS NOT WORKING. AND I SEARCH LOTS AND LOTS OF TUTORIALS BUT I CANT GET THE CORRECT ONE. NOW YOUR CODE IS VERY USEFUL AND SUITE MY PROJECT TOO.

    THANKS !!! THANKS !!! THANKS !!! THANKS !!! THANKS !!!

  28. I can’t seem to get my drag or button to work with this code, if you see anything I’m missing. I’m using actionscript 2 and it seems that my buttons will only work if I attach the code to them. I’m having trouble getting buttons to work in the frames timeline:

    container_mc.drag_btn.onPress = function() {
    startDrag(this._parent);
    };

    container_mc.drag_btn.onRelease = function() {
    stopDrag();
    };

    container_mc.button_close.onRelease = function() {
    _root.gotoAndStop(“home”);
    };

  29. Hi Nancy,

    It could be a few different things but you probably either haven’t named an object, or you’ve named an object differently and haven’t updated the code, or you’ve added an object and didn’t add it to the code (placed the container_mc inside another mc and didn’t put the outer mc in the code for example).

    Glenn

  30. Hello. I would appreciate it if some would please post the proper code for this project for action script 3 and applicable also for flash cs4 as soon as possible and also let me know when they do so.

  31. Hi,

    This is exactly what i am looking for! I have a question. Is there any way to make it dragable just on a horizontal axis?

    Also if the button inside the movie clip was the same height as the dragable area would that count as clicking the button if you dragged the movieclip?

  32. Hi Matt,

    The startDrag function allows you to constrain the area where the object can be dragged. If you use the same coordinate for top and bottom then you will be constraining it to horizontal dragging. You can check out the AS2 or AS3 Adobe Livedocs entry for startDrag for more detail information.

    If the button is the same size as the underlying draggable area, the area will not be draggable in AS2. Only the button will be draggable in AS3 and it will register a click.

    Glenn

  33. Hi Glenn,

    Looks like your code works a treat and I am desperate to use it but, because I am new to actionscript and not all that quick on the uptake, can’t figure out how,

    I’ve downloaded the fla file and tried to find out where all the code should go but don’t understand. For instance I don’t understand where the code for your button goes?

    Would you be so kind as to break it down for me?

    Many thanks…

  34. Hi Helen,

    All the code is in Layer 1. Just click on the frame with the little “a” in it and you’ll see it. The drag button code is defined by the container_mc.drag_btn.onPress & onRelease functions, and the counter code is the container_mc.btn.onRelease function. Aside from stopping the movie and defining the counter, all of the code is literally shown and broken down above in the post.

    Glenn

  35. Wow OK, so simple! I haven’t come across the counter function before, so didn’t realize that related to the button.

    Thanks Glenn,

    much appreciated!

  36. Hi Helen,

    counter is not a function. It’s a numeric variable that I define and give a value of 0 when the swf first runs. Whenever container_mc.btn is clicked the value is increased by one ( counter++ ) and the new value of counter is displayed in the text field ( this._parent._parent.text_txt.text=”\rclick #”+counter; ).

    Glenn

  37. Thank you for this sample! Though I didn’t use the exact code, it helped me find a work around be creating a button over the graphic and dynamic text box with the alpha set to 0% and then a btn to click was on the top most layer. I couldn’t have figured that out without you!

Comments are closed.