AS3 scrollbar variation

Here’s a quick rewrite of a fun little basic scrollbar class written by Flashscaper.

The original was written pretty good and it was easy to drop into a project but there was one thing that would’ve made it more difficult for others to find out what’s happening in my code. The original Scrollbar.as was assigned directly to Scrollbar MovieClip via the Library’s Properties panel, rather than being instantiated through code. This technique works OK, but if some other developer had to pick up my code a year from now it would’ve been more difficult for her to find what’s where. To solve this issue, I rewrote the Scrollbar class so it can be started up via composition in Actionscript.

Made a few other small changes, like switching the animation code from Tweener to TweenLite. Had to move the stage listeners like this one:
“stage.addEventListener(MouseEvent.MOUSE_UP, stopScroll);”
to the “user” or client class called Main and use ScrollbarInstanceName.stopScroll to access public methods like stopScroll().

package com.flashscaper
{	
	import com.greensock.TweenLite; //TweenLite v.11.1
	import com.greensock.easing.Sine;	
	
	import flash.events.MouseEvent;	
	import flash.events.Event;	
	import flash.display.MovieClip;
	import flash.display.Sprite;	
	import flash.geom.Rectangle;

	public class BasicScrollbar extends MovieClip 
	{
		//data is "protected" instead of "private" so 
		//this class can be subclassed to add additional functionality 
		protected var myBar				:MovieClip; 		
		protected var target			:MovieClip;
		protected var top				:Number;
		protected var bottom			:Number;
		protected var dragBot			:Number;
		protected var range				:Number;
		protected var ratio				:Number;
		protected var sPos				:Number;
		protected var sRect				:Rectangle;
		protected var ctrl				:Number;
		protected var trans				:String;
		protected var timing			:Number;
		protected var isUp				:Boolean;
		protected var isDown			:Boolean;
		protected var isArrow			:Boolean;
		protected var arrowMove			:Number;
		protected var upArrowHt			:Number;
		protected var downArrowHt		:Number;
		protected var sBuffer			:Number;
		
		public function BasicScrollbar(t1:MovieClip, tr1:String, tt1:Number, sa1:Boolean, b1:Number) 
		{ 					 
			init(t1, tr1, tt1, sa1, b1); 
		}		
		
		public function	createBar():void 
		{			
			myBar = new Scrollbar_Lib_Asset(); //Library asset in the main .fla 					
			myBar.x = 201;
			myBar.y = 17;			
			addChild(myBar);
			
			myBar.scroller.addEventListener(MouseEvent.MOUSE_DOWN, dragScroll);					

		}		
		
		public function init(t:MovieClip, tr:String,tt:Number,sa:Boolean,b:Number):void {
			
			createBar();								
			
			target = t;
			trans = tr;
			timing = tt;
			isArrow = sa;
			sBuffer = b; 						

			if (target.height <= myBar.track.height) {
				this.visible = false;
			}			
						
			myBar.upArrow.buttonMode = true; //library & stage asset
			myBar.downArrow.buttonMode = true; //library & stage asset 
			
			upArrowHt = myBar.upArrow.height;
			downArrowHt = myBar.downArrow.height;
			if (isArrow) {
				top = myBar.scroller.y;
				dragBot = (myBar.scroller.y + myBar.track.height) - myBar.scroller.height;
				bottom = myBar.track.height - (myBar.scroller.height/sBuffer);

			} else {
				top = myBar.scroller.y;
				dragBot = (myBar.scroller.y + myBar.track.height) - myBar.scroller.height;
				bottom = myBar.track.height - (myBar.scroller.height/sBuffer);

				upArrowHt = 0;
				downArrowHt = 0;
				removeChild(myBar.upArrow);
				removeChild(myBar.downArrow);
			}
			range = bottom - top;
			sRect = new Rectangle(0,top,0,dragBot);
			ctrl = target.y;
			//set Mask
			isUp = false;
			isDown = false;
			arrowMove = 10;
			
			if (isArrow) {
				myBar.upArrow.addEventListener(Event.ENTER_FRAME, upArrowHandler);
				myBar.upArrow.addEventListener(MouseEvent.MOUSE_DOWN, upScroll);
				myBar.upArrow.addEventListener(MouseEvent.MOUSE_UP, stopScroll);
				//
				myBar.downArrow.addEventListener(Event.ENTER_FRAME, downArrowHandler);
				myBar.downArrow.addEventListener(MouseEvent.MOUSE_DOWN, downScroll);
				myBar.downArrow.addEventListener(MouseEvent.MOUSE_UP, stopScroll);
			}
			var square:Sprite = new Sprite();
			square.graphics.beginFill(0xFF0000);
			square.graphics.drawRect(target.x, target.y, target.width+5, (myBar.track.height+upArrowHt+downArrowHt));
			
			//trace("parent = " + parent); // = null			
			addChild(square); 
			
			target.mask = square;			
		}
		
		public function upScroll(event:MouseEvent):void 
		{
			isUp = true;
		}
		
		public function downScroll(event:MouseEvent):void 
		{
			isDown = true;
		}
		
		public function upArrowHandler(event:Event):void 
		{
			if (isUp) {
				if (myBar.scroller.y > top) {
					myBar.scroller.y -= arrowMove;
					if (myBar.scroller.y < top) {
						myBar.scroller.y = top;
					}
					startScroll();
				}
			}
		}
		
		public function downArrowHandler(event:Event):void 
		{
			if (isDown) {
				if (myBar.scroller.y < dragBot) {
					myBar.scroller.y += arrowMove;
					if (myBar.scroller.y > dragBot) {
						myBar.scroller.y = dragBot;
					}
					startScroll();
				}
			}
		}
		
		public function dragScroll(event:MouseEvent):void 
		{			
			myBar.scroller.startDrag(false, sRect);
			stage.addEventListener(MouseEvent.MOUSE_MOVE, moveScroll);
		}
		
		public function mouseWheelHandler(event:MouseEvent):void 
		{
			if (event.delta < 0) {
				if (myBar.scroller.y < dragBot) {
					myBar.scroller.y-=(event.delta*2);
					if (myBar.scroller.y > dragBot) {
						myBar.scroller.y = dragBot;
					}
					startScroll();
				}
			} else {
				if (myBar.scroller.y > top) {
					myBar.scroller.y -= (event.delta*2);
					if (myBar.scroller.y < top) {
						myBar.scroller.y = top;
					}
					startScroll();
				}
			}
		}
		
		public function stopScroll(event:MouseEvent):void 
		{
			isUp = false;
			isDown = false;
			myBar.scroller.stopDrag();

			stage.removeEventListener(MouseEvent.MOUSE_MOVE, moveScroll);
		}
		
		public function moveScroll(event:MouseEvent):void 
		{
			startScroll();
		}
		
		public function startScroll():void 
		{
			ratio = (target.height - range)/range;
			sPos = (myBar.scroller.y * ratio)-ctrl;
			
			TweenLite.to(target, timing, {y:-sPos, ease:trans}); 
		}
	}
}

An example “user” class for the Flash IDE that creates an instance of the scrollbar:

package {
		
	import com.flashscaper.BasicScrollbar;
	
	import flash.display.MovieClip;
	import flash.events.MouseEvent;

	public class Main extends MovieClip {
		
		private var scrollBr:MovieClip;
		private var whatToSroll:MovieClip;
				
		public function Main() 
		{ 		
			whatToSroll = new TextMC();	//Library asset (MovieClip with anything you like inside)			
			addChild(whatToSroll);
			
			scrollBr = new BasicScrollbar(whatToSroll, "Sine.easeOut", 2, true, 2); //uses a Library asset: Scrollbar_Lib_Asset			
			stage.addEventListener(MouseEvent.MOUSE_UP, scrollBr.stopScroll);
			stage.addEventListener(MouseEvent.MOUSE_WHEEL, scrollBr.mouseWheelHandler);			
			addChild(scrollBr);			
		}				
	}
}
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s