The example above shows six different ways to scroll a textfield. Because the last three textfields include text behind a mask, which requires that the text be embedded, I have published the movie for the Flash 8 player, to take advantage of its ability to show embedded dynamic textfields without anti-aliasing. If you're looking at it with the Flash 7 player, you'll probably see the bottom 3 samples with fuzzy text. Flash 8's ability to display crisp embedded fonts is one good reason to recommend or require that site visitors upgrade.
The six examples shown in the movie above all use some kind of custom movieclips to provide scrolling instead of using a v2 component. It should be noted that the easiest way of all to provide scrollable textfields in Flash is to drag a TextArea component onto the stage (from the Components window, UI components folder), name it, size it with the transform tool, and add a line to frame 1 of the movie to assign the text to the .text property of that component. The reason I used a different approach above is to show some other ways to provide scrolling, in case you don't want the standard look of a v2 component, and/or don't want to go to the trouble of skinning it, or don't want the additional filesize that a component adds to the movie.
In the top left sample above, a textfield was created on stage (with the text tool), specified as Dynamic, selectable and with regular (non-html) formatting (the defaults), multiline (not the default) and named descrip1, all in the Properties panel. Movieclip "bubble 2 blue" was dragged out of the library and named up, and another copy dragged out, flipped, and named down.
Making a button movieclip from a button:
The up and down circle movieclips in the example above were created by opening the library of buttons that comes with Flash 8 (Window, Common Libraries, Buttons), looking in the Buttons Bubble 2 folder and dragging a copy of bubble 2 blue onto the stage. With the button on stage selected, I changed its type to Movieclip in the Properties panel, and in the Library (by right-clicking, choosing Type and selecting Movieclip). That made it a movieclip with 3 frames, corresponding to its original 3 states: up, over and down. I deleted the 3rd frame, modified the content in frames 1 and 2 to look like I wanted it to look on mouseout and mouseover, added a stop action to the first frame, and labelled the first frame _up and the second _over. Using those labels makes the movieclip respond to the mouse as though it were a button, but allows you to put code in your movie that treats it like a movieclip. You can also label the 3rd frame _down, but I didn't care about a down state in this example.
In the movie, within my init function, I first assigned a string to the .text property of descrip1 (using \n to add line breaks), and then assigned appropriate functions to the .onRelease property of the up and down buttons. In those functions, the .scroll property of textfields is used to scroll descrip1 up and down. The .maxscroll property is checked to find out when the end of the textfield has been reached:
// Scroll textfield descrip1 up one line if not at beginning
function scrollUpOneLine() {
if (descrip1.scroll > 0) {
descrip1.scroll--;
}
}
// Scroll textfield descrip1 down one line if not at end
function scrollDownOneLine() {
if (descrip1.scroll < descrip1.maxscroll) {
descrip1.scroll++;
}
}
function init() {
descrip1.text = "National Philharmonic\nJung Lin Piano Recital\n\nPerformance Dates:\nApril 8, 7:30pm\nApril 9, 2:00pm\n\nTaiwanese pianist Jung Lin appears for the first time with the Piano Recital Series performing Mozart's Sonata in F Major and Liszt's Sonata in B minor.\n\nAbout the National Philharmonic:\nPiotr Gajewski, Music Director and Conductor\nThe metropolitan area's premiere professional chamber orchestra, National Philharmonic presents a variety of classical orchestral repertoire for Rockville audiences.";
up1.onRelease = up1.onReleaseOutside = scrollUpOneLine;
down1.onRelease = scrollDownOneLine;
}
init();
The second (upper right) example uses a different type of scrolling, and also has some formatting applied to the textfield. The easiest way to apply formatting is to make the textfield html-formatted by clicking the html button in the Properties panel, as shown below, and using HTML tags in the text where needed.

Now that the text is html-formatted, we'll use <br /> tags to add line breaks, instead of \n, and apply any other formatting we want. Notice that we're setting the .htmlText property now, instead of .text, because the textfield is html-formatted:
function init() {
descrip2.htmlText = "<b>National Philharmonic<br />Jung Lin Piano Recital<br /><br />Performance Dates:<br>April 8, 7:30pm<br />April 9, 2:00pm<br /><br />Taiwanese pianist Jung Lin appears for the first time with the Piano Recital Series performing Mozart's Sonata in F Major and Liszt's Sonata in B minor.<br /><br /><i>About the National Philharmonic</i>:<br />Piotr Gajewski, Music Director and Conductor<br />The metropolitan area's premiere professional chamber orchestra, National Philharmonic presents a variety of classical orchestral repertoire for Rockville audiences.";
}
To get the textfield to scroll continuously (at the frame rate of the movie, which is 20fps), we assigned these functions to the event properties of our up and down movieclips:
// Scroll continuously up at frame rate of movie
function continuousScrollUp2() {
this.onEnterFrame = function() {
if (descrip2.scroll > 0) {
descrip2.scroll--;
}
}
}
// Scroll continuously down at frame rate of movie
function continuousScrollDown2() {
this.onEnterFrame = function() {
if (descrip2.scroll < descrip2.maxscroll) {
descrip2.scroll++;
}
}
}
// Stop continuous scroll
function stopScroll() {
delete this.onEnterFrame;
}
// in function init:
up2.onPress = continuousScrollUp2;
down2.onPress = continuousScrollDown2;
up2.onRelease = up2.onReleaseOutside = stopScroll;
down2.onRelease = down2.onReleaseOutside = stopScroll;
The third (middle left) sample also uses an html-formatted textfield, but applies slightly different formatting to it:
descrip3.htmlText = "<p align='center'><b>National Philharmonic</b><br />Jung Lin Piano Recital<br /></p><p align='center'>Performance Dates:<br />April 8, 7:30pm<br />April 9, 2:00pm<br /></p><p>Taiwanese pianist Jung Lin appears for the first time with the Piano Recital Series performing Mozart's Sonata in F Major and Liszt's Sonata in B minor.<br /></p><p><i>About the National Philharmonic</i>:<br />Piotr Gajewski, Music Director and Conductor<br />The metropolitan area's premiere professional chamber orchestra, National Philharmonic presents a variety of classical orchestral repertoire for Rockville audiences.</p>";
The scrolling is similar to the scrolling above, but uses a counter to slow the rate of scroll. (Because the .scroll property can only be specified as an integer value, some fraction like 0.2 cannot be used to slow the scrolling). These are the new scroll up and down functions (stopScroll is the same as before):
// Scroll continuously (one line at a time) at a rate less than the movie frame rate
// Rate = frame rate of movie divided by max value of counter
function continuousScrollUp3() {
this.counter = 0;
this.onEnterFrame = function() {
if (descrip3.scroll > 0) {
// only scroll when counter goes beyond some max value (1 here)
if (this.counter > 1) {
descrip3.scroll--;
// reset counter
this.counter = 0;
} else {
this.counter++;
}
}
}
}
function continuousScrollDown3() {
this.counter = 0;
this.onEnterFrame = function() {
if (descrip3.scroll < descrip3.maxscroll) {
if (this.counter > 1) {
descrip3.scroll++;
this.counter = 0;
} else {
this.counter++;
}
}
}
}
Scrolling anything on stage by pixel (as in the middle right example) rather than by line of text provides a smoother operation, but requires that the textfield be extended to its full height (at runtime, after it is filled with text) and be placed behind a mask, and so (because it is dynamic) have its font embedded, which adds filesize to the movie. To accomplish all these, we made a mask in a layer above the existing textfield in the size that we want to have text showing, and converted that mask to a movieclip named mask4. We also embedded the font by clicking the Embed button in the Properties panel, choosing only those glyphs which are required in the textfield (this increased the published size of the swf from 1k to about 8k, but when we checked 'all glyphs' instead, it made the movie 162k! so be careful not to just check that by default). We also used the new Bitmap text feature (circled in yellow) in Flash 8 to keep the text crisp:

In the code, we added a variable to keep track of the height of the textfield after text was put into it, and used that to calculate the point when the textfield was scrolled all the way up under the mask:
// variable to store height of textfield after text added
var textheight:Number;
// Scroll continuously 5 pixels per frame if not at top
function continuousScrollUp4() {
this.onEnterFrame = function() {
if (descrip4._y < mask4._y) {
descrip4._y += 5;
}
}
}
// Scroll continuously 5 pixels per frame if not at bottom
function continuousScrollDown4() {
this.onEnterFrame = function() {
if (descrip4._y > mask4._y - (textheight - mask4._height)) {
descrip4._y -= 5;
}
}
}
// in function init:
descrip4.text = [same as for descrip1 above];
descrip4.autoSize = "left";
textheight = descrip4.textHeight + 5; // add some extra pixels for insurance
up4.onPress = continuousScrollUp4;
down4.onPress = continuousScrollDown4;
up4.onRelease = up4.onReleaseOutside = stopScroll;
down4.onRelease = down4.onReleaseOutside = stopScroll;
In the 5th example (bottom left), we went back to using html-formatted text and used a scrollbar to control scrolling instead of buttons. Because the textfield is both html formatted and behind a mask, we have to make sure all forms of the font that will be included in the textfield are embedded. This includes, as can be seen in the example, bold and italic fonts. To do that, we added two new font symbols to the library: verdanaBold and verdanaItalic, as shown in the picture below. This was done by selecting the drop-down menu at the upper right of the Library window, choosing New Font and filling in the information shown here:

One more step is required to make sure the embedded font is used, and that is to right-click the new library entry and make sure it gets exported:

Those steps were then repeated to create verdanaItalic in the library. Finally, code as assigned to the scrollbar's onPress property to make the text scroll with the scrollbar. This code requires that we calculate the position of the extended textfield relative to the mask (which is why we make the mask a movieclip), and also calculate the position of the scrollbar relative to the overall height it operates in, to calculate the amount of scroll to apply to the textfield:
// variable to store height of textfield after text added
var textheight:Number;
// variables for calculating scrollbar/textfield relationships
// position of scrollbar when at bottom:
var scrollbarbottom:Number = scrollbar5._y + (mask5._height - scrollbar5._height);
// range of scrollbar is from mask._y to scrollbarbottom:
var scrollbarrange:Number = scrollbarbottom - mask5._y;
// Scrolls descrip5 to follow scrollbar
function scrollOnMouseMove() {
this.startDrag(false, this._x, mask5._y, this._x, scrollbarbottom);
this.onMouseMove = function() {
descrip5._y = mask5._y - (textheight - mask5._height) * ((this._y-mask5._y) / scrollbarrange);
}
}
function stopScrollOnMouseMove() {
this.stopDrag();
delete this.onMouseMove;
}
// in init function:
descrip5.autoSize = "left";
// can use same textheight variable calculated for example 4
scrollbar5.onPress = scrollOnMouseMove;
scrollbar5.onRelease = scrollbar5.onReleaseOutside = stopScrollOnMouseMove;
The last example is the nicest, in my opinion. It does the same thing as the previous example but with easing applied, using the easing and Tween classes. So, of course, we now need to import those into the movie. We'll use the same variables we calculated for examples 4 and 5 (since all textfields are exactly the same height and use the same text) and change the scroll function to apply easing:
import mx.transitions.Tween;
import mx.transitions.easing.*;
// Scrolls descrip6 to follow scrollbar, with easing
function scrollOnMouseMoveEase() {
this.startDrag(false, this._x, mask6._y, this._x, scrollbarbottom);
this.onMouseMove = function() {
new Tween(descrip6, "_y", Strong.easeOut, descrip6._y, mask6._y - (textheight - mask6._height) * ((this._y-mask6._y) / scrollbarrange), 1, true);
}
}
Fla's for each of the six examples above, and a 7th sample in which eased scrolling is triggered by mousing over the text, are included in scrolltext.zip, available by subscription from the link at right.
last update: 1 Apr 2006
Discussed on this page:
scroll text, html format text, text behind a mask, scrollbar, embed font, make button movieclip from button, flash 8 text aliasing options
Files:
scrolltext1.fla - scrolltext6.fla
In scrolltext.zip, password required
(Separated into 6 separate fla's on 18 Sep 2006. Separate MX2004 versions included also)
Subscription:
A password may be obtained by subscription ($20 for one month)
An access password will be emailed to the address you specify within 24 hours of receipt of payment, and will remain active for 30 days thereafter. A list of all files currently available at the site may be viewed here.