Movieclip Scroller
Published
November 5, 2007
Difficulty
Beginner - Intermediate
A popular effect used in flash websites is the mouse to movieclip scroller - in other words the movieclip moves vertical or horizontal in relation to the position of the mouse. See above for a demonstration. Be careful though as this may be a cool effect, but can become unprofessional if used inappropriately. Generally it is good to use in like a photo gallery or similar.
This example is a horizontal scroller that has minimum and maximum edge based on the stage width. To begin you will need a movieclip to scroll. Create something but make sure it is bigger than the stage width. Drag the movieclip on the main timeline and add the following actionscript to it.
onClipEvent(enterFrame) {
var speed = 10;
var xpos = _root._xmouse - (Stage.width / 2);
this._x = this._x - (xpos / speed);
var left_edge = 0;
var right_edge = -(this._width - Stage.width);
if (this._x < right_edge) {
this._x = right_edge;
} else if (this._x > left_edge) {
this._x = left_edge;
}
}
Test you movie, for a small amount of code it should be working really well and moving the movieclip depending on the mouse’s position. It is even stopping once the movieclip reaches the left and right edge of the stage. But how does it work…let's break it down.
onClipEvent(enterFrame) {
var speed = 10;
var xpos = _root._xmouse - (Stage.width / 2);
this._x = this._x - (xpos / speed);
...
Firstly we created an onClipEvent handler that executes each frame of the movie. Next we define a variable called ‘speed’ which will determine how fast the motion of the movieclip plays. Our second variable is ‘xpos’ which uses the horizontal position of the mouse and minuses the width of the stage divided by 2. What this means is say we have a stage width of 500 pixels, if the mouse is in the center of the stage, the xpos value will read zero, but if we go hard up against the left side the value will equal negative 250, and positive 250 if the mouse goes hard up against the right side of the stage. This value is important because we want the motion of the movieclip to stop when in the center of the stage, but go faster the closer we are to each edge. Trace the xpos value to see what I mean.
onClipEvent(enterFrame) {
...
this._x = this._x - (xpos / speed);
...
This line of code is the one setting the x position. We are setting it to equal its current x position minus the xpos value divided by the speed. We do not need to divide by the speed variable, but if left out the motion will be very fast. So by doing this calculation we are making the negative and positive value of xpos smaller, therefore making the steps for the motion slower. With only these 3 lines of code the scroller works fine, but you will notice that it will not stop on each side, instead animating off the page. This is what the if statement if for.
onClipEvent(enterFrame) {
...
var left_edge = 0;
var right_edge = -(this._width - Stage.width);
if (this._x < right_edge) {
this._x = right_edge;
} else if (this._x > left_edge) {
this._x = left_edge;
}
}
Firstly we define two variables, one for the left edge and another for the right edge. These can be any value depending on your requirements. If you are not setting the min/max edge based on the stage, the best way to find your required values are to place the movieclip on the stage and move it to the points it will stop, while noting the x position in the properties panel. For this example, I want the movieclip to stop at the left and right edge of the stage so therefore the left edge is simply zero and the right edge is a negative value of the movieclips width minus the stage width. Then the if statement checks to see if the movieclips x is less than the right edge, if so it sets the x position to the right edge meaning it will be stuck in that position. The same for the left edge only we want to check if it is greater than the left edge value.
There are many ways to do this, but this is by far one of the most simplistic. You can change the xpos, speed, left edge, and right edge variables to customise the scrolling parameters. You would do this if you didn’t want to scroll based on the stage width - instead restricting it inside a smaller area. It is also effective to use a mask around the movieclip if you were to restrict it to an area, for instance inside a TV. It is also easy to change it to a vertical scroller, just change the width to height, _xmouse to _ymouse, left to top, right to bottom, and also reversing both operators (less than and greater than). See below:
onClipEvent(enterFrame) {
var speed = 10;
var ypos = _root._ymouse - (Stage.height / 2);
this._y = this._y - (ypos / speed);
var top_edge = 0;
var bottom_edge = -(this._height - Stage.height);
if (this._y > bottom_edge) {
this._y = bottom_edge;
} else if (this._y < top_edge) {
this._y = top_edge;
}
}
About the Author 'Ryan'
Ryan Davis
http://www.evolutionmultimedia.com.au Ryan Davis is the founder of Multimedia Life. In an industry where the geography of clientele is not important, he freelance his skill to all parts of the world. Ryan is a huge fan of flash, and loves designing, animating, and programming.
More about Ryan »
Comments
Thanks Ryan, great tutorial which has helped me a lot.
I have put together a vertically scrolling movie on a stage which is scrolling perfectly but continues to scroll when I roll out of the movie and go to the menu.
Is there anyway I can get my movie to only scroll when the cursor is over it, and to automatically scroll back to the top when I rollout?
Thanks again,
Jamie
Hi Jodonnell, You can use hitTest in an if statement to check if the mouse has rolled over the movieclip.
What this does is check if the mouses x and y position are in the movieclip, if so it runs the code as normal. Else it will move the movieclip until it is back to its original position. You may need to adjust your operators (<, +=) for the else statement depending on how you've set things up.
Cheers Ryan
Thanks Ryan, that worked a treat. Much appreciated.
Ryan, thanks for the tutorial! I'm new to actionscript and am having a problem with adding the hitTest part. Could you please put all the code together with the hitTest? I would also like for the movie clip to stop where it is at instead of it returning back to the original position, would I just use stop();? Thanks for your time.
Hi jpainter,
We do not need the stop() function because stop() is used to control the timeline of the movieclip or stage - whereas this actionscript moves the movieclip based on the mouses position. Below is the code including the hitTest condition:
hi ryan
suppose there are 10 images like this
i want to create a vertical scrolling image gallery
without timeline
and there is a button
if the button is pressed the scrolling stops at the current position
and if the button is released it starts scrolling
another point is that
if any of the 10 images are clicked it should set focus or position it to the 3rd image(particular image)
pls help me
also show the code
im very grateful to u
if u could find out a solution
pls reply within 6 hrs
pls friend
Awesome Tutorial.
I am have an issue though. I have the movie clip working when its by it self however when I load the .swf which hold the scroll nav bar it doesnt work. just apprears to blink continusouly. the buttons inside the same scroll nav bar finally got working but using the code:
on (release) {
_parent.gotoAndPlay ("My Frame Label");
}
Maybe I have to do something similar here?
I tried changeing the line
FROM: " var ypos = _root._ymouse - (Stage.height / 2); "
TO >> " var ypos = _parent._ymouse - (Stage.height / 2); "
but that makes no difference either.
the size of this movie stage is 1013.7 x 443.9
code for scroll nav bar.
onClipEvent(enterFrame) {
var speed = 10;
var ypos = _root._ymouse - (Stage.height / 2);
this._y = this._y - (ypos / speed);
var top_edge = 0;
var bottom_edge = -(this._height - Stage.height);
if (this._y < bottom_edge) {
this._y = bottom_edge;
} else if (this._y > top_edge) {
this._y = top_edge;
}
Can anyone please help me? I'm lost.
Thanks
I have tried this using the exact original swf and using loadMovie to load it in a blank flash canvas - and it works perfectly. Have you changed the original actionscript in any way?
Try it with the original movieclip_scroller.swf and if it works compare this to your loaded file. If it doesn't work something in your main movie is controlling the swf.
FYI never use _parent._ymouse as it always must be _root._ymouse.
Cheers,
Ryan
Thanks for the reply Ryan
I can see where the problem is and hope you can help.
The issue I am experiencing is because the stage size for the Main Movie is different from the stage size of the movie holding the scroll bar nav.
Main movie 1024x768
loaded movie 1013.7x443.9
Loading movie work perfect when the stage size is the same.
As soon as I changed the stage size in the main during testing i was able to reproduce the issue.
what do I have to change?
is it the Stage.height causing the problem?
Thanks
Tim
Well I figured it out. I had to adjust the scrolling nav bar movie clip bigger then the main stage. so by itself its off but looks ok when loaded into main stage. I wish there was a prettier way of fixing this though.
Thanks
Yes you are right I done a few tests loading the scrolling movie onto a blank canvas. Because the scroller movie uses Stage.width, this value will depend on the main stages level (_level0). When I changed the width of the main stage, the scroller movie always worked unless the main stages width was bigger than the loaded movies scrolling movieclip.
You should be able to change the Stage.width value to a custom one. I'm not sure what you are trying to do, but if you wanted to scroll inside a masked area, not the main stage, then you would need a set value instead of the stages width.
can u create this in vertical scrolling gallery
Yes the vertical scrolling code can be found above (you may need to change the operators depending on your set up). Here it is again:
see Ryan's code above.
ryan the code is right
but it is going too fast when trying vertical scrolling
pls help
Hey Ryan.. this is a great tute.. Thank you.
I have a question about if I want the x position and movement based on the width of a Movie Clip and not the stage... My moveclips are nested a few times.
I have a main movieclip on the stage... "mc_1".. inside of that moveclip, I have another one called "mc_2". mc_2's width is the one I want the xpos to be based off of.. and inside of that I have "mc_3".. which is the actuall movieclip that I want to move back and forth.
I figured that all I would have to do is target the movie clip inside the code instead of using "stage" and "this"... some thing like this below ?
But Alas, I can't seem to get it to work.. Any idea's on how to make this work ?
Thanks so much!
When basing the scroll area to a movieclip, you should be able to use the original code, but only change two variables 'left_edge' and 'right_edge'. We will set these variables based on the target movieclips _x position and _width. So use the original actionscript and change these variables to:
Make sure this code is placed on mc_3. Also don't place mc_3 inside mc_2 as this will alter the _width of mc_2. The above code is based on mc_3 at the same level as mc_2.
Cheers
I see.. it is now using mc_2 to determine the left and right edge for it's stopping point..
but.. the scroll is occurring based on the mouse being either to the left or the right of the center of the stage..
I am trying to make the movie scroll based on the mouse being to the left or the right of the center of mc_2's width.. because the movieclip with the scrolling thumbnails doesn't span the whole stage..
I think I would need to make a change to the first variable calling xpos.. but I've not had luck adjusting that code..
Hey Ryan.. Any idea's on how I might accomplish the result in the above mentioned post ?
thanks!
You are right xpos needs to be changed. Bit of a tricky one but it is self explanatory.
Thanks so much Ryan for your help with this... the code worked out!
I also figured out that if I made the xpos 'stage / 2 - (the # of pixels to be midway over the MC i wanted it to be over)' that also worked... along with the hit test.. it has the same effect !
Cheers!
Hai Ryan,
Great Work!.... I need looping, means after finished 10 it will continue from 1,2,3....10,1,2....10...
At first it sounds difficult but looping the movieclip scroller requires only a few changes. Starting off you need a new movieclip containing two instances of the scrolled movieclip next to each other - this is because there are points where it scrolls and it needs to show both the start and end of the scrolled movieclip. Drop this new movieclip onto the stage, add the exact same code in the original tutorial but change the last if statement to:
What it is doing is adding or subtracting half of the movieclips width when it reaches either end. This way it seamlessly adjusts the _x position so it looks as though it loops.
Cheers
thanks for the nice tut but i will not work for me and i dont know why :(
i tried the vertical one but when i put the code on the mc
and test it, it dont scroll smooth like the horizontal, it blink weird.
can u tell me where the bug is ??
Hi Ryan.
Any ideas how can I incorporate your code above using the stagewidth for user to scroll left and right on a dynamic movieclip based on an xml and images in my folder?