External images with text and image effects demo with sourcecode

Posted by jinxmcg 
External images with text and image effects demo with sourcecode
October 01, 2009 12:53PM
Hi,

First of all I really liked the FLASHeff. Good Job, and sorry for the long post.

I developed a demo app with loading images and texts from xml and afterwards applying flashEff effects.
I decided to post it here to help everyone who tries to do similar things and might find it useful.

You can find it here along with the source code :
[www.whi.ro]

Of course it could be done better but the point is the coding and use of flashEff not the graphical.

In the developing process I encountered some issues (almost all were because of not reading well the documentation :) ) and i will list them here:

1. wait for images to load completely and after create the effect and apply (onImage compelte) if you apply before the effect will not work (only alfa effects work because - I think - they use the last bitmapData in the object) the complex effects i think use the bitmap data on setting the target and this is empty if the image is not loaded.
2. targetVisibility reffers to visible = true/false not to alpha - my mistake was that i setted alpha 0 and tergetVisibility=false and effect was not working
3. do not reuse on complex effects on multiple targets, too many times, the effect will get broken. use one effect for each slide (If i am wrong someone who knows better please help me)

I am not to good on as3, the code might be improved feel free.
* the images are not mine are used only for demonstration purposes.

have fun,
jinx.

Here I will post the code with comments:

//add UILoader component to library too (otherwise will throw error)
import fl.containers.UILoader;
import flash.net.navigateToURL;
import flash.net.URLRequest;

//i used this for the delayed call and blur for links...there are also other ways but
//feel free to change
import gs.TweenMax;
import gs.easing.*;
import gs.plugins.*;
TweenPlugin.activate([BlurFilterPlugin, GlowFilterPlugin]);

//we will make an array of effects for each one to apply (show/hide)
//i like to keep them into arrays for easy access
var effects:Array = new Array();
var textEffects:Array = new Array();
var textEffectsLong:Array = new Array();
//the file name of the xml
var xmlpath:String = "main-flash.xml";

//we will have picture slides and menus in the left
var slides:Number=0;
//number of menus
var menus:Number=0;

var slidesArray:Array = new Array();
var menuArray:Array = new Array();
var slidesObj:Array = new Array();
//last slide
var lSlide:Number = -1;
//current slide
var cSlide:Number = 0;

//loaded images
var loaded:Number = 0;

//this is an object in the library with linkage to POSTIT
var postItMenu:MovieClip = new postit;

//create a container to put all images ... and texts inside
var container:MovieClip = new MovieClip();
container.name = "container";
addChild(container);

//create a container over the image container for texts...if they are in the
//same container with the images...when applying effects the image will come in front
var txtcontainer:MovieClip = new MovieClip();
txtcontainer.name = "container";
addChild(txtcontainer);

//if the xml-path is sended as a parameter in HTML on load of swf
var paramObj:Object = LoaderInfo(this.root.loaderInfo).parameters;
try {
var keyStr:String;
var valueStr:String;
for (keyStr in paramObj) {
valueStr = String(paramObj[keyStr]);
if (keyStr == "xmlpath") {
//if parameter is xmlpath then override the value we used on test / local
xmlpath = valueStr;
}
}
} catch (error:Error) {
//throwed error
}

//load the XML
var xmlloader:URLLoader = new URLLoader();
xmlloader.addEventListener(Event.COMPLETE, loadXML);
xmlloader.load(new URLRequest(xmlpath));

function loadXML(ev:Event):void {
try {
var xDoc:XMLDocument = new XMLDocument();
xDoc.ignoreWhite = true;
var myXML:XML = new XML(ev.target.data);

var i:int;
//in the xml sample we have some slides
slides = myXML.slide.length();
//and some menus
menus = myXML.postit.length();


trace(myXML.slide.length() + " slides loaded");
trace(menus + " menus loaded");

//My way is to put all the xml into an array and after process the array and create objects
for (i=0; i < slides; i++) {
slidesArray[i] = new Array();
slidesArray[i]["id"] = i;
slidesArray[i]["img"] = myXML.slide[i].img.text();
slidesArray[i]["imglink"] = myXML.slide[i].imglink.text();
slidesArray[i]["textmic"] = myXML.slide[i].textmic.text();
slidesArray[i]["descr"] = myXML.slide[i].descr.text();
slidesArray[i]["lnktxt"] = myXML.slide[i].lnktxt.text();
slidesArray[i]["xpos"] = myXML.slide[i].txtx.text();
slidesArray[i]["txtcolor"] = myXML.slide[i].txtcolor.text();
}

//reading the menus in the left
for (i=0; i < menus; i++) {
menuArray[i] = new Array();
menuArray[i]["id"] = i;
menuArray[i]["lnk"] = myXML.postit[i].lnk.text();
menuArray[i]["txt"] = myXML.postit[i].txt.text();
}


} catch (e:TypeError) {
trace("Could not parse the XML");
trace(e.message);
}

//create slides
createObjs();
//add the menu on top
addChild(createMenus());
}



function createObjs(){

var i:Number;
for (i=0;i<slides;i++){
//create slide container
var cnt:MovieClip = new MovieClip();
cnt.name = "cntu"+i;
//create + load img into slide container and apply effects after loading !!!verry important after loading
var img:MovieClip = new MovieClip();
img.name = "imgu"+i;
//create loader
var loader:UILoader = new UILoader();
//display progress bar
loader.name = "u"+i;
loader.addEventListener(ProgressEvent.PROGRESS, progressHandler);
//on complete create effects for later apply
loader.addEventListener(Event.COMPLETE, completeHandler);
loader.scaleContent = false;
loader.source = slidesArray[i]["img"];

//no visibility on after load
img.visible=false;
img.addChild(loader);
//do the dew
cnt.addChild(img);
//addin the main container
container.addChild(cnt);
//create the texts and add to the container
txtcontainer.addChild(createTexts(i,slidesArray[i]["xpos"],slidesArray[i]["txtcolor"],slidesArray[i]["textmic"],slidesArray[i]["descr"],slidesArray[i]["lnktxt"],slidesArray[i]["imglink"]));
}
}


function animate(){
//if we reached the last slide go to first one
if (cSlide>=slides) {cSlide=0;}

//the first slide is shown with no delay
var addedDelay:Number = 0;

//to alpha tween the link on the texts I used TweenMax so this is to get the object
var mc:MovieClip;

//if last Slide is >= 0 hide it
if (lSlide>=0)
{
trace("I'm hiding " + lSlide);

//i use delayedCall so we can set delays to hide/show effects
//and here we can benefit of the arrays with the effects we created
//it's easyer to set effect[slidenumber].show/hide
//when we call with delayedCall there is no need for effect.hide() - paranthesis missing
TweenMax.delayedCall(0, textEffects[lSlide].hide );
TweenMax.delayedCall(0.5, textEffectsLong[lSlide].hide );
TweenMax.delayedCall(2, effects[lSlide].hide );

//here we hide the link with a simpe effect
//there are easyer ways to reach the subcontainer with the link
//i did it this way
mc = MovieClip(txtcontainer.getChildByName("tcnt"+lSlide));
mc = MovieClip(mc.getChildByName("innerTxt"));
TweenMax.to(mc.linker,0.5,{autoAlpha:0,ease:Quad.easeOut,delay:1,overwrite:0});

//if we hidden a slide we should leave enough time to finish before we
//show the next one
addedDelay = 2;
}

if (cSlide>=0) {

trace("showing " + cSlide);

//same as by hiding
TweenMax.delayedCall(1+addedDelay, textEffects[cSlide].show );
TweenMax.delayedCall(1.5+addedDelay, textEffectsLong[cSlide].show );
TweenMax.delayedCall(0+addedDelay, effects[cSlide].show );

mc = MovieClip(txtcontainer.getChildByName("tcnt"+cSlide));
mc = MovieClip(mc.getChildByName("innerTxt"));
TweenMax.to(mc.linker,1,{autoAlpha:1,ease:Quad.easeOut,delay:2+addedDelay,overwrite:0});

//last slide will be the current one on the next calling of this function
lSlide = cSlide;
//increase the current slide
cSlide +=1;
}

//recall this function after 7 seconds
TweenMax.delayedCall(7, animate);
}

function createTexts(slideNumber:Number,xpos:String,col:String,textmic:String,desc:String,lnktxt:String,url:String):MovieClip{
//create the texts from xml
//parameters number of slide, x position of the texts,
//color, the title, description, link text, and url of the link

//setting the color as format
var newFormat:TextFormat = new TextFormat();
newFormat.color = col;

//create the text container
var txtContainer:MovieClip = new MovieClip();
txtContainer.name = "tcnt"+slideNumber;

//bring from library the text fields
//txt is an object in the library
//with 3 textfields and linked for action script in the linkage
var innerTxt:txt = new txt;
innerTxt.name = "innerTxt";

innerTxt.desctext.multiline = true;
innerTxt.desctext.wordWrap = true;
innerTxt.desctext.htmlText = textmic;
innerTxt.desctext.embedFonts=true;
innerTxt.desctext.setTextFormat(newFormat);
innerTxt.desctext.antiAliasType = "advanced";
innerTxt.desctext.autoSize = TextFieldAutoSize.LEFT;

//the long text will reposition after the first one
innerTxt.longtext.y = innerTxt.desctext.height + innerTxt.desctext.y+10;
innerTxt.longtext.multiline = true;
innerTxt.longtext.wordWrap = true;
innerTxt.longtext.htmlText = desc;
innerTxt.longtext.setTextFormat(newFormat);
innerTxt.longtext.embedFonts=true;
innerTxt.longtext.antiAliasType = "advanced";
innerTxt.longtext.autoSize = TextFieldAutoSize.LEFT;


//if we have a link we put a link
//also I forgot not to animate the link if there isn't one
//noticed when writing the comments :)
if (lnktxt!="") {
innerTxt.linker.y = innerTxt.longtext.height + innerTxt.longtext.y+17;
innerTxt.linker.lnk.autoSize = TextFieldAutoSize.LEFT;
innerTxt.linker.lnk.htmlText = lnktxt;
innerTxt.linker.lnk.setTextFormat(newFormat);
innerTxt.linker.lnk.embedFonts=true;
innerTxt.linker.lnk.antiAliasType = "advanced";
innerTxt.linker.urlul = url;
if (url!="") {
innerTxt.linker.over.x = innerTxt.linker.lnk.x-5;
innerTxt.linker.over.y = innerTxt.linker.lnk.y-5;
innerTxt.linker.over.width = innerTxt.linker.lnk.width+10;
innerTxt.linker.over.height = innerTxt.linker.lnk.height+10;
innerTxt.linker.buttonMode = true;
innerTxt.linker.addEventListener(MouseEvent.MOUSE_OVER,overlnk);
innerTxt.linker.addEventListener(MouseEvent.MOUSE_OUT,outlnk);
innerTxt.linker.addEventListener(MouseEvent.CLICK,clicklnk);
}
}

innerTxt.x = Number(xpos);
innerTxt.y = (260-(innerTxt.y+innerTxt.height))/2;

//hiding the stuff
innerTxt.linker.visible = false;
innerTxt.linker.alpha = 0;

//here is verry important to create effect for each transition
//i tried changing the target and using one effect for all
//but the effect jams so the best option is to create an effect for each slide and texts

var myEffect:FlashEff2Code = new FlashEff2Code();
myEffect.showTransitionName = "com.jumpeye.flashEff2.text.blur.FETBlur";
myEffect.hideTransitionName = "com.jumpeye.flashEff2.text.blur.FETBlur";
myEffect.showAutoPlay = false;
myEffect.hideAutoPlay = false;
myEffect.hideDelay = 0;
myEffect.showDelay = 1;

//i confused this option with the alpha and the effect was not working
//targetVisibility reffers to visible=true/false not to alpha
myEffect.targetVisibility = false;
//adding the container with the texts
txtContainer.addChild(innerTxt);
//adding the effect for the title
txtContainer.addChild(myEffect);

var myEffectLongtext:FlashEff2Code = new FlashEff2Code();
myEffectLongtext.showTransitionName = "com.jumpeye.flashEff2.text.blur.FETBlur";
myEffectLongtext.hideTransitionName = "com.jumpeye.flashEff2.text.blur.FETBlur";
myEffectLongtext.showAutoPlay = false;
myEffectLongtext.hideAutoPlay = false;
myEffectLongtext.hideDelay = 0;
myEffectLongtext.showDelay = 1;
myEffectLongtext.targetVisibility = false;
txtContainer.addChild(myEffectLongtext);

//setting the target for first effect
myEffect.target = innerTxt.desctext;
//setting the target for second
myEffectLongtext.target = innerTxt.longtext;

//adding them in the arrays at the slideNumber position so we can access them easily
textEffects[slideNumber] = myEffect;
textEffectsLong[slideNumber] = myEffectLongtext;


return txtContainer;
}

//function used to slide the menu
//feel free to use flasheff effect
function showPostit(){
trace("showing menu");
TweenMax.to(postItMenu,0.7,{autoAlpha:1,x:-1,ease:Linear.easeOut,delay:1});
}


//this is a debug for loading the pictures
function progressHandler(event:ProgressEvent):void {
var uiLdr:UILoader = event.currentTarget as UILoader;
var kbLoaded:String = Number(uiLdr.bytesLoaded / 1024).toFixed(1);
var kbTotal:String = Number(uiLdr.bytesTotal / 1024).toFixed(1);
trace(kbLoaded + " of " + kbTotal + " KB" + " (" + Math.round(uiLdr.percentLoaded) + "%)");
}

//APPPLY EFFECTS TO IMAGES ONLY AFTER THEY ARE COMPLEETLY LOADED
//otherwise the effect will not work
function completeHandler(event:Event):void {
var uiLdr:UILoader = event.currentTarget as UILoader;
uiLdr.removeEventListener(ProgressEvent.PROGRESS, progressHandler);
uiLdr.removeEventListener(Event.COMPLETE, completeHandler);

trace("completed "+"img"+uiLdr.name);

var myEffect:FlashEff2Code = new FlashEff2Code();
myEffect.showTransitionName = "com.jumpeye.flashEff2.symbol.squareEffect.FESRoundedSquareScale";
myEffect.hideTransitionName = "com.jumpeye.flashEff2.symbol.alpha.FESAlpha";
myEffect.showAutoPlay = false;
myEffect.hideAutoPlay = false;
myEffect.hideDelay = 1;
myEffect.targetVisibility = false;

//i didn't know how to get the slideNumber of a loaded image from
//the complete event of UILoader
//so i used the name of the loader as u1...u2...uX and
//extract the X :)

var mc:MovieClip = MovieClip(container.getChildByName("cnt"+uiLdr.name));
mc.addChild(myEffect);
//we can use _targetInstanceName because we will add the efect in the same conainer
myEffect._targetInstanceName = "img"+uiLdr.name;

//effects[x] = myEffect ... X is u1...uX
effects[Number(uiLdr.name.split(/\u([0-9])/)[1])] = myEffect;

//increase the loaded images number
loaded++;

//if we loaded all start switching...
//this could be done also serial after one loads...
//display it and after start loading other
if (loaded==slides) {
trace("all loaded start switching");

//show menu
showPostit();
//start animating
animate();
}

}

function createMenus(){

//postit menu we created it in the library linked it from linkage
//and we reuse here
postItMenu.y=-5;
postItMenu.x=-50;
postItMenu.name="postmenu";
postItMenu.alpha=0;
postItMenu.visible=true;

var i:Number;
for (i=0;i<menus;i++){
//create slide container
var lnker:menulnk = new menulnk;

lnker.urlul = menuArray[i]["lnk"];
lnker.txt.text = menuArray[i]["txt"];
lnker.txt.x = 20;
lnker.txt.y = 20+i*25;
lnker.overl.x=15;
lnker.overl.y=20+i*25;
lnker.overl.width=190;
lnker.overl.height=20;
lnker.overl.alpha=0;
lnker.buttonMode = true;

lnker.addEventListener(MouseEvent.MOUSE_OVER,overlnkMenu);
lnker.addEventListener(MouseEvent.MOUSE_OUT,outlnkMenu);
lnker.addEventListener(MouseEvent.CLICK,clicklnk);
postItMenu.addChild(lnker);
}


return postItMenu;
}


//handlers for hover mouse out menus and link in the text
//glow with TweenMax
//but you can use flashEff also

function overlnk(e:MouseEvent):void{
TweenMax.to(e.currentTarget,0.3,{glowFilter:{color:0xffffff, alpha:1, blurX:10, blurY:10},ease:Linear.easeOut,delay:0,overwrite:0});
}
function outlnk(e:MouseEvent){
TweenMax.to(e.currentTarget,0.3,{glowFilter:{color:0xffffff, alpha:0, blurX:0, blurY:0},ease:Linear.easeOut,delay:0,overwrite:0});
}


function overlnkMenu(e:MouseEvent):void{
TweenMax.to(e.currentTarget,0.3,{glowFilter:{color:0xffffff, alpha:1, blurX:10, blurY:10},ease:Linear.easeOut,delay:0,overwrite:1});
}
function outlnkMenu(e:MouseEvent){
TweenMax.to(e.currentTarget,0.3,{glowFilter:{color:0xffffff, alpha:0, blurX:0, blurY:0},ease:Linear.easeOut,delay:0,overwrite:1});
}
function clicklnk(e:MouseEvent){
trace(e.currentTarget.urlul);
var request:URLRequest = new URLRequest(e.currentTarget.urlul);
navigateToURL(request,"_self");
}

//have fun
Re: External images with text and image effects demo with sourcecode
October 12, 2009 01:40PM
jinxmcg,

Congratulation, you've done a good work. Keep it up.
Sorry, you do not have permission to post/reply in this forum.