flash actionscript:
I am not very good at writing classes but am determined to crack em, would any one please guide me. The class is below with the script off the fla to initiate it below that. Essentially I am trying to firstly define the properties I am using, create a new XML instance, create the text field to put text in, load the page, load the css script. I wanna getBytes eventually in the onLoadProgress. I would ideally like to put values of the size coordinates of the text field in to the fla initiating the class?? Any support would be really appreciated :) Si fla: var load_txt:LoadTxt = new LoadTxt; load_txt.LoadPage("home.htm");
I wrote a class that's almost exactly like what you're trying to do... It's the "News Feed" on www.sdpurtill.com and I created a class file that loads an atom feed from my blogspot blog and parses it and everything and puts it into the textfield that I want. However, it is designed specifically to parse a blogspot atom feed so I don't know how good it will be to you. I can send it to you, if you can give me your email (private message me or something). I won't be able to get it to you for a lil while because I'm at school and then I have work after. I'll probably be able to get it to you in four hours. Sam
Yep, your in a pickle here. 1. using the onLoadProgress and onLoadInit handlers of the MovieClipLoader class for an XML and Stylesheet object... won't work. Both the XML and TextField.StyleSheet objects have onLoad callback handlers. 2. timing is essential when it comes to textfields. First create the textfield, then assign its props, including the stylesheet which must be available at that time. So, you have to use the onLoad handlers of the XML and TextField.StyleSheet objects to control the flow of the script. Here is an example which is commented so you can follow what is happening. The class will load external html-pages and an external stylesheet in any movieclip. But remember, Flash only supports a small subset of html-tags so the pages you load must be 'valid' to be able to load them. class Page { // class to load external html-pages in any movieclip private var target_mc:MovieClip; // mc where we will display our page private var stage_mc:MovieClip; // reference to the created mc that will hold the textfield private var stageDepth:Number; // depth of our stage_mc in the target_mc private var page_xml:XML; // a data container that holds our page private var page_id:String; // holds the name of the page to load private var styles:TextField.StyleSheet; // our external stylesheet // constructor public function Page(){ // initialize our data container and stylesheet page_xml=new XML(); styles=new TextField.StyleSheet(); } // initializes the load public function loadPage(target_mc:MovieClip,depth:Number,page_name:String):Void{ this.target_mc=target_mc; stageDepth=depth; page_id=page_name; var thisObj:Page=this; // local reference to the current class, used in the onLoad-handler of our XML-object var page:XML=new XML(); page.onLoad=function(success:Boolean){ if(success){ // assign the content to our datacontainer thisObj.page_xml=this; // and load our stylesheet thisObj.loadCSS("external.css"); } else { trace("Error parsing the content"); } } page.load(page_id); } // when loading assets is completed, creates the page private function makePage():Void{ stage_mc=target_mc.createEmptyMovieClip("stage_mc",stageDepth); stage_mc._x=0; stage_mc._y=0; stage_mc.createTextField("body_txt",0,0,0,Stage.width,Stage.height); stage_mc.body_txt.styleSheet=styles; stage_mc.body_txt.html=true; stage_mc.body_txt.htmlText=page_xml; } // loads the external stylesheet private function loadCSS(css:String):Void{ var thisObj:Page=this; styles.onLoad=function(success:Boolean):Void{ if(success){ // all loading has completed, we can make our page thisObj.makePage(); } else { trace("Failed to load CSS."); break; } } styles.load(css); } } In the fla: var page:Page=new Page(); page.loadPage(this,0,"index.html"); class Page { // class to load external html-pages in any movieclip private var target_mc:MovieClip; // mc where we will display our page private var stage_mc:MovieClip; // reference to the created mc that will hold the textfield private var stageDepth:Number; // depth of our stage_mc in the target_mc private var page_xml:XML; // a data container that holds our page private var page_id:String; // holds the name of the page to load private var styles:TextField.StyleSheet; // our external stylesheet // constructor public function Page(){ // initialize our data container and stylesheet page_xml=new XML(); styles=new TextField.StyleSheet(); } // initializes the load public function loadPage(target_mc:MovieClip,depth:Number,page_name:String):Void{ this.target_mc=target_mc; stageDepth=depth; page_id=page_name; var thisObj:Page=this; // local reference to the current class, used in the onLoad-handler of our XML-object var page:XML=new XML(); page.onLoad=function(success:Boolean){ if(success){ // assign the content to our datacontainer thisObj.page_xml=this; // and load our stylesheet thisObj.loadCSS("external.css"); } else { trace("Error parsing the content"); } } page.load(page_id); } // when loading assets is completed, creates the page private function makePage():Void{ stage_mc=target_mc.createEmptyMovieClip("stage_mc",stageDepth); stage_mc._x=0; stage_mc._y=0; stage_mc.createTextField("body_txt",0,0,0,Stage.width,Stage.height); stage_mc.body_txt.styleSheet=styles; stage_mc.body_txt.html=true; stage_mc.body_txt.htmlText=page_xml; } // loads the external stylesheet private function loadCSS(css:String):Void{ var thisObj:Page=this; styles.onLoad=function(success:Boolean):Void{ if(success){ // all loading has completed, we can make our page thisObj.makePage(); } else { trace("Failed to load CSS."); break; } } styles.load(css); } } // in the fla var page:Page=new Page(); page.loadPage(this,0,"index.html");
Love the pickle pun there mate :) Hey you must get this a lot but your a frickin genius mate thanks so so much..... Many thanks,
Hey LuigiL, Do you think this is advised. Using a tutorial by Colin Moock I created a class to load swf's into mc's. Could I amalgamate the two classes or would it be better as two individual classes? The reason I ask, is that in the Page class it creates mc's to put the text in....... and in the McHolder class it is creating mc's to load content into. So is it appropriate to put your loadPage, makePage and loadCSS functions into the McHolder script? Cheers Bud, Simon import mx.transitions.Tween; import mx.transitions.easing.*; /* Class to create a container mc which holds a * target mc to load different content (swfs) into... */ class McHolder { // Movie clip references private var container_mc:MovieClip; private var target_mc:MovieClip; private var contentLoader:MovieClipLoader; // Movie clip depths private var containerDepth:Number; private static var contentDepth:Number = 0; private static var maskDepth:Number = 1; private static var statusDepth:Number = 2; // Constructor public function McHolder (target:MovieClip, depth:Number, x:Number, y:Number, w:Number, h:Number){ // Assign property values target_mc = target; containerDepth = depth; /* Create the MovieClipLoader instance and store it in * the new contentLoader property */ contentLoader = new MovieClipLoader(); /* Register this McHolder instance to receive events * from the MovieClipLoader instance */ contentLoader.addListener(this); // Set up visual assets buildHolder(x, y, w, h); } /* Create the clips to hold the content * this method subcontracts all its work to * individual clip creation methods... */ private function buildHolder(x:Number, y:Number, w:Number, h:Number):Void { createMainContainer(x, y); createHolderClip(); createHolderClipMask(w, h); } // Create the container that holds all the assets private function createMainContainer(x:Number, y:Number):Void { container_mc = target_mc.createEmptyMovieClip("container_mc" + containerDepth, containerDepth); // Position the container clip container_mc._x = x; container_mc._y = y; } // Creates the clip into which the content is actually loaded private function createHolderClip():Void{ container_mc.createEmptyMovieClip("content_mc", contentDepth); } // Create the mask over the image private function createHolderClipMask (w:Number, h:Number):Void { // Create the mask only if valid width and height are specified if (!(w > 0 && h > 0)) { return; } // In the container, create a clip to act as mask over image container_mc.createEmptyMovieClip("mask_mc", maskDepth); // Draw a rectangle in the mask container_mc.mask_mc.moveTo(0, 0); container_mc.mask_mc.beginFill(0x0000FF); // Use blue for debugging container_mc.mask_mc.lineTo(w, 0); container_mc.mask_mc.lineTo(w, h); container_mc.mask_mc.lineTo(0, h); container_mc.mask_mc.lineTo(0, 0); container_mc.mask_mc.endFill(); // Set the mask over the content layer container_mc.setMask(container_mc.mask_mc); // Hide the mask (it will still function as a mask when invisible) //container_mc.mask_mc._visible = false; } // Loads the content public function loadContent (URL:String):Void { // Use the MovieClipLoader instance to load the image contentLoader.loadClip(URL, container_mc.content_mc); // Create a load-status text field to show the user load progress container_mc.createTextField("loadStatus_txt", statusDepth, 0, 0, 0, 0); container_mc.loadStatus_txt.background = false; container_mc.loadStatus_txt.border = true; container_mc.loadStatus_txt.setNewTextFormat(new TextFormat( "Arial, Helvetica, _sans", 10, 666666, false, false, false, null, null, "right")); container_mc.loadStatus_txt.autoSize = "left"; // Position the load-status text field container_mc.loadStatus_txt._y = 3; container_mc.loadStatus_txt._x = 3; // Indicate that the content is loading container_mc.loadStatus_txt.text = "LOADING CONTENT"; } // MovieClipLoader handler. Triggered by contentLoader when data arrives public function onLoadProgress (target:MovieClip, bytesLoaded:Number, bytesTotal:Number):Void { // Display load progress in the on-screen text field // Divide bytesLoaded and bytesTotal by 1024 to get kilobytes container_mc.loadStatus_txt.text = "LOADING: " + Math.floor(bytesLoaded / 1024) + "/" + Math.floor(bytesTotal / 1024) + " KB"; } // MovieClipLoader handler. Triggered by contentLoader when loading is done public function onLoadInit (target:MovieClip):Void { // Remove the loading message container_mc.loadStatus_txt.removeTextField(); new Tween(container_mc.content_mc, "_alpha", Strong.easeIn, 0, 100, 1, true); } // MovieClipLoader handler. Triggered by contentLoader when loading fails public function onLoadError (target:MovieClip, errorCode:String):Void { if (errorCode == "URLNotFound") { container_mc.loadStatus_txt.text = "ERROR: File not found."; } else if (errorCode == "LoadNeverCompleted") { container_mc.loadStatus_txt.text = "ERROR: Load failed."; } else { // Catch-all to handle possible future error codes container_mc.loadStatus_txt.text = "Load error: " + errorCode; } } /* * Must be called before the McHolder instance is deleted * Gives the instance a chance to destroy any resources it has created */ public function destroy ():Void { // Cancel load event notifications contentLoader.removeListener(this); // Remove movie clips from Stage (removing container_mc removes subclips) container_mc.removeMovieClip(); } }
Ooh got thinkin now, maybe take out the create mc's elements of Page.as and use it as an sub class of McHolder.as???
Hi, Ok tried amalgamating the two class and had trouble calling the loadPage function? Do you think that I should treat Page.as as a subClass of McHolder.as? Any suggestions on the loading text into ?mc part guys??? Cheers Si
Well, if you want to do it the OOP way, use a wrapper class to bring it all together: (just a skeleton, needs additional props,methods...) import mcHolder; import Page; class BuildSite { private var target_mc:MovieClip; public function BuildSite(target_mc:MovieClip){ this.target_mc=target_mc; } public function loadImages():Void{ var images:McHolder=new McHolder(); images.loadContent(); // of course provide the url here } public function loadText():Void{ var page:Page=new Page(); page.loadPage(); // provide the correct parameters } } on the timeline: var site:BuildSite=new BuildSite(this); site.loadImages(); // provide the parameters site.loadText(); // provide the parameters The goal is the cut up the software is small pieces, each piece does its own trick. Bring it all together in a wrapper (or more wrappers...). When you need to change something... when you architect the app correct, it's just changing some lines in one of your small pieces of software.
Wicked thanks again, I am sure I will be back but for now, cheers......
ok so I got 3 classes: (1) McHolder to load the img/swf (2) Page to load the text (3) BuildSite wrapper the 2 together In my .fla I have: var site:BuildSite=new BuildSite(this); site.loadImages(this, 1, 50, 75, 600, 300); // provide the parameters site.loadText(this, 0); // provide the parameters Is it possible to define the loadText paramaters as loadImages i.e. choose x,y,h&w? in the wrapper I have: import mcHolder; import Page; class BuildSite { private var target_mc:MovieClip; public function BuildSite(target_mc:MovieClip){ this.target_mc=target_mc; } public function loadImages():Void{ var images:McHolder=new McHolder(); images.loadContent("joel.jpg"); // of course provide the url here } public function loadText():Void{ var page:Page=new Page(); page.loadPage("home.htm"); // provide the correct parameters } } Gives the following error : BuildSite.as: Line 18: Type mismatch. page.loadPage("home.htm"); // provide the correct parameters Total ActionScript Errors: 1 Reported Errors: 1
Let's have a look at the loadPage() function: public function loadPage(target_mc:MovieClip,depth:Number,page_name:String):Void{} It requires 3 params! And you are providing 1, a string. And that generates an error since the function expects a movieclip as its first parameter! I should spank you!!!
Ooh......................oops No excuses from me......but man a spanking sounds brutal :0 LOL
Ok LuigiL, changed the parameters accordingly and think I am slowly getting this. Success in the sense I manage to load the text, but no Img from the mcHolder class is loading, no errors or anything just nadda nowt. Also struggling to find what parameter to put into : site.loadText(); // provide the parameters as accordings to the Page constructor there are no parameters, it just does this: public function Page(){ //initialize our data container and stylesheet page_xml=new XML(); styles=new TextField.StyleSheet(); } ?? I have uploaded the files to: http://www.picklejarrecordings.com/vars/oldnews/site/ cheers mate
Wrapping it up: Revised Page class to accept x,y,w,h: class Page { // class to load external html-pages in any movieclip private var target_mc:MovieClip; // mc where we will display our page private var stage_mc:MovieClip; // reference to the created mc that will hold the textfield private var stageDepth:Number; // depth of our stage_mc in the target_mc private var page_xml:XML; // a data container that holds our page private var page_id:String; // holds the name of the page to load private var styles:TextField.StyleSheet; // our external stylesheet private var xPos:Number; // x of stage_mc private var yPos:Number; // y of stage_mc private var xWidth:Number; // width of the text field that loads the page private var yHeight:Number; // height of the text field that loads the page // constructor, initialize our data container,stylesheet and set position/size public function Page(x:Number,y:Number,w:Number,h:Number){ page_xml=new XML(); styles=new TextField.StyleSheet(); xPos=x; yPos=y; xWidth=w; yHeight=h; } // initializes the load public function loadPage(target_mc:MovieClip,depth:Number,page_name:String):Void{ this.target_mc=target_mc; stageDepth=depth; page_id=page_name; var thisObj:Page=this; // local reference to the current class, used in the onLoad-handler of our XML-object var page:XML=new XML(); page.onLoad=function(success:Boolean){ if(success){ // assign the content to our datacontainer thisObj.page_xml=this; // and load our stylesheet thisObj.loadCSS("external.css"); } else { trace("Error parsing the content"); } } page.load(page_id); } // when loading assets is completed, creates the page private function makePage():Void{ stage_mc=target_mc.createEmptyMovieClip("stage_mc",stageDepth); stage_mc._x=xPos; stage_mc._y=yPos; stage_mc.createTextField("body_txt",0,0,0,xWidth,yHeight); stage_mc.body_txt.styleSheet=styles; stage_mc.body_txt.html=true; stage_mc.body_txt.htmlText=page_xml; } // loads the external stylesheet private function loadCSS(css:String):Void{ var thisObj:Page=this; styles.onLoad=function(success:Boolean):Void{ if(success){ // all loading has completed, we can make our page thisObj.makePage(); } else { trace("Failed to load CSS."); break; } } styles.load(css); } } The wrapper class: import mcHolder; import Page; class BuildSite { private var target_mc:MovieClip; public function BuildSite(target_mc:MovieClip){ this.target_mc=target_mc; } public function loadImages(target:MovieClip,depth:Number,x:Number,y:Number,w:Number,h:Number,url :String):Void{ var images:McHolder=new McHolder(target,depth,x,y,w,h); images.loadContent(url); } public function loadText(target:MovieClip,depth:Number,x:Number,y:Number,w:Number,h:Number,url:S tring):Void{ var page:Page=new Page(x,y,w,h); page.loadPage(target,10,url); } } And in the fla: var site:BuildSite=new BuildSite(this); // parameters: target_mc, depth, x, y, width, height, url site.loadImages(this, 1, 50, 75, 600, 300, "jason.jpg"); // parameters: target_mc, depth, x, y, width, height, url site.loadText(this, 10, 0, 0, 500, 425, "home.htm"); Now, I would probably use getter and setter methods to set and get x, y, w, h, url's and such to makes things a little bit easier to type but you've got an idea now of how this can work. // revised Page class class Page { // class to load external html-pages in any movieclip private var target_mc:MovieClip; // mc where we will display our page private var stage_mc:MovieClip; // reference to the created mc that will hold the textfield private var stageDepth:Number; // depth of our stage_mc in the target_mc private var page_xml:XML; // a data container that holds our page private var page_id:String; // holds the name of the page to load private var styles:TextField.StyleSheet; // our external stylesheet private var xPos:Number; // x of stage_mc private var yPos:Number; // y of stage_mc private var xWidth:Number; // width of the text field that loads the page private var yHeight:Number; // height of the text field that loads the page // constructor, initialize our data container,stylesheet and set position/size public function Page(x:Number,y:Number,w:Number,h:Number){ page_xml=new XML(); styles=new TextField.StyleSheet(); xPos=x; yPos=y; xWidth=w; yHeight=h; } // initializes the load public function loadPage(target_mc:MovieClip,depth:Number,page_name:String):Void{ this.target_mc=target_mc; stageDepth=depth; page_id=page_name; var thisObj:Page=this; // local reference to the current class, used in the onLoad-handler of our XML-object var page:XML=new XML(); page.onLoad=function(success:Boolean){ if(success){ // assign the content to our datacontainer thisObj.page_xml=this; // and load our stylesheet thisObj.loadCSS("external.css"); } else { trace("Error parsing the content"); } } page.load(page_id); } // when loading assets is completed, creates the page private function makePage():Void{ stage_mc=target_mc.createEmptyMovieClip("stage_mc",stageDepth); stage_mc._x=xPos; stage_mc._y=yPos; stage_mc.createTextField("body_txt",0,0,0,xWidth,yHeight); stage_mc.body_txt.styleSheet=styles; stage_mc.body_txt.html=true; stage_mc.body_txt.htmlText=page_xml; } // loads the external stylesheet private function loadCSS(css:String):Void{ var thisObj:Page=this; styles.onLoad=function(success:Boolean):Void{ if(success){ // all loading has completed, we can make our page thisObj.makePage(); } else { trace("Failed to load CSS."); break; } } styles.load(css); } } // the wrapper import mcHolder; import Page; class BuildSite { private var target_mc:MovieClip; public function BuildSite(target_mc:MovieClip){ this.target_mc=target_mc; } public function loadImages(target:MovieClip,depth:Number,x:Number,y:Number,w:Number,h:Number,url :String):Void{ var images:McHolder=new McHolder(target,depth,x,y,w,h); images.loadContent(url); } public function loadText(target:MovieClip,depth:Number,x:Number,y:Number,w:Number,h:Number,url:S tring):Void{ var page:Page=new Page(x,y,w,h); page.loadPage(target,10,url); } } // in the fla var site:BuildSite=new BuildSite(this); // parameters: target_mc, depth, x, y, width, height, url site.loadImages(this, 1, 50, 75, 600, 300, "jason.jpg"); // parameters: target_mc, depth, x, y, width, height, url site.loadText(this, 10, 0, 0, 500, 425, "home.htm");
OOP(s), change the loadText() in BuildSite: public function loadText(target:MovieClip,depth:Number,x:Number,y:Number,w:Number,h:Number,url:S tring):Void{ var page:Page=new Page(x,y,w,h); page.loadPage(target,depth,url); } to accept the depth we provided.
Cheers very much for all the hard work you have put into this mate your help is so appreciated...
Oh it works a dream, absolute dream, well on my way to having a class based site, simple looking without all the clutter like a lot of sites but hey, simple look for me is nice as..... Your a great help LuigiL my many thanks.... Simon
All lookin fantastic however here is my final (I hope) question. I am loading the content in no problem, positioning it lovely but when it comes to loading in new content I hit a stumbling block, do I juts copy the paramaters in the ..fla but different URL (if so it loads the content in a different x,y coordinates and doesn't remove the img it is meant to be loading in and replacing)????? I have put the same depth so I thought it would just be simple and replacing the current content? Last one Buddy :) simon var site:BuildSite=new BuildSite(this); // parameters: target_mc, depth, x, y, width, height, url site.loadImages(this, 1, 50, 75, 600, 300, "joel.jpg"); site.loadImages(this, 3, 530, 190, 0, 0, "logo.swf"); site.loadText(this, 2, 50, 425, 600, 300, "home.htm"); // ditch the load message loadmsg_txt.removeTextField (); // event handlers this.one_btn.onRelease = function () { site.loadImages(this, 1, 50, 75, 600, 300, "joel.jpg"); site.loadText(this, 2, 50, 425, 600, 300, "home.htm"); }; this.two_btn.onRelease = function () { site.loadImages(this, 1, 50, 75, 600, 300, "iola_2.jpg"); site.loadText(this, 2, 50, 425, 600, 300, "science.htm"); }; this.three_btn.onRelease = function () { site.loadImages(this, 1, 50, 75, 600, 300, "joel.jpg"); site.loadText(this, 2, 50, 425, 600, 300, "home.htm"); };
With: this.one_btn.onRelease = function () { site.loadImages(this, 1, 50, 75, 600, 300, "joel.jpg"); site.loadText(this, 2, 50, 425, 600, 300, "home.htm"); }; you're in the scope of the button when you refer to 'this' as the target_mc site.loadImages(this, 1, 50, 75, 600, 300, "joel.jpg"); (I'm reconsidering the spanking....) So, you need a reference to the main timeline: var owner:MovieClip=this; // reference to the current timeline // initialize the site and show the first page var site:BuildSite=new BuildSite(this); // parameters: target_mc, depth, x, y, width, height, url site.loadImages(this, 1, 50, 75, 600, 300, "joel.jpg"); site.loadImages(this, 3, 530, 190, 0, 0, "logo.swf"); site.loadText(this, 2, 50, 425, 600, 300, "home.htm"); // ditch the load message loadmsg_txt.removeTextField (); // event handlers this.one_btn.onRelease = function () { site.loadImages(owner, 1, 50, 75, 600, 300, "joel.jpg"); site.loadText(owner, 2, 50, 425, 600, 300, "home.htm"); }; this.two_btn.onRelease = function () { site.loadImages(owner, 1, 50, 75, 600, 300, "iola_2.jpg"); site.loadText(owner, 2, 50, 425, 600, 300, "science.htm"); }; this.three_btn.onRelease = function () { site.loadImages(owner, 1, 50, 75, 600, 300, "joel.jpg"); site.loadText(owner, 2, 50, 425, 600, 300, "home.htm"); }; And yes, because you load on the same depth, content gets replaced. That's why we are setting the depth of every mc manually. If we were using getNextHighestDepth() you would need to remove the 'current' content before you load any new content. Providing _root or _parent as a parameter instead of owner would also work in this case. But I always use references in my code, so you can decide for yourself how you code it.
Spankyou very much for all that man, I did want the content replacing so thats perfect that it is being set manually. Cheers again ( how many times can one man thank someone ey?)..
Don't see what you're looking for? Try a search.
|