astaroth Posted July 14, 2015 Share Posted July 14, 2015 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 More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now