Easy Flash Custom Scrollbar Class (AS2)

– taterboy | September 10th, 2008

Filed under: ActionScript 2, Design, Flash, Free Components/Classes, Tips

I know there are some really nice scroll components similar to this on the web, but I think this still has merit. It seems like every job comes with a different scroll bar design, the buttons and scroll bar can be any shape, size or configuration. While most Flash scroll bar components are easily skinned, this is kind of the opposite of skinning. You create the artwork, convert each item to a MovieClip, then apply the class. The code wraps the artwork instead of the artwork skinning the code.

This class started around 3 years ago and has been modified for many different projects and continued to evolve into what we have today. It is not perfect, but it can handle most jobs needing custom scroll bars.

Demo:

Some of the features include:
Auto On/Off – you may need a scrolling clip that could change in size as dynamic content is displayed or entered. When the scroll bar is not needed, it will turn itself off and back on when it is needed. Or you can manually turn it on and with your code.

Easing – Control the amount of ease or delay of the scrolling object.

Scroll Bar Resizing – To simulate the function of desktop applications, the scroll bar will automatically scale depending on the amount of scroll, This feature can be turned on or off.

Auto Resize – Say you have a project that needs multiple scroll bars. One 150 px tall, the other 500 px tall. With this class you can build one set of artwork and the class will automatically adjust the bottom button, scroll background, scrollbar scroll area to fit the needed size. Based on Mask size.

Down Button Flip – This will not change the world, but if you have an Up Button that is exactly like the bottom button just flipped vertically. The class will compensate for this, saving a few minutes of development time and a few kilobytes.

Scroll Background Hiding and resizing – Many scroll bars have a background track, you may want it visible when the scroll bars are disabled as a visual place holder. This feature can be turned on or off.

Works without a scroll bar or without up and down buttons.

Button Type Behaviors – Even though the buttons and scrollbars are made with movieClips, sample code and calls are provided to give them button type effects on rollOver, rollOut, press and release.

Usage may seem a little complex at first, but if you like designing and using custom scroll bars and buttons, it is totally worth it.

1. Create all your scroll objects, they should be converted to MovieClips.
(upButton, DownButton, ScrollBar, and ScrollBkg)

2. Place the up and down buttons, scroll bar, and scroll background into a new movieClip.
(ScrollObject)

3. Align the top button and scrollbar to it’s starting position.

4. Create the MovieClip to be scrolled, can include a TextField, graphics or both.
(ScrollMovieClip)

5. Create a mask and convert it to a MovieClip and mask the viewable area of the “ScrollMovieClip”.
(MaskMC)

5. Apply the class, this is the most complex part.

var scrollVert:HDScrollMC = HDScrollMC(ScrollObject, ScrollMovieClip, MaskMC, UpButton, DownButton, ScrollBar, ScrollBarResize, ScrollBkg, ScrollBkgHide, DownButtonFlip, ResizeScrollObjects, AutoOn, Ease);

This is where you assign all the MovieClips and enable any of the features. Other than the 7 MovieClips that the class points to, the other 6 arguments are features to enable or disable.

ScrollBarResize: Boolean (true/false)
ScrollBkgHide: Boolean (true/false)
DownButtonFlip: Boolean (true/false)
ResizeScrollObjects: Boolean (true/false)
AutoOn: Boolean (true/false)
Ease: Number (0-100) *(5 – 20) for best effect.

Once enabled, it can manage itself or you can manage it manually with a method like so:
scrollVert.ScrollStatus(true); or scrollVert.ScrollStatus(false);

When you are done with everything, you can strip all the code out by calling scrollVert.killScrollBar();

You can check the status of the scrollbar at anytime using
scrollVert.scrollStat; returns true or false.

?View Code ACTIONSCRIPT
import mx.utils.Delegate;
class com.hdi.as2.HDScrollMC{
	/*
	HDScrollMC oringinally created 11/2005 by Todd Williams and HD Interactive.
	©2005 - 2010 HD Interactive & Taterboy, Inc.
	version: 2.4
	Date: 7-26-10
 
	Compatibility:  Action Script 2, Flash Player 7 and higher.
	Purpose:
	To Build a scrollbar class that is truly portable and can be applied to custom artwork
	of any size and shape. This class wraps the graphics instead of graphics wrapping the code.
	This gives the designer complete 	control over look and feel. One of the major features
	needed was to have one set of scroll objects to be 	used in multiple instances and allow
	them to automatically conform to different scrolling needs. One set of scroll objects can
	control a scroll window that is 200 pixels tall or 600 pixels tall on the same stage at the 
	same time.
 
	HDScrollMC handles Vertical Scrolling Only, for horizontal scrolling use HDScrollHorizontal.
 
	Features:
		1. Automatically arranges scroll objects so that one set scrollbar objects can be used in multiple 
		    instances with different sized scrolling windows.
		2. Resizing scroll bar similar to OS and desktop application scroll bar behavior.
		3. Customizable Easing options for enhanced feel and response.
		4. Code Wraps to custom artwork instead of skinning a preexisting component.
		5. Auto on and off. The scroll bar is smart enough to know when it is needed or not.
		6. Code provided to build button type behavior into MovieClip buttons and scrollbar.
		7. Have multiple scrolling objects visible and functioning on the same stage at a time.
 
 
	Preparation:
	To prepare graphic objects for use with HDScrollMC, you will need to create 7 MovieClips.
	MC 1. The MovieClip to be scrolled:
		 For scrolling text, create a TextField inside of a MovieClip, fill it with text manually, 
		 or use dynamic text and the TextField.autoSize = true;
 
	MC 2. Mask for MC 1 display area: This must be a MovieClip so that class can determine the size of the 
		masked area.
 
	MC 3. Container for Scroll Objects: To make it possible to have multiple scrolling objects on the
	stage at the same time, it is best to have at least the scrollbar and scroll button objects in a
	container, the mask and MC to be scrolled can also be in this container if desired.
 
	MC 4 & 5.  Scroll buttons UP and Down. These buttons are not required if a scrollbar only design is 
		needed. Scroll buttons can be MovieClips or buttons. Code for rollover and press events will be
		sent to each MovieClip. If you want to use a MovieClip, disperse your button states on frames as you
		would a button and add a stop action to the first frame. Also the down button and be a vertically
		flipped instance if the top button if the design allows for this.
 
		The scroll button MovieClips receive the following method calls from the class. 
		btnEvent(1); roll on
		btnEvent(0); roll out
		btnEvent(2); mouse down
		btnEvent(1); mouse up
 
		Use the sample method below for MovieClips with button type behavior.
		**Super Simple Sample:
		function btnEvent(val){
			gotoAndStop(val+1);
		}
 
		Long-hand Sample:
		function btnEvent(val){
			if(val == 1){
				//roll on / release
			}
			else if(val == 2){
				//press
			}
			else{
				//roll out
			}
		}
 
	MC 6. Scroll Bar: Must be a MovieClip and like the buttons, code will be sent for rollover and press events.
		A scrollbar is not required if a button only design is required. The scroll bar has a resize feature 
		with two modes. The scroll bar will resize based on the amount of scroll and the size of the scroll 
		area, similar to OS scroll bars.
 
		Mode 1: (recommended) The scrollbar MovieClip resizes the whole Scroll Bar MovieClip. Some graphic distortion or stretching may occur.
		You can set the scale9Grid to this MovieClip prior to enabling this class. 
 
		Mode 2: Three individual MovieClips within the Scroll Bar are used to represent the top, middle 
		and bottom of the scroll bar, the middle will be stretched the top and bottom MovieClips will retain 
		their graphic integrity. To use this option divide the Scrollbar into three horizontal slices. Create 
		MovieClip instances named scrollbBarTop, scrollBarBot, and scrollBarMid. 
		(this was implimented before scale9Grid capibilities (Flash Player 7))
 
		The scrollbar receives the following method calls from the class.
		barEvent(1); roll on
		barEvent(0); roll out
		barEvent(2); mouse down
		barEvent(1); mouse up
 
		Use the method below for MovieClips with button type Behavior.
		**Super Simple Sample:
		function btnEvent(val){
			gotoAndStop(val+1);
		}
 
		Long-hand Sample:
		function barEvent(val){
			if(val == 1){
				//roll on / release
			}
			else if(val == 2){
				//press
			}
			else{
				//roll out
			}
		}
 
	MC 7. Scroll background, Must be a MovieClip,  will span the entire size of the scroll area
		if the class is set to resize the objects. This MovieClip can be used to have a decorative
		track for the scroll area and can be set to vanish or remain when the scrollbar is disabled
		or enabled. This object is not required.
 
	Usage:
		Place the class folder in the working directory next to the fla you are using;
		add import com.hdi.as2.HDScrollMC; to the actions panel before the code below.
 
	var vertScroll:HDScrollMC = new HDScrollMC(ScrollObject, ScrollMovieClip, MaskMC, UpButton,
	DownButton, ScrollBar, ScrollBarResize, ScrollBkg, ScrollBkgHide, DownButtonFlip ResizeScrollObjects,
	AutoOn, Ease);
 
	**should be all one line.
 
	I know there are a lot of arguments, and the descriptions/Usage are as follows:
	1. ScrollObject - (required) target of scroll object container, MC 3 from the preparation list.
	2. ScrollMovieClip - (required) target of MovieClip to be scrolled, MC 1 from preparation list.
	3. MaskMC - (required) target to Mask for the scrolling MovieClip, MC 2 from preparation list.
	4. UpButton - target or null, to Up Button MovieClip or Button. MC 4 & 5 from preparation list.
	5. DownButton - target  or null, to Down Button MovieClip or Button. MC 4 & 5 from preparation list.
	6. ScrollBar - target or null, to Scroll Bar MovieClip. MC 6 from preparation list.
	7. ScrollBarResize - Boolean: true or false, To enable scroll bar resizing depending on scroll amount.
	8. ScrollBkg - target or null, to resize scroll background graphic.
	9. ScrollBkgHide - Boolean: true or false, default behavior is to hide scroll background and scroll objects
	   when scrollbar is disabled;
	10. DownButtonFlip - Boolean: true or false, If the down button is an instance of the up button that is
		vertically flipped.
	11. ResizeScrollObjects - Boolean: true or false, when scroll bar loads, it calculates the size of the mask, 
		buttons, scrollbars and distributes them to the appropriate height and coordinates. This allows 
		different instances of a set of scroll objects to be used with different sized scrolling Objects. 
	12. AutoOn - Boolean: true or false, Turns control of turning the scroll bar objects on and off to the class.
		If the scrolling MovieClip changes in size the class will automatically enable or disable the
		scroll objects.
	13. Ease - Number, changes the scrolling MovieClip's response to scroll events. set to 0 for no delay.
 
 
	Other methods and properties:
	You can use these properties and methods for external control and monitoring.
 
	scrollStatus:  property (Boolean) - tells if scrolling is enabled or disabled.
	setScrollStatus: Function (Boolean)- manually enables/disables scrolling - use with AutoOn set to false.
	killScrollBar: Function - permanently disables the scrollbar and removes all listeners and events.
	setScrollPos: Function (Number) manually sets the scroll position of the scrolling clip and uptdates the scrollbar position.
 
	Tips:
	1. For best performance, zero out  x and y coordinates to whole numbers on all MovieClips. 	
	Also try to build artwork with artwork rounded to the nearest whole pixel. This stops a lot
	of the little glitches 	that can appear when a user interacts with the scrolling objects.
 
	2. If you do not want your scroll objects to flash on then off on load, set the scroll Object
	Container's (MC 3) 	alpha property to 0. The class will automatically set it to 100 when enabled.
 
	3. By default the class uses the scroll background  and/or the up button to align and distribute
	the rest of the objects. You should align the top button and the top of the scroll background.
	The top of the scrollbar should be aligned to the button of the top button. These coordinates
	are used as starting points for all of 	the scroll objects and will used as return positions
	when the scroll bar is reset.
 
	*/
	private var scrollObj:Object; //scroll MovieClip containing up button, down button, scrollbar, background.
	private var tClip:Object; //MovieClip that holds the text clip.
	private var tMask:Object; //Mask for the Text MovieClip, must be a MovieClip.
	private var dwnBtn:Object; //Down button, should be movieClip or button.
	private var upBtn:Object; //Down button, should be movieClip or button.
	private var scrollBar:Object; //MovieClip to do the scrolling.
	private var barAutoSize:Boolean; //Resizes the scroll bar to the scroll amount.
	private var scrollBkg:Object; //Background behind scrollButtons and scrollBar.
	private var scrollBkgHide:Boolean; //When scroll objects are not on, ScrollBkg is can be visible or not.
	private var flipDwnButton:Boolean; // If you have flipped the upBtn to make the dwnBtn. Used for autoResize.
	private var resizeObj:Boolean; // Resizes scroll objects to match the mask size and location.
	private var autoOn:Boolean; //Let's the scroll object control if the scrollBar is on or off, depending on the size of the text box.
	private var easeIn:Number; // Amount of delay for scrolling text to ease into possition.
	private var scrollYPos:Number;
	public var scrollStatus:Boolean; //Scrollbar is On or Off.
	private var startParams:Boolean;
	private var inc:Number;
	private var resetAllSizes:Function;
	function HDScrollMC(targObj,tclip,tmask,upbtn,dwnbtn,sbar,barsize,sbkg,sbkgHide,flip,reSize,auto,ease){
		scrollObj = targObj;
		tClip = tclip;
		tMask = tmask;
		upBtn = upbtn;
		dwnBtn = dwnbtn;
		scrollBar = sbar;
		barAutoSize = barsize;
		scrollBkg = sbkg;
		scrollBkgHide = sbkgHide;
		flipDwnButton = flip;
		resizeObj = reSize;
		autoOn = auto;
		easeIn = ease;
		scrollYPos = tClip._y;
		if(tMask._height >= tClip._height){
			scrollStatus = false;
			if(scrollBkgHide && scrollBkg){
				scrollBkg._visible = false;
			}
 
		}
		else{
			scrollStatus = true;
		}
		var testConfig:Boolean = true;
		if(scrollObj == null || scrollObj == undefined){
			trace("ERROR: ScrollObject (arg 0) needs to be a valid MovieClip ");
			testConfig = false;
		}
		if(tMask == null || tMask == undefined){
			trace("ERROR: MaskMC (arg 2) needs to be a valid MovieClip - please mask the scrolling object with a named instance of a MovieClip");
			testConfig = false;
		}
		if(easeIn == NaN || easeIn == undefined){
			trace("ERROR: Ease (arg 12) needs to be a Number - 0 for no ease, 1 and higher to add ease/delay to the scrolling object");
			testConfig = false;
		}
		if((scrollBar == null || scrollBar == undefined) && (upBtn == null || upBtn == undefined) && (dwnBtn == null || dwnBtn == undefined)){
			trace("ERROR: Very funny, you need at least 1 control object (scrollBar, upBtn or dwnBtn) assigned to initiate scrolling");
			testConfig = false;
		}
		if(testConfig){
			init();
		}
	}
	public function setScrollStatus(val){
		scrollStatus = val;
		scrollObj.stat = val;
		scrollObj.tmask = tMask;
		scrollObj.yPos = scrollObj.starty;
		tClip._y = scrollObj.starty;
		scrollBar._y = scrollObj.bary;
		setSizes();
		if(val){
			upBtn._visible = true;
			dwnBtn._visible = true;
			scrollBar._visible = true;
			scrollBkg._visible = true;
		}
		else{
			upBtn._visible = false;
			dwnBtn._visible = false;
			scrollBar._visible = false;
			if(scrollBkgHide){
				scrollBkg._visible = false;
			}
		}
	}
	public function setScrollPos(val){
		setSizes();
		var tempY:Number = val;
		if(tempY > scrollObj.starty){
			tempY = scrollObj.starty;
		}
		else if(tempY < scrollObj.starty - scrollObj.scrolldist){
			tempY = scrollObj.starty - scrollObj.scrolldist;
		}
 
		scrollObj.yPos = tempY
		tClip._y = tempY;
		scrollBar._y = (((scrollObj.starty - scrollObj.yPos) / scrollObj.scrolldist) * scrollObj.barslack) + scrollObj.topy;
	}
	public function killScrollBar(){
		tClip._y = scrollObj.starty;
		scrollBar._y = scrollObj.bary;
		scrollObj.yPos = scrollObj.starty;
		upBtn._visible = false;
		dwnBtn._visible = false;
		scrollBar._visible = false;
		delete scrollObj.onEnterFrame;
		delete scrollBar.onMouseUp;
		delete scrollBar.onMouseDown;
		delete scrollBar.onMouseMove;
		delete upBtn.onMouseUp;
		delete upBtn.onMouseDown;
		delete dwnBtn.onMouseUp;
		delete dwnBtn.onMouseDown;
		delete upBtn.onRollOut;
		delete upBtn.onRollOver;
		delete dwnBtn.onRollOut;
		delete dwnBtn.onRollOver;
		delete scrollBar.onRollOut;
		delete scrollBar.onRollOver;
		clearInterval(inc);
		Mouse.removeListener(scrollObj.myWheel);
	}
	private function setSizes(){
		scrollObj.maskh = tMask._height;
		if(tClip._y < scrollObj.starty - (tClip._height - scrollObj.maskh)){
			if(tClip._height <= scrollObj.maskh){
				scrollObj.yPos = scrollObj.starty;
			}
			else{
				scrollObj.yPos = scrollObj.starty - (tClip._height - scrollObj.maskh);
			}
		}
		else if(tClip._y > scrollObj.starty){
			scrollObj.yPos = scrollObj.starty;
		}
 
		tClip._y = scrollObj.yPos;
 
		if(barAutoSize == true){
		//setup dynamic scrollbar height.
			var sbHeight:Number;
			if(tClip._height > scrollObj.maskh){
				sbHeight = Math.floor((scrollObj.maskh / Math.ceil(tClip._height)) * scrollObj.bardist);
			}
			else{
				//sbHeight = 
			}
			if(sbHeight < 20){
				sbHeight = 20;
			}
			if(scrollBar.scrollbBarTop._name == undefined){
 
				scrollBar._height = sbHeight;
			}
			else{
				scrollBar.sheight = sbHeight
				scrollBar.scrollBarMid._height = scrollBar.sheight - (scrollBar.scrollbBarTop._height + scrollBar.scrollbBarTop._height);
				scrollBar.scrollbBarTop._y = scrollBar.scrollBarMid._height + scrollBar.scrollBarMid._y;
			}
 
		}
		scrollObj.bht = Math.ceil(scrollBar._height);
		scrollObj.barslack = (scrollObj.boty - scrollObj.topy) - scrollObj.bht;
		scrollObj.scrolldist = Math.ceil(Math.ceil(tClip._height) - (scrollObj.maskh));// + 10;
		scrollObj.scrollspeed = scrollObj.scrolldist / 8;
		scrollObj.yspeed = tMask._height/10;//16;
		scrollObj.upscroll = 0;
		scrollObj.dwnscroll = 0;
		scrollBar._y = (((scrollObj.starty - scrollObj.yPos) / scrollObj.scrolldist) * scrollObj.barslack) + scrollObj.topy;
	}
	private function setCoors(){
		tMask._height = Math.ceil(tMask._height);
		scrollObj.maskh = tMask._height;
		if(resizeObj){
			flipDwnButton == true? dwnBtn._y = Math.round(tMask._height): dwnBtn._y = Math.round((tMask._height) - dwnBtn._height);
			//flipDwnButton == true? dwnBtn._y = Math.round(tMask._height + tMask._y): dwnBtn._y = Math.round((tMask._height + tMask._y) - dwnBtn._height);
 
			if(scrollBkg != null){
				upBtn != null ? scrollBkg._height = scrollObj.maskh: scrollBkg._height = scrollObj.maskh;
			}
 
		}
		upBtn._y = Math.floor(upBtn._y);
		scrollObj.tht = Math.ceil(tClip._height);
		if(!startParams){
			scrollObj.starty = tClip._y;
			startParams = true;
		}
		//scrollObj.starty = tClip._y;
		scrollObj.barx = scrollBar._x;
		scrollObj.bary = scrollBar._y;
		if(upBtn != null){
			scrollObj.topy = Math.round(upBtn._y + upBtn._height);
			flipDwnButton == true? scrollObj.boty = Math.round(dwnBtn._y - dwnBtn._height): scrollObj.boty = Math.round(dwnBtn._y);
		}
		else{
			scrollObj.topy = Math.round(scrollBar._y);
			scrollObj.boty = Math.round(scrollBar._y + tMask._height);
		}
		scrollObj.bardist = (scrollObj.boty - scrollObj.topy);
		setSizes();
	}
 
	private function init(){
		setCoors();
		if(scrollStatus == false){
			upBtn._visible = false;
			dwnBtn._visible = false;
			scrollBar._visible = false;
		}
		else{
			upBtn._visible = true;
			dwnBtn._visible = true;
			scrollBar._visible = true;
		}
		scrollObj._alpha = 100;
		scrollObj.objectRef = this;
		scrollBar.objectRef = this;
		upBtn.objectRef = this;
		dwnBtn.objectRef = this;
		var scrollParent:Object = scrollObj;
 
		scrollObj.stat = scrollStatus;
		scrollObj.yPos = scrollYPos;
 
		var ref:Object = this;
		scrollObj.myWheel = new Object();
		scrollObj.myWheel.onMouseWheel = function(delta){
			trace(delta);
 
 			if(ref.scrollObj.stat && ref.scrollObj.tmask.hitTest(_root._xmouse, _root._ymouse)){
				if(delta > 0){
					if(ref.scrollObj.yPos < ref.scrollObj.starty - ref.scrollObj.yspeed){
						ref.scrollObj.yPos += Math.round(ref.scrollObj.yspeed);
						ref.scrollBar._y = (((ref.scrollObj.starty - ref.scrollObj.yPos) / ref.scrollObj.scrolldist) * ref.scrollObj.barslack) + ref.scrollObj.topy;
					}
					else{
						ref.scrollObj.yPos = ref.scrollObj.starty;
						ref.scrollBar._y = ref.scrollObj.topy;
					}
				}
				else if(delta < 0){
					if(ref.scrollObj.yPos > ref.scrollObj.starty - (ref.scrollObj.scrolldist - ref.scrollObj.yspeed)){
						ref.scrollObj.yPos -= Math.round(ref.scrollObj.yspeed);
						ref.scrollBar._y = (((ref.scrollObj.starty - ref.scrollObj.yPos) / ref.scrollObj.scrolldist) * ref.scrollObj.barslack) + ref.scrollObj.topy; 
					}
					else{
						ref.scrollObj.yPos = ref.scrollObj.starty - ref.scrollObj.scrolldist;
						ref.scrollBar._y = ref.scrollObj.boty - ref.scrollObj.bht;
					}
				}
			}
		}
		Mouse.addListener(scrollObj.myWheel);
 
		if(resizeObj){
			resetAllSizes = setCoors;//setSizes;
		}
 
		scrollBar.onMouseDown = function(){
			if(this._visible == true){
				if(this.hitTest(_root._xmouse, _root._ymouse, false)){
					this.barEvent(2);
					scrollParent.scrollchk = true;
					this.startDrag(false,scrollParent.barx,scrollParent.topy,scrollParent.barx,scrollParent.boty - scrollParent.bht);
					this.onMouseMove = function(){
						if(scrollParent.scrollchk == true){
							scrollParent.yPos = scrollParent.starty - (scrollParent.scrolldist * ((this._y - scrollParent.topy)  / scrollParent.barslack));
						}
 
					}
				}
			}
			else{
			}
		}
		scrollBar.onMouseUp = function(){
			scrollParent.scrollchk = false;
			if(this.hitTest(_root._xmouse, _root._ymouse, false)){
				this.barEvent(1);
			}
			this.stopDrag();
		}
		scrollBar.onRollOut = function(){
			this.barEvent(0);
		}
		scrollBar.onRollOver = function(){
			this.barEvent(1);
		}
		upBtn.onMouseDown = function(){
			if(this._visible == true){
				if(this.hitTest(_root._xmouse, _root._ymouse, false)){
					this.btnEvent(2);
					scrollParent.upscroll = 1;
				}
			}
		}
		upBtn.onMouseUp = function(){
			if(this.hitTest(_root._xmouse, _root._ymouse, false)){
				this.btnEvent(1);
			}
			else{
				this.btnEvent(0);
			}
			scrollParent.upscroll = 0;
		}
		upBtn.onRollOut = function(){
			this.btnEvent(0);
		}
		upBtn.onRollOver = function(){
			this.btnEvent(1);
		}
		dwnBtn.onMouseDown = function(){
			if(this._visible == true){
				if(this.hitTest(_root._xmouse, _root._ymouse, false)){
					this.btnEvent(2);
					scrollParent.dwnscroll = 1;
				}
			}
		}
		dwnBtn.onMouseUp = function(){
			if(this.hitTest(_root._xmouse, _root._ymouse, false)){
				this.btnEvent(1);
			}
			else{
				this.btnEvent(0);
			}
			scrollParent.dwnscroll = 0;
		}
		dwnBtn.onRollOut = function(){
			this.btnEvent(0);
		}
		dwnBtn.onRollOver = function(){
			this.btnEvent(1);
		}
 
		inc = setInterval(Delegate.create(this, frameLoop),10);
	}
 
	private function frameLoop(){
		if(scrollObj.upscroll == 1){
			if(scrollObj.yPos < scrollObj.starty - scrollObj.yspeed){
				scrollObj.yPos += Math.round(scrollObj.yspeed);
				scrollBar._y = (((scrollObj.starty - scrollObj.yPos) / scrollObj.scrolldist) * scrollObj.barslack) + scrollObj.topy;
			}
			else{
				scrollObj.yPos = scrollObj.starty;
				scrollBar._y = scrollObj.topy;
			}
		}
		if(scrollObj.dwnscroll == 1){
			if(scrollObj.yPos > scrollObj.starty - (scrollObj.scrolldist - scrollObj.yspeed)){
				scrollObj.yPos -= Math.round(scrollObj.yspeed);
				scrollBar._y = (((scrollObj.starty - scrollObj.yPos) / scrollObj.scrolldist) * scrollObj.barslack) + scrollObj.topy; 
			}
			else{
				scrollObj.yPos = scrollObj.starty - scrollObj.scrolldist;
				scrollBar._y = scrollObj.boty - scrollObj.bht;
			}
		}
 
		if(scrollStatus){
			var dirStat:Number = 0;
			scrollObj.dwnscroll == 1 ? dirStat = -1:null;
			scrollObj.upscroll == 1 ? dirStat = 1:null;
			easeMainClip(tClip,scrollObj.yPos,easeIn,dirStat);
			if(autoOn){
				if(tClip._height <= tMask._height){
					setScrollStatus(false);
				}
				var checkScrollDist:Number = Math.ceil(Math.ceil(tClip._height) - (scrollObj.maskh));// + 10;
				if(scrollObj.scrolldist < checkScrollDist || (scrollObj.maskh != tMask._height)){
					//reset size - ;
					if(resetAllSizes && tMask._height != scrollObj.maskh){
						resetAllSizes();
					}
					setSizes();
				}
				else if (scrollObj.scrolldist > checkScrollDist){
					//reset size + ;
					if(resetAllSizes && tMask._height != scrollObj.maskh){
						resetAllSizes();
					}
					setSizes();
				}
			}
 
		}
		else{
			if(autoOn){
				if(tClip._height > tMask._height){
					setScrollStatus(true);
				}
				resetAllSizes();
			}
		}
		updateAfterEvent();
	}
	private function easeMainClip(obj,val,ease,dir){
		if(ease > 0){
			if(dir == 0){
				if(Math.floor(obj._y) > val + 1){
					dir = -1;
				}
				else if(Math.ceil(obj._y) < val - 1){
					dir = 1;
				}
			}
			if(dir == -1){
				obj._y -= (obj._y - val)/ease;
			}
			else if(dir == 1){
				obj._y += (val - obj._y)/ease;
			}
			else{
				obj._y = val;
			}
		}
		else{
			obj._y = val;
		}
	}
 
}

Source Here

***** Some of the applications of this class may be better suited for HDSlide, a newer AS2 class to make things slide horizontally or vertically, without scroll bars using mouse movement.

Major Update and rewrite (2.0), Please download again to update your files

1. Multiple instances now work
2. Scrollbar background will be invisible if the text is not the correct size.
3. Added in code for resizing the text MC and mask to be more browser like. Not fully tested but does not seem to break other features.
4. Added code for scroll wheel support, but is it commented out. I have not tested it yet with multiple instances.

Horizontal version (2.2) is is available here.
Horizontal Scroll Source

UPDATE: 2.1

Source can be updated, using the links above.
added – clearInterval(inc); to the killScrollBar method.

UPDATE: 2.2

Source can be updated, using the links above.
1. Minor bug fixes adding reliability.
2. Scrollbars adjust if content is resized when autoOn and ResizeScrollObjects are set to true, like browser window functionality.
3. Horizontal scroll bar has been fully tested to work with vertical scroll bar on the same ScrollMovieClip. (browser type functionality)
4. Some of the documentation and usage in the class files has been clarified.
5. Both class files are included in each download above (horizontal and vertical).

UPDATE: 2.3

1. MouseWheel is now enabled by default. Thanks Pawe for pointing out the ref reference. MouseWheel support in AS2 still only works on Windows, not my fault, that is a dispute with Flash Player and Apple.
2. Added setScrollPos(Number) function to manually set the scroll position of the scrolling clip and uptdate the scrollbar position. In my testing calling this right after a textField autoSize call did not work until the next frame. Giving the scrolling clip a chance to redraw. Just pass in a number of where you want the scrolling clip to go. If the number is out of range, it will automatically correct itself.
3. Moved the class path from com.hdi.util.HDScrollMC to com.hdi.as2.HDScrollMC. All previous and future asctionScript 2 classes with organized this way.

UPDATE: 2.4

1. Fixed an issue when overriding scrollMC postition after changing the size of the scrollMC.

Thanks for the input and testing.

Technorati Tags: , , , , , ,

| 84 Comments » | facebook:

84 Comments »

  1. hey, i started to use this and got the graphics made and went to load this in and got stuck this is y first AS project (yes my school is nuts) and was wondering if i could get help with what i need to code inside my Timeline to get this to work thanks

    Comment by richard — September 19, 2008 @ 8:19 am

  2. Did you get the source files?

    Make sure you have the com folder in the same directory as the fla you are working. If you copied the code, then place it in a file called HDScrollMC.as. Then place it in the following folder structure.
    com > hdi > util > HDScrollMC.as

    **place this on the first frame.
    //import HDScrollMS Class
    import com.hdi.util.HDScrollMC;

    ** then something like this:
    // my scrollbar and buttons are inside a MovieClip instance called sbars. this makes it so the scrollbars do not flash on load.
    sbars._alpha = 0;
    // if you want to use scale9Grid on the scroll graphics so there is not any distortion
    sbars.sbar.scale9Grid = true;
    // actual code to start the scroll bar working.
    var scrollSet:HDScrollMC = new HDScrollMC(sbars,sClip,tMask,sbars.upBtn,sbars.dwnBtn,sbars.sbar,true,sbars.sbkg,false,false,true,true,10);

    Arguments
    1. all my buttons and scroll bars are MovieClip instances inside a MovieClip instance called sbars
    2. sClip is the instance name of the MovieClip I want to scroll.
    3. tMask is the MovieClip instance of the mask that defines the viewable area.
    4.sbars.upBtn = target to up button instance
    5. sbars.dwnBtn = target to down Button instance
    6.sbars.sbar = target to scrollbar instance
    7. tells the class if the scrollbar should resize or not
    8. sbars.sbkg = target to scroll background track instance.
    9. tells class if the background graphic should hide when scrollbar is disabled.
    10. tells the class if the button button is a veritcally flipped version of the top button. (sometimes I am really lazy)
    11. tells class if it should monitor the scroll area to see if it needs to enable/disable the scrollbars automatically.
    If the the scroll MC will change in size because of dynamic text or loaded elements, the scroll bar can set the status automatically
    12. easing. 10 is nice and smooth but responsive.

    Hope this helps. Good luck.

    Comment by taterboy — September 19, 2008 @ 8:46 am

  3. Hey,

    first of all, this scroller class is great! I have one question. I’m trying to use this for a full browser project and need the scroller to scale the _y with onResize. can I call a method from with the onResize function to do this?
    When I use the original call:
    var scrollSet:HDScrollMC = new HDScrollMC(sbars, sClip, tMask, sbars.upBtn, sbars.dwnBtn, sbars.sbar, true, sbars.sbkg, false, false, true, true, 10);

    it works but the sBar resets to the top without resetting the target movieclip.

    Is there a way to stop the sBar from resetting, or can I call something else to re size the scroll on stage resize?

    Thanks a lot!!
    J

    Comment by Jason — September 19, 2008 @ 6:44 pm

  4. Here is a mod, you can replace the old HDScrollMC.as with.
    http://www.taterboy.com/blog/downloads/HDScrollMC.as.zip

    On resize, change the height of the MaskMC. If you have it set to resize and auto scroll status is true, it should work.

    I am not sure if this still works for with the original features without resizing the mask, when I have more time I will post a complete update.

    Thanks,

    Comment by taterboy — September 19, 2008 @ 7:52 pm

  5. Perfect! That works great. the mask is set to scale onResize and the scroller goes with it.
    Thanks for putting this out there.

    Comment by Jason — September 20, 2008 @ 6:22 am

  6. hi, nice work !!
    love how it works, can i set the scrollbar vertical and have a vertical easing?
    is it simple?

    Ben

    Comment by ben — September 23, 2008 @ 7:08 am

  7. Not sure if I understand your question.

    Comment by taterboy — September 23, 2008 @ 7:15 am

  8. lol yeah i made a mistake!!
    fast reply and thx for that,
    I mean instead of a vertical scollbar and easing i just want an horizontal one with horizontal easing.

    If its possible it will made my day!!

    Comment by ben — September 23, 2008 @ 7:22 am

  9. I was afraid that is what you were talking about, I have had that in the back of my mind for a while, just haven’t had time to update it. I should be able to modify it pretty fast to do that though, hang on.

    Comment by taterboy — September 23, 2008 @ 7:27 am

  10. yeah, that can be very cool. I looked your code but my AS is limited, as i just need horizontal scrolling i tryed to change all y in x & x in y :)
    don’t joke….

    thx for the help!

    Comment by ben — September 23, 2008 @ 7:38 am

  11. Here is a horizontal version.
    http://www.taterboy.com/blog/downloads/scrollHorizontal.zip

    Hope it helps.

    Comment by taterboy — September 23, 2008 @ 7:56 am

  12. I basically did a find and replace for _y to _x, and _height to _width. Then there were a few tweaks for the button/mouse hitTest and the scrollbar startdrag.

    Comment by taterboy — September 23, 2008 @ 8:00 am

  13. Wonderfull, many thx for the help, it made my day I appreciate dat!
    exactly what i wanted, will now try to integrate it in my project !
    i put your site in my favorite, we keep in touch.

    Comment by ben — September 23, 2008 @ 8:12 am

  14. Thank you!

    Comment by taterboy — September 23, 2008 @ 8:25 am

  15. Its me again, I have one more question….
    watch >>> on home page >>> http://www.realityshock.com/marc/template.html
    i just want when i click on the next buton it slide to the 4 next photo.
    can you help me again, would be wicked !

    thx again for your source!

    Comment by ben — September 24, 2008 @ 3:32 pm

  16. That would be a little different solution, You need something like this.

    http://www.taterboy.com/blog/downloads/MoveHorizontal.zip
    code below.

    ?View Code ACTIONSCRIPT
    // set on load, sets the default x position and the width of one full movement.
    // looks for the mask as a MovieClip. or you can enter the coordinates and x position manually.
    var portX:Number = tMask._x;
    var portWidth:Number = tMask._width;
     
    //set this once all the slides are in place.
    var id:Number = 1;
    var pages:Number = Math.floor(sClip._width/portWidth);
     
     
    // When you want to move the slides back an forth set this variable
    // id is the location of the portfolio.
    var newX:Number = portX - (portWidth * (id));
    // then call this function. portDisplay is the target to the scrolling movieclip.
    moveAni(portDisplay,newX);
     
    //You could have a function like this.
    function nextPage(val){
    	if(val > 0 && id <= pages){
    		id += 1;
    	}
    	else if(val < 0 && id > 1){
    		id -= 1;
    	}
    	var newX:Number = portX - (portWidth * (id - 1));
     
    	// just in case the port is not divided into exact equal parts.
    	// and you want the last page to not to go too far to the left.
    	// if it does not matter then comment this out.
    	if(val > 0 && id > pages){
    		if(Math.floor(sClip._width/portWidth) < (sClip._width/portWidth)){
    			newX = portX - (sClip._width - portWidth);
    		}
    	}
     
    	// then call this function. portDisplay is the target to the scrolling movieclip.
    	moveAni(sClip,newX);
    }
     
    //your buttons would call this like so.
    rtBtn.onRelease = function(){
    	nextPage(1);
     
    }
    ltBtn.onRelease = function(){
    	nextPage(-1);
    }
     
     
    //then add this code somewhere on the maintimeline.
    var moveCnt:Number = 0;
    var moveObj:MovieClip;
    function moveAni(obj,val){
    	if(moveObj){
    		moveObj.removeMovieClip();
    	}
    	moveObj = this.createEmptyMovieClip("m" + moveCnt,this.getNextHighestDepth());
    	moveObj.targ = obj;
    	moveObj.val = val;
    	if(moveObj.targ._x > val){
    		moveObj.dir = 0;
    	}
    	else{
    		moveObj.dir = 1;
    	}
    	moveObj.onEnterFrame = function(){
    		if(this.dir == 1){
    			if(Math.ceil(this.targ._x) < this.val - 1){
    				this.targ._x += (this.val - this.targ._x)/10;
    			}
    			else{
    				this.targ._x = this.val;
    				delete this.onEnterFrame;
    				this.removeMovieClip();
    			}
    		}
    		else{
    			if(Math.floor(this.targ._x) > this.val + 1){
    				this.targ._x -= (this.targ._x - this.val)/10;
    			}
    			else{
    				this.targ._x = this.val;
    				delete this.onEnterFrame;
    				this.removeMovieClip();
    			}
    		}
    	}
     
    	moveCnt ++;
    }
     
     
    stop();

    Comment by taterboy — September 24, 2008 @ 4:42 pm

  17. Your god >> You have all the answers of my questions…
    Exactly what i wanted, it work very well !!
    many thx Taterboy !

    Comment by ben — September 24, 2008 @ 5:41 pm

  18. Nice site by the way. Has a lot of nice features. I really like the texture in the background.
    Thanks.

    Comment by taterboy — September 25, 2008 @ 6:35 am

  19. awesome scrollbar, and so easy to use
    thank

    Comment by Zack — October 3, 2008 @ 1:43 am

  20. First off all great work.
    embeding non latin characters is possible?
    cause I am working with it for a day and always brings up problems.

    Comment by bill — October 8, 2008 @ 12:16 am

  21. Do you mean using non-latin characters as arguments for the new class instance or in the MovieClip that is to be scrolled?

    Comment by taterboy — October 8, 2008 @ 6:34 am

  22. This is a great scroll bar, thank you for it! One question though. How would you set the mask dynamically with as2?

    sClip.setMask(tMask);

    gives the error:

    ERROR: MaskMC (arg 2) needs to be a valid MovieClip – please mask the scrolling object with a named instance of a MovieClip

    I’d like to attach the scrollbar to dynamically created text objects in a separate movie but am trying to get things working on the sample you provided first. Any guidance would be greatly appreciated. Thanks again!

    Comment by eighty4 — October 20, 2008 @ 8:38 pm

  23. sClip.setMask(tMask); is correct.

    Just make sure you set it before you set the scrollbar.
    sClip.setMask(tMask);
    var scrollSet:HDScrollMC = new HDScrollMC(sbars,sClip,tMask,sbars.upBtn,sbars.dwnBtn,sbars.sbar,true,sbars.sbkg,false,false,true,true,10);

    Also check to make sure all the arguments for the HDscrollMC are valid. That error is saying that the sClip does not exist . sClip should be the MovieClip with your dynamic text objects. If the new MC has a different name, make sure you replace sClip with the new name in the arguments.

    Comment by taterboy — October 21, 2008 @ 6:45 am

  24. hey taterboy awesome scoller!

    Just trying to implement multiple scrollers, and I’m fairly new to this. See below what i have so far:

    - Movie clip with multiple frames
    - Each frame has a new sClip and sbars mc
    - Each frame calls the class…

    import com.hdi.util.HDScrollMC;

    sbars._alpha = 0;
    sbars.sbar.scale9Grid = true;

    var scrollSet:HDScrollMC = new HDScrollMC(sbars,sClip,tMask,sbars.upBtn,sbars.dwnBtn,sbars.sbar,true,sbars.sbkg,false,false,true,true,10);

    What am I doing wrong? if you scroll down on any item, and then change to another frame, the scrollbar is way off on the _y

    Your help will be much appreciated

    Comment by Colin — October 23, 2008 @ 1:19 am

  25. Before you call the HDScrollMC Class you need to reset the y position of the scrollbar(sbar). When the class loads it checks the y position to determine where the top _y is. If the class is called and the scrollbar is not at the top position, then it sets the current position as top _y.

    You can try something like, sbars.sbar._y = 0 (if 0 is the top position).

    Another issue may be the previous call to the class has not ended, and it still executing. you may want to kill the current instance of the class before advancing to the next frame.
    try this scrollSet.killScrollBar();

    Hope this helps.

    Comment by taterboy — October 23, 2008 @ 7:08 am

  26. Mate I have to agree with everyone here you really are a legend! you have all the answers

    I managed to fix my problem. It turns out by giving the sbars MC and sClip MC all a different instance name … ie sClip1 and sBars1, etc… this solved my problem site works great and looks great with your scollers… http://www.vipportfolio.com.au

    thanks again

    Comment by Colin — October 23, 2008 @ 3:31 pm

  27. Thanks for the kind words and the link.

    Comment by taterboy — October 24, 2008 @ 6:28 am

  28. Your Scrollbar Class is awesome!!!
    I guess you never use the UIScrollBar component in Flash, right?
    One more idea: do you think it is possible to add mousewheel function to your class?

    Comment by Jochen — October 27, 2008 @ 7:43 am

  29. You mean there is already a UIScrollBar? :) We use a ton of custom UI elements, we find it easier this way. Thanks for the compliment.

    MouseWheel does not work cross platform (Mac) that is why I did not include it in the original class. If you want to modify it to add this functionality, use this code below.

    //Place this line in the killScrollBar() function – removes listener

    ?View Code ACTIONSCRIPT
    Mouse.removeListener(scrollObj.myWheel);

    //Place this code in the init() function – I placed mine right above this line: scrollObj.stat = scrollStat;

    ?View Code ACTIONSCRIPT
                    //Enable MouseWheel - PC only
    		scrollObj.myWheel = new Object();
    		scrollObj.myWheel.onMouseWheel = function(delta){
    			trace(delta);
     
    			if(scrollObj.stat){
    				_root.dt.text = delta + " /  " +  scrollObj.stat;
    				if(delta > 0){
    					if(scrollObj.yPos < scrollObj.starty - scrollObj.yspeed){
    						scrollObj.yPos += Math.round(scrollObj.yspeed);
    						scrollBarClip._y = (((scrollObj.starty - scrollObj.yPos) / scrollObj.scrolldist) * scrollObj.barslack) + scrollObj.topy;
    					}
    					else{
    						scrollObj.yPos = scrollObj.starty;
    						scrollBarClip._y = scrollObj.topy;
    					}
    				}
    				else if(delta < 0){
    					if(scrollObj.yPos > scrollObj.starty - (scrollObj.scrolldist - scrollObj.yspeed)){
    						scrollObj.yPos -= Math.round(scrollObj.yspeed);
    						scrollBarClip._y = (((scrollObj.starty - scrollObj.yPos) / scrollObj.scrolldist) * scrollObj.barslack) + scrollObj.topy; 
    					}
    					else{
    						scrollObj.yPos = scrollObj.starty - scrollObj.scrolldist;
    						scrollBarClip._y = scrollObj.boty - scrollObj.bht;
    					}
    				}
    			}
    		}
    		Mouse.addListener(scrollObj.myWheel);

    There is a little bug when scrolling a MovieClip with a TextField. When auto is set to true and the scrollbar is turned on, if the textfield changes size smaller then the scroll area, the MouseWheel will still move the TextField’s text up and down one line. pretty minor.

    Comment by taterboy — October 27, 2008 @ 11:19 am

  30. Like the other ones, I only have good comments for your scrollbar class, very weel designed, it’s perfect for my needs!!

    But I think I found two bugs…

    1- did you try using two instances at the same time? Ex : I have a scroller MC and made two instances on the stage for two diffenrent group of content MC and mask MC (off course each with different instance name). I created two new HDScrollMC objects one for each group of scroll elements… of course again everything with different names… well it doesn’t work quite well… you might want to check it out.

    2- I did put the hideBkgnd to true, put it does not hide on init if the content is empty right on the begining (the scroller does hide, but not the background!). Once the content is filled then emptied, only then will the background disapear.

    Once again, all in all, it’s a fantastic class.
    Thanks

    Comment by Skipp — November 14, 2008 @ 7:13 pm

  31. I will have to look into that, I have used it on two instances at the same time and that is why it is designed that way it is, but I may have done some updates to it since which may have added some bugs, I will look into it and post an update if needed.

    also good catch on the background not working on init, I will check that out too.

    Thanks,

    Comment by taterboy — November 14, 2008 @ 7:24 pm

  32. So I am trying to load a loadVars and then style sheet into the sClip movie and it comes up invisible. I am not getting errors and if I like select the “invisible” text I can in fact copy and past. I have my own non-eased version of a scroller but this I cannot get to work on your wonderful class.

    ?View Code ACTIONSCRIPT
     
     
    import com.hdi.util.HDScrollMC;	
     
     
    var myFlashVar:String = myVars;
     
    sectionLabel.text = sectionTitle;
    var tvColor:String = sectionColor;
     
     
    trace("the TV BG color is" + tvColor);
     
    //---------------------------------\\
    var myLV:LoadVars = new LoadVars();
     
    myLV.onLoad = function (success) {
    	if (success){
    		trace("initial load vars success");
    		sClip.op.htmlText = myLV.info;
    	} else {
    		sClip.op.text = "There has been an error loading the requested information.  Please contact the Webmaster and report your error.";
    	}
    }
    //---------------------------------\\
     
    //---------------------------\\
    var cssStyles:TextField.StyleSheet = new TextField.StyleSheet ();
    cssStyles.load ("whiteStyles.css");
    trace("css var loaded");
    cssStyles.onLoad = function (success) {
    	if (success) {
    		sClip.op.styleSheet = cssStyles;
    		myLV.load(myVars);
    		trace("css styled text has loaded into dynamic text field");
    	} else {
    		sClip.op.text = "There has been an error loading the requested information.  Please contact the Webmaster and report your error.";
    	}
    }	
    //---------------------------\\
     
     
     
    tvBody_mc.gotoAndPlay(tvColor);
     
    stop();
     
     
     
    sectionLabel.autoSize = TextFieldAutoSize.LEFT;
     
     
    tvBody_mc.host_mc.setMask(screenMask_mc);
     
     
     
    // NEW SCROLLER ACTIONS
     
    //HDScrollMC(ScrollObject,ScrollMovieClip,MaskMC,UpButton,DownButton,ScrollBar,
    	//ScrollBarResize,ScrollBkg,ScrollBkgHide,DownButtonFlip,ResizeScrollObjects,AutoOn,Ease);
     
    sbars._alpha = 0;
    sbars.sbar.scale9Grid = true;
    var scrollSet:HDScrollMC = new HDScrollMC(sbars,sClip,tMask,sbars.upBtn,sbars.dwnBtn,sbars.sbar,true,sbars.sbkg,false,false,true,true,10);
     
    btn1.onRelease = function(){
    	sClip.op.htmlText = myLV.info;
    	sClip.op.autoSize = true;
    }
    btn2.onRelease = function(){
    	sClip.op.htmlText = myLV2.info;
    	sClip.op.autoSize = true;
    }
     
    stop();
     
    </code>
     
     
    From my txt file that gets called from a flashVars set on the html:
     
    <code>
    info=PRIZE BONANZA 
     
    Win $750, $1,000, or $1,250 if you refer a winner.
    New this year. Every month several HOT JOBS will qualify for double loot. HOT JOBS are SSOE%27s hard to fill positions. Prizes for a HOT JOBS hire are $1,500, $2,000 and $2,500.
    THERE%27S MORE! You%27ll get to spin the wheel and win one of these prizes:
     
     Big screen TV 
     Navigation system

    Comment by Carlitos — November 18, 2008 @ 12:33 pm

  33. Sorry didnt know how to wrap code. Tried using the typical syntax but didnt work.

    c.

    Comment by Carlitos — November 18, 2008 @ 12:45 pm

  34. Nice coding!

    But is there already a fix for comment 30 – problem 1?

    I’m having the same problem, please help!

    Comment by Rood — November 25, 2008 @ 3:45 pm

  35. The class has been updated to fix both issues from comment 30.

    Comment by taterboy — November 26, 2008 @ 12:25 pm

  36. Here is some sample code I used to get css to work with this setup.

    first change the textField font type to Device Font.

    ?View Code ACTIONSCRIPT
    //to load css
    var cssStyles:TextField.StyleSheet = new TextField.StyleSheet();
    cssStyles.onLoad = function (success) {
    	trace(success);
    	if (success) {
    		sClip.op.styleSheet = cssStyles;
    		sClip.op.htmlText = "<p class='body'>" + lessText +"</p>";
    		sClip.setMask(tMask);
    		//myLV.load(myVars);
    		trace("css styled text has loaded into dynamic text field");
    	} else {
    		trace("error");
    		sClip.op.text = "There has been an error loading the requested information.  Please contact the Webmaster and report your error.";
    	}
    }	
    cssStyles.load ("whiteStyles.css");

    //css file (whiteStyles.css)
    .body {
    font-family: Arial, Helvetica, sans-serif;
    font-size: 24px;
    font-weight: bold;
    color:#00ff00;
    }

    Comment by taterboy — November 26, 2008 @ 12:28 pm

  37. I swapped your “less text” variable for my myLV.load(myVars) statement but it works. Thanks a ton I dig the edit ability of this and I wanted to use it as I have a couple others that I normally use but this was more fitting to what I was working on.

    Thanks again

    c.

    Comment by Carlitos — November 26, 2008 @ 1:18 pm

  38. Thanks for the bugs fix!! Do you have de fix for the Horizontal version also?

    When you have time, it would be nice to have the horizontal version in the same class and specified by a parameter…. I’m making your work here!! ;)

    Thanks a lot, very nice work!!

    Comment by Skipp — November 28, 2008 @ 10:20 am

  39. The horizontal version has been updated, http://www.taterboy.com/blog/downloads/scrollHorizontal.zip
    I was planning on updating everything, thanks for keeping me honest.

    Comment by taterboy — November 29, 2008 @ 8:52 pm

  40. Great scroller! Nice and simple. Easy to customize. Quick question, can I add a “buffer” to the end of the horizontal scroll? My scroll bar goes about 5-10 pixels to far to the right.

    Comment by Jason — December 3, 2008 @ 10:52 pm

  41. These variables control how far the scroll bar moves left and right
    scrollObj.barslack
    scrollObj.scrolldist (this is the one I would try first)

    also in the startDrag method, there are calculations for the left and right end points. You would have to add some buffer code in there too.

    First make sure all the art work and scroll object’s x and y coordinates are whole numbers if you are placing things on the stage. This helps the calculations. For some reason, things start to over lap when the coordinates are not whole numbers. I try to adjust this in the class and this may not be an issue, but something worth looking into.

    Comment by taterboy — December 4, 2008 @ 1:27 am

  42. Hi Taterboy,

    I’m fairly new to Flash and AS. Sorry to waste your time, but, long story short I’m stuck on steps 4 and 5 of your tutorial.

    “4. Create the MovieClip to be scrolled and mask it with another MovieClip.
    (ScrollMovieClip, MaskMC)

    5. Apply the class, this is the most complex part.”

    You’ve completely lost me with “create the Movie Clip to be scrolled and mask it with another Movie Clip.” Would you mind explaining to me what this means? :)

    Thanks in advance, Nicholas.

    Comment by Nicholas — March 1, 2009 @ 4:34 am

  43. You can scroll anything with this class, a bunch of photos, TextField or a combination of the two. Select all the artwork you want to scroll, then press “F8″ on the keyboard to convert it to a symbol. Make sure the drop-down in the Convert to Symbol properties window has “Movie Clip” selected as the Type. If you select then new MovieClip on the stage, you can give it a name in the property inspector. Name it “ScrollMovieClip”.

    Then on the layer above the ScrollMovieClip, create a rectangle to represent the viewable area of the previous MovieClip and convert that to a MovieClip Symbol (F8). Name this MovieClip “MaskMC”.

    The class needs to get properties from the mask, so it needs to be a MovieClip to make that process simpler.

    These line apply the class to all the MovieClips you created.
    //import HDScrollMS Class
    import com.hdi.util.HDScrollMC;
    var scrollSet:HDScrollMC = HDScrollMC(ScrollObject, ScrollMovieClip,MaskMC, UpButton, DownButton, ScrollBar, ScrollBarResize, ScrollBkg, ScrollBkgHide, DownButtonFlip, ResizeScrollObjects, AutoOn, Ease);

    You will need to define some of the arguments to match the names on the MovieClip instances as well as the settings. References for the settings are listed below, the rest are MovieClip instance names.

    ScrollBarResize: Boolean (true/false)
    ScrollBkgHide: Boolean (true/false)
    DownButtonFlip: Boolean (true/false)
    ResizeScrollObjects: Boolean (true/false)
    AutoOn: Boolean (true/false)
    Ease: Number (0-100)

    You will need to make sure you have the class file saved in the correct directory. You can download the source above, directly beneath the working demo (“Source Here”, I should make a nice button for this) , just place the “com” folder in the same directory as the FLA you are working on.

    I apologize for being so vague, I could have explained all that a lot better.

    Comment by taterboy — March 2, 2009 @ 8:16 am

  44. Hi,

    I found a little bug…

    When no buttons are used, if the mask is taller than the scrollbar, and resize scroll bar is false, the scroller will not stop at the end of the scroll background, it will go on for the height of the mask. When buttons are used, it’s fine. I’ll try usign fake buttons as a work around.. just tought you would like to know what I found.

    Comment by Skipp — March 9, 2009 @ 10:42 am

  45. Hey taterboy. I love the scrollbar. however, I’m running into a problem….

    I’ve got the following code inserted into the frame where my text is created:

    import com.hdi.util.HDScrollMC;

    var vertScroll:HDScrollMC = new HDScrollMC(scroll_obj, pg_cont, pg_msk, _root.scroll_obj.upBtn, _root.scroll_obj.dwnBtn, _root.scroll_obj.sc_Bar, false, _root.scroll_obj.sbkg, false, false, true, true, 10);

    Everything works great, the text scrolls fine, but when I’m scrolled down as far as I can scroll, then hit a button to change the text content, the scrollbar jumps to the top, and the text field appears scrolled down, making it impossible to scroll up and view the content.

    IE: go to this site, click on “About”, scroll down to the bottom, then click on the title and you will see what i mean.

    http://www.semag-games.com/test/index_scrollfx.swf

    I would greatly appreciate any help you can offer.

    Thanx again.

    Comment by computerguygeek — March 20, 2009 @ 9:57 am

  46. Are you sending the text to the same MovieClip? Or are the TextClips on different frames? The scrollbar will figure out where it is supposed to be when the text or content changes. If you reset the scrollbar each time you load text, you can cause this problem. When the scrollbar is initialized, it registers the current _y position of the content MC as the top. Seems like the code is being called again after the content is moved up, reseting the _y value of top.

    I can tell you more if I see some code or get more information on how the content is being updated and the navigation is setup.

    Comment by taterboy — March 20, 2009 @ 11:39 am

  47. thnx. i got it to work. Seems I was remaking the scrollbar every time i went back to the homepage. I moved it back a frame, and it worked flawlessly. thnx for the help, and the speedy reply.

    Comment by computerguygeek — March 20, 2009 @ 12:05 pm

  48. easy custum for scrollBar?? you have shure??

    Comment by Roberto — March 31, 2009 @ 2:01 pm

  49. Hi…Thanks for the great class.

    I’m having trouble getting the startDrag method to work. When I use “attachMovie” to load the scrollbar it doesn’t work after the first time. Have you seen or heard about this before?

    I can’t figure out what could be the issue.

    Thanks again!

    Comment by Alex — May 2, 2009 @ 8:34 pm

  50. Alex,

    Are you trying to customize the class? There is sample code and usage found here, fla included,
    http://www.taterboy.com/blog/downloads/HDScrollMC.zip

    Comment by taterboy — May 5, 2009 @ 9:04 am

  51. For enable wheel scroll, You must add reference to values outside onMouseWheel function.

    ?View Code ACTIONSCRIPT
    var ref:Object = this;
    scrollObj.myWheel = new Object();
    scrollObj.myWheel.onMouseWheel = function(delta){
       if(ref.scrollObj.stat){
          if(delta > 0){
             if(ref.scrollObj.yPos < ref.scrollObj.starty - ref.scrollObj.yspeed){
                ref.scrollObj.yPos += Math.round(ref.scrollObj.yspeed);
                ref.scrollBar._y = (((ref.scrollObj.starty - ref.scrollObj.yPos) /ref.scrollObj.scrolldist) *    ref.scrollObj.barslack) + ref.scrollObj.topy;
             }
          else{
             ref.scrollObj.yPos = ref.scrollObj.starty;
             ref.scrollBar._y = ref.scrollObj.topy;
          }
       }
       else if(delta  ref.scrollObj.starty - (ref.scrollObj.scrolldist - ref.scrollObj.yspeed)){
          ref.scrollObj.yPos -= Math.round(ref.scrollObj.yspeed);
          ref.scrollBar._y = (((ref.scrollObj.starty - ref.scrollObj.yPos) / ref.scrollObj.scrolldist) * ref.scrollObj.barslack) + ref.scrollObj.topy; 
       }
       else{
          ref.scrollObj.yPos = ref.scrollObj.starty - ref.scrollObj.scrolldist;
          ref.scrollBar._y = ref.scrollObj.boty - ref.scrollObj.bht;
       }
    }
    }
    }
    Mouse.addListener(scrollObj.myWheel);

    Greetings

    Comment by Pawe? — May 24, 2009 @ 3:09 am

  52. Todd, I am having a few issues that you’d probably be able to help me resolve quickly.

    SETUP: I am dynamically loading several XML files into the scroll/field, but I am only instantiating the Class once and simply changing the “txt_area.htmlText” contents

    1) I have button in the interface that are supposed to jump to txt_area. htmlText.scroll = blah
    2) If I happen to load text that doesn’t need a scroller first, it will not subsequently show up

    1- any ideas on how I can make this work
    2- what gives, I know it’s me probably doing something wrong

    Comment by Chad — May 31, 2009 @ 1:53 pm

  53. You need to make sure you are using the autoOn or setting the scrollbars manually

    The next to last argument(12) is a boolean for auto on, if you add text later that is more then the previous text the scrollbars should show up.
    var scrollVert:HDScrollMC = HDScrollMC(ScrollObject, ScrollMovieClip, MaskMC, UpButton, DownButton, ScrollBar, ScrollBarResize, ScrollBkg, ScrollBkgHide, DownButtonFlip, ResizeScrollObjects, AutoOn, Ease);

    Also you will have to autoSize the textField after adding the new text.
    txt_area.htmlText = “blah blah blah”;
    txt_area.autoSize = true;

    This will force the text Field to grow with the text you just placed into it.
    If you have the autoOn turned off, then you will have to manage the scrollbars yourself.
    scrollVert.ScrollStatus(true); turns the scrollbars on
    or scrollVert.ScrollStatus(false); turns them off.

    txt_area.htmlText = “blah blah blah”;
    txt_area.autoSize = true;
    scrollVert.ScrollStatus(true);

    Good luck.

    Comment by taterboy — May 31, 2009 @ 5:51 pm

  54. Thanks Todd, have you got any suggestions on how I can gain control over the scroll property or the _y as it is in your Class? I am also getting the issue of when I change the text and if the previous text was scrolled down, the new text is at the same _y. I would like to be able to reset AND set to a specific scroll line or _y

    Thanks again!

    Comment by Chad — May 31, 2009 @ 6:03 pm

  55. You should be able to reset the y position to the top by calling scrollBar.setScrollStatus(true); Even if the status is already on, it should move everything back to the starting position.

    The equation for the scroll bar is a little complex, you can try adding this function to the class to move everything manually. I have not tested this, but it should work in theory. I can test it out tomorrow if you can not get it working right.

    I would place it before or after the setScrollStatus function.

    public function setSPos(val){
    scrollObj.yPos = val
    tClip._y = val;
    scrollBar._y = (((scrollObj.starty – scrollObj.yPos) / scrollObj.scrolldist) * scrollObj.barslack) + scrollObj.topy;
    }

    Comment by taterboy — May 31, 2009 @ 6:36 pm

  56. hi! I have a problem: “ease” only works once. In the principal swf I load diferent swf with pictures and the scrollbar. the scrollbar works perfect but the easing effect only the first time i load the swf.

    sorry for my english.

    i hope you understand me

    Comment by santiago — June 17, 2009 @ 10:22 am

  57. hey guys just a question how i change the size of the height of the scrollbar???

    Comment by skill — July 10, 2009 @ 9:13 am

  58. The height is based on the height of the mask or view area. Inside the class the height of the mask is taken and the height of the scrollbar is dynamically applied. If you need a different height then the view area will take some modification to the class.

    Comment by taterboy — July 10, 2009 @ 9:26 am

  59. hello! now I have a problem when one picture with scroll is loading: If I don´t wait untill 100% and I press to load anotherone, after it is loaded the picture blinks…… you can see it in http://www.martinlucesole.com.ar (go to “Moda”) thanks! sorry for my bad english.

    Comment by santiago — July 30, 2009 @ 1:03 pm

  60. I was able to look through my old emails a find all the source files. The problem is the interval you are using for the loader. If you click on a new image while the first one is loading, the first interval is still running and calls the loading function (cargando) over and over again.

    You need to clear the interval in level4 before adding the new swf witch starts a new instance of interval.
    clearInterval(_level4.hiloPrecarga);

    on(release){
    _level4.scrollSet.killScrollBar();
    clearInterval(_level4.hiloPrecarga);
    unloadMovieNum(4);
    loadMovieNum(“2m.swf”,4);
    }

    Hope that helps.

    Comment by taterboy — July 30, 2009 @ 1:30 pm

  61. hello Taterboy!

    i don´t know if you remember my work http://www.martinlucesole.com.ar

    in moda, when you select a photo, 2 or more pictures are loaded inside one scroll.

    my question is: when the scroll has inside 3 or more pictures, there is a code to stop de scrolling between picture and picture?…or with the buttons when you press the up button it scrolls untill picture 2 and if you press again it scrolls untill picture 3?

    thanks a lot!

    Comment by santiago — August 11, 2009 @ 10:40 am

  62. Santiago,

    You are getting into something more complex than just a scroll bar. Comment #16 above has some code for horizontally paging a movieclip full of images. You will need something that combines that and the scrollbar. I have a horizontally scrolling image browser that I am planning on releasing soon. Just not sure when I can finish it.

    Comment by taterboy — August 11, 2009 @ 11:52 am

  63. Hey-

    It’s been a year and I’m still finding this class very useful.
    I do have a question though.
    Have you by chance worked out the scroll wheel integration for mac and pc?
    is there a way to use this in conjunction with pixelbreaker?
    I am a designer trying to develop the best I can, so my knowledge of js and SwfOblect is limited.

    I am using this for a full browser site and it would be nice to have scroll wheel functionality.

    Any help would be great.

    thanks

    j

    Comment by Jason — October 10, 2009 @ 7:14 am

  64. The scrollwheel support is in the class file but it is commented out, just uncomment it and it should work. There is a comment in the code pointing out where to uncomment.

    Comment by taterboy — October 10, 2009 @ 1:32 pm

  65. Good day man,

    I’m still a newbie to flash actionscript. I just wanted to know on how to incorporate a functionality like: I want to put a button on the scrolling movieclip. And once I click that button the content will animate to the content of the button on the same movieclip the structure looks like this.

    Patient Info’s

    Patient 1 -> button
    Patient 2 -> button
    Patient 3 -> button

    Patient 1
    This is the information about
    Patient 1.

    Patient 2
    This is the information about
    Patient 2.

    Patient 3
    This is the information about
    Patient 3.

    When I click on the Patient 3 which is a button the content will animate to the information which will be the viewable part. It would be likely in the top right position and while doing so the scroller will animate also to where the position is.

    Any help would be very great.

    Comment by Jun — March 10, 2010 @ 6:37 am

  66. Jun,

    if you have the latest version of the scrollbar, you can use one of the newest features, setScrollPos(Number).

    Once everything is set up, you can have the buttons call to the scrollbar instance to set the new position, or to jump to the position in the movieClip.

    if the scrollbar is set on the root,
    var scroll:HDScollMC = new HDScrollMC(……..

    then your buttons could call
    _root.scroll.setScrollPos(126);

    The scrolling movieClip should then scroll to the y position of 126

    Good Luck

    Comment by taterboy — March 11, 2010 @ 7:53 am

  67. Thanks so much for this! It’s been incredibly helpful!! The only question I’ve run into is how to slow down the speed of the scrolling. I’ve tried changing the easing and I don’t like that effect – is there another way to make the scrolling a little slower. I’m using a scroller with just buttons and no scroll bar, and clicking the buttons makes it scroll really fast. Thanks!!

    Comment by Rebecca — March 22, 2010 @ 1:53 am

  68. In the HDScrollMC.as file there is a line like this.
    scrollObj.yspeed = tMask._height/10;//16;

    This sets how far the scrolling clip with move on each click of the scroll buttons. If you divide by a higher number , like 16, it will move less distance on each click. Right now it is set to move from top to bottom of the scrolling area in 10 clicks, you may want it to jump just a few lines each click, just increase the number 10 or hard code it without dividing by the scrolling mask height.

    scrollObj.yspeed = 24; each time you click the button, it will now scroll 24 pixels.

    Comment by taterboy — March 22, 2010 @ 6:08 am

  69. Thank you!!! Works beautifully.

    Comment by Rebecca — March 23, 2010 @ 1:30 am

  70. Hi again…I ran into another issue. The client decided to add the scrollbar and slider back in on some of the pages (I was working with just the buttons before). I’ve added the scrollbar and slider and it’s working, apart from this little issue. After scrolling down, when I drag or scroll the slider back up, it doesn’t go all the way to the top. The slider stops about 100 px from the top, although the content does scroll all the way back up. The slider starts at the top initially, before the user scrolls anything. What am I doing wrong? Has anyone else encountered this?

    Comment by Rebecca — March 25, 2010 @ 11:59 am

  71. It would be hard to tell without seeing it or looking at code. Some things to double check are to make sure all your scroll element x and y positions are set to whole numbers. There are can calculation issues if not, but normally they are only a pixel or two. Make sure your artwork in side the scroll slider MovieClip has a y and x position of 0. The calculations normally work from the top left, if your orientation is set to the center, then it could through things off. Also check to see if the scroll bar is set to autoSize, maybe try turning that on or off may help narrow things down.

    Comment by taterboy — March 26, 2010 @ 6:59 am

  72. I’ll check again to make sure everything’s in whole numbers and the slider is positioned at 0,0 and has a top left orientation. Here’s my site as it is now…still a work in progress.
    http://www.rebeccapotts.com/peter/flash/peter9.html
    The pages with the scroller that I’m having trouble with are the news page (under about) and the credits pages.
    Thanks.

    Comment by Rebecca — March 28, 2010 @ 1:58 am

  73. It seems to be working now (still haven’t uploaded the new version, though)…not sure what changed, but it’s great that it’s working. Thanks again for this – it’s fantastic and your help has also been incredible.

    Comment by Rebecca — March 28, 2010 @ 5:17 pm

  74. I think it was caused by the distance between the scroll up and down buttons being the same as the height of the scroll area mask. The scroll area started at the bottom of the scroll up button and the top of the scroll down button instead of being flush with the buttons. Glad to hear everything is working.

    Comment by taterboy — March 29, 2010 @ 10:32 am

  75. This is awesome! Thanks so much for sharing this :)

    There’s just one thing I’m having problems with.
    My content is multiple frames, all at different lengths.

    When the content MC loads a new frame, the scroll bar stays where it is, and I just need it to snap back to the top whenever the frame changes.

    I would think something like this would work:
    button.onRelease=function(){
    sbars.sbar._y = 0;

    But thats not working.

    I’m kind of a newb so any help would be greatly appreciated!

    Comment by Zach — July 27, 2010 @ 7:13 pm

  76. Try sbars.setScrollPos(0);

    This moves the scrolling MovieClip to a new position, then the scroll bar will update it self based on the new position. Pass in the y postition your scrolling MovieClip is starting at.

    P.S. I just found a bug relating to this functionality, so download the newest version (2.4).

    I have never tested content on multiple frames, but I do not see why it wouldn’t work.

    Good Luck

    Comment by taterboy — July 27, 2010 @ 7:41 pm

  77. Thank you so much for the reply!

    I still am unable to get this to work though,
    here’s what I’m trying:

    button.onRelease=function(){
    sClip.gotoAndStop(“page2″);
    sbars.setScrollPos(0);
    }

    I’m not sure if I’m just missing something? Like I said before, I’m kind of a newb, so I really appreciate your help with this.

    Thanks taterboy

    Comment by Zach — July 29, 2010 @ 9:09 am

  78. This functionality should work,

    Make sure the setScrollPos passes in the correct value. 0 may not work, make it a large number, like 500. We are trying to push the scrolling MovieClip (sClip) back to the starting positions. The code will figure out the correct starting position if a greater value is passed in.

    If you are still having problems, I can look at your fla.

    Comment by taterboy — July 29, 2010 @ 9:11 pm

  79. Arg, still can’t figure this out. I’m pulling my hair out!
    If you could take a look at my FLA that would be incredible.

    Download: http://www.thedriveback.com/HDScrollMC-4.zip

    thank you SO MUCH!

    Comment by Zach — July 30, 2010 @ 4:03 pm

  80. No problem, easy fix.
    Change sbars.setScrollPos(60.5) to scrollSet.setScrollPos(60);

    scrollSet is the instance of the class HDScrollMC where all the methods are.
    var scrollSet = new com.hdi.as2.HDScrollMC(…..);

    page1_btn.onRelease = function ()
    {
    sClip.gotoAndStop(1);
    scrollSet.setScrollPos(60);
    }

    Comment by taterboy — July 30, 2010 @ 4:19 pm

  81. Worked like a charm! Thank you! You’ve been extremely helpful, I really appreciate it! :D

    Comment by Zach — July 30, 2010 @ 8:50 pm

  82. Many thank for the class! I think it is very good and helpful. Unfortunately, after I set everything up exactly the same way as what you instructed, my scrollbar does not respond to any click and drag action.

    There is no error message when I export the movie. It’s just that the scrollbar is not responding. What would be the possible problem?

    Thank you very much for your help!

    This is my code:

    import com.hdi.as2.HDScrollMC;

    ScrollObject._alpha=0;

    var scrollSet:HDScrollMC = new HDScrollMC(ScrollObject, ScrollMovieClip, MaskMC, ScrollObject.UpButton, ScrollObject.DownButton, ScrollObject.Scroller, true, ScrollObject.ScrollBkg, false, false, true, true, 10);

    Thanks for your help in advance!

    Comment by Jenny — March 22, 2011 @ 12:03 am

  83. Jenny,

    Everything looks correct from the code you provided, could you post the fla for me to look at?

    Comment by taterboy — March 22, 2011 @ 7:43 am

  84. Everyrhing is Ok as long as the textField(target for scroll) is not created “on the fly”. Just this class is based on Masking the textField – which should already exist in project.
    For objects created dynamically (“on the fly” with different sizes), this class not works…

    For textFields created “on the fly” I recommend thic class:
    http://www.taterboy.com/blog/2008/09/easy-custom-scrollbar-class-for-textfields-as2/
    without easing, but much easier to implement if you have ready project.

    Comment by Philip — June 19, 2011 @ 4:08 am

RSS feed for comments on this post. TrackBack URL

Leave a comment

*