Posts Tagged ‘gallery’

Deconstruct red-issue.com

Sunday, March 22nd, 2009

In one of my Flash courses taught at Humber College we often choose web sites to deconstruct. Today we have chosen red-issue.com.

First let’s figure out what we want to learn from this web site. We are going to create a grid of images where each image will occupy the full screen. This grid will be navigated by drawing arrows.

First lets import all the Flash and custom classes we will need:

import flash.display.StageScaleMode;
import flash.display.StageAlign;
import flash.events.Event;
import fl.transitions.Tween;
import fl.transitions.easing.*;
import fl.transitions.TweenEvent;
import com.foxaweb.ui.gesture.*;

The last import statement is a class that helps us recognize mouse gestures. The Mouse Gestures Class was written by Didier Brun.

Next we need a few variables to define the grid dimensions and to keep track of what row and column we are currently looking at.

var verticalCounter:Number = new Number();
var horizontalCounter:Number = new Number();
var gridWidth:Number=new Number(4);
var gridHeight:Number=new Number(3);

On the Enter Frame Event we will check the values in the horizontalCounter and verticalCounter variable and position the grid accordingly. That way when someone draws a down arrow we will simply add one to the verticalCounter variable.

stage.addEventListener(Event.ENTER_FRAME,enterFrameHandler);
function enterFrameHandler(evt:Event):void {
     var targetX:Number = new Number(stage.stageWidth * horizontalCounter);
     grid_mc.x += (targetX - grid_mc.x) / 3;
     var targetY:Number = new Number(stage.stageHeight * verticalCounter);
     grid_mc.y += (targetY - grid_mc.y) / 3;
}

Wen using the Mouse Gestures Class we need to tell the Class what gestures to look for. These gestures are determined by a set of numbers. For example a up arrow starting from the left consists of a 7 motion and then a 1 motion. Here are the motions tracked and the numbers for each.

Here is the code to create a new Mouse Gesture and add the four different directions as well as the zoom in and zoom out gestures.

var mg:MouseGesture = new MouseGesture(stage);
mg.addGesture("UP","71");
mg.addGesture("UP","53");
mg.addGesture("DOWN","17");
mg.addGesture("DOWN","35");
mg.addGesture("LEFT","13");
mg.addGesture("LEFT","75");
mg.addGesture("RIGHT","31");
mg.addGesture("RIGHT","57");
mg.addGesture("OUT","0");
mg.addGesture("OUT","4");
mg.addGesture("IN","4321076542");

Now with this class we are going to listen for a few specific events.

mg.addEventListener(GestureEvent.GESTURE_MATCH,matchHandler);
mg.addEventListener(GestureEvent.NO_MATCH,noMatchHandler);
mg.addEventListener(GestureEvent.START_CAPTURE,startHandler);
mg.addEventListener(GestureEvent.STOP_CAPTURE,stopHandler);

A Mouse Gesture is defined by the user pressing their mouse down, moving the mouse and then releasing. When a Mouse Gesture matches one of the items defines in our list the matchHandler function is executed. This function makes the necessary changes to verticalCounter or horizontalCounter and then removes the drawing.

function matchHandler(evt:GestureEvent):void{
     switch (evt.datas){
          case "UP":
               if(verticalCounter < 0){
                    verticalCounter++;
               }
          break;
          case "DOWN":
               if(verticalCounter > 1 - gridHeight){
                    verticalCounter--;
               }
          break;
          case "LEFT":
               if(horizontalCounter > 1 - gridWidth){
                    horizontalCounter--;
          }
          break;
          case "RIGHT":
               if(horizontalCounter < 0){
                    horizontalCounter++;
               }
          break;
          case "IN":
               // Zoom in code would go here
          break;
          case "OUT":
               // Zoom out code would go here
          break;
     }
     var tweenOut:Tween = new Tween(draw_mc,"alpha",Strong.easeOut,1,0,6);
}

This code was taken from the GesturesDemo.as file that comes with the Mouse Gestures Class. When the Start Capture Event is triggered this code draws whatever the user does.

function startHandler(e:GestureEvent):void{
     draw_mc.graphics.clear();
     draw_mc.alpha = 1;
     draw_mc.graphics.lineStyle(4,0x444444);
     draw_mc.graphics.moveTo(mouseX,mouseY);
     addEventListener(Event.ENTER_FRAME,capturingHandler);
}

When the user lets go of their mouse the Stop Capture Event is triggered and executes the startHandler function. This function stops the drawing initialized by the startHandler function.

function stopHandler(e:GestureEvent):void{
     removeEventListener(Event.ENTER_FRAME,capturingHandler);
}

This function actually performs the drawing. It is started by the startHandler function and is stopped by the stopHandler function.

function capturingHandler(e:Event):void{
     draw_mc.graphics.lineTo(mouseX,mouseY);
}

When the user releases the mouse button if there is no match the noMatchHandler function removes the drawing.

function noMatchHandler(e:GestureEvent):void{
     var tweenOut:Tween = new Tween(draw_mc,"alpha",Strong.easeOut,1,0,6);
}

The next set of code creates the photo grid and makes any necessary changes when the Stage is re-sized. You can get a much more in depth description of this code from the Photo Grid post.

stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;

This list of images could eventually come from an XML document but for now we will just use an array.

var imageDir:String = new String( "http://adambenjamin.com/blog/wp-content/" );
var gridArray:Array=new Array(
     ({image:"img_0001.jpg",imageWidth:800,imageHeight:532}),
     ({image:"img_0002.jpg",imageWidth:800,imageHeight:532}),
     ({image:"img_0003.jpg",imageWidth:800,imageHeight:532}),
     ({image:"img_0004.jpg",imageWidth:800,imageHeight:532}),
     ({image:"img_0005.jpg",imageWidth:800,imageHeight:532}),
     ({image:"img_0006.jpg",imageWidth:800,imageHeight:532}),
     ({image:"img_0007.jpg",imageWidth:800,imageHeight:532}),
     ({image:"img_0008.jpg",imageWidth:800,imageHeight:532}),
     ({image:"img_0009.jpg",imageWidth:800,imageHeight:532}),
     ({image:"img_0010.jpg",imageWidth:800,imageHeight:532}),
     ({image:"img_0011.jpg",imageWidth:800,imageHeight:532}),
     ({image:"img_0012.jpg",imageWidth:800,imageHeight:532}));

var movieArray:Array = new Array();
var maskArray:Array = new Array();
var loaderArray:Array = new Array();

stage.addEventListener(Event.RESIZE, resizeHandler);
function resizeHandler(evt:Event):void {
     for (var i:int = 0; i < gridArray.length; i ++) {
          resizeMask(i);
          resizeImage(i);
          reposition(i);
     }
}

for (var i:int = 0; i < gridArray.length; i ++) {
     maskArray[i] = new MovieClip();
     maskArray[i].graphics.lineStyle(0,0x000088);
     maskArray[i].graphics.beginFill(0x000088);
     maskArray[i].graphics.drawRect(0,0,1,1);
     maskArray[i].graphics.endFill();
     resizeMask(i);
     grid_mc.addChild(maskArray[i]);
     movieArray[i] = new MovieClip();
     var request:URLRequest=new URLRequest(imageDir + gridArray[i]["image"]);
     loaderArray[i] = new Loader();

     loaderArray[i].load(request);
     resizeImage(i);
     movieArray[i].addChild(loaderArray[i]);
     grid_mc.addChild(movieArray[i]);
     movieArray[i].mask=maskArray[i];
     reposition(i);
}

function reposition(i:int):void{
     maskArray[i].x = i % gridWidth * Number(stage.stageWidth);
     maskArray[i].y = Math.floor( i / gridWidth ) * Number(stage.stageHeight);
     movieArray[i].x = i % gridWidth * Number(stage.stageWidth);
     movieArray[i].y = Math.floor( i / gridWidth ) * Number(stage.stageHeight);
}

function resizeMask(i:int):void{
     maskArray[i].width = Number(stage.stageWidth);
     maskArray[i].height = Number(stage.stageHeight);
}

function resizeImage(i:int):void {
     var widthRatio:Number = Number(stage.stageWidth)/gridArray[i]["imageWidth"];
     var heightRatio:Number = Number(stage.stageHeight)/gridArray[i]["imageHeight"];
     if( widthRatio > heightRatio){
          movieArray[i].scaleX = widthRatio;
          movieArray[i].scaleY = widthRatio;
     }else{
          movieArray[i].scaleX = heightRatio;
          movieArray[i].scaleY = heightRatio;
     }
}

The Flash plugin is required to view this object.

Download Red Issue FLA

Flash XML Gallery

Friday, February 27th, 2009

This post will walk through the construction of a simple XML and Flash gallery. If you want to use the images and XML file we are referring to in this example you can download our XML document here and download our images here. Our gallery will simply load the first image and then with each click it’ll load the next image form our XML document.

The Flash plugin is required to view this object.

First of all here is the XML we will be working with:

<?xml version="1.0" encoding="utf-8"?>
<gallery>
     <photo>
          <filename>http://adambenjamin.com/blog/wp-content/img_0001.jpg</filename>
          <width>800</width>
          <height>531</height>
          <title>Field at Night</title>
     </photo>
     <photo>
          <filename>http://adambenjamin.com/blog/wp-content/img_0002.jpg</filename>
          <width>800</width>
          <height>531</height>
          <title>Van on the Road</title>
     </photo>
     <photo>
          <filename>http://adambenjamin.com/blog/wp-content/img_0003.jpg</filename>
          <width>800</width>
          <height>531</height>
          <title>Van on the Road Close Up</title>
     </photo>
     <photo>
          <filename>http://adambenjamin.com/blog/wp-content/img_0004.jpg</filename>
          <width>800</width>
          <height>531</height>
          <title>Mountains</title>
     </photo>
     <photo>
          <filename>http://adambenjamin.com/blog/wp-content/img_0005.jpg</filename>
          <width>800</width>
          <height>531</height>
          <title>Edge of a Cliff</title>
     </photo>
     <photo>
          <filename>http://adambenjamin.com/blog/wp-content/img_0006.jpg</filename>
          <width>800</width>
          <height>531</height>
          <title>Another Road</title>
     </photo>
     <photo>
          <filename>http://adambenjamin.com/blog/wp-content/img_0007.jpg</filename>
          <width>800</width>
          <height>531</height>
          <title>Tight Path</title>
     </photo>
     <photo>
          <filename>http://adambenjamin.com/blog/wp-content/img_0008.jpg</filename>
          <width>800</width>
          <height>531</height>
          <title>Yellow Pickup</title>
     </photo>
     <photo>
          <filename>http://adambenjamin.com/blog/wp-content/img_0009.jpg</filename>
          <width>800</width>
          <height>531</height>
          <title>Power Lines</title>
     </photo>
     <photo>
          <filename>http://adambenjamin.com/blog/wp-content/img_0010.jpg</filename>
          <width>800</width>
          <height>531</height>
          <title>Pig</title>
     </photo>
     <photo>
          <filename>http://adambenjamin.com/blog/wp-content/img_0011.jpg</filename>
          <width>800</width>
          <height>531</height>
          <title>Drying Coffee Beans</title>
     </photo>
     <photo>
          <filename>http://adambenjamin.com/blog/wp-content/img_0012.jpg</filename>
          <width>800</width>
          <height>531</height>
          <title>Homes</title>
     </photo>
</gallery>

In this example the only piece of information we will need is the filename. In future posts we may use the image titles and dimensions.

First we need to import a few Classes:

import fl.transitions.Tween;
import fl.transitions.easing.*;
import fl.transitions.TweenEvent;

Next we need a Movie Clip to load images into and apply Tweens to:

var containerMovie:MovieClip = new MovieClip();
addChild(containerMovie);

Then we define a URL Loarder and an XML Object:

var xmlLoader:URLLoader = new URLLoader();
var xmlData:XML = new XML();

We are going to need two variables: one to keep track of what image we are currently viewing and another to keep track of whether or not we are in the progress of loading the next image.

var galleryCounter:Number=new Number(0);
var galleryStatus:Boolean=new Boolean(false);

Then we are gong to add an Event LIstener to the main Movie Clip to listen for Click Events.

containerMovie.buttonMode = true;
containerMovie.addEventListener(MouseEvent.CLICK,clickHandler);

When some one clicks the main Movie Clip we check to make sure another image isn’t half way through loading; and if it isn’t we add one to the counter Variable, check to make sure it hasn’t gone too high and then load that photo.

function clickHandler(evt:MouseEvent):void {
     if (galleryStatus==false) {
          galleryCounter++;
          if (galleryCounter>=xmlData.photo.length()) {
               galleryCounter=0;
          }
          loadPhotoStep1(galleryCounter);
     }
}

Now that our containers and butons are all set up lets load our XML.

xmlLoader.load(new URLRequest("gallery.xml"));

Once that loading is complete we put the loaded information into our XML Object and start eh first step of loading our image.

xmlLoader.addEventListener(Event.COMPLETE, LoadXML);
function LoadXML(e:Event):void {
     xmlData=new XML(e.target.data);
     loadPhotoStep1(galleryCounter);
}

Setp 1 - we save the loaded image number into our galleryCounter variable and set galleryStatus to true. This prevents our clickHandler function above from loading another image before this one has finished loading. And we Tween the Alpha out of the current image.

function loadPhotoStep1(photoNumber:Number):void {
     galleryCounter=photoNumber;
     galleryStatus=true;
     var tweenOut:Tween=new Tween(containerMovie,"alpha",Strong.easeOut,1,0,15);
     tweenOut.addEventListener(TweenEvent.MOTION_FINISH,loadPhotoStep2);
}

Step 2 - once the first Tween has completed we load empty the container Movie Clip and load in the new image.

function loadPhotoStep2(evt:TweenEvent):void {
     var imageLoader:Loader = new Loader();
     var imageRequest:URLRequest=new URLRequest(xmlData.photo[galleryCounter].filename);
     imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,loadPhotoStep3);
     imageLoader.load(imageRequest);
     emptyContainer();
     containerMovie.addChild(imageLoader);
}

One the image has loaded in we Tween the Alpha back in.

function loadPhotoStep3(evt:Event):void {
     var tweenIn:Tween=new Tween(containerMovie,"alpha",Strong.easeOut,0,1,15);
     tweenIn.addEventListener(TweenEvent.MOTION_FINISH,loadPhotoStep4);
}

Once that Tween is complete we set galleryStatus back to false so the next time the user clicks the Movie Clip i’s good to go!

function loadPhotoStep4(evt:Event):void {
     galleryStatus=false;
}

This last function removes all Children from the containerMovie Movie Clip. It is called by the step 2 function.

function emptyContainer() :void {
     for (var i:int; i < containerMovie.numChildren; i++){
          containerMovie.removeChildAt(i);
     }
}

Download the Gallery Flash File

Download a Version of this Gallery with Thumbnails