Skip to content

Instantly share code, notes, and snippets.

@FrancescoMaisto
Created July 16, 2013 10:18
Show Gist options
  • Save FrancescoMaisto/6007526 to your computer and use it in GitHub Desktop.
Save FrancescoMaisto/6007526 to your computer and use it in GitHub Desktop.
Page flipping using swiping gestures
package navigation.screens
{
import constants.Colors;
import constants.Constants;
import constants.Fonts;
import constants.Navigation;
import constants.Text;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.utils.getTimer;
import navigation.components.Box;
import navigation.components.Levels_Small_Buttons;
import navigation.components.StandardPage;
import starling.core.Starling;
import starling.display.Quad;
import starling.display.Sprite;
import starling.events.Event;
import starling.events.Touch;
import starling.events.TouchEvent;
import starling.events.TouchPhase;
import starling.text.TextField;
import starling.utils.HAlign;
import ui.IdButton;
import variables.Global;
public class ScrollingPanel extends Sprite
{
private var _width:uint = Constants.STAGE_WIDTH;
private var _height:uint = Constants.STAGE_HEIGHT - 80;
private var _container:Sprite;
private var _panelBounds:Rectangle = new Rectangle(0, 0, _width, _height);
private var _currentPageIndex:int = 0;
private var _pageCount:int;
private var _position:Point;
private var _x1:Number;
private var _x2:Number;
private var _t1:uint;
private var _t2:uint;
private var _startX:Number;
private var _offsetX:Number;
private var btn_NextPage:IdButton;
private var btn_PrevPage:IdButton;
private var btn_Back:IdButton;
private var _btn_Home_W:Number;
private static const BTN_BACK_Y:Number = 390;
private static const PAGE_BUTTONS_PADDING:uint = 10;
private var _pageCounter:Sprite;
private var pageIndicator_Vector:Vector.<Quad> = new Vector.<Quad>();
private static const PAGE_INDICATOR_WIDTH:uint = 15;
private static const PAGE_INDICATOR_PADDING:uint = 10;
private static const PAGE_TURNING_TIME:Number = 0.5; // in seconds
public function ScrollingPanel()
{
this.addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
}
// ----------------------------------------------------------------------------------------------------------------------
private function onAddedToStage (event:Event) : void
{
this.removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
createDesign();
}
// ----------------------------------------------------------------------------------------------------------------------
private function createDesign():void {
/* STANDARD PAGE */
var standardPage:StandardPage = new StandardPage();
standardPage.touchable = false;
this.addChild(standardPage);
_pageCount = Math.ceil(Global.TOTAL_LEVELS[Global.GAME_MODE] / Constants.LEVELS_PER_PAGE);
trace( "TOTAL_LEVELS : " + Global.TOTAL_LEVELS );
trace( "_pageCount : " + _pageCount );
/* CONTAINER (Sprite) */
_container = new Sprite();
_container.x = _panelBounds.x;
_container.y = _panelBounds.y;
_container.addEventListener(TouchEvent.TOUCH, touchHandler);
this.addChild(_container);
/* PAGES BACKGROUND */
for (var i:uint = 0; i < _pageCount; i++)
{
var page:Box = new Box(Navigation.PAGE_W, Navigation.PAGE_H, Navigation.PAGE_FRAME_THICKNESS, Colors.BLACK, true, Colors.WHITE_RED, Colors.WHITE_YELLOW, Colors.WHITE_GREEN, Colors.WHITE_BLUE, Navigation.PAGE_ALPHA);
page.x = (Constants.STAGE_WIDTH * i) + Navigation.PAGE_X;
page.y = Navigation.PAGE_Y;
this._container.addChild(page);
}
/* TOUCHABLE SURFACE */
var q:Quad = new Quad(_width * _pageCount, _height);
// q.color = 0xFF0000;
q.alpha = 0;
_container.addChild(q);
/* PAGE COUNTER (Sprite) */
_pageCounter = new Sprite();
_pageCounter.touchable = false;
this.addChild(_pageCounter);
for (var j:uint = 0; j < _pageCount; j++)
{
/* PAGE INDICATORS */
var pi:Quad = new Quad(PAGE_INDICATOR_WIDTH, PAGE_INDICATOR_WIDTH);
pi.x = (PAGE_INDICATOR_WIDTH + PAGE_INDICATOR_PADDING) * j;
pageIndicator_Vector.push(pi);
_pageCounter.addChild(pi);
/* TEXT: HEADING (one per page, bearing the name of the corresponding Time Attack Level Pack */
var txt_Heading:TextField = new TextField(Navigation.TXT_HEADING_W, Navigation.TXT_HEADING_H, Text.TIMEATTACK_LEVEL_PACK[j], Fonts.FONT_IMAGINE);
txt_Heading.touchable = false;
txt_Heading.x = (Constants.STAGE_WIDTH * j) + ((Constants.STAGE_WIDTH - txt_Heading.width) / 2);
txt_Heading.y = Navigation.TXT_HEADING_Y;
txt_Heading.color = Colors.YELLOW;
txt_Heading.hAlign = HAlign.CENTER;
txt_Heading.fontSize = Navigation.TXT_HEADING_FONTSIZE;
txt_Heading.nativeFilters = [Navigation.outlineFilter_Thick];
_container.addChild(txt_Heading);
}
_pageCounter.x = (Constants.STAGE_WIDTH - _pageCounter.width) / 2;
_pageCounter.y = 80;
/** PAGE COUNTERS - ONE PER PAGE
for (var k:uint = 0; k < _pageCount; k++)
{
var _pageCounter:Sprite = new Sprite();
this._container.addChild(_pageCounter);
for (var j:uint = 0; j < _pageCount; j++)
{
var pi:Quad = new Quad(PAGE_INDICATOR_WIDTH, PAGE_INDICATOR_WIDTH);
pi.alpha = (j == k)? 1 : 0.3;
pi.color = (j == k)? Colors.RED : Colors.BLACK;
pi.x = (PAGE_INDICATOR_WIDTH + PAGE_INDICATOR_PADDING) * j;
_pageCounter.addChild(pi);
}
_pageCounter.x = (Constants.STAGE_WIDTH * k) + ((Constants.STAGE_WIDTH - _pageCounter.width) / 2);
_pageCounter.y = 80;
}
*/
/* Buttons: LEVELS*/
var levels_Small_Buttons:Levels_Small_Buttons = new Levels_Small_Buttons();
this._container.addChild(levels_Small_Buttons);
/* Button: BACK TO LEVEL PACKS (IdButton)*/
btn_Back = new IdButton(Game.assets.getTexture("btn_Levels_up"), "", Game.assets.getTexture("btn_Levels_down"));
// Update _btn_Home_W
_btn_Home_W = btn_Back.width;
btn_Back.scaleWhenDown = Constants.BUTTON_SCALEDOWN;
btn_Back.x = int((Constants.STAGE_WIDTH - _btn_Home_W)/ 2);
btn_Back.y = BTN_BACK_Y;
btn_Back.name = "showScreen_LEVELS";
btn_Back.id = 0;
this.addChild(btn_Back);
/* Button: PREV PAGE (IdButton)*/
btn_PrevPage = new IdButton(Game.assets.getTexture("btn_PrevPage_up"), "", Game.assets.getTexture("btn_PrevPage_down"));
btn_PrevPage.scaleWhenDown = Constants.BUTTON_SCALEDOWN;
btn_PrevPage.alphaWhenDisabled = 1;
btn_PrevPage.x = Constants.STAGE_W_HALF - (_btn_Home_W / 2) - PAGE_BUTTONS_PADDING - btn_PrevPage.width;
btn_PrevPage.y = BTN_BACK_Y + ((btn_Back.height - btn_PrevPage.height)/2);
btn_PrevPage.name = "prevPage";
this.addChild(btn_PrevPage);
/* Button: NEXT PAGE (IdButton)*/
btn_NextPage = new IdButton(Game.assets.getTexture("btn_NextPage_up"), "", Game.assets.getTexture("btn_NextPage_down"));
btn_NextPage.scaleWhenDown = Constants.BUTTON_SCALEDOWN;
btn_NextPage.alphaWhenDisabled = 1;
btn_NextPage.x = Constants.STAGE_W_HALF + (_btn_Home_W/2) + PAGE_BUTTONS_PADDING;
btn_NextPage.y = btn_PrevPage.y;
btn_NextPage.name = "nextPage";
this.addChild(btn_NextPage);
// Update navigation buttons
btn_PrevPage.enabled = false;
btn_PrevPage.alpha = 0;
if (_pageCount == 1)
btn_NextPage.visible = false;
updatePageIndicators();
}
// ----------------------------------------------------------------------------------------------------------------------
public function turnPage(increment:int = 0):void
{
if (increment != 0)
{
Game.soundManager.playSound("page_turn");
var oldIndex:uint = _currentPageIndex;
_currentPageIndex += increment;
updateButtons(oldIndex, true);
}
Starling.juggler.tween(_container, PAGE_TURNING_TIME, {
transition: "easeOutCubic",
//transition: Transitions.EASE_OUT,
x:_currentPageIndex * -_panelBounds.width + _panelBounds.x,
onComplete: updatePageIndicators()
});
}
// ----------------------------------------------------------------------------------------------------------------------
public function goToPage(pageNumber:uint):void {
var oldIndex:uint = _currentPageIndex;
_currentPageIndex = pageNumber;
updateButtons(oldIndex, false);
_container.x = _currentPageIndex * -_panelBounds.width + _panelBounds.x;
updatePageIndicators();
}
// ----------------------------------------------------------------------------------------------------------------------
private function updatePageIndicators():void {
for (var i:uint = 0; i < _pageCount; i++)
{
pageIndicator_Vector[i].alpha = 0.3;
pageIndicator_Vector[i].color = Colors.BLACK;
}
pageIndicator_Vector[_currentPageIndex].alpha = 1;
pageIndicator_Vector[_currentPageIndex].color = Colors.RED;
}
// ----------------------------------------------------------------------------------------------------------------------
private function updateButtons(oldIndex:uint, hasTween:Boolean):void {
/* PREV BUTTON */
if (_currentPageIndex == 0)
{
btn_PrevPage.enabled = false;
if (hasTween)
Starling.juggler.tween(btn_PrevPage, PAGE_TURNING_TIME, { alpha: 0 } );
else
btn_PrevPage.alpha = 0;
}
else if (_currentPageIndex > 0 && oldIndex == 0)
{
btn_PrevPage.enabled = true;
if (hasTween)
Starling.juggler.tween(btn_PrevPage, PAGE_TURNING_TIME, { alpha: 1 } );
else
btn_PrevPage.alpha = 1;
}
/* NEXT BUTTON */
if (_currentPageIndex == _pageCount - 1)
{
btn_NextPage.enabled = false;
if (hasTween)
Starling.juggler.tween(btn_NextPage, PAGE_TURNING_TIME, { alpha: 0 } );
else
btn_NextPage.alpha = 0;
}
else if (_currentPageIndex < (_pageCount - 1) && oldIndex == (_pageCount - 1))
{
btn_NextPage.enabled = true;
if (hasTween)
Starling.juggler.tween(btn_NextPage, PAGE_TURNING_TIME, { alpha: 1 } );
else
btn_NextPage.alpha = 1;
}
}
// ----------------------------------------------------------------------------------------------------------------------
private function touchHandler(event:TouchEvent) : void
{
var touch:Touch = event.getTouch(stage);
if (touch)
{
_position = touch.getLocation(this);
var target:Quad = event.target as Quad;
if(touch.phase == TouchPhase.BEGAN )
{
_startX = _position.x;
_offsetX = _container.x;
_x1 = _x2 = _position.x;
_t1 = _t2 = getTimer();
this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
if(touch.phase == TouchPhase.MOVED )
{
_container.x = _offsetX + _position.x - _startX;
}
if(touch.phase == TouchPhase.ENDED )
{
this.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
var elapsedTime:Number = (getTimer() - _t2) / 1000;
var xVelocity:Number = (_position.x - _x2) / elapsedTime;
if (_currentPageIndex > 0 && (xVelocity > 20 || _container.x > (_currentPageIndex - 0.5) * -_panelBounds.width + _panelBounds.x))
{
turnPage(-1);
}
else if (_currentPageIndex < _pageCount - 1 && (xVelocity < -20 || _container.x < (_currentPageIndex + 0.5) * -_panelBounds.width + _panelBounds.x))
{
turnPage(1);
}
// tween page back to initial position in case the page hasn't been turned
turnPage(0);
}
}
}
// ----------------------------------------------------------------------------------------------------------------------
private function onEnterFrame(event : Event) : void
{
_x2 = _x1;
_t2 = _t1;
_x1 = _position.x;
_t1 = getTimer();
}
// ----------------------------------------------------------------------------------------------------------------------
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment