Jump to content
GreenSock

eigenface

layout changes

Recommended Posts

Looks like several new classes have been added to the layout folder, LiquidWrapper has been removed, and much of the code has been rewritten. I'd more or less gotten my head around the old setup and incorporated it into a project I'm currently working on, but I assume the new setup is supposed to be more powerful and/or intuitive. Can you help me understand what the changes entail?

 

Looks like

LiquidStage.pinObject(sprite, LiquidStage.TOP_LEFT)

is now

liquidStage.attach(sprite, liquidStage.TOP_LEFT)

 

But I don't see a parallel for

LiquidStage.stretchObject(sprite, LiquidStage.TOP_LEFT, LiquidStage.TOP_RIGHT, LiquidStage.BOTTOM_LEFT).

How do I achieve the same effect?

 

Also, I had been using a LiquidWrapper like

wrapper = new LiquidWrapper(parent, NaN, NaN, LiquidWrapper.ALIGN_TOP, LiquidWrapper.ALIGN_LEFT)

I assume LiquidArea is the new LiquidWrapper, but the constructor arguments are quite different. How do I achieve the same effect?

 

In general, can you give me some overall advice about what changes were made and why? How should I think about what the new layout classes do, intuitively? For example, previously I could specify several pin points, whereas now it looks like I can only specify one. Conceptually, what's the difference?

Link to comment
Share on other sites

Looks like several new classes have been added to the layout folder, LiquidWrapper has been removed, and much of the code has been rewritten. I'd more or less gotten my head around the old setup and incorporated it into a project I'm currently working on, but I assume the new setup is supposed to be more powerful and/or intuitive. Can you help me understand what the changes entail?

 

Looks like

LiquidStage.pinObject(sprite, LiquidStage.TOP_LEFT)

is now

liquidStage.attach(sprite, liquidStage.TOP_LEFT)

 

But I don't see a parallel for

LiquidStage.stretchObject(sprite, LiquidStage.TOP_LEFT, LiquidStage.TOP_RIGHT, LiquidStage.BOTTOM_LEFT).

How do I achieve the same effect?

 

Also, I had been using a LiquidWrapper like

wrapper = new LiquidWrapper(parent, NaN, NaN, LiquidWrapper.ALIGN_TOP, LiquidWrapper.ALIGN_LEFT)

I assume LiquidArea is the new LiquidWrapper, but the constructor arguments are quite different. How do I achieve the same effect?

 

In general, can you give me some overall advice about what changes were made and why? How should I think about what the new layout classes do, intuitively? For example, previously I could specify several pin points, whereas now it looks like I can only specify one. Conceptually, what's the difference?

 

Glad you asked. One of the key weaknesses of the original LiquidStage was that it didn't adequately accommodate one of the most common requests from users (which I didn't anticipate when I created the original LiquidStage) - they wanted a robust, flexible way to proportionally scale objects within a certain area. For example, they wanted to create a background image that would FILL the entire background proportionally and scale when the browser scaled. LiquidWrapper was a stop-gap measure that made it possible to visually scale things proportionally inside another DisplayObjectContainer, but there were three weaknesses:

 

1) You had to add your objects as children of the LiquidWrapper which meant changing the display list hierarchy (your object's parent had to be the LiquidWrapper).

 

2) You couldn't have the objects scale proportionally to FILL the entire LiquidWrapper so that the excess spilled over outside the bounds. Think of a square background image - if you stretched the browser very wide (and not tall), you'd get gaps on the left and right sides.

 

3) Scaling the LiquidWrapper itself forced the objects to scale in the opposite way to visually remain proportional. For example, if you set the LiquidWrapper's scaleX to 2, the child object's scaleX would become 0.5 to compensate (that's somewhat oversimplified but it's basically what happened). If your code relied on being able to accurately measure your object's size/position, this wasn't ideal.

 

The more I thought about it, the more sense it made to combine the whole "stretchObject()" and LiquidWrapper into a separate class that would serve both purposes (LiquidArea). After all, stretchObject() was essentially asking you to define an area (a main PinPoint for position, another for where to stretch the width, and a third for where to stretch the height). Instead of cramming that all into the LiquidStage class, splitting it out into a LiquidArea class streamlined LiquidStage much better, allowed it to be faster and more lightweight, and even allowed me to create an AutoFitArea class (which LiquidArea extends) that's not tied to LiquidStage at all which can be extremely useful for many users (AutoFitArea is freely available at http://www.greensock.com/autofitarea/). I think once you look at how things are structured in the new version, you'll see why it makes more sense this way (although I'm open to suggestions/input).

 

Another weakness was that LiquidStage only accommodated one stage which is all most people need, but in some AIR projects it's possible to have multiple stages. Plus there was at least one bug in the old version that was tricky to fix because of the way things were engineered, but the new re-engineered code easily avoids that bug. There's a new DynamicPinPoint that lets you base its position on your own custom logic as well (imagine "pin it to the center of the distance between these two DisplayObjects" or something highly customized like that).

 

So the new LiquidStage is faster, more lightweight, more robust and flexible, and it fixes a bug in the previous version.

 

As far as how to think about it intuitively, the main difference is just seeing LiquidStage as something to which you "pin" objects whereas if you need to stretch/scale/resize things, you use LiquidArea. A LiquidArea is just an AutoFitArea that has its upper-left corner and lower-right corners pinned. That way, when the stage resizes, it pulls/pushes the edges of the LiquidArea with it. By default, the LiquidArea's upper left corner is pinned to the upper left corner of the stage and the bottom right corner is pinned to the bottom right corner of the stage but you can use the pinCorners() method to use any PinPoints that you want. And don't miss the static createAround() method in LiquidArea - it's similar to the old stretchObject() in that it allows you to just pass in your DisplayObject reference and it'll automatically create a LiquidArea around that object. Here's how they compare:

 

OLD WAY:

LiquidStage.init(this.stage, 550, 400, 550, 400);
LiquidStage.stretchObject(myObject, LiquidStage.TOP_LEFT, LiquidStage.TOP_RIGHT, LiquidStage.BOTTOM_RIGHT);

 

NEW WAY:

var ls:LiquidStage = new LiquidStage(this.stage, 550, 400, 550, 400);
var area:LiquidArea = LiquidArea.createAround(myObject, ScaleMode.STRETCH);

 

But again, there are a lot of new features you can tap into if you want, like defining different ScaleModes, setting minimum/maximum heights/widths, and even cropping the object with a mask. Another nice thing about LiquidArea is that you can set the "preview" property to true and it'll draw itself on the screen so that you can see it behind any attached objects which makes it easier to visualize and see exactly where the edges are, how your object is scaling inside of it, etc. Full ASDoc documentation is available at http://www.greensock.com/as/docs/tween/ ... stage.html

 

To wrap your head around LiquidArea, I'd highly recommend looking at the interactive demo on

Link to comment
Share on other sites

Thanks for all the explanation. I will definitely give feedback as I continue to work.

 

My first question is, how do I get LiquidStage to work when the swf is embedded in a webpage? The resizing works correctly if I open the swf in the standalone player, but if I use swfobject2 to embed in html, then when I resize the window in Firefox the swf does not resize. Do I need a special scale mode or other settings?

Link to comment
Share on other sites

That's something you handle on the HTML/JS side of things and has nothing to do with LiquidStage. Feel free to check swfobject's documentation for how to make an swf fill the screen. Or view source on the example I put on http://www.greensock.com/liquidstage/.

Link to comment
Share on other sites

I'm having a lot of trouble getting liquid stage to do what I want, even though what I want is very simple. Here is what I'm trying to do:

 

I have an image box. This box should keep the correct aspect ratio, resize when the screen resizes, and keep it's top left point anchored. This code seems to work perfectly for that:

 

imageBoxArea = LiquidArea.createAround(screen.imageBox, ScaleMode.PROPORTIONAL_INSIDE, AlignMode.LEFT, AlignMode.TOP);

 

I have a grey box. This box should stretch to fit the width of the stage, and should also stretch to fit the height of the image box. The grey box should remain anchored at the same y-value, the same y-value as the image box. In other words, the grey box forms a horizontal stripe behind the image box.

 

It seems like what I want to do is put the grey box in a LiquidArea, and then something like horizontalScaleMode = STRETCH, verticalScaleMode = PROPORTIONAL_INSIDE, but of course liquid stage doesn't work that way. How does it work?

Link to comment
Share on other sites

It would be a very simple thing to do if you didn't need for the height of your gray box to be conditional on the height of your other image that's scaling proportionally. Actually, it's not that difficult anyway. If I understand your goal correctly, all you'd need to do is create a LiquidArea around your gray bar with its ScaleMode as WIDTH_ONLY and then set up a listener to set its height manually according to your image's height. Kinda like:

 

imageBoxArea = LiquidArea.createAround(screen.imageBox, ScaleMode.PROPORTIONAL_INSIDE, AlignMode.LEFT, AlignMode.TOP);
grayBoxArea = LiquidArea.createAround(screen.grayBox, ScaleMode.WIDTH_ONLY, AlignMode.LEFT, AlignMode.TOP);
imageBoxArea.addEventListener(Event.CHANGE, adjustGrayHeight);
function adjustGrayHeight(event:Event):void {
   screen.grayBox.height = screen.imageBox.height;
}

 

Here's another alternative: you could use a DynamicPinPoint that you pin the BOTTOM_RIGHT corner of your grayBoxArea with. That DynamicPinPoint would report its position based on the imageBox's height/position and the stage size, but frankly I think the previous solution is simpler.

Link to comment
Share on other sites

  • 3 months later...

Hi,

 

i dont´t now if i understand the handling of the layout manager right, but i have the following problem.

I hope it´s not getting to overcomplicated, because of my english :-)

 

I created a navigation layer which visual borders are 340px width and 1078px height.

That navigation is integrated inside a page which is 1920px width and 1078px height.

I created a transparent layer inside the navigation which has the same size as the root page, so that the navigation layer scales with the right proportions inside the liquid stage object (also 1920 x 1078). That solution work for me but i don´t know if it´s the best way.

Maybe i did something wrong :-)

 

But here is my real problem...

I want to get the real x position of a liquid area which is attached inside my scaleable navigation.

 

Because that the real borders of the navigation are 1920px x 1078px instead of 340 x 1078, i created a liquid area on stage which behaves like the navigation with that code -> refNavPage = new LiquidArea(refToMyNavigationLayerFromAbove, 340, 0, 340, 100, 0x313f19);

So the scaling is like the exact same way as with my navigation, it starts at 340px inside my PageMc and the alignment is like it should be.

Everytime when i try to catch the x position of that movie i get back only 340px, but because of the scaling to a smaller size i wanted to get back the real global position like 260 or something else, to attach another movie of a different level to that scaled x position. I think my problem is to understand how to use your PinPoint Class the right way.

I tried it with Adobes Point Class but it also doesn´t work for me.

 

Maybe you have a little hint for me.

 

Regards

 

Peter

Link to comment
Share on other sites

If you're trying to translate a Point's coordinates from a local scope to a global one, you can use the Point's localToGlobal() method. And to translate it back to any other clip's local coordinate system, you use globalToLocal(). See Adobe's docs for specifics.

Link to comment
Share on other sites

Create an account or sign in to comment

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

Create an account

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

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×