Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
astaroth

scrolling DisplayContainer

Recommended Posts

I read a lot of articles after I decided to make my own scrollable DisplayContainer in mobileStyle.

There are a lot of people who had problems with clickable Items they want to scroll and here is my solution after coding a bit around to find a solution. The Class isn't optimized yet but for those who wants to start with a similar project it could help.

Feedback or optimisations are really welcome.

 

Cheers

package ui.components 
{
	import flash.display.Sprite;
	import flash.display.DisplayObject;
	import com.greensock.BlitMask;
	import flash.events.Event;
	import com.greensock.plugins.TweenPlugin;
	import com.greensock.plugins.ThrowPropsPlugin;
	import flash.ui.Multitouch;
	import flash.ui.MultitouchInputMode;
	import flash.events.GestureEvent;
	import flash.events.TransformGestureEvent;
	import flash.events.MouseEvent;
	import fl.transitions.Tween;
	import fl.transitions.easing.Elastic;
	import fl.transitions.TweenEvent;
	
	public class ScrollableDisplayContainer extends Sprite
	{
		Multitouch.inputMode = MultitouchInputMode.GESTURE;
		TweenPlugin.activate([ThrowPropsPlugin]);
		
		protected const MIN_WIDTH:Number = 20;
		protected const MIN_HEIGHT:Number = 20;
		
		private var _width:Number;
		private var _height:Number;
		
		private var _mask:BlitMask;
		private var _maskHolder:Sprite;
		private var _maskContent:DisplayObject;
		private var _maskContentHolder:Sprite;
		
		private var hScroll:Boolean = false;
		private var vScroll:Boolean = false;
		
		private var scrollBarV:Sprite;
		private var scrollBarH:Sprite;
		
		private var enableScrolling:Boolean = false;
		private var allowScrolling:Boolean = false;
		
		private var startingPointX:Number;
		private var startingPointY:Number;
		
		private var scrollContentPadding:Number	= 50;
		
		private var bounceAnimation:Tween;
		
		
		public function ScrollableDisplayContainer(width:Number, height:Number, content:DisplayObject, name:String = "content") 
		{
			super();
			this._width = width;
			this._height = height;
			this._maskContent = content;
			this._maskContent.name = name;
			
			if(!Multitouch.supportsGestureEvents)
			{
				throw new Error("This Device doesn't support GestureEvents, please go home ... nothing to see here");
			}
			
			this.addEventListener(Event.ADDED_TO_STAGE, added);
		}
		
		
		public function changeContent(content:DisplayObject, name:String = "content"):void
		{
			_maskContentHolder.removeChild(_maskContent);
			_maskContent = content;
			_maskContentHolder.addChild(_maskContent)
		}
		
		private function added(e:Event):void
		{
			this.removeEventListener(Event.REMOVED, removed);
			init();
		}
		
		private function removed(e:Event):void
		{
			this.removeEventListener(Event.REMOVED, removed);
			_mask.dispose();
			_mask = null;
			
			if (enableScrolling)
			{
				this.removeEventListener(TransformGestureEvent.GESTURE_SWIPE, scrollFast);
				this.removeEventListener(MouseEvent.MOUSE_DOWN, scroll);
				allowScrolling = true;
			}
		}
		
		private function init():void
		{
			_maskHolder = new Sprite();
			this.addChild(_maskHolder);
			
			_maskContentHolder = new Sprite();
			_maskHolder.addChild(_maskContentHolder);
			
			_maskContentHolder.addChild(_maskContent);
			
			_mask = new BlitMask(_maskContentHolder);
			_mask.x = 0;
			_mask.y	= 0;
			_mask.width = this._width;
			_mask.height = this._height;
			_mask.bitmapMode = false;
			_mask.autoUpdate = true;

			setScroller();
		}
		
		private function setScroller():void
		{			
			_maskContent.width > _mask.width ? drawScrollBarH() : 0;
			_maskContent.height > _mask.height ? drawScrollBarV() : 0;
			if (enableScrolling)
			{
				allowScrolling	= true;
				this.addEventListener(TransformGestureEvent.GESTURE_SWIPE, scrollFast);
				this.addEventListener(MouseEvent.MOUSE_DOWN, scroll);
			}
		}
						
		private function drawScrollBarH():void
		{
			enableScrolling = true;
			hScroll = true;
			var barWidth:Number = _mask.width/(_maskContentHolder.width/_mask.width);
			
			scrollBarH = new Sprite;
			scrollBarH.graphics.lineStyle(0, 0x333333);
			scrollBarH.graphics.beginFill(0x333333, 1);
			scrollBarH.graphics.drawRoundRect(0, 0, barWidth, 4, 3, 3);
			scrollBarH.graphics.endFill();
			
			this.addChild(scrollBarH);
			scrollBarH.alpha = 0;
			scrollBarH.x = 1;
			scrollBarH.y = _mask.height - scrollBarH.height-1;
		}
		
		private function drawScrollBarV():void
		{
			enableScrolling = true;
			vScroll = true;
			var barHeight:Number = _mask.height/(_maskContentHolder.height/_mask.height);
			
			scrollBarV = new Sprite;
			scrollBarV.graphics.lineStyle(0, 0x333333);
			scrollBarV.graphics.beginFill(0x333333, 1);
			scrollBarV.graphics.drawRoundRect(0, 0, 4, barHeight, 3, 3);
			scrollBarV.graphics.endFill();
			
			this.addChild(scrollBarV);
			scrollBarV.alpha = 0;
			scrollBarV.x = _mask.width - scrollBarV.width-1;
			scrollBarV.y = 1;
		}
		
		private function scrollFast(t:TransformGestureEvent):void
		{
			t.offsetX == -1 && hScroll && allowScrolling ? scrollFastToLeft() : 0;
			t.offsetX == 1 && hScroll && allowScrolling ? scrollFastToRight() : 0;
			t.offsetY == 1 && vScroll && allowScrolling ? scrollFastDown() : 0;
			t.offsetY == -1 && vScroll && allowScrolling ? scrollFastUp() : 0;
		}
		
		private function scrollFastToLeft():void
		{
			hScroll ? scrollBarH.alpha = 0.3 : 0;
			_maskContentHolder.x = Math.max( _maskContentHolder.x - (_maskContentHolder.width/3), (_maskContentHolder.width-_mask.width)*-1 );
			if (_maskContentHolder.x < (_maskContentHolder.width-_mask.width)*-1)
			{
				_maskContentHolder.x = (_maskContentHolder.width-_mask.width)*-1;
			}
			scrollBarH.x = calcScrollBarXaxis();
			checkFinish();
		}
		
		private function scrollFastToRight():void
		{
			hScroll ? scrollBarH.alpha = 0.3 : 0;
			_maskContentHolder.x = Math.min(_maskContentHolder.x + (_maskContentHolder.width/3), 0);
			if (_maskContentHolder.x > 0)
			{
				_maskContentHolder.x = 0;
			}
			scrollBarH.x = calcScrollBarXaxis();
			checkFinish();
		}
		
		private function scrollFastDown():void
		{
			vScroll ? scrollBarV.alpha = 0.3 : 0;
			_maskContentHolder.y = _maskContentHolder.y + (_maskContentHolder.height/3);
			if (_maskContentHolder.y > scrollContentPadding)
			{
				_maskContentHolder.y = scrollContentPadding;
			}
			scrollBarV.y = calcScrollBarYaxis();
			checkFinish();
		}
		
		private function scrollFastUp():void
		{
			vScroll ? scrollBarV.alpha = 0.3 : 0;
			_maskContentHolder.y = _maskContentHolder.y - (_maskContentHolder.height/3);
			if (_maskContentHolder.y < (_maskContentHolder.height-_mask.height+scrollContentPadding)*-1)
			{
				_maskContentHolder.y = (_maskContentHolder.height-_mask.height+scrollContentPadding)*-1;
			}
			scrollBarV.y = calcScrollBarYaxis();
			checkFinish();
		}
		
		private function scroll(m:MouseEvent):void
		{
			if (allowScrolling)
			{
				allowScrolling	= false;
				startingPointX	= m.stageX;
				startingPointY	= m.stageY;
				this.addEventListener(MouseEvent.MOUSE_UP, endScrolling);
				this.addEventListener(MouseEvent.MOUSE_MOVE, scrollToDirection);
			}
		}
		
		private function endScrolling(m:MouseEvent):void
		{
			this.removeEventListener(MouseEvent.MOUSE_UP, endScrolling);
			this.removeEventListener(MouseEvent.MOUSE_MOVE, scrollToDirection);
			checkFinish();
			_mask.bitmapMode = false;
		}
		
		private function checkFinish():void
		{			
			hScroll ? scrollBarH.alpha = 0 : 0;
			vScroll ? scrollBarV.alpha = 0 : 0;
			
			if (_maskContentHolder.y < (_maskContentHolder.height-_mask.height)*-1)
			{
				startAnimation("y", _maskContentHolder.y, (_maskContentHolder.height-_mask.height)*-1);
			}
			else if (_maskContentHolder.y > 0)
			{
				startAnimation("y", _maskContentHolder.y, 0);
			}
			else
			{
				allowScrolling = true;
			}
		}
		
		
		private function startAnimation(axis:String, start:Number, end:Number):void
		{
			bounceAnimation = new Tween(_maskContentHolder, axis, Elastic.easeOut, start, end, 1, true); 
			bounceAnimation.addEventListener(TweenEvent.MOTION_FINISH, animationFinished);
		}
		
		private function animationFinished(t:TweenEvent):void
		{
			bounceAnimation.removeEventListener(TweenEvent.MOTION_FINISH, animationFinished);
			allowScrolling = true;
		}
		
		private function scrollToDirection(m:MouseEvent):void
		{
			m.stageX < startingPointX ? scrollLeft(m.stageX, m.stageY) : 0;
			m.stageX > startingPointX ? scrollRight(m.stageX, m.stageY) : 0;
			m.stageY < startingPointY ? scrollUp(m.stageX, m.stageY) : 0;			
			m.stageY > startingPointY ? scrollDown(m.stageX, m.stageY) : 0;
		}
		
		private function setNewStartingCoordinates(xPos:Number, yPos:Number):void
		{
			startingPointX = xPos;
			startingPointY = yPos;
		}
		
		private function calcScrollBarXaxis():Number
		{
			var cont:Number = (_maskContentHolder.width+_maskContentHolder.x)-_mask.width;
			var base:Number = _maskContentHolder.width-_mask.width;
			var max:Number 	= _mask.width - scrollBarH.width;
			var act:Number  = cont*max/base;		
			return Math.floor(max - act);
		}
		
		private function calcScrollBarYaxis():Number
		{
			var cont:Number = (_maskContentHolder.height+_maskContentHolder.y)-_mask.height;			
			var base:Number = _maskContentHolder.height-_mask.height;
			var max:Number 	= _mask.height - scrollBarV.height;
			var act:Number 	= cont*max/base;	
			var ret:Number	= Math.floor(max - act);
			ret < 0 ? ret = 0 : 0;
			ret > max ? ret = max : 0;
			return ret;
		}
		
		private function scrollLeft(xPos:Number, yPos:Number):void
		{
			_mask.bitmapMode = true;
			hScroll ? scrollBarH.alpha = 0.3 : 0;
			setNewStartingCoordinates(xPos, yPos);
			_maskContentHolder.x = _maskContentHolder.x -3;
			
			if (_maskContentHolder.x < (_maskContentHolder.width-_mask.width)*-1)
			{
				_maskContentHolder.x = (_maskContentHolder.width-_mask.width)*-1;
			}
			
			scrollBarH.x = calcScrollBarXaxis();
		}
		
		private function scrollRight(xPos:Number, yPos:Number):void
		{
			_mask.bitmapMode = true;
			hScroll ? scrollBarH.alpha = 0.3 : 0;
			setNewStartingCoordinates(xPos, yPos);
			_maskContentHolder.x = _maskContentHolder.x +3;
			
			if (_maskContentHolder.x > 0)
			{
				_maskContentHolder.x = 0;
			}
			
			scrollBarH.x = calcScrollBarXaxis();
		}
		
		private function scrollUp(xPos:Number, yPos:Number):void
		{
			_mask.bitmapMode = true;
			vScroll ? scrollBarV.alpha = 0.3 : 0;
			setNewStartingCoordinates(xPos, yPos);
			_maskContentHolder.y = _maskContentHolder.y -3;
			
			if (_maskContentHolder.y < (_maskContentHolder.height-_mask.height+scrollContentPadding)*-1)
			{
				_maskContentHolder.y = (_maskContentHolder.height-_mask.height+scrollContentPadding)*-1;
			}
			scrollBarV.y = calcScrollBarYaxis();
		}
		
		private function scrollDown(xPos:Number, yPos:Number):void
		{
			_mask.bitmapMode = true;
			vScroll ? scrollBarV.alpha = 0.3 : 0;
			setNewStartingCoordinates(xPos, yPos);
			_maskContentHolder.y = _maskContentHolder.y +3;
			
			if (_maskContentHolder.y > scrollContentPadding)
			{
				_maskContentHolder.y = scrollContentPadding;
			}
			scrollBarV.y = calcScrollBarYaxis();
		}

	}
	
}

Usage:

import flash.display.Sprite;
import ui.components.ScrollableDisplayContainer;
import flash.events.MouseEvent;

var a:Sprite = new Sprite();
a.graphics.lineStyle(0, 0xFF0000);
a.graphics.beginFill(0xFF0000, 1);
a.graphics.drawRect(0, 0, 1000, 800);
a.graphics.endFill();

var aa:Sprite = new Sprite();
aa.graphics.lineStyle(0, 0xFF0000);
aa.graphics.beginFill(0x00FF00, 1);
aa.graphics.drawRect(0, 0, 1000, 500);
aa.graphics.endFill();
aa.buttonMode=true;
aa.addEventListener(MouseEvent.CLICK, clicked);


function clicked(m:MouseEvent):void
{
	trace ('clicked: '+m.target);
}


var c:Sprite = new Sprite();
c.addChild(a);
a.x = 0;
a.y = 0;

c.addChild(aa);
aa.x = 0;
aa.y = 200;


var b:ScrollableDisplayContainer;

b = new ScrollableDisplayContainer(600, 560, c);

addChild(;
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×