|
FlashFlowFactory
Description of flashflowfactory
Phase-Implementation This is a working draft and will frequently be changed. The framework is currently in beta. Let me know what you think and what can be improved.
Flashflowfactory Frameworkcurrent version: 0.9 beta This lightweight framework helps you to easily setup a flash website. It is called flashflowfactory. The framework makes use of SWFAddress 2.5 for deeplinking. Flashflowfactory is compatible to multiple tweenengines for transitions and easing. Content overview
AboutOver time I have created this lightweight framework which helps you to easily setup a flash website. It is called flashflowfactory. The framework makes use of SWFAddress 2.5 for deeplinking and your favorite tweenengine for transitions (TweenLite, Tweener, gTween or Eaze-Tween). When you need to create small/medium websites with deeplinking and basic transitions, flashflowfactory could help you develop faster. The best of flashflowfactory is its simplicity; no need to learn hard design-patterns, it is really straight-forward if you know the basics. You don't have to develop a page setup with deeplinking and transitions or start from scratch, but keep the freedom to build the site in your style. Flashflowfactory FeaturesThese are the features of flashflowfactory
Download the framework in 2 steps
http://stroep.googlecode.com/files/flashflowfactory.swc DOCUMENTATION
Flashflowfactory TutorialHow to useBefore starting, you should know a few things: how to create link classes to MovieClips, and the basics from actionscript 3. I really recommend to use flash just for the graphics (link it to classes, 'export as SWC'), and use an external AS editor for ultimate coding-fun. All classes related to the framework are inside package nl.stroep.flashflowfactory I have separated the framework from the transitions since this allows me to give you multiple transition packs and some freedom to create an SWC file from the framework without any tweenengine. You should add both things (the SWC and the transition pack classes) to your project. Step 1: Create flashfileJust to start, create a new flash file / project. Save it and place the flashflowframework files next to the flash, or create your own setup where the framework is included. Make sure you included the tween engine and SWFAddress too. In case you want to use TweenLite, you should download the SWC/sources from greensock.com, since I cannot offer the file from googlecode (because of it's license). Now we need to design some pages. In the next examples I am using the TweenLite pack. Step 2: Create PagesCreate a MovieClip called HomePageVC. Draw a square in it (about 500x400 px) and add some text and a title called 'Home'. Imaging this is your homepage. The centerpoint of the page should be on the top left. Find the MovieClip in your library and go to the linkage screen (right-click). Choose "export for ActionScript". In the class input you should enter HomePageVC and the base class should be nl.stroep.flashflowfactory.Page. You are now extending the Page class from the framework. Create two other pages, called ContactPageVC and InfoPageVC, all should extend nl.stroep.flashflowfactory.Page. You now have 3 pages, ready to be used. Step 3: Create Document classCreate a Main.as and place it in the root of your project, and use this as Document Class. If you are creating a project from external code editor, mark this file as 'always compile' or compile starting point. Note: This is the most simple usage of the framework. Ofcourse there are more settings available. package
{
import flash.display.Sprite;
import nl.stroep.flashflowfactory.PageFactory;
public class Main extends Sprite
{
private var pageFactory:PageFactory;
public function Main():void
{
pageFactory = new PageFactory();
// add your pages here
pageFactory.add( "/home", HomePageVC );
pageFactory.add( "/contact", ContactPageVC );
pageFactory.add( "/info", InfoPageVC );
// add page holder to stage
addChild( pageFactory.view );
// load intropage
pageFactory.init();
}
}
}It would be better to create a Pages.as file, which contains constants with all paths. This is very useful when pointing at multiple places to the same page. package
{
public class Pages
{
public static const HOME_PAGE:String = "/home";
public static const CONTACT_PAGE:String = "/contact";
public static const INFO_PAGE:String = "/info";
}
}Step 4: Create simple navigationNow you have 3 pages ready to be used. You need some navigation buttons to navigate through the pages. Create 3 buttons for each page (home, contact, info). Find the buttons in your library and go to the linkage screen (right-click). Choose "export for ActionScript". In the class input you should enter HomePageButtonVC and the base class should be nl.stroep.flashflowfactory.navigation.NavigationButton. Apply this rule for all buttons, they should all extend nl.stroep.flashflowfactory.navigation.NavigationButton. Place the buttons on the stage and give them the instance names 'buttonHome', 'buttonInfo', 'buttonContact'. Go to your Main.as. Replace all code to this code: package
{
import flash.display.Sprite;
import nl.stroep.flashflowfactory.PageFactory;
import nl.stroep.flashflowfactory.navigation.NavigationButton;
public class Main extends Sprite
{
private var pageFactory:PageFactory;
// stage instances
public var buttonHome:NavigationButton;
public var buttonInfo:NavigationButton;
public var buttonContact:NavigationButton;
public function Main():void
{
pageFactory = new PageFactory();
pageFactory.add( Pages.HOME_PAGE, HomePageVC );
pageFactory.add( Pages.CONTACT_PAGE, ContactPageVC );
pageFactory.add( Pages.INFO_PAGE, InfoPageVC );
addChild( pageFactory.view );
pageFactory.init();
initButtons();
}
private function initButtons():void
{
// set button home to go to "/home" on click
buttonHome.click(Pages.HOME_PAGE);
// set button home to go to "/info" on click
buttonInfo.click(Pages.INFO_PAGE);
// set button home to go to "/contact" on click
buttonContact.click(Pages.CONTACT_PAGE);
}
}
}The NavigationButton is very powerful, please do read this section about the options Note: If you are creating an as3-only project, you should create instances of the buttons, like buttonHome = new HomePageButtonVC() etc. Run the movie; you should have a clickable+working "website" with navigation and deeplinking. If you don't want to use the NavigationButton from the framework you can also call PageFactory.gotoPage(Pages.HOME_PAGE) from any point inside your application. Step 5: Customize settings + add TransitionsLets manipulate the default settings and add a slide transition (fading in from left). The animation-in effect should have an Elastic.easeOut and should take 1 second. The animation-out effect should be an Strong.EaseIn and should take 0.7 seconds. Note the easing functions are used from TweenLite package. package
{
import flash.display.Sprite;
import com.greensock.easing.Elastic;
import com.greensock.easing.Strong;
import nl.stroep.flashflowfactory.PageFactory;
import nl.stroep.flashflowfactory.PageSettings;
import nl.stroep.flashflowfactory.navigation.NavigationButton;
import nl.stroep.flashflowfactory.enum.Alignment;
import nl.stroep.flashflowfactory.transitions.*;
public class Main extends Sprite
{
private var pageFactory:PageFactory;
// stage instances
public var buttonHome:NavigationButton;
public var buttonInfo:NavigationButton;
public var buttonContact:NavigationButton;
public function Main():void
{
pageFactory = new PageFactory();
pageFactory.add( Pages.HOME_PAGE, HomePageVC );
pageFactory.add( Pages.CONTACT_PAGE, ContactPageVC );
pageFactory.add( Pages.INFO_PAGE, InfoPageVC );
// add default page settings, can also be overridden from the Page class
pageFactory.defaultSettings = new PageSettings(
new SlideTransition(), // transition (there are more transitions + you can easily create your own)
Elastic.easeOut, // easing of the in-transition
Strong.easeIn, // easing of the out-transition
1, // duration of the in-transition
0.7, // duration of the out-transition
Alignment.CENTER_MIDDLE, // alignment of the page on the stage
Alignment.LEFT_TOP // centerpoint position of the page
);
addChild( pageFactory.view );
pageFactory.init();
initButtons();
}
private function initButtons():void
{
buttonHome.click(Pages.HOME_PAGE);
buttonInfo.click(Pages.INFO_PAGE);
buttonContact.click(Pages.CONTACT_PAGE);
}
}
}If you now run the flashfile, you should have a website with buttons, transition and deeplinking. There are a few transitions build in the framework, and some of them have some customizable options (see Transitions). Easing noteYou are using easing functions from your tween engine, this means you have to import the right easings functions. Special note on easing (only applies for Tweener) Normally when you use Tweener, you would use something like transition:"linear" to define an easing. The string definitions are not compatible with flashflowfactory. If you want to define easing in your pageSetting when you are using the Tweener pack, you should use the static functions from 'caurina.transitions.Equations'. for example Equations.easeOutElastic Step 6: Finishing touchesAdd titlesIt is possible to add a title to all page references, which will be shown as browser title (and also in your browserhistory). You can add a prefix for all pages using pageFactory.titlePrefix to show a global text message before that. For example, use that variable for your projectname or companyname. Manipulate first pageDefault the first item you'll add to the pageFactory. will be used as start page. You can override this by setting pageFactory.defaultPageName. package
{
import flash.display.Sprite;
import com.greensock.easing.Elastic;
import com.greensock.easing.Strong;
import nl.stroep.flashflowfactory.PageFactory;
import nl.stroep.flashflowfactory.PageSettings;
import nl.stroep.flashflowfactory.navigation.NavigationButton;
import nl.stroep.flashflowfactory.enum.Alignment;
import nl.stroep.flashflowfactory.transitions.*;
public class Main extends Sprite
{
private var pageFactory:PageFactory;
// stage instances
public var buttonHome:NavigationButton;
public var buttonInfo:NavigationButton;
public var buttonContact:NavigationButton;
public function Main():void
{
pageFactory = new PageFactory();
pageFactory.add( Pages.HOME_PAGE, HomePageVC, "Welcome!" );
pageFactory.add( Pages.CONTACT_PAGE, ContactPageVC, "Contact us");
pageFactory.add( Pages.INFO_PAGE, InfoPageVC, "About us" );
// set the default title prefix text
pageFactory.titlePrefix = "Our website - ";
// set the info page start page as start page.
pageFactory.defaultPageName = Pages.INFO_PAGE;
pageFactory.defaultSettings = new PageSettings(
new SlideTransition(),
Elastic.easeOut,
Strong.easeIn,
1,
0.7,
Alignment.CENTER_MIDDLE,
Alignment.LEFT_TOP
);
addChild( pageFactory.view );
pageFactory.init();
initButtons();
}
private function initButtons():void
{
buttonHome.click(Pages.HOME_PAGE);
buttonInfo.click(Pages.INFO_PAGE);
buttonContact.click(Pages.CONTACT_PAGE);
}
}
}Flashflowfactory Navigation ButtonFlashflowframework includes a NavigationButton class. This is a semi-intelligent MovieClip with smart states and an uber-clickfunction. Just extend NavigationButton and the features below are enabled. Smart statesYou can add framelabels called 'out', 'over', 'down' and/or 'active'. The button will automatically add the needed events for that, and gotoAndPlay() to that framelabel. If you extend the class, you can basically add your button-state-animation and it should work Do not forget to set a stop() commando at the end of each button-state-animation. GroupingIf you have multiple buttons, you can group them, to create an active state. Just pass a name (String) of the group to all buttons using the group-property. If you click on one member of the group, it will gotoAndPlay() to framelabel 'active' if exist. This should make it easy to create simple buttons with cool states. Click functionsBut that is not it. The NavigationButton class is very easy to configure. There is a click function, which should basically cover all types of button-click-functions you would ever create. See code below for the divers navigation button possibilities. import nl.stroep.flashflowfactory.navigation.NavigationButton;
import nl.stroep.flashflowfactory.navigation.ButtonTypes;
// link to normal page inside application
myButton.click(Pages.HOME_PAGE);
// link to normal page inside application (equivalent)
myButton.click(Pages.HOME_PAGE, ButtonTypes.INTERNAL);
// link to external url outside the flash application. default target='_blank'
myButton.click("http://www.google.nl/", ButtonTypes.EXTERNAL);
// link to external url outside the flash application, with other target
myButton.click("http://www.google.nl/", ButtonTypes.EXTERNAL, "_self");
// link to javascript function (it's using ExternalInterface)
myButton.click("myJavascriptFunc", ButtonTypes.JAVASCRIPT);
// link to javascript function with parameters
myButton.click("alert", ButtonTypes.JAVASCRIPT, "Works like a charm");
// link to javascript function with multiple parameters
myButton.click("myJavascriptFunc", ButtonTypes.JAVASCRIPT, "param 1", "param 2", "param 3");
// link to function 'sayHello' inside flashapplication
myButton.click(sayHello, ButtonTypes.FUNCTION);
function sayHello(){
trace("Hello!")
}
// link to function 'sayHelloTo' inside flashapplication with parameters
myButton.click(sayHelloTo, ButtonTypes.FUNCTION, "Mark", "Knol");
function sayHelloTo( firstName:String, lastName:String ){
trace("Hello " + firstName + " " + lastName );
}
It is even possible to dispatch global events. You can use the EventCenter.getInstance() to listen to them. Note; inside the Page-classes there is already an reference to the EventCenter Singleton, it is named eventcenter. // OPTION 1. dispatch event without parameters (type only, thats always required)
myButton.click(MyCustomEvent, ButtonTypes.EVENT, "say_hello");
// OPTION 2. dispatch event with parameters
myButton.click(MyCustomEvent, ButtonTypes.EVENT, "say_hello_to", "Mark");
// Anywhere else inside the application you could receive the event
EventCenter.getInstance().addEventListener(MyCustomEvent.SAY_HELLO, onSayHello);
function onSayHello( e:MyCustomEvent ):void {
trace('Say hello')
}
EventCenter.getInstance().addEventListener(MyCustomEvent.SAY_HELLO_TO, onSayHelloTo);
function onSayHelloTo( e:MyCustomEvent ):void {
trace('Hello ' + e.firstName)
}
// example custom event: MyCustomEvent.as
package
{
import flash.events.Event;
public class MyCustomEvent extends Event
{
public static const SAY_HELLO:String = "say_hello";
public static const SAY_HELLO_TO:String = "say_hello_to";
private var _firstName:String;
public function MyCustomEvent(type:String, firstname:String, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
this._firstName = firstname;
}
public function get firstName():String { return _firstName; }
}
}DocumentationYou can find code documentation here. Page FactoryThis is the Page system which creates/destroys pages and takes care of SWFAddress and it's handling. It is a custom factory design pattern.
Default prefix title for all pages. The PageFactory will set the browser title like this: 'titlePrefix pageTitle' All pages will be added to this Sprite. Don't forget to addChild 'em in your main document. If you want to use another view instead of this one; It is possible to assign another Sprite as view. You can use this value to start on this page, after you call init() PageSettings class which will be applied on every Page. These settings can be overridden in the Page Class itself. Registers a page reference with optional title to the pageFactory. The name reflects the deeplink url. These should start with a forwardslash "/". You can (optional) pass a title too, this title will be displayed in your browser-title. Normally an url represents one page (because the exact pageName links to a classReference). It is possible to add a wildcard to the url, which means you can add optional directories, without have declare them all (mostly on dynamic pages). This (optional) feature is still under construction. Unregisters a page reference from the pageFactory Start the factory, opens first page Removes + cleans pageFactory data Static function. Easy way to navigate to a new page. PageStandard page class. This class should be extended.
When enabled, the show() function is called onAddedToStage, otherwise you can call show() yourself (Useful when you want to load something before showing the page). Default true
Internal page name, auto filled by the PageFactory. The pageName reflects the deeplink url, which is set using SWFAddress. There is no need to modify this value.
Page title, auto filled by the PageFactory. The pageTitle reflects the browser title, which is set using SWFAddress. There is no need to modify this value.
Settings from the page. auto filled by the PageFactory. All values from these settings can be overwritten.
Protected. Overridable method to detect if page is added from stage
Protected. Overridable method to detect if page is removed from stage
Protected. Overridable method to detect if page is ready (ready means after completing transition-in animation)
Final. Starts transition-in animation and dispatches global event PageEvent.SHOW_START. Cannot be overridden. Listen to PageEvent.SHOW_START instead.
Final. Starts transition-out animation and dispatches global event PageEvent.HIDE_START. Cannot be overridden. Listen to PageEvent.HIDE_START instead.
protected. Dispatches global event PageEvent.SHOW_COMPLETE after completing transition-in animation. Cannot be overridden. Listen to PageEvent.SHOW_COMPLETE instead.
Protected. Dispatches global event PageEvent.HIDE_COMPLETE after completing transition-out animation. Cannot be overridden. Listen to PageEvent.HIDE_COMPLETE instead.
Protected. Disable page interactions
Protected. Enable page interactions Page Settings
Transition (interface) which will be applied on the page when navigating from/to it, which includes the following functions. There are already 4 transitions available in the framework (BlurTransition, FadeTransition, SlideTransition and ExplosionTransition), and some of them have some customizable options (see auto-completion / online docs). This is the easing function which will be applied on the transitionIn animation. You should pass a easing equation from TweenLite (like Strong.easeInOut or Elastic.EaseOut). This is the easing function which will be applied on the transitionOut animation. You should pass a easing equation from TweenLite (like Strong.easeInOut or Elastic.EaseOut). This is the easing speed which will be applied on the transitionIn animation, which represents the duration of the transitionIn animation. This should not be negative. This is the easing speed which will be applied on the transitionOut animation, which represents the duration of the transitionOut animation. This should not be negative. Alignment of the page to the stage. You can use the Alignment class for this settings: Default value: "left_top" Alignment of the centerpoint inside the page. Normally you should place the centerpoint to the upperleft, You can use the Alignment class for this settings. Default value: "left_top" How to overwrite default page settingsSometimes default settings aren't enough. It is possible to overwrite the settings of all pages. This should be done inside a custom class which extends Page, see this example: package
{
import flash.events.Event;
import nl.stroep.flashflowfactory.enum.Alignment;
import nl.stroep.flashflowfactory.Page;
public class MyCustomPage extends Page
{
override protected function onAddedToStage(e:Event):void
{
// overwrite your settings here
settings.clipAlignment = Alignment.CENTER_TOP;
// call super to show page
super.onAddedToStage(e);
}
}
}
When autoShow is false (not default) you are a bit more free where to place the custom settings, as long as it is before calling the show() function Flashflowfactory Transitions
Default transition, without options. If you define a speed-value higher than 0, it will use a delay.
Transition which slides from a specified distance to a direction. type options:
Transition which slides from a specified distance to a direction. Only available if you target FlashPlayer 10 or higher. type options:
Transition which blurs the page with a specified blur quality and blur amount. Keep in mind blurring could be a CPU heavy task.
Transition which fades the page. Without options.
Transition which explodes the children of the page to random positions. Created for fun. impact distance from each child. levels levels which indicates how much 'children of children' the effect will apply. How to create your own transitionWhen you want to create your own transition, you have to Implement ITransition, This means you have to create 2 functions:
You can build your own in-animation here. This is the animation when you are entering the page. When the animation is done, you should call page.onShowComplete. You can build your own out-animation here. This is the animation when you are leaving the page. When the animation is done, you should call page.onHideComplete. Creating a transition is a bit abstract because you don't have to set the time or easing (just pass the function parameters), but I think this makes it very powerful and dynamic. Think of the SlideTransition, you can make it bounce or just slide it in/out very fast with same transition, only with other settings, which are editable on every Page. ExampleTake a look at a simple transition, called FadeTransition. This one is already included in the transition packs, and this is from the TweenLite pack. This should give a clear example of how to setup an own transition: package nl.stroep.flashflowfactory.transitions
{
import com.greensock.plugins.AutoAlphaPlugin;
import com.greensock.plugins.TweenPlugin;
import com.greensock.TweenLite;
import nl.stroep.flashflowfactory.Page;
import nl.stroep.flashflowfactory.transitions.interfaces.ITransition;
public class FadeTransition implements ITransition
{
public function FadeTransition()
{
TweenPlugin.activate([AutoAlphaPlugin]);
}
public function animateIn(page:Page, speed:Number, easing:Function):void
{
page.alpha = 0;
TweenLite.to( page, speed, { autoAlpha: 1, onComplete: page.onShowComplete, ease: easing } );
}
public function animateOut(page:Page, speed:Number, easing:Function):void
{
TweenLite.to( page, speed, { autoAlpha: 0, onComplete: page.onHideComplete, ease: easing } );
}
}
}Troubleshooting checklist
EventCenter.getInstance().addListener(this, MyCustomEvent.SAY_HELLO, onSayHello);
// listen when clip is removed from the stage
this.addEventListener(Event.REMOVED_FROM_STAGE, onRemovedFromStage);
function onRemovedFromStage(e:Event):void
{
EventCenter.getInstance().removeListeners(this);
}
| |
Great Framework, exactly what I've been trying to drum up for a while now...just had too many ideas not focusing on one direction. My question is regarding the onPageReady() and show() methods. When is it appropriate to call show()? I am confused from your example because the buttons are dictating when to transition in the new section, I have overriden the onPageReady() method in my Page subclasses but it is never called. I see that you say to make sure to call show() when the page is "ready" but could you clarify what the "show()" method actually does? I would like to know for instance when the page is being called to build, so that I can load assets etc. Is there a way to do this? I see that the onShowComplete and onHideComplete are FINAL methods, so how would I be able to know when I can build the page? Thanks in advance for all your hard work. - tyler
Hi Tyler, Thanks for trying the framework and your reply, it's really useful. The idea in the current version (its still alpha) is to manually call the show() on the extended page at onPageReady, which you have to override. The idea was that in some cases you would load some data before showing the page, so that's why you have to call in yourself in your custom page at the onPageReady function.
I am strongly thinking to include the show() in Page.onPageReady, and adding an autoShow:Boolean to the page, which you can disable inside the constructor.
BTW I am working on example projects which should make this things more clear!
Tyler, I haved changed it. The show() is now automaticly called in page.onPageReady. There is a boolean called autoShow which allows you to disable automatically show(). Documentation is updated too.
tested this this morning .. and it's nice .. i see in that framework a good alternative to gaia when using just one fla . Would be very convenient for exported flas from indesign.
although , i dislike the fact that you can't have a "Page" clip disposed on the timeline ( compilation errors ). It could be very convenient to keep the design / layout like indesign export pages (one page /one frame) keep going , very interesting stuff . I would be interested to in a haxe port ( i could give a hand on that if you want to )
Hi ronpish, Thanks for your reply, it is really helpful. If you want to use a timeline, it would be better to put the animation inside an MovieClip?. It is an idea to create a Page class with timeline (which would extend MovieClip? instead of Sprite). I have to think about this. About a haxe port; how many people use haxe these days? I don't use it, and I wonder and if it is useful to port it. However if you want to port it and all of its classes, I am enthusiast!
hello ! About haxe: Sure , there is not so much people using haxe but i think it is increasing . One benefit i see in using it for this kind of stuff is compilation speed. you can't imagine how speed it is to compile compared to flash/mxmlc .
Bugs / features can be requested here: http://groups.google.com/group/flashflowfactory
Hi, thanks for the framwork. I've just created a demo site in order to test the framework. SWFAdress is working properly. There is just a minor problem that I don't understand. when I click back/forward button from the browser nothing happens. However, when I copy and paste the to the browser it goes to page. You can check it from http://alptugan.com/deneme2/fff/
Everything is generated by code. I didn't use any assets or something else. Do you have any suggestion for the issue?
With problems with deeplinking/backbuttons; Make sure you are using the swfaddress version 2.5 everywhere (in actionscript and javascript)
no way. I have the version 2.5 of js and in action script. I've downloaded swfaddress.js v 2.5 from here https://swfaddress.svn.sourceforge.net/svnroot/swfaddress/trunk/swfaddress/dist/js/ ? Don't understand, I suppose I'm missing something.