Jump to content
Search Community

astaroth

Members
  • Posts

    1
  • Joined

  • Last visited

Posts posted by astaroth

  1. 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(;
    
×
×
  • Create New...