How to Make a Scrolling Movie Clip that Wraps

Here’s one that comes up frequently: “How do I make a scrolling movie clip wrap when it reaches the end of the screen?” Usually this is asked by someone creating a scrolling nav or a scrolling background for a game. The answer is the same for both. This post will take you through the steps needed to reproduce this swf:

Download the source here

It took only 45 lines of code including the hover functionality for the buttons to create the effect.

The big secret to wrapping, as you can see from the example, is that you use two movie clips.

Set up your environment by creating your movie clip and placing it on the screen. Then create a second identical clip directly behind it. I manually placed the clips on the screen but this can be done dynamically using duplicateMovieClip. Now create back and forward buttons like those in my sample. I named my clips clip1 and clip2 and my buttons forward_btn and back_btn. I also created a 'screen_mc' clip. This is only so you can see the functionality. You can change the screen_mc references to Stage references if you want to wrap based on the stage width.

Now let's get to the code. I start off by declaring my variables:


var intervalID:Number;
var clipW:Number = clip1._width;
var screenStart:Number = screen_mc._x;
var screenEnd:Number = screen_mc._x + screen_mc._width;
var clipSpeed:Number = 5;

intervalID is the variable that will hold the interval ID. I use setInterval in conjunction with functions to move the clips.

clipW is the width of the clip. I'll use this in the code to calculate the placement of the clips when it's time to 'wrap.'

screenStart and screenEnd hold the left and right x positions of the faux screen. This can be changed to 0 and Stage.width if you want to wrap using the Stage.

clipSpeed controls how quickly the clip will move across the screen.

Next, I define the functions that will evaluate the clip positions relative to the screen:


function goForward() {
	clip1._x += clipSpeed;
	clip2._x += clipSpeed;
	if (clip1._x > screenEnd) {
		clip1._x = clip2._x - clipW;
	} else {
		if (clip2._x > screenEnd) {
			clip2._x = clip1._x - clipW;
		}
	}
}

function goBack() {
	clip1._x -= clipSpeed;
	clip2._x -= clipSpeed;
	if (clip1._x + clipW < screenStart) {
		clip1._x = clip2._x + clipW;
	} else {
		if (clip2._x + clipW < screenStart) {
			clip2._x = clip1._x + clipW;
		}
	}
}

Here's the meat of the code. The first thing I do is initiate the move by adding the speed value to the current _x value.. This won't be reflected on screen yet because the screen will not render until the code is compete. Next I evaluate whether one of the clips has gone offscreen. If it has, I move it back to the opposite side of the onscreen clip.

Now I need to implement a method of making those functions fire repeatedly while the mouse is hovering over the directional buttons. I achieve this by using setInterval and clearInterval:


forward_btn.onRollOver = function() {
	intervalID = setInterval(this._parent,"goForward",50);
}

forward_btn.onRollOut = function() {
	clearInterval(intervalID);
}

back_btn.onRollOver = function() {
	intervalID = setInterval(this._parent,"goBack",50);
}

back_btn.onRollOut = function() {
	clearInterval(intervalID);
}

The setInterval code makesw the appropriate function fire once every 50 milliseconds while the mouse is hovering over the button. So, once every 50 milliseconds, the clips will be moved the value of clipSpeed. Once the mouse is moved off the button, the interval is cleared so the function stops firing.

Hope that helps!

-rG

2 thoughts on “How to Make a Scrolling Movie Clip that Wraps

  1. Hi there.
    This little movie worked just great for a client of mine. I changed the OnRollOver to onPress and onRelease, however, they’re now reporting that if you hold the mouse button down on the arrow for over 30 seconds, the movie continues to scroll indefinitely. It seems as though the interval isn’t getting cleared properly. Please help.

    Thanks,
    Mark Field

  2. Hi Mark,

    I’m glad you found this post helpful.

    Holding the mouse down will only trigger one event so it wouldn’t make a difference how long the button was held down for. It’s more likely that you aren’t coding for an onReleaseOutside or an onDragOut event in addition to your onRelease.

    Try changing your onRelease code to something like this:

    arrow_mc.onRelease = arrow_mc.onReleaseOutside = function() {
    //function code here
    }

    Good luck!

Comments are closed.