Jump to content
GreenSock

Marcus Aurelius

Loading an image or swf based on xml data

Recommended Posts

Hi guys,

 

Ive been trying to figure out how set an image or swf via xml data with XMLLoader:

 

xml:

 

<?xml version="1.0" encoding="UTF-8"?>
<configSettings>
<!-- MAIN PAGE CONFIGURATION SETTINGS -->
<mainPage>
<!-- Logo Setup -->
<logo>
<useImage>true</useImage>
<useSwf>false</useSwf>
<logoImageUrl><ImageLoader url="com/siteA/assets/images/logos/ivanko_logo.png" name="logoImage" estimatedBytes = "8000" container= "this"load="true"/></logoImageUrl>
<logoSwfUrl></logoSwfUrl>

<logoX>5</logoX>
<logoY>5</logoY>
</logo>
</mainPage>
</configSettings>

 

This is the AS3 code (Im using lots of code and wont add it all, so hope you get the idea?):

 

package
{
// Flash Classes
import flash.display.*;
import flash.geom.*;
import flash.text.*;
import flash.utils.getDefinitionByName;
import flash.utils.getQualifiedClassName;
import flash.events.*
// Greensock Tweening Platform V11
import com.greensock.*;

// activate Greensocks classes;
LoaderMax.activate([LoaderMax, CSSLoader, XMLLoader, SWFLoader, ImageLoader]);

//----------------------------------------------mainIndex class----------------------------------------------//
public class mainIndex extends MovieClip
{
// XML Variables
 private var xml:XML;
 // Logo Variables
 private var logoX:int;
 private var logoY:int;
 private var logoWidth:int;
 private var logoHeight:int;
 private var useImageLogo:Boolean;
 private var useSwfLogo:Boolean;
 private var logoImageUrl:String;
 private var logoSwfUrl:String;
 private var logoSWF:MovieClip;
 private var logoContainer:Sprite = new Sprite();
public function mainIndex():void
 {
  addChild(logoContainer);

  logoImageUrl = xml.mainPage.logo.logoImageUrl.text();
  logoSwfUrl = xml.mainPage.logo.logoSwfUrl.text();
  useImageLogo = stringToBoolean(xml.mainPage.logo.useImage.text());
  useSwfLogo = stringToBoolean(xml.mainPage.logo.useSwf.text());

  if(useImageLogo)
  {
  logoImageUrl;
  }
  else
  {
  logoSwfUrl;
  }

  logoX = parseInt(xml.mainPage.logo.logoX);
  logoY = parseInt(xml.mainPage.logo.logoY);
 }
public static function stringToBoolean($string:String):Boolean
 {
  return ($string.toLowerCase() == "true" || $string.toLowerCase() == "1");
 }

 

Any help would be great.

Link to comment
Share on other sites

If you need to configure the xml to allow easy switching between a swf and image for your logo

you can just do:

 

<logo>
<ImageLoader url="com/siteA/assets/images/logos/ivanko_logo.png" name="logoImage" estimatedBytes = "8000" load="true"/>
<SWFLoader url="com/siteA/assets/images/logos/ivanko_logo.swf" name="logoSWF" estimatedBytes = "4000" load="false"/>
</logo>

//note i removed the container attribute as you can't set the container in the xml

 

just set the load attribute in each loader to the proper value true/false. In the code above an image will load, but not the swf

 

when your xml and assets are done loading you can check the load status of

LoaderMax.getLoader("logoSwf") and LoaderMax.getLoader("logoImage") to see which one is being used.

 

Or you could keep your <useImage> node in there and if the value is true, you know the logo loader has the name "logoImage" and it is an ImageLoader

 

OR you could keep both the SWFLoader and ImageLoader in the <logo> node and set both load attributes to true. Once the XML is loaded and the child loaders are created you can use the <useImage> value (true or false) to set load = true on the proper logo loader. I'm pretty sure you could run that logic on the XMLLoader's init event.

Link to comment
Share on other sites

Ok I put the code in the xml file (not all the data is here just to save over coding this post):

 

<!-- Logo Setup -->
<logo>
<useImage>false</useImage>
<useSwf>true</useSwf>
<ImageLoader url="com/siteA/assets/images/logos/ivanko_logo.png" name="logoImage" estimatedBytes = "8000" load="true"/>
<SWFLoader url="com/siteA/assets/swfs/logo.swf" name="logoSWF" estimatedBytes = "4000" load="false"/>
</logo>

<logoX>5</logoX>
<logoY>5</logoY>
</logo>

 

and my AS is this:

 


useImageLogo = stringToBoolean(xml.mainPage.logo.useImage.text());
  useSwfLogo = stringToBoolean(xml.mainPage.logo.useSwf.text());

  if(useImageLogo)
  {
  addChild(logoImageSpt);
  var logoImage:ContentDisplay = LoaderMax.getContent("logoImage");
  logoImageSpt.addChild(logoImage);
  }
  else if (useSwfLogo)
  {
  addChild(logoSwfSpt);
  var logoSWF:ContentDisplay = LoaderMax.getContent("logoSwf");
  logoSwfSpt.addChild(logoSWF);
  }

  logoX = parseInt(xml.mainPage.logo.logoX);
  logoY = parseInt(xml.mainPage.logo.logoY);

  logoImageSpt.x = logoX;
  logoImageSpt.y = logoY;

  logoSwfSpt.x = logoX;
  logoSwfSpt.y = logoY;

 

This is an extension of my other work and its not working probably because I have other swf being loaded in a array and the array tries to get the logo swf also: I dont know how to stop the swf array using the logo swf. this is part code for swf arrays e.t.c.

 

// XMLLoader - onChildComplete:childLoaded
 private function childLoaded(e:LoaderEvent):void
 {
  if (e.target is LoaderMax)
  {
trace("this is a LoaderMax: " + e.target);
  }
  else if (e.target is CSSLoader)
  {
trace("this is a css: " + e.target);
  }
  else if (e.target is XMLLoader)
  {
trace("this is a xml: " + e.target);
  }
  else if (e.target is SWFLoader)
  {
var swf:ContentDisplay = e.target.content as ContentDisplay;
swfArray.push(swf);
currentPage = e.target.rawContent;
previousPage = e.target.rawContent;
currentPage.pagesIntro();
trace(e.target.url + " = " + e.target.name + " page");
trace("this is an swf: " + e.target);
  }
  else if (e.target is ImageLoader)
  {
trace("this is a image: " + e.target);
  }
 }
 // XMLLoader - onComplete:appLoaded
 private function appLoaded(e:LoaderEvent):void
 {
  xml = new XML(LoaderMax.getContent("xmlData"));
  styles = LoaderMax.getContent("customCSS");
  parseFile(LoaderMax.getContent("xmlData"));
  preLoader.progressText.text = "";
  preLoader.childText.text = "";
  TweenMax.to(preLoader.childP,.5,{scaleX:0,ease:Strong.easeIn});
  TweenMax.to(preLoader,1,{alpha:0,onComplete:initApp,onCompleteParams:[swfArray.length]});
  trace("xml and css loaded");
  trace(LoaderMax.getContent("customCSS"));
  trace(e.target + ", is complete!");
  trace(e.target.content + ", is complete!");
 }

Link to comment
Share on other sites

Ok I have had another look at it and I cant figure out how to do it. I can do it using normal flash loaders e.g.:

 

xml:

 

<?xml version="1.0" encoding="utf-8"?>
<configSettings>
<!-- MAIN PAGE CONFIGURATION SETTINGS -->
<mainPage>
<!-- Logo Setup -->
<logo></logo>
<!-- header Setup -->
<header></header>
<!-- footer Setup -->
<footer></footer>
</mainPage>
<!-- END OF MAIN PAGE CONFIGURATION SETTINGS -->

<!-- Swf page Setup -->
<swfPages>
<!-- Welcome page -->
 <page title="Welcome">
<url>pageA.swf</url>
 </page>
<!-- About Us page -->
 <page title="About Us">
<url>pageB.swf</url>
 </page>
<!-- Services page -->
 <page title="Services">
<url>pageC.swf</url>
 </page>
<!-- Portfolio page -->
 <page title="Portfolio">
<url>pageD.swf</url>
 </page>
<!--Contact Us page -->
 <page title="Contact Us">
<url>pageE.swf</url>
 </page>
</swfPages>
</configSettings>

 

AS3:

 

import flash.display.*;
import flash.events.*;
import flash.net.*;
var xml:XML;
var xmlLoader:URLLoader = new URLLoader();
var swfArray:Array = new Array();
//Adding an event listener to notify when loading is completed
xmlLoader.addEventListener(Event.COMPLETE, LoadXML);
//Load the XML file;
xmlLoader.load(new URLRequest("config.xml"));
function LoadXML(e:Event):void
{
var i:Number;
var totalSwfs:Number;

xml = new XML(e.target.data);
totalSwfs = xml.configSettings.swfPages.length();
for (i = 0; i < totalSwfs; i+=1)
{
 swfArray.push( {title: xml.configSettings.swfPages[i].page.toXMLString(),
	url: xml.configSettings.swfPages[i].url.toString()} );
}
 trace (xml);
}

 

but I cant seem to get it to work with the XMLLoader...

 

My problem I think has to do with how the swf pages and btns are calling the content display:

 

AS:

 

// XMLLoader - onChildComplete:childLoaded
 private function childLoaded(e:LoaderEvent):void
 {
  if (e.target is LoaderMax)
  {
   trace("this is a LoaderMax: " + e.target);
  }
  else if (e.target is SWFLoader)
  {
   var swf:ContentDisplay = e.target.content as ContentDisplay;
   swfArray.push(swf);
   currentPage = e.target.rawContent;
   previousPage = e.target.rawContent;
   currentPage.pagesIntro();
   trace(e.target.url + " = " + e.target.name + " page");
   trace("this is an swf: " + e.target);
  }
  else if (e.target is ImageLoader)
  {
   trace("this is a image: " + e.target);
  }
 }
var pageIndex:int;
  pageIndex = 0;
  prevPage = ContentDisplay(swfArray[pageIndex]);
  targetPage = prevPage;
  prevBtn = MovieClip(buttonsArray[pageIndex]);

  private function makeButton(index:int):MovieClip
 {
  var _b:MovieClip = new btnMc  ;
  _b.page = ContentDisplay(swfArray[index]);
  _b.id = index;
  _b.btnLabel.text = String(_b.page.name);
  _b.btnLabel.width = _b.btnLabel.textWidth + 40;
  _b.btnBase.width = _b.btnLabel.width;
  _b.addEventListener(MouseEvent.MOUSE_DOWN,DOWNCLICK);
  _b.addEventListener(MouseEvent.ROLL_OVER,ROLLOVER);
  _b.addEventListener(MouseEvent.ROLL_OUT,ROLLOUT);
  _b.buttonMode = true;
  _b.mouseChildren = false;
  _b.x = xPos + 2;
  xPos = _b.x + _b.btnBase.width;
  _b.y = 0;
  return _b;
 }

 

But again not sure how to resolve it.

Link to comment
Share on other sites

I have tried everything but I still cant get it to work, my latest attempt was to put this code into the child complete function:

 

// XMLLoader - onChildComplete:childLoaded
 private function childLoaded(e:LoaderEvent):void
 {
  if (e.target is LoaderMax)
  {
   trace("this is a LoaderMax: " + e.target);

  else if (e.target is SWFLoader)
  {
   xml = e.target.content;
   var swf:ContentDisplay = e.target.content as ContentDisplay;
   var swfData:XMLList = xml.swfPages.page;
   for each (var page:XML in swfData) {
 }trace("SWF Name: " + page.@name);
 swfArray.push(page.@name);

   currentPage = e.target.rawContent;
   previousPage = e.target.rawContent;
   currentPage.pagesIntro();
   trace(e.target.url + " = " + e.target.name + " page");
   trace("this is an swf: " + e.target);
  }
}

 

but I get this error:

 

TypeError: Error #1034: Type Coercion failed: cannot convert com.greensock.loading.display::ContentDisplay@258fa741 to XML.

 

I dont know what else to do.

Link to comment
Share on other sites

I think your error is happening at in your conditional that checks

if (e. target is SWFLoader){

xml = e.target.content

}

The ccontent of a SWFLoader is not XML. That's why you are most likely getting the error.

Link to comment
Share on other sites

But I dont know how to get the <swfPages></swfPages> <page></page> node instead of the SWFLoader?

Link to comment
Share on other sites

How would I use a custom node in the SWFLoader for example:

 

xml:

 

<page title="Welcome">

<SWFLoader

name="Welcome"

url="pageA.swf"

estimatedBytes = "99999"

load="true"

requireWithRoot = "true"

array="true"

alpha="1"/>

</page>

 

 

and in the function:

 

else if (e.target is SWFLoader)
  {
if(array== true)// node inside xml SWFLoader's
{
var swf:ContentDisplay = e.target.content as ContentDisplay;
swfArray.push(swf);
currentPage = e.target.rawContent;
previousPage = e.target.rawContent;
currentPage.pagesIntro();
}
else
{
trace(e.target.url + " = " + e.target.name + " page");
trace("this is an swf: " + e.target);
}

 

This might be a solution.

Link to comment
Share on other sites

HI Marcus,

 

I have been reading your updates but at this point I'm really quite lost trying to figure out what you need to happen and where it isn't working.

 

I'm probably most confused by the 2 ways you are using external swf information in the xml

 

 

<!-- About Us page -->
 <page title="About Us">
   <url>pageB.swf</url>
 </page><logo>

 

AND

 

<useImage>false</useImage>
<useSwf>true</useSwf>
<ImageLoader url="com/siteA/assets/images/logos/ivanko_logo.png" name="logoImage" estimatedBytes = "8000" load="true"/>
<SWFLoader url="com/siteA/assets/swfs/logo.swf" name="logoSWF" estimatedBytes = "4000" load="false"/>
</logo>

 

 

But I dont know how to get the <swfPages></swfPages> <page></page> node instead of the SWFLoader?

 

I really don't understand how the SWFLoader is related to the <swfPages> nodes.

 

In the XMLLoader documentation the rawXML var is described which illustrates how to attach xml-formatted data to any type of loader. Maybe that will help.

 

If you can make a super simple example with a minimum of 1 or 2 external swfs and very very limited xml, perhaps I will have a better idea of what is happening and be able to provide a suitable answer.

 

Right now the girth of your code and the intricacy of what appears to be multiple objects trying to communicate with each other has me a bit lost. :|

Link to comment
Share on other sites

Ok, I will try and simplify this.

 

1. in the main document class I have:

 

var swfArray:Array = new Array();
var swf:Sprite;
var prevPage:ContentDisplay;
var targetPage:ContentDisplay;
var pages:MovieClip = new MovieClip();
var currentPage:MovieClip = new MovieClip();
var previousPage:MovieClip = new MovieClip();
var pageIndex:int;

// load the xml data
  var xmlLoader:XMLLoader = new XMLLoader("com/siteA/assets/data/xml/config.xml",{name:"xmlData",
  requireWithRoot:this.root,
  container:swfContainer_mc,
  maxConnections:1,
  estimatedBytes:10000,
  onChildComplete:childLoaded
  });
  XML.ignoreWhitespace = true;
  xmlLoader.load(true);

// XMLLoader - onChildComplete:childLoaded
 private function childLoaded(e:LoaderEvent):void
 {
  if (e.target is LoaderMax)
  {
trace("this is a LoaderMax: " + e.target);
  }
  else if (e.target is SWFLoader)
  {
var swf:ContentDisplay = e.target.content as ContentDisplay;
  swfArray.push(swf);
  currentPage = e.target.rawContent;
  previousPage = e.target.rawContent;
  currentPage.pagesIntro();
  }
}

// add swfContainer_mc to the stage
addChild(swfContainer_mc);
// position swfContainer_mc
swfContainer_mc.x = maxWidth / 2 - minWidth / 2;
swfContainer_mc.y = maxHeight / 2 - minHeight / 2;

pageIndex = 0;
prevPage = ContentDisplay(swfArray[pageIndex]);
targetPage = prevPage;

 

The swfArray is being used for the pages (Welcome, About Us, Services e.t.c.) in the xml file.

 

So what ever SWFLoaders I have in the xml file it will add them to the swfArray.

 

So if I wanted to load a logo swf in a different mc it wont work because of the array.

 

I have had a break through from a very kind gentleman at actionscript.org.

 

It was to do with the SWFLoaderVars but I couldnt figure out how to get it to work. But he has got it to work.

 

This is the code that I was missing;

 

else if (e.target is SWFLoader)
  {
var swf:ContentDisplay = e.target.content as ContentDisplay;
var swfLoader:SWFLoader = LoaderMax.getLoader(e.target.name);
  if (swfLoader.vars.array)
{
 swfArray.push(swf);
 currentPage = e.target.rawContent;
 previousPage = e.target.rawContent;
 currentPage.pagesIntro();
 trace(swfLoader.vars.array);
}
else
{
 //trace(e.target.url + " = " + e.target.name + " page");
 trace("this is an swf: " + e.target);
}

Link to comment
Share on other sites

The other part

<useImage>false</useImage>

<useSwf>true</useSwf>

<ImageLoader url="com/siteA/assets/images/logos/ivanko_logo.png" name="logoImage" estimatedBytes = "8000" load="true"/>

<SWFLoader url="com/siteA/assets/swfs/logo.swf" name="logoSWF" estimatedBytes = "4000" load="false"/>

</logo>

 

Im am using a Boolean statement inside the document class so I can have a .jpg or .swf.

 

xml:

 

<!-- Logo Setup -->
<logo>

<logoX>5</logoX>
<logoY>5</logoY>
<useImage>true</useImage>
<useSwf>false</useSwf>
<ImageLoader url="com/siteA/assets/images/logos/ivanko_logo.png" name="logoImage" estimatedBytes = "8000" load="true" alpha="1"/>
<SWFLoader url="logo.swf" name="logoSwf" estimatedBytes = "8000" load="true" alpha="1"/>
</logo>

 

AS3:

 

// Logo Variables
 private var logoX:int;
 private var logoY:int;
 private var useImageLogo:Boolean;
 private var useSwfLogo:Boolean;
 private var logoImageSpt:Sprite = new Sprite();
 private var logoSwfSpt:Sprite = new Sprite();
useImageLogo = stringToBoolean(xml.mainPage.logo.useImage.text());
  useSwfLogo = stringToBoolean(xml.mainPage.logo.useSwf.text());
  if (useImageLogo)
  {
   addChild(logoImageSpt);
   var logoImage:ContentDisplay = LoaderMax.getContent("logoImage");
   logoImageSpt.addChild(logoImage);
   trace("logoImage :" + " LOADED");
  }
  else if (useSwfLogo)
  {
   addChild(logoSwfSpt);
   var logoSWF:ContentDisplay = LoaderMax.getContent("logoSwf");
   logoSwfSpt.addChild(logoSWF);
   trace("logoSWF :" + " LOADED");
  }
  logoX = parseInt(xml.mainPage.logo.logoX);
  logoY = parseInt(xml.mainPage.logo.logoY);
  logoImageSpt.x = logoX;
  logoImageSpt.y = logoY;
  logoSwfSpt.x = logoX;
  logoSwfSpt.y = logoY;

 

Its all seems to be working ok at the moment.

 

I will post/update the attached files on the "Loading Multiple swf's with page transitions" thread as it is an

on-going project, if thats ok?

Link to comment
Share on other sites

cool. glad you got help. the extra attributes that you can tack onto a SWFLoader in the XML are very handy.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×