I want to loop a swf file that has been loaded with via the Loader class in AS3.
My code looks as following:
public class MyLoader extends MovieClip {
public function MyLoader() {
var myLoader:Loader = new Loader();
var url:URLRequest = new URLRequest("external-movie.swf");
myLoader.load(url);
myLoader.contentLoaderInfo.addEventListener("complete", function() {
});
addChild(myLoader);
}
}
From what I understand the Loader has no event for when the embedded movie is finished? Is there a way to figure that out? It must not be a AS3 implementation. I just want a movie that has been exported from Indesign to run in a loop. Thanks in advance
Especially when you have little experience programming you should avoid dirty shortcuts as they'll only get you a lot of trouble. So avoid anonymous function and avoid using string in place of static event variables.
This being said, if your loaded movie has its own timeline then it will be converted into a MovieClip. Also that movie is not embedded but loaded and that's a big difference.
Keep a reference of that movie and the loader:
private var theLoadedMovie:MovieClip;
private var myLoader:Loader;
Listen for the INIT event instead of the COMPLETE event (movies with timeline start to play when their first frame is loaded "INIT", the COMPLETE event fires when the whole movie is loaded).
myLoader = new Loader();
var url:URLRequest = new URLRequest("external-movie.swf");
myLoader.load(url);
myLoader.contentLoaderInfo.addEventListener(Event.INIT, handleInit);
In your handleInit method keep a reference of that movie:
theLoadedMovie = myLoader.content as MovieClip;
addChild(theLoadedMovie);
theLoadedMovie.addEventListener(Event.ENTERFRAME, handleEnterFrame);
in your handleEnterFrame method check the movie progress to know when it has ended:
if(theLoadedMovie.currentFrame == theLoadedMovie.totalFrames)
{
//movie has reached then end
}
Related
I am loading one swf file inside a main swf by using swfloader and i want to pass the parameters to the loaded swf. How can i get the loaded child reference to pass data.
My sample code is as follows
TestFile1.mxml
public var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, myFun);
loader.load(new URLRequest("/view/flex/TestFile2.swf"), new LoaderContext(false, ApplicationDomain.currentDomain));
viewId.addChild(loader);
public function myFun(event:Event):void{
Alert.show("loader.content-"+loader.content); // here alert coming like this [object_TestFile2_mx_managers_SystemManager]
var testfile2:TestFile2 = loader.content as TestFile2; // here testfile2 is null
testfile2.param1 = "val1";
}
There are 2 options.
If you just need simple startup values, you can pass arguments in the loader string and have TestFile2 grab them on start.
new URLRequest("/view/flex/TestFile2.swf?param1=val1")
If you need to interact with the child, you need to grab a reference to it after the application complete event. Event.COMPLETE only fires when the loader is loaded. In the Event.COMPLETE event, add an event to fire when the content is ready.
public function myFun(event:Event):void{
Alert.show("loader.content-"+loader.content); // here alert coming like this [object_TestFile2_mx_managers_SystemManager]
loader.content.addEventListener(FlexEvent.APPLICATION_COMPLETE, appCreationComplete);
}
private function appCreationComplete(event:FlexEvent):void
{
var testfile2:TestFile2 = loader.content["application"] as TestFile2; // here testfile2 is not null
testfile2.param1 = "val1";
}
i am currently working in adobe flash cc 2014 and i have loaded one .swf file that contains about 5000 frames of animation. And then i want to go to next scene after this loaded file finished playing.
this is the code i have, just simple loader code :
stop();
var myLoader:Loader = new Loader();
var url:URLRequest = new URLRequest("jenissendi.swf");
myLoader.load(url);
addChild(myLoader);
now, what should i do to this code?
can someone give me a simple step, because i am still newbie here
thanks.
The thing about Loader class that can confuse beginners is that events, related to loading process, are dispatched from a LoaderInfo object attached to Loader rather than Loader itself.
stop();
var myLoader:Loader = new Loader;
var url:URLRequest = new URLRequest("jenissendi.swf");
myLoader.contentLoaderInfo.addEventListener(Event.INIT, onInit);
myLoader.load(url);
addChild(myLoader);
function onInit(e:Event):void
{
nextScene();
}
First, you will need to listen for when your content has completed it's load - as you won't know how many frames the content has until then.
Then, you need to figure out when the timeline of that loaded content has finished playing.
Here is a code example with comments explaining what's going on.
stop();
var myLoader:Loader = new Loader();
var url:URLRequest = new URLRequest("jenissendi.swf");
//before you load, listen for the complete event on the contentLoaderInfo object of your loader
myLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, contentLoaded, false, 0, true);
myLoader.load(url);
addChild(myLoader);
//this function runs when the content is fully loaded
function contentLoaded(e:Event):void {
var loadedSwf:MovieClip = myLoader.content as MovieClip; //this is the main timeline of the loaded content
loadedSwf.addFrameScript(loadedSwf.totalFrames - 1, contentFinished);
//the line above tells the movie clip to run the function 'contentFinished' when it reaches the last frame.
}
//this function runs when the loaded content reaches it's last frame
function contentFinished():void {
//clean up to avoid memory leaks
removeChild(myLoader);
loadedSwf.addFrameScript(loadedSwf.totalFrames - 1, null);
nextScene();
}
addFrameScript has a few nuances. First, is that it reads frame numbers as 0 based. So that means the first frame is frame 0. That's why you subtract 1 from the totalframes to get the last frame. Second, addFrameScript is an undocumented feature - which means it may on some future flash player/AIR release not work anymore - though that's very unlikely at this point.
It's also very important to remove your frame scripts (by passing null as the function) to prevent memory leaks.
What I'm trying is unload an as2's swf from and as3's swf containner. So It's running okay when loading the as2 swf from an as3 swf cointainner's button as you can see in the next code:
//AS3 cointainner "AS3Loader_TEST1":
var loader:Loader = new Loader();
loader.load(new URLRequest("AS2animation_TEST1.swf"));
addChild(loader);
// and for solving the pitfall, I tryed this:
var AVM_lc:LocalConnection = new LocalConnection();
loader.addEventListener(MouseEvent.CLICK, stopandback);
function stopandback(event:MouseEvent):void {
AVM_lc.send("AVM2toAVM1", "disappear");
}
=======================================================
//then, into the "AS2animation_TEST1.swf" it's written
var AVM_lc:LocalConnection = new LocalConnection();
AVM_lc.dissapear = function(){
animation_mc.unloadMovie();
}
AVM_lc.connect("AVM2toAVM1");
So, the last script unload a movieclip nested in AS2animation_TEST1.swf at addEventListener dispatched from a mouse click into the as3 containner
but that's not the way I'm looking for.
So, What do you figure out to unload the whole AS2animation_TEST1.swf
So I'd like to set this up to where you click on a button it loads a new scene and unloads the previous scene.
This is what I have so far.
staart.addEventListener(MouseEvent.CLICK, fl_MouseClickHandler);
function fl_MouseClickHandler(event:MouseEvent):void
{
function loadSWF(swfURL){
var myLoader:Loader = new Loader();
var mySWF:URLRequest = new URLRequest(swfURL);
myLoader.contentLoaderInfo.addEventListener
(Event.COMPLETE,onCompleteHandler);
myLoader.contentLoaderInfo.addEventListener
(ProgressEvent.PROGRESS,onProgressHandler);
myLoader.load(mySWF);
}
function onCompleteHandler(loadEvent:Event){
addChild(loadEvent.currentTarget.content);
loadEvent.currentTarget.content.gotoAndStop(swfFrame);
}
function onProgressHandler(myProgress:ProgressEvent){
var percent:Number =
Math.round(myProgress.bytesLoaded/myProgress.bytesTotal*100);
trace(percent+"% loaded");
}
}
var swfFrame:Number= 1;
loadSWF("home.swf");
}
Is it possible to unload a specific swf file or previous swf file through a newly loaded swf file?
You should create a variable for your swf.
Add this to your code :
var mc:MovieClip = new MovieClip();
// Adds the movie clip at initialization.
addChild(mc);
and modify your onCompleteHandler method like this :
function onCompleteHandler(loadEvent:Event){
// Changes the content of your movie clip.
mc = loadEvent.currentTarget.content;
mc.gotoAndStop(swfFrame);
}
shawn gave you the right answer but there are 2 other problems in your code:
There's a typo in element staart and a potential memory leak because you add event listeners without removing them. You should add the following two lines in onCompleteListener function:
loadEvent.currentTarget.removeEventListeners(Event.COMPLETE,onCompleteHandler)
loadEvent.currentTarget.removeEventListeners(ProgressEvent.PROGRESS,onProgressHandler)
If you don't remove the listeners, the garbage collector will be unable to free the memory of every loader you create on each click
Hi I'm loading an external swf into a MovieClip, and I want it to stop until I choose to play. Currently it plays upon loading immediately.
var mc:MovieClip;
var swfLoader:Loader = new Loader();
swfLoader.contentLoaderInfo.addEventListener (Event.COMPLETE, eventLoaded);
var request:URLRequest;
request = new URLRequest("external.swf");
swfLoader.load (request);
function eventLoaded(e:Event): void
{
mc = e.target.content as MovieClip;
// does not stop the clip
mc.Stop ();
}
So I tried adding a Event.ENTER_FRAME to the movieclip and stop it there, that will stop but it will play the first frame. Is there a way to get it to stay stopped when loaded until I choose Play?
It's actually very close to what Jochen Hilgers suggested. However, in this instance, the event you want is actually INIT instead of COMPLETE. INIT is fired when the content is not yet fully loaded but is ready for use (and will start playing on its own).
Attach the event with
loader.contentLoaderInfo.addEventListener(Event.INIT, handleReady );
And handle it with
public function handleReady( initEvent:Event ):void{
MovieClip(initEvent.currentTarget.content).stop();
}
You'll notice that you can cast the content property of currentTarget as a MovieClip and stop it even before it has been attached to the stage.
It is important to note that it is not safe to use the content property in a PROGRESS event (or any time prior to an INIT or COMPLETE event). You will get an error to the effect that the object is not ready.
I wrote this simple TestCase and it works fine... the loaded swf is quite simple, just a tween on the main timeline.
package {
import flash.display.Loader;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
import flash.net.URLRequest;
public class Test extends Sprite
{
private var loader:Loader = new Loader;
public function Test()
{
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, handleLoaded );
loader.load( new URLRequest( 'testFile.swf' ) );
}
public function handleLoaded( event:Event ):void
{
addChild( loader.content );
var mc:MovieClip = loader.content as MovieClip ;
mc.stop();
}
}
}
I was looking for a similar problem/solution, but my problem was little diferent. I know this was not your issue, but looks fair to share my solution. When I tried to do
event.currentTarget.stop(); // AS1&AS2 -> BAD swf to import
with the content of a loader, my Flash IDE showed me this error:
"Property stop not found on flash.display.AVM1Movie and there is no default value."
This happened to me because the swf I imported was created using AS1, and not AS3 as the main movie ( so I decompiled the swf to a fla and recompiled using as3, it was an output from After Effects). Now I know AVM1 and AVM2 are classes that represent actionscript 1 and 2 files.