17 Replies Latest reply on Feb 13, 2008 5:49 AM by Newsgroup_User

    loadMovie _width problem

    bartonsmith
      Can someone explain why this is happening:

      When the "About" button is pressed, "about_image.png" is loaded into image_holder.
      image_holder previously had "main_image.png" loaded into it.

      "main_image.png" is not as high as "about_image.png"

      I then set image_holder to the centre of the stage (Sw and Sh)
      However - it is taking the dimensions of image_holder when "main_image.png" is loaded rather than "about_image.png" which means that it isn't sitting in the centre of the stage.

      Why would this happen when I am asking for it to get the image_holder _height after "about_image.png" is loaded?

      Just a side note - when I click About for a second time in a row, it centers it on stage, because "about_image.png" is already loaded.

      Cheers
      B
        • 1. Re: loadMovie _width problem
          Level 7
          It's how you are loading and setting that is the problem. Loading is an
          asynchronous operation - and as such you should use the MovieClipLoader
          class, and its associated onLoadInit method - which is fired when the target
          clip is loaded, and available for modification.

          --
          Dave -
          Head Developer
          http://www.blurredistinction.com
          Adobe Community Expert
          http://www.adobe.com/communities/experts/


          • 2. Re: loadMovie _width problem
            Level 7
            expansion17,

            > Just a side note - when I click About for a second time in a
            > row, it centers it on stage, because "about_image.png" is
            > already loaded.

            That, right there, is the answer! :) In your code ...

            loadMovie("about_image.png", _root.content.image_holder);

            ... which is immediately followed by this ...

            var Sw = (Stage.width/2) - (_root.content.image_holder._width/2);
            var Sh = (Stage.height/2) - (_root.content.image_holder._height/2);

            ... you're setting your Sw and Sh values almost immediately after issuing
            the loadMovie() funciton -- from a practical standpoint, it *is* immediate,
            even though about_image.png hasn't yet had the chance to load.

            In order to repond to the new dimensions, you'll have to set up a
            mechanism that listens for the completion of your load. Here are a couple
            of approaches:

            http://www.quip.net/blog/2006/flash/how-to-tell-when-external-swf-loaded

            The article is about loading SWFs, but the exact ideas work for JPGs,
            PNGs, etc.


            David Stiller
            Co-author, Foundation Flash CS3 for Designers
            http://tinyurl.com/2k29mj
            "Luck is the residue of good design."


            • 3. Re: loadMovie _width problem
              bartonsmith Level 1
              yeh of course. I already did all that for another part of the site to have a loader bar, and to move on objects onLoadComplete (size was set through onLoadInit)

              So why is it that you have to go through all the listeners to achieve that. Cos I did just try:

              _root.content.image_holder.onLoadInit = function() {
              var Sw = (Stage.width/2) - (_root.content.image_holder._width/2);
              var Sh = (Stage.height/2) - (_root.content.image_holder._height/2);
              }

              but obviously that did work...

              Also from your site, David - is the "mc" in
              mclListener.onLoadInit = function(mc:MovieClip) {
              just a reference to whatever clip is loaded into the empty container?


              Thanks for the help guys.
              B
              • 4. Re: loadMovie _width problem
                Level 7
                B,

                > yeh of course. I already did all that for another part of the
                > site to have a loader bar, and to move on objects
                > onLoadComplete (size was set through onLoadInit)

                Good stuff! Having done those other parts should be able to help.

                > So why is it that you have to go through all the listeners
                > to achieve that.

                If you update the value of those variables right away, they get set to
                the current width and height of your content. If you wait, thanks to a
                listener, then they get set to the updated with and height of the new
                content -- which is what you want.

                > Cos I did just try:
                >
                > _root.content.image_holder.onLoadInit = function() {
                > var Sw = (Stage.width/2) - (_root.content.image_holder._width/2);
                > var Sh = (Stage.height/2) - (_root.content.image_holder._height/2);
                > }
                >
                > but obviously that did work...

                How do you know this isn't working? I hear what you're saying, and I
                believe you, but I'm curious if you've taken any steps to verify your
                values. You might, for example, use the trace() function to see what's
                going on:

                _root.content.image_holder.onLoadInit = function():Void {
                var Sw = (Stage.width/2) - (_root.content.image_holder._width/2);
                var Sh = (Stage.height/2) - (_root.content.image_holder._height/2);
                trace(Sw);
                trace(Sh);
                }

                That will put the values of those variables into the Output panel when
                you test in the Flash authoring tool. For additional tips on
                troubleshooting, you may want to check out this Dev Center article:

                http://www.adobe.com/devnet/flash/articles/debugging_actionscript.html

                > Also from your site, David - is the "mc" in
                > mclListener.onLoadInit = function(mc:MovieClip) {
                > just a reference to whatever clip is loaded into the
                > empty container?

                Yes, that's a parameter of the function assigned to the onLoadInit
                event. It's just like a parameter you might feed into gotoAndPlay() --
                only, to gotoAndPlay(), you feed in a frame number. Here, a movie clip
                reference is passed in for you by the MovieClipLoader instance. You can
                access that movie clip reference (if you want to) by referencing the
                variable name. In my suggested code, I went with mc because "mc" reminds me
                of movie clip.


                David Stiller
                Contributor, How to Cheat in Flash CS3
                http://tinyurl.com/2cp6na
                "Luck is the residue of good design."


                • 5. Re: loadMovie _width problem
                  Level 7
                  B,

                  Ah, one more thing. In your code ...

                  _root.content.image_holder.onLoadInit = function() {
                  var Sw = (Stage.width/2) - (_root.content.image_holder._width/2);
                  // etc.

                  I noticed you're declaring those two variables inside the function itself.
                  That may or may not be effective in this context. If you declared the
                  variables in the function, they're only available to that function (not in
                  the timeline, for example). So if you only need them there -- and that
                  depends on how you use them -- that might be fine, but if other object need
                  to reference them (such as your Tween instances later), you'll need to
                  declare those variables outside the function.

                  var Sw:Number;
                  var Sh:Number;
                  _root.content.image_holder.onLoadInit = function():Void {
                  Sw = (Stage.width/2) - (_root.content.image_holder._width/2);
                  Sh = (Stage.height/2) - (_root.content.image_holder._height/2);
                  }


                  David Stiller
                  Adobe Community Expert
                  Dev blog, http://www.quip.net/blog/
                  "Luck is the residue of good design."


                  • 6. Re: loadMovie _width problem
                    bartonsmith Level 1
                    Thanks David,
                    just a couple of things:

                    > So why is it that you have to go through all the listeners
                    > to achieve that.

                    What I was meaning is why do you have to set up MCL's and listeners. Why doesn't

                    _root.content.image_holder.onLoadInit = function() {
                    trace ("when it is loaded do this");
                    }

                    produce the same result on its own? Isn't this just saying.. when image_holder loads do something.


                    > Yes, that's a parameter of the function assigned to the onLoadInit

                    Is it necessary to have it tho - as with my previous question it seems like there is more code than needed (although im sure this is just how actionscript works, so that it can be applied to more complex stuff)

                    Instead of this:
                    mclListener.onLoadInit = function(target_mc:MovieClip) {
                    target_mc._height = Stage.height + 30;
                    }

                    Couldn't you have this:
                    mclListener.onLoadInit = function() {
                    _root.content.image_holder._height = Stage.height + 30;
                    }

                    where image_holder is the loaded and targeted mc.

                    Im assuming that all these answers are that its good practice, because you may come across a situation with more complex code, where you will need to write it the way you have.

                    Cheers,
                    Really appreciating the replies.
                    • 7. Re: loadMovie _width problem
                      Level 7
                      B,

                      > Why doesn't
                      >
                      > _root.content.image_holder.onLoadInit = function() {
                      > trace ("when it is loaded do this");
                      > }
                      >
                      > produce the same result on its own?

                      This might be an eye-opener. (It certainly was for me, when I finally
                      made this connection!) Check it out ... the reason image_holder.onLoadInit
                      doesn't do anything is because image_holder is a movie clip symbol. This
                      means it's an object defined by the MovieClip class (just like text fields
                      are defined by the TextField class, and movie clip loader objects are
                      defined by the MovieClipLoader class).

                      Classes are basically blueprints that determine the characteristics an
                      object has (called properties), the things it can do (called methods), and
                      the things it can react to (called events). The MovieClip class defines
                      methods like play(), stop(), gotoAndPlay(), etc., which is why all movie
                      clips can be programmed to do those things. If you look in the Events
                      Summary of the ActionScript 2.0 Language Reference for this class, you'll
                      see a bunch of events, too -- onPress, onRelease, onEnterFrame, etc. -- but
                      you won't find onLoadInit. That's because onLoadInit isn't a member of the
                      MovieClip class. What it *is* is a member of the MovieClipLoader class,
                      which is why you need an instance of MovieClipLoader in order to use it.

                      >> Yes, that's a parameter of the function assigned to
                      >> the onLoadInit
                      >
                      > Is it necessary to have it tho

                      Exactly. If you don't want to reference the movie clip inside the
                      handler function, you don't need the parameter. Just so you know, the
                      parameter always gets passed in with this particular event, but that doesn't
                      mean you have to "catch" it.

                      > as with my previous question it seems like there is more
                      > code than needed (although im sure this is just how
                      > actionscript works, so that it can be applied to more
                      > complex stuff)

                      The cool thing is, you're the one in control, so ActionScript works
                      however you want it to -- provided you follow its rules. ;)

                      > Couldn't you have this:
                      > mclListener.onLoadInit = function() {
                      > _root.content.image_holder._height = Stage.height + 30;
                      > }

                      You could.

                      > Im assuming that all these answers are that its good practice,
                      > because you may come across a situation with more complex
                      > code, where you will need to write it the way you have.

                      Bingo!


                      David Stiller
                      Co-author, Foundation Flash CS3 for Designers
                      http://tinyurl.com/2k29mj
                      "Luck is the residue of good design."


                      • 8. Re: loadMovie _width problem
                        bartonsmith Level 1
                        Great, that makes me happy. I understand exactly what your saying.

                        One last thing in relation to parameter.

                        mclListener.onLoadProgress = function(target_mc:MovieClip, bytesLoaded:Number, bytesTotal:Number) {
                        _root.content.image_loader.image_loader_mask._xscale = Math.round(bytesLoaded/bytesTotal*100);
                        }

                        The loader bar doesn't work without target_mc:MovieClip (or anyRandomWord:MovieClip)
                        What I'm struggling to understand is how mc:MovieClip is linking to the rest of the code.
                        There is no physical object called target_mc and nothing seems to go in or out of it...

                        Cheers
                        B
                        • 9. Re: loadMovie _width problem
                          bartonsmith Level 1
                          Also (sorry) why do you need a mclListener

                          instead of:
                          mclListener.onLoadStart = function() {

                          could you not just have:
                          image_mcl.onLoadStart = function() {

                          where image_mcl comes from var image_mcl:MovieClipLoader = new MovieClipLoader();

                          My guess would be that with a Listener, you can run image_mcl.addListener(mclListener); after all the previous script has been performed..?
                          • 10. Re: loadMovie _width problem
                            bartonsmith Level 1
                            Hey David,

                            I thought I'd post this here instead of a new thread as I thought it was somewhat related.
                            I made a new document and just copied the code that was related.
                            In the original file, Stage.scaleMode... was in the _root timeline and button.onRelease... was a few mcs deep. In both files I get the same result.

                            When I click the button, "id_pebble.swf" is only about 1/10 the size of the stage - rather than the height of the stage.
                            When I resize the browser, it fixes itself and makes it the height of the stage..
                            Any idea why this may be?

                            I understand that resizing an mc before a file is loaded can cause it to stuff up, however in this case it is saying to change the size either when the load is complete or the stage is resized.

                            The only way I could get it to work was to have a MCL in the main timeline and have the Stage.scaleMode... inside it.
                            This seemed messy and I didn't understand why it was working this way.

                            Really what I am after is for "id_pebble.swf" to be the height of the stage when it is loaded, and to stay the height of the stage when the window is resized.

                            I appreciate the time ur taking to help me,
                            Cheers,
                            Barton
                            • 11. Re: loadMovie _width problem
                              Level 7
                              B,

                              > One last thing in relation to parameter.
                              >
                              > The loader bar doesn't work without target_mc:MovieClip (or
                              > anyRandomWord:MovieClip)

                              I'm looking at the docs as I write this. The onLoadProgress event
                              accepts up to three parameters: a) a movie clip reference, which is
                              supposedly optional; b) a reference to the number of bytes that have been
                              loaded; and c) a reference to the total number of bytes expected to load.
                              According to the MovieClipLoader class entry, you should be able to leave
                              off that first parameter, but in actual practice, I don't see that this is
                              true.

                              To prove it, copy the example right from the documentation (from the
                              onLoadProgress event entry) ...

                              var container:MovieClip = this.createEmptyMovieClip("container",
                              this.getNextHighestDepth());
                              var mcLoader:MovieClipLoader = new MovieClipLoader();
                              var listener:Object = new Object();
                              listener.onLoadProgress = function(target:MovieClip, bytesLoaded:Number,
                              bytesTotal:Number):Void {
                              trace(target + ".onLoadProgress with " + bytesLoaded + " bytes of " +
                              bytesTotal);
                              }
                              listener.onLoadInit = function(target:MovieClip):Void {
                              trace(target + ".onLoadInit");
                              }
                              mcLoader.addListener(listener);
                              mcLoader.loadClip(" http://www.w3.org/Icons/w3c_main.png", container);

                              ... then test. When I run this test, I get the expected trace() results:
                              several for onLoadProgress, and one for onLoadInit. Given the code as is,
                              the onLoadProgress traces the target parameter first -- that's the same
                              parameter as mc, target_mc, etc., in previous replies -- and then the two
                              number parameters.

                              Now remove the parameter from the function and the trace:

                              listener.onLoadProgress = function(bytesLoaded:Number,
                              bytesTotal:Number):Void {
                              trace(".onLoadProgress with " + bytesLoaded + " bytes of " +
                              bytesTotal);
                              }

                              ... now test again. When I run this revision, I still see the target (in
                              this case, _level0.container). But I shouldn't, right? After all, I took
                              out that first parameter. But facts are facts. By using the trace()
                              function, I can see that all three parameters are still coming in. The
                              first slot, no matter what it gets called, refers to the movie clip. The
                              second slot refers to bytes loaded, and the third slot refers to bytes
                              total. There's no arguing with practical results.

                              > What I'm struggling to understand is how mc:MovieClip is
                              > linking to the rest of the code.

                              It may not be. But again, when you take out that first parameter, the
                              other two simply slide over to fill up the empty spot. Instead of comparing
                              bytes loaded to bytes total, you're comparing a movie clip reference to
                              bytes loaded.

                              > Also (sorry) why do you need a mclListener
                              >
                              > instead of:
                              > mclListener.onLoadStart = function() {
                              >
                              > could you not just have:
                              > image_mcl.onLoadStart = function() {
                              > ...
                              > where image_mcl comes from var image_mcl:MovieClipLoader = new
                              > MovieClipLoader();

                              There are a handful of ways to handle events in ActionScript 2.0, and
                              MovieClipLoader is simply one of the objects that requires an "ambassador"
                              object to act on its behalf. The event model in ActionScript 3.0 is
                              significantly changed, so that these inconsistences are almost entirely
                              reduced to a single approach. This is just one of the quirks of AS2 ...
                              there's on(), onClipEvent(), dot syntax (myMovieClip.onRelease =
                              function(){}), addListener(), and addEventListener(). In AS3, 99% of the
                              time it's addEventListner only.


                              David Stiller
                              Contributor, How to Cheat in Flash CS3
                              http://tinyurl.com/2cp6na
                              "Luck is the residue of good design."


                              • 12. Re: loadMovie _width problem
                                Level 7
                                Barton,

                                > I understand that resizing an mc before a file is loaded can
                                > cause it to stuff up, however in this case it is saying to
                                > change the size either when the load is complete or the
                                > stage is resized.

                                Those are two criteria -- when load is complete or the stage is
                                resized -- and they need to happen in order. I would probably do it like
                                this:


                                Stage.scaleMode = "noScale";
                                Stage.align = "TL";

                                var listener:Object = new Object();

                                listener.onResize = positionImage;
                                function positionImage():Void {
                                image_holder._rotation = 0;
                                image_holder._height = Stage.height + 30;
                                image_holder._xscale = image_holder._yscale;
                                image_holder._rotation = 1;
                                }

                                listener.onLoadInit = assignResizeHandler;
                                function assignResizeHandler():Void {
                                Stage.addListener(listener);
                                positionImage();
                                }

                                var mcl:MovieClipLoader = new MovieClipLoader();
                                mcl.loadClip("id_pebble.swf", image_holder);
                                mcl.addListener(listener);


                                Note that I renamed stageListener to listener. It doesn't really matter
                                what the variable's name is, but in this case, there are two event handlers
                                using the object, so it's more than just a "stage listener": it's a
                                listener in general. So ... ehh, I renamed it plain old "listener." The
                                first thing that happens is the Stage prep, scaleMode and align. After
                                that, the listener variable is declared and set to an instance of the Object
                                class. This listener -- this liaison, as it were -- is going to manage two
                                different events ... for two different classes. First, Stage.onResize on
                                behalf of Stage class, then MovieClipLoader.onLoadInit on behalf of the
                                MovieClipLoader class. (As long as the event names don't overlap, it's
                                perfectly valid -- and convenient -- to use the same listener object for as
                                many events as you want.)

                                The onResize handler does the positioning stuff, like you had. (I'm not
                                sure why you're rotating to zero, then rotating to one, but that's fine.)
                                The onLoadInit handler associates the listener object to the Stage. This is
                                important. This assignment occurs here, because it's at this point only
                                (after the content has loaded) that image_holder can properly be addressed
                                in this context. The loading of content "resets" movie clips, in a way, so
                                this listener assignment needs to happen after the reset. After the
                                addListener() assignment, positionImage() is called on its own, to position
                                the content in case the user happens not to resize the Stage.

                                Finally, the MovieClipLoader instance is created, instructed to load the
                                SWF, and associated with listener for its own purposes.

                                The fact that some of this stuff doesn't seem 100% intuitive, honestly,
                                is because of some of the quirks inherent in ActionScript 2.0.


                                David Stiller
                                Contributor, How to Cheat in Flash CS3
                                http://tinyurl.com/2cp6na
                                "Luck is the residue of good design."


                                • 13. loadMovie _width problem
                                  bartonsmith Level 1
                                  hey, thanks...
                                  yeh that works in the example document i had... but the thing is with the real file (my website) its kinda a different situation, because the Stage prep is on the main timeline and the onLoadInit is 3 mcs deep. I try having the Stage prep with the onLoadInit (3 mcs deep), exactly like your script above, but that doesn't work. I'll keep going at it, but I only 80% understand the script so its a little hard. Still, 5hrs left in the day. Ha

                                  One bit of the 20% i don't understand is why:

                                  listener.onLoadInit = assignResizeHandler;
                                  function assignResizeHandler():Void {
                                  Stage.addListener(listener);
                                  positionImage();
                                  }

                                  isn't just:

                                  listener.onLoadInit = function() {
                                  Stage.addListener(listener);
                                  positionImage();
                                  }

                                  cheers
                                  • 14. Re: loadMovie _width problem
                                    bartonsmith Level 1
                                    I was going to scream yay its working! But after I got it working I did some copy and paste to try something that I thought should work... and it did. I then discovered that it is exactly the same script as when I posted to problem... only now it works?!

                                    Anyway you taught me something in that last post which I will use now anyway because it means I can do other this I otherwise couldn't.

                                    So thanks, I learnt a lot, especially in regard to listeners and onLoad...
                                    Cheers David,
                                    Barton

                                    Edit: Ok so it goes back to the original problem when I remove the rotation = 0...?
                                    • 15. Re: loadMovie _width problem
                                      bartonsmith Level 1
                                      I did it kinda your way, and got everything working how i want. i think ill just put those weird resizing/rotation issues down to AS2 and my scripting :D

                                      I think im officially done with this thread!
                                      Thanks, learnt a lot!

                                      expansiondesign.com - if your interested. About and Work > Industrial Design are the areas related to this thread.

                                      Cheers
                                      Barton
                                      • 17. Re: loadMovie _width problem
                                        Level 7
                                        Barton,

                                        Don't give it! ;) You'll get it if you keep tinkering. If you
                                        understand about 80% of the code, like you said, then you're not far off.

                                        > it was all working fine, i played with different values for
                                        > location/size and it was fine. then i go and change a file
                                        > which is being loaded in and things are stuffing up.

                                        This can be a helpful thing, actually, because it allows you to
                                        troubleshoot. If you switch back to your original settings, does the code
                                        suddenly work again?

                                        > i have
                                        >
                                        > mclListener.onLoadInit = function() {
                                        > positionImage();
                                        > ...
                                        > }

                                        Right.

                                        > and
                                        >
                                        > var stageListener:Object = new Object();
                                        > stageListener.onResize = positionImage;
                                        > Stage.addListener(stageListener);

                                        Fine so far, though I do see you're using two different listener objects
                                        (mclListener and stageListener). That's perfectly fine, of course, but then
                                        I'm not sure what the rest of your code looks like (you said earlier that
                                        our two code snippets were exactly the same). So it's hard to say ... maybe
                                        something else has changed?

                                        > both executing the positionImage function. But when
                                        > it moves the file on after LoadInit it puts it in the same
                                        > spot (it seems to be x = 0, y = -10+) no matter
                                        > what the values of positionImage are set on.

                                        What code do you have in your positionImage() function at this point?

                                        > When I resize the stage, however, it goes to the correct
                                        > spot according to positionImage.

                                        It will likely help if you put a few trace() statements inside
                                        positionImage(), just to get a glimpse into what Flash is seeing when the
                                        function is invoked.


                                        David Stiller
                                        Adobe Community Expert
                                        Dev blog, http://www.quip.net/blog/
                                        "Luck is the residue of good design."