6/19/2011

Looping Gallery

Some clever thinking and a small change to our cover flow code in the last post can make the gallery loop...

Today's post builds off of our previous code for a cover flow gallery. So make sure to give that a read and run through it before attempting this.

Thinking it Through
In a looping gallery, items loop itself so that you could go forever in any one direction. Recall that we used an Array to store our items, and to achieve this loop, we need to move items from one end to the other as we move in either direction. In other words, there will always be an equal number to either side of our item being shown.

To do this, our first thought would be to move array elements from one end to the other as our showing iterator moves through the array. Implementing this, we will quickly realize that we only need to move the array! In other words we should move the array while showing remains stationary in the middle of the array.

And this is how we will modify the code for it.

The Code Change
Instead of a simple change of the showing variable, we'll need to replace it with a function that cuts pieces of the array from one end and move it to the other. The following function moves n pieces in either direction (positive or negative).
function moveArray(n:int){ var i:int; var moved:Array; // this array will hold the pieces that will be moved if(n>0){ // move forward // cut n pieces from the front and attach to end of array moved=thumbs.splice(0,n); thumbs=thumbs.concat(moved); // move the pieces to the other side of the stage // so they don't animate across the stage for(i=0;i<moved.length;i++){ moved[i].x=stage.stageWidth+moved[i].width; } }else if(n<0){ // move backward // cut n pieces from the end of the array // to add to the front of array moved=thumbs.splice(thumbs.length+n,-n); thumbs=moved.concat(thumbs); // move the pieces to the other side of the stage // so they don't animate across the stage for(i=0;i<moved.length;i++){ moved[i].x=-moved[i].width; } } show(); // animate the pieces to place } AND THAT'S IT!
well... still need to make a few adjustments to our previous code to make it work.

First, need to set show at the middle of the array in our init function.showing = int(thumbs.length/2);
Then use our moveArray function in the keydown function which moves the gallery one left/right. function keydown(e:KeyboardEvent):void{ switch(e.keyCode){ case 37: // press right moveArray(-1); break; case 39: // press left moveArray(1); break; } }
One last part to modify, the jump-to-image-on-click function: function clickthumb(e:MouseEvent):void{ // find clicked thumb's position in array var n:int=thumbs.indexOf(e.currentTarget); if(showing==n){ // when user clicks the thumb that is currently showing // do something (i.e. show full image) }else{ // find difference between showing and the one you want to move to. var diff:int=showing-n; // then move that amount moveArray(-diff); } } presenting... a looping cover flow~

The Full Code
As last time, supply your own thumbPaths. import flash.display.Sprite; import flash.display.Loader; import flash.net.URLRequest; import flash.events.KeyboardEvent; import flash.events.MouseEvent; import com.greensock.TweenLite; import com.greensock.plugins.TweenPlugin; import com.greensock.plugins.ColorMatrixFilterPlugin; TweenPlugin.activate([ColorMatrixFilterPlugin]); var container:Sprite; // just a container to hold all the thumbnails var thumbs:Array; // array of thumbnail display objects (Sprites) var showing:int; // keeps track of the current showing thumbnail var tsize:int=200; // size of your thumbnail var thumbPaths:Array; // this is your array of image urls to load from stage.addEventListener(KeyboardEvent.KEY_DOWN,keydown); createGallery(); function createGallery(){ thumbs=new Array(); container=new Sprite(); container.y=stage.stageHeight/2; addChild(container); var thumb:Sprite; var l:Loader; for(var i=0;i<thumbPaths.length;i++){ // create the thumbs thumb=new Sprite(); // draw background box with registration at center thumb.graphics.beginFill(0x333333); thumb.graphics.drawRect(-tsize/2,-tsize/2,tsize,tsize); thumb.name="t"+i; thumb.addEventListener(MouseEvent.CLICK,clickthumb); // use a Loader to load image, registration center l=new Loader(); l.x=l.y=-tsize/2; l.load(new URLRequest(thumbPaths[i])); thumb.addChild(l); thumbs.push(thumb); container.addChild(thumb); } showing = int(thumbs.length/2); show(); } function moveToPlace(){ var diff:int; // distance from showing var dir:int; // direction from showing var gx:Number; // x position it will move to var scale:Number; // scale it will transform to var rotY:Number; // rotation Y var br:Number; // brightness for(var i:int=0;i<thumbs.length;i++){ diff=i-showing; // distance from showing dir=Math.abs(diff)/diff; // -1 or 1 if(i==showing){ gx=stage.stageWidth/2; scale=1; rotY=0; br=1; }else{ gx=stage.stageWidth/2+(100*dir)+(diff*30); scale=0.5+Math.abs(diff)*0.05; if(scale>1.2)scale=1.2; rotY=90*dir; br=1-(Math.abs(diff)*0.4); if(br<-3)br=-3; } // tween to it TweenLite.to(thumbs[i],0.5,{colorMatrixFilter:{brightness:br},scaleX:scale,scaleY:scale,x:gx,rotationY:rotY}); } } function zOrderSort():void{ var obj:Object; var zArray:Array=new Array(); var l:int=thumbs.length; for(var i:int=0;i<l;i++){ // save thumb and its distance from showing into array obj={img:thumbs[i],dist:Math.abs(showing-i)}; zArray.push(obj); } //sort array by distance zArray.sortOn("dist",Array.NUMERIC|Array.DESCENDING); // assign depths according to sorted array for(i=0;i<l;i++){ container.setChildIndex(zArray[i].img,i); } } function show(){ zOrderSort(); moveToPlace(); } function keydown(e:KeyboardEvent):void{ switch(e.keyCode){ case 37: // press right moveArray(-1); break; case 39: // press left moveArray(1); break; } } function clickthumb(e:MouseEvent):void{ // find clicked thumb's position in array var n:int=thumbs.indexOf(e.currentTarget); if(showing==n){ // when user clicks the thumb that is currently showing // do something (i.e. show full image) }else{ // find difference between showing and the one you want to move to. var diff:int=showing-n; // then move that amount moveArray(-diff); } } function moveArray(n:int){ var i:int; var moved:Array; // this array will hold the pieces that will be moved if(n>0){ // move forward // cut n pieces from the front and attach to end of array moved=thumbs.splice(0,n); thumbs=thumbs.concat(moved); // move the pieces to the other side of the stage // so they don't animate across the stage for(i=0;i<moved.length;i++){ moved[i].x=stage.stageWidth+moved[i].width; } }else if(n<0){ // move backward // cut n pieces from the end of the array // to add to the front of array moved=thumbs.splice(thumbs.length+n,-n); thumbs=moved.concat(thumbs); // move the pieces to the other side of the stage // so they don't animate across the stage for(i=0;i<moved.length;i++){ moved[i].x=-moved[i].width; } } show(); // animate the pieces to place }

1 comment: