11 Replies Latest reply on Feb 28, 2007 9:32 AM by MrBritton

    Can't Flex apps scale to fit browser window?

    MrBritton Level 1
      This has been brought up a couple of times, but seems to be a mystery: How does one scale all content to fit the browser window, preserving aspect ratio, and centering the content vertically or horizontally (depending on whether the window aspect ratio is less than or greater than the content aspect ratio)?

      Since Flash is vector-based, I would have thought this would be straightforward and encouraged!

      Some information in an earlier post, plus experimentation on my part, has yielded a bizarre and inflexible partial solution - using StageScaleMode, and sizing the app's base container to exactly 500x375 pixels, I can get content that scales with the window size and doesn't have mismatched margins (though I haven't figured out how to center it yet). In addition, there are ugly scaling artifacts (look at the drop-shadows as you change the browser window size).

      Again, not being a Flash programmer, I baffled that this isn't better supported, but I have to admit, most of the Flash apps I've seen in the wild seem to all be fixed at some ridiculous size like 640x480 or something. Are there some serious bugs here, or am I missing something? Is there a better approach?

      Here's a simple, complete, example (based on an example from an earlier thread, but simplified a good bit):

      <?xml version="1.0" encoding="utf-8"?>
      <mx:Application xmlns:mx=' http://www.adobe.com/2006/mxml'
      pageTitle="Resize Test"
      layout="absolute" autoLayout="false"
      addedToStage="event.currentTarget.stage.scaleMode = StageScaleMode.SHOW_ALL"
      >
      <mx:Style>
      VBox {
      cornerRadius: 4;
      borderStyle: solid; border-color: #000000; borderSize: 1;
      horizontalAlign: center; verticalAlign: middle;
      dropShadowEnabled: true;
      }
      </mx:Style>

      <mx:VBox width="500" height="375"
      backgroundColor="#808080"
      paddingTop="20" paddingBottom="20" paddingLeft="20" paddingRight="20">
      <mx:VBox width="100%" height="100%" backgroundColor="#808000">
      <mx:Label text="This is some text" fontSize="12" width="128" textAlign="center"/>
      <mx:Button label="Button"/>
      </mx:VBox>
      </mx:VBox>

      </mx:Application>
        • 1. Re: Can't Flex apps scale to fit browser window?
          MrBritton Level 1
          One of my engineers, who works with Microsoft's WPF/XAML, claimed scaling to fit a window was simple in XAML, so I challenged him to do so. 5 minutes later he showed me a working result, included below. Not only does it scale, maintaining the aspect ratio, but it also centers the content just as I would like to do in Flex. The secret is the object called a "Viewbox".

          Is Flex just broken with regard to this, or am I missing something? This seems so fundamental to me - I'm puzzled.

          <Window
          xmlns=" http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x=" http://schemas.microsoft.com/winfx/2006/xaml"
          xml:lang="en-US"
          x:Class="UntitledProject9.Window1"
          x:Name="Window"
          Title="Window1"
          Width="640" Height="480">

          <Viewbox Stretch="Uniform">
          <Border
          Width="200"
          Height="100"
          Background="Green"
          Margin="5"
          BorderBrush="Gray"
          BorderThickness="5"
          CornerRadius="10">
          <Button
          HorizontalAlignment="Center"
          VerticalAlignment="Center"
          Width="128"
          Height="24"
          Content="Button"/>
          </Border>
          </Viewbox>
          </Window>
          • 2. Re: Can't Flex apps scale to fit browser window?
            PierreEnsemble
            This works for me: In any top level component, insert
            creationComplete="parent.stage.scaleMode=StageScaleMode.SHOW_ALL"
            Example:
            <?xml version="1.0"?>
            <!-- Simple example to demonstrate scaling. -->
            <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml">
            <mx:Panel title="Button Control Example"
            height="75%" width="75%" layout="horizontal"
            paddingTop="10" paddingBottom="10" paddingLeft="10" paddingRight="10"
            creationComplete="parent.stage.scaleMode=StageScaleMode.SHOW_ALL">
            <mx:VBox>
            <mx:Label width="100%" color="blue"
            text="Select a Button control."/>
            <mx:Button label="Customized Button" color="#993300" toggle="true" selected="true"
            textAlign="left" fontStyle="italic" fontSize="13" />
            <mx:Button label="Default Button" />
            </mx:VBox>
            </mx:Panel>
            </mx:Application>
            • 3. Re: Can't Flex apps scale to fit browser window?
              MrBritton Level 1
              Interesting, Pierre. Your example works for me, but not in a browser - it works if I manually launch the .swf, but in the latest Firefox and IE browsers, it displays much too large, with most of the content clipped on the right and bottom. Does it display okay for you in a browser?

              Even running in the standalone Flashplayer, however, the drop-shadows show some ugly artifacts, and if the aspect ratio of the window is wider, or taller, than the content, the application background gradient tiles with an obvious discontinuity.

              Thanks for the reply.

              • 4. Re: Can't Flex apps scale to fit browser window?
                MrBritton Level 1
                quote:

                Originally posted by: MrBritton
                Interesting, Pierre. Your example works for me, but not in a browser - it works if I manually launch the .swf, but in the latest Firefox and IE browsers, it displays much too large, with most of the content clipped on the right and bottom...


                I discovered the condition that causes this - if the initial size of the browser window is beyond a certain size, your example is quite broken. If you resize the browser down and reload, it works better. Running it in the standalone Flashplayer happens to open it up in a smaller window, so it appeared to work better in the case.
                At least these are the result on my XP machine and a colleagues Vista machine!

                • 5. Re: Can't Flex apps scale to fit browser window?
                  jpwrunyan Level 1
                  quote:

                  Originally posted by: MrBritton
                  This has been brought up a couple of times, but seems to be a mystery: How does one scale all content to fit the browser window, preserving aspect ratio, and centering the content vertically or horizontally (depending on whether the window aspect ratio is less than or greater than the content aspect ratio)?

                  Since Flash is vector-based, I would have thought this would be straightforward and encouraged!

                  Again, not being a Flash programmer, I baffled that this isn't better supported, but I have to admit, most of the Flash apps I've seen in the wild seem to all be fixed at some ridiculous size like 640x480 or something. Are there some serious bugs here, or am I missing something? Is there a better approach?


                  I can give you some explanation as to why changing the browswer window size only repositions content as opposed to rescaling it to the same aspect ratio:

                  Many online applications import external images which get converted into bitmaps inside of Flex. This is highly encouraged as browsing any of the samples will show. Think about it, probably 90% (at least) of all RIA applications on the web are shopping catalogues which show a picture of your order item. Now, if you resize the application to become larger and these bitmaps are consequently upscaled, you will probably get really ugly pixelation. As default behavior, the current system is best for nearly all applications.

                  That said, the SWFLoader class has a maintainAspectRatio property that can be used to scale content the way you are expecting. You can use this class to load external .swf applications. If you use this class properly as a sort of wrapper for your content, you can probably obtain the result you want while still working within the regular Flex framework/design pattern.

                  Anyway, that is what I would probably do and it *should* work despite whatever browser you are using.

                  SWFLoader is here:
                  SWFLoader API
                  • 6. Re: Can't Flex apps scale to fit browser window?
                    PierreEnsemble Level 1
                    quote:

                    Does it display okay for you in a browser?

                    No, I see the same problem you describe.
                    I'm currently targeting the player, not a browser, but I'll look into it.
                    • 7. Re: Can't Flex apps scale to fit browser window?
                      MrBritton Level 1
                      quote:

                      Originally posted by: jpwrunyan
                      Many online applications import external images which get converted into bitmaps inside of Flex. This is highly encouraged as browsing any of the samples will show. Think about it, probably 90% (at least) of all RIA applications on the web are shopping catalogues which show a picture of your order item. Now, if you resize the application to become larger and these bitmaps are consequently upscaled, you will probably get really ugly pixelation. As default behavior, the current system is best for nearly all applications.

                      That said, the SWFLoader class has a maintainAspectRatio property that can be used to scale content the way you are expecting. You can use this class to load external .swf applications. If you use this class properly as a sort of wrapper for your content, you can probably obtain the result you want while still working within the regular Flex framework/design pattern.

                      Anyway, that is what I would probably do and it *should* work despite whatever browser you are using.


                      No luck with SWFLoader - if anything, it is worse than the other technique:

                      Application to be loaded:
                      <?xml version="1.0"?>
                      <!-- loader_test_loadee.mxml -->
                      <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml" height="75" width="350">
                      <mx:Label text="The Label control of the embedded application."/>
                      </mx:Application>

                      Application which does the loading:
                      <?xml version="1.0"?>
                      <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml">
                      <mx:SWFLoader id="Load" source="loader_test_loadee.swf"
                      width="100%" height="100%"
                      scaleContent="true"/>
                      </mx:Application>

                      I'm skeptical that 90+% of RIAs contain bitmaps, but even if they did, the "resize" approach would be to embed images of sufficient resolution to scale up nicely. I personally use 6 displays ranging from 3 inches to 47 inches, all of which can browse the web - I see this as a Big Deal, and I'm starting to think WPF/E is going to win this race (though I know that web designers traditionally (maddenly) have thought in terms of fixed, non-scaling interfaces).

                      I'm beginning to think that Flex is just broken with regard to scaling. Anyone from Adobe reading this, please comment.
                      • 8. Re: Can't Flex apps scale to fit browser window?
                        PierreEnsemble Level 1
                        quote:

                        Originally posted by: PierreEnsemble
                        quote:

                        Does it display okay for you in a browser?

                        No, I see the same problem you describe.
                        I'm currently targeting the player, not a browser, but I'll look into it.


                        OK I've looked, but I don't have a 100% solution. I have almost eliminated the clipping by adding
                        horizontalAlign="left" verticalAlign="top" to the Application.

                        I also added an embedded JPG image to my experiments and it scales down fine.
                        • 9. Re: Can't Flex apps scale to fit browser window?
                          jfillman Level 1
                          I have a fairly large screen (21 inch) and this appears to work fine without modification (Windows XP, IE7).

                          You might try changing your VBox like the code below, instead of specifying specific width and height:

                          <mx:VBox
                          backgroundColor="#808080"
                          paddingTop="20" paddingBottom="20" paddingLeft="20" paddingRight="20" top="10" left="10" bottom="10" right="10">

                          AND change your application tag to this:

                          <mx:Application xmlns:mx=' http://www.adobe.com/2006/mxml'
                          pageTitle="Resize Test"
                          layout="absolute">
                          • 10. Re: Can't Flex apps scale to fit browser window?
                            jpwrunyan Level 1
                            quote:

                            Originally posted by: MrBritton
                            I'm skeptical that 90+% of RIAs contain bitmaps, but even if they did, the "resize" approach would be to embed images of sufficient resolution to scale up nicely. I personally use 6 displays ranging from 3 inches to 47 inches, all of which can browse the web - I see this as a Big Deal, and I'm starting to think WPF/E is going to win this race (though I know that web designers traditionally (maddenly) have thought in terms of fixed, non-scaling interfaces).

                            I'm beginning to think that Flex is just broken with regard to scaling. Anyone from Adobe reading this, please comment.


                            Not bitmaps. Externally loaded images that get converted to bitmaps. What I said is that 90%+ are online catalogues. Logically it would be safe to assume they display external images of a set size. Sorry that was unclear. It would interesting to see an official survey.

                            And good luck getting anyone from Adobe to pay attention to this forum let alone comment. Better to contact their support if you're ever really stuck.

                            Another reason I thought of why resizing does not result in rescaling by default:
                            HTML and JSP applications don't rescale when you change the browser size. Just go to hotmail or msn and check. They reposition. Flex applications are intended to behave the same way but with RIA capabilities. That is probably the more likely explanation than bitmaps merely not scaling well. Anyway, this behaviour was a thought-out decision and I happen to agree with it. By the way, older Flash applications do rescale to fit the window by default.

                            Now if you want the Flash Player to be able to import huge .jpg files with 1000px+ resolution and selectively only load enough information to make a smaller size bitmap image so you can rescale with impunity, more power to you. Sounds great. I would love this. But it still doesn't address what should happen when the image goes beyond the original size. I know you're only using vector graphics so it's not an issue for you.

                            Finally to get back on the main topic:
                            if SWFLoader isn't working well, you could programatically do the same thing. Have a sub-contaier inside the application container which adjusts its scale accordingly to the size of the parent application container. I have done this myself with the Image class for zooming in and out from images (ironically 1000px+ images which were displayed at much smaller sizes).

                            <Application resize="adjustSize()" creationComplete="adjustSize()" paddingLeft="0" paddingRight="0" paddingTop="0" paddingBottom="0">
                             <Script>
                              private function adjustSize():void {
                               var newScaleX = this.width/content.width
                               var newScaleY = this.height/content.height
                               content.scaleX = newScaleX;
                               content.scaleY = newScaleY;
                              }
                             </Script>
                             <Box id="content" borderStyle="none" width=400 height=300 /> <!-- the width and height are arbitrary -->
                            </Application>

                            Something along the lines of the above should definately work. I am just basing it off my own previous code. You may have to be careful of borders and padding if you decide to add them. Whether it works better than the other suggestions you'll have to decide.
                            • 11. Re: Can't Flex apps scale to fit browser window?
                              MrBritton Level 1
                              quote:

                              Originally posted by: jpwrunyan
                              Not bitmaps. Externally loaded images that get converted to bitmaps. What I said is that 90%+ are online catalogues. Logically it would be safe to assume they display external images of a set size. Sorry that was unclear. It would interesting to see an official survey.


                              Yeah, I was using "bitmap" to mean raster graphics, whether the actual source be jpg, png or what have you.

                              quote:

                              Originally posted by: jpwrunyan
                              And good luck getting anyone from Adobe to pay attention to this forum let alone comment. Better to contact their support if you're ever really stuck.


                              Another reason I'm thinking MS is going to win this war - my colleague is having great luck in the WPF forums.

                              quote:

                              Originally posted by: jpwrunyan
                              Another reason I thought of why resizing does not result in rescaling by default:
                              HTML and JSP applications don't rescale when you change the browser size. Just go to hotmail or msn and check. They reposition. Flex applications are intended to behave the same way but with RIA capabilities. That is probably the more likely explanation than bitmaps merely not scaling well. Anyway, this behaviour was a thought-out decision and I happen to agree with it. By the way, older Flash applications do rescale to fit the window by default.


                              Exactly! That's the big problem, in my view, with the HTML/JPG based web, and is what a vector-based solution (discounting raster graphics) should solve.
                              Firefox, and now IE7, have features to allow you to scale web pages to overcome, in a stop-gap way, this problem. IE even scales images and Flash apps, though some Flash suffers problems when scaled. Firefox does not (yet?) scale images or Flash along with the other content. Flash-based Elmo games at sesamestree.org, at 640x480, look pretty stupid on my 42" 1920x1080 LCD (played by my 3-year old, not me!), but at least I can now (try) to scale them up with IE7 for him.
                              I do not believe this was a thought-out decision, it's just inertia from the bad old ways of doing things. There should be a working option to easily scale content to the browser window, and if Flex doesn't provide one, Microsoft certainly is going to (with WPF/E) as they have with WPF. I'm not a big MS fan, but I think they get the way things are going with the proliferation in the range of screen resolutions and sizes that web content is being displayed on.
                              That said, I realize there is more to dealing with different screen sizes than just scaling - you may have to change the amount of content on the screen, dependent on what the subject is.

                              quote:

                              Originally posted by: jpwrunyan
                              Now if you want the Flash Player to be able to import huge .jpg files with 1000px+ resolution and selectively only load enough information to make a smaller size bitmap image so you can rescale with impunity, more power to you. Sounds great. I would love this. But it still doesn't address what should happen when the image goes beyond the original size. I know you're only using vector graphics so it's not an issue for you.


                              Yep, raster graphics are troublesome. Worst case, a beautiful picture frame grows to surround the image as one zooms beyond its original size (insert smiley icon of choice here)

                              quote:

                              Originally posted by: jpwrunyan
                              Finally to get back on the main topic:
                              if SWFLoader isn't working well, you could programatically do the same thing. Have a sub-contaier inside the application container which adjusts its scale accordingly to the size of the parent application container. I have done this myself with the Image class for zooming in and out from images (ironically 1000px+ images which were displayed at much smaller sizes).

                              <Application resize="adjustSize()" creationComplete="adjustSize()" paddingLeft="0" paddingRight="0" paddingTop="0" paddingBottom="0">
                              <Script>
                              private function adjustSize():void {
                              var newScaleX = this.width/content.width
                              var newScaleY = this.height/content.height
                              content.scaleX = newScaleX;
                              content.scaleY = newScaleY;
                              }
                              </Script>
                              <Box id="content" borderStyle="none" width=400 height=300 /> <!-- the width and height are arbitrary -->
                              </Application>

                              Something along the lines of the above should definitely work. I am just basing it off my own previous code. You may have to be careful of borders and padding if you decide to add them. Whether it works better than the other suggestions you'll have to decide.

                              Thanks for the code, and I'll try it. I'm new to Flex, and so I'm still struggling with some things (such as when objects are available for manipulation).