I originally wrote this function in 2007 in Actionscript 2 (remember createEmptyMovieClip) and recently rewrote it in as3. The concept is to present a series of “shelves” that move together vertically as a group but move independently of each other when moving horizontally. Instead of a grid of rows and buttons imagine shelves of books with each shelf holding a different category e.g. history, biography, art & photography…
The buttons that control the movement of the shelves automatically show/hide themselves based on the status of the uppermost shelf visible.
The code below create a main sprite which is tweened vertically while serving as a container for all the rows. The rows, in turn, are independently tweened horizontally while also serving as a container for all its buttons. The custom ButtonPressedEvent class communicates from within each button its id and function.
import com.dtk.Button_WH; import com.dtk.NavIconLoader; import com.dtk.ButtonPressedEvent; import com.dtk.HTMLText; import caurina.transitions.*; /** * basic settings */ var rows:uint = 10; var cols:uint = 10; var maskedRows:uint = 5; var maskedCols:uint = 5; // upper left position of grid var xStart:uint = 60; var yStart:uint = 60; var btnWidth:uint = 30; var btnHeight:uint = 30; var spacing:uint = 10; // calc mask width, height var maskWidth:uint = maskedCols * ( btnWidth + spacing ); var maskHeight:uint = maskedRows * ( btnHeight + spacing ); // first button id number var btnID:uint = 0; // init vars var xPos:uint = xStart; var yPos:uint = yStart; // init var to define tweened movement var movement:int; // current top visible row id var rowID:uint = 0; // sprite to contain all rows var main:Sprite = new Sprite( ); main.name = 'main'; addChild( main ); // loop through columns one row at a time for ( var r:uint=0; r<rows; r++ ) { // reset starting postion for each row xPos = xStart + spacing / 2; // row spite holds buttons var rw:Sprite = new Sprite( ); rw.name = 'row_' + r; main.addChild( rw ); for ( var c:uint=0; c<cols; c++ ) { // add button instance to row var b:Button_WH = new Button_WH( btnID, btnWidth, btnHeight, btnID.toString( ) ); b.x = xPos; b.y = yPos; b.name = 'btn_' + c; b.addEventListener( ButtonPressedEvent.BUTTON_PRESSED, onGridButtonPressed ); rw.addChild( b ); // calc next button position & increment button id xPos += ( btnWidth + spacing ); btnID++; } // calc next row position yPos += ( btnHeight + spacing ); } // draw & set mask var ms:Sprite = new Sprite( ); ms.graphics.beginFill( 0xff0000 ); ms.graphics.drawRect( xStart, yStart, maskWidth, maskHeight ); ms.graphics.endFill( ); addChild( ms ); main.mask = ms; /* * load UP, DOWN, LEFT, RIGHT nav buttons with DOWN & RIGHT not visible * set each with own event listener * */ var down:NavIconLoader = new NavIconLoader( 'DOWN', 'arrows/down.jpg', 40, 40 ); down.x = xStart + 2 * btnWidth + 2 * spacing; down.y = 10; down.visible = false; down.addEventListener( ButtonPressedEvent.BUTTON_PRESSED, onNavButtonPressed ); down.name = 'down'; addChild( down ); var up:NavIconLoader = new NavIconLoader( 'UP', 'arrows/up.jpg', 40, 40 ); up.x = xStart + 2 * btnWidth + 2 * spacing; up.y = yStart + 5 * ( btnHeight + spacing ); up.addEventListener( ButtonPressedEvent.BUTTON_PRESSED, onNavButtonPressed ); up.name = 'up'; addChild( up ); var left:NavIconLoader = new NavIconLoader( 'LEFT', 'arrows/left.jpg', 40, 40 ); left.x = xStart + ( 5 * btnWidth ) + ( 6 * spacing ); left.y = yStart - spacing + 4; left.addEventListener( ButtonPressedEvent.BUTTON_PRESSED, onNavButtonPressed ); left.name = 'left'; addChild( left ); var right:NavIconLoader = new NavIconLoader( 'RIGHT', 'arrows/right.jpg', 40, 40 ); right.x = 10; right.y = yStart - spacing + 4; right.visible = false; right.addEventListener( ButtonPressedEvent.BUTTON_PRESSED, onNavButtonPressed ); right.name = 'right'; addChild( right ); /* * function called by each button press calculates tween movement & current row * */ function onNavButtonPressed( e:ButtonPressedEvent ):void { switch( e.buttonEvent ) { // UP case 0: movement = main.y - btnHeight - spacing; Tweener.addTween ( main, { y: movement, time: 1, onComplete: tweenedUp } ); rowID++; break; // DOWN case 1: movement = main.y + btnHeight + spacing; Tweener.addTween ( main, { y: movement, time: 1, onComplete: tweenedDown } ); rowID--; break; // LEFT case 2: movement = main.x - 5 * ( btnWidth + spacing ); Tweener.addTween ( main.getChildAt( rowID ), { x: movement, time: 2, onComplete: tweenedLeft } ); break; // RIGHT case 3: movement = main.getChildAt( rowID ).x + 5 * ( btnWidth + spacing ); Tweener.addTween ( main.getChildAt( rowID ), { x: movement, time: 2, onComplete: tweenedRight } ); break; } } function tweenedUp( ):void { if ( main.y + main.height <= btnHeight + ( 2 * spacing ) ) { getChildByName( 'up' ).visible = false; } getChildByName( 'down' ).visible = true; testLeftRight( ); } /* * after down tween of row is completed set visibilty of up, down buttons * */ function tweenedDown( ):void { if ( main.y >= 0 ) { getChildByName( 'down' ).visible = false; } getChildByName( 'up' ).visible = true; // update visibility of left, right buttons testLeftRight( ); } function tweenedLeft( ):void { getChildByName( 'right' ).visible = true; if ( main.getChildAt( rowID ).x <= maskWidth ) { getChildByName( 'left' ).visible = false; } } function tweenedRight( ):void { getChildByName( 'left' ).visible = true; if ( main.getChildAt( rowID ).x == 0 ) { getChildByName( 'right' ).visible = false; } } /* * control visibility of left, right buttons as rows move up/down * */ function testLeftRight( ):void { if ( main.getChildAt( rowID ).x <= maskWidth ) { getChildByName( 'right' ).visible = true; getChildByName( 'left' ).visible = false; } if ( main.getChildAt( rowID ).x == 0 ) { getChildByName( 'left' ).visible = true; getChildByName( 'right' ).visible = false; } } /* * display id of button pressed * */ function onGridButtonPressed( e:ButtonPressedEvent ):void { // remove previous instance of text displayed for ( var i:uint=0; i<numChildren; i++ ) { if ( getChildAt(i).name == 'txt' ) { removeChildAt(i); } } // instance of HTMLText class var txt:HTMLText = new HTMLText( 100, 'Verdana', 48, 0xcccccc, 'RIGHT', '<b>'+e.buttonEvent.toString( )+'</b>' ); txt.x = xStart + 190; txt.y = yStart + 140; txt.name = 'txt'; addChild( txt ); } |
The download includes bookshelves.fla, a folder containing the nav button jpg’s and the four custom classes used.
Download files: Bookshelves.zip (41)
No Comments so far ↓
There are no comments yet...Kick things off by filling out the form below.