Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
thehat

Centering LiquidArea

Recommended Posts

I'm trying to build an image viewer that behaves similar to a classic lightbox implementation using LiquidArea. The basic setup is a previos next and close button with an image, where the previous and next are centered relative to the height of the image, and anchored to either side, and the close button is top center. The idea is that when the stage is less than 1280 wide, the area will scale, maintaining the ratio of the image and repositioning but not not scaling the buttons. That much works fine on the horizontal plane at least. When the stage is wider than 1280, the area should stop scaling the image and instead the whole thing should stay in the center of the screen. The problems:


  • [*:91od1k5r]Upon reaching the max width, the area stays anchored to the top left.
    [*:91od1k5r]Because my chosen maximum height is much smaller than the LiquidStage minimum height the controls don't reposition vertically as the image scales.

 

To fix the first problem I've tried to repin the area when the stage goes above a certain size, but just repinning to top center causes the content to jump and I'm struggling to figure out how to offset that.

 

Here's the code so far, can you suggest how I might do this?

 

BASESIZEWIDTH = 960;

BASESIZEHEIGHT = 918

 

public class ScreenshotLargeDisplay extends MovieClip
{
//- PRIVATE & PROTECTED VARIABLES -------------------------------------------------------------------------

	protected var ls				:LiquidStage;
	protected var la				:LiquidArea;

	protected var _margin			:int = 30;
	protected var _maxScreenWidth	:int = 1280;
	protected var _maxScreenHeight	:int = 720;

	protected var _singleMode		:Boolean;

//- PUBLIC & INTERNAL VARIABLES ---------------------------------------------------------------------------

	public var m_imageHolder		:MovieClip;
	public var mc_loader			:MovieClip;

	public var m_close				:simpleButton;
	public var m_next				:simpleButton;
	public var m_previous			:simpleButton;


//- CONSTRUCTOR	-------------------------------------------------------------------------------------------

	public function ScreenshotLargeDisplay():void
	{
		ls = LiquidStage.defaultStage;
		la = new LiquidArea(this,(0-(applicationSettings.BASESIZEWIDTH/2))+_margin,30,applicationSettings.BASESIZEWIDTH-(_margin*2),applicationSettings.BASESIZEHEIGHT-(_margin*2),0xFF0000,applicationSettings.BASESIZEWIDTH-(_margin*2),applicationSettings.BASESIZEHEIGHT-(_margin*2),_maxScreenWidth,_maxScreenHeight);
		la.preview = true;
	}

//- PRIVATE & PROTECTED METHODS ---------------------------------------------------------------------------

	protected function prepareButtons():void
	{

		la.attach(m_close,ScaleMode.NONE,AlignMode.CENTER,AlignMode.TOP);
		la.attach(m_next,ScaleMode.NONE,AlignMode.RIGHT,AlignMode.CENTER);
		la.attach(m_previous,ScaleMode.NONE,AlignMode.LEFT,AlignMode.CENTER);

	}

//- PUBLIC & INTERNAL METHODS -----------------------------------------------------------------------------

	public function init():void
	{
		this.stage.addEventListener(Event.RESIZE,onStageResize);
		prepareButtons();
	}


	public function addScreenshot(img:DisplayObject):void
	{
		this.addChildAt(img,0);
		la.attach(img,ScaleMode.PROPORTIONAL_INSIDE,AlignMode.CENTER,AlignMode.TOP);
	}

//- EVENT HANDLERS ----------------------------------------------------------------------------------------

	protected function onStageResize(evt:Event):void
	{
		trace(ls.stageBox.width+(_margin*2));
		if(ls.stageBox.width > _maxScreenWidth) {
			la.pinCorners(new PinPoint((applicationSettings.BASESIZEWIDTH/2)-((_maxScreenWidth-applicationSettings.BASESIZEWIDTH)/2),0,ls.stageBox,ls), ls.BOTTOM_RIGHT);
			//la.pinCorners(ls.TOP_CENTER, ls.RIGHT_CENTER);
		} else {
			la.pinCorners(ls.TOP_LEFT, ls.BOTTOM_RIGHT);
		}
	}
    }

Link to comment
Share on other sites

It'd be swell if you posted an example that gave us a better way to visualize what you're talking about.

 

You're using a pretty complex set of rules for your LiquidArea pinning - you should use DynamicPinPoints for stuff that complex & specific. A DynamicPinPoint basically allows you to link your own custom function with a PinPoint so that its x/y position are dynamically determined by whatever criteria/logic you want. Your function simply has to return a Point that has x/y properties reflecting the new local position. You could use DynamicPionPoints for your LiquidArea as well as for your PinPoints that define where your buttons go.

Link to comment
Share on other sites

Thanks for the reply. You're right, it is absurdly complicated. I think I'd been chasing a solution for a little too long!

 

I realised last night that this probably isn't the best direction to go in anyway. The site we're building is a full screen flash site that uses SWFFit to ensure the minimum height of the SWF is 918px. This class is supposed to display large images that fill the screen up to their native resolution and then become centered as the viewport increases in size. This means that I can't use the stageBox for the vertical sizing because it never gets small enough. I'm now going to look into SWFFit to take my viewport dimensions from there instead, and then hopefully dynamic pin points will be able to use those values.

 

Edit: as an example, this is an earlier version of the same idea that only uses liquidStage. I'm trying to improve this because you can see the controls aren't always positioned perfectly and the image is verticaly centered to the SWF, not the viewport. http://www.finalfantasy13game.com/#/uk/media/screenshots/3

Link to comment
Share on other sites

So I'm trying to get DynamicPinPoints working before I start messing around with getting any values from JavaScript. Problem is they don't seem to be working (or more likely I'm using them wrong!). I've ditched my onStageResize function and so now the constructor looks like this:

public function ScreenshotLargeDisplay():void
{
	ls = LiquidStage.defaultStage;
	la = new LiquidArea(this,(0-(applicationSettings.BASESIZEWIDTH/2))+_margin,_margin,applicationSettings.BASESIZEWIDTH-(_margin*2),applicationSettings.BASESIZEHEIGHT-(_margin*2),0xFF0000,applicationSettings.BASESIZEWIDTH-(_margin*2),applicationSettings.BASESIZEHEIGHT-(_margin*2),_maxScreenWidth,_maxScreenHeight,false);
	var point1:DynamicPinPoint = new DynamicPinPoint(this,getTopLeft);
	var point2:DynamicPinPoint = new DynamicPinPoint(this,getBottomRight);
	la.pinCorners(point1,point2);
	la.preview = true;
}

And these are my getter functions:

public function getTopLeft():Point
{
	var temp:Point =  new Point(0,_margin);
	if(ls.stageBox.width > _maxScreenWidth+(_margin*2)) {
		//handle oversize screen
	} else {
		temp.x = (0-(applicationSettings.BASESIZEWIDTH/2))+_margin;
	}
	return temp;
}

public function getBottomRight():Point
{
	var temp:Point =  new Point(0,_maxScreenHeight+(_margin*2));
	if(ls.stageBox.width > _maxScreenWidth+(_margin*2)) {
		//handle oversize screen
	} else {
		temp.x = applicationSettings.BASESIZEWIDTH/2;
	}
	return temp;
}

 

As you can see, I'm not bothered about the larger screen sizes yet, just trying to get it working as the image scales up to its maximum width of 1280 plus a 30px margin on either side. However all I get is an error from LiquidArea suggesting that it doesn't like my DynamicPinPoints.

 

TypeError: Error #1009: Cannot access a property or method of a null object reference.

at com.greensock.layout::LiquidArea/pinCorners()

at com.biff.components.screenshots.v2::ScreenshotLargeDisplay()

Link to comment
Share on other sites

Aha, I see the cause of the error - you set the autoPinCorners parameter of your LiquidArea to false which prevented it from figuring out which LiquidStage was associated with it - I needed to add one condition to the pinCorners() method to eliminate that error. I'll post an update shortly but in the mean time, all you need to do is remove that last parameter of your LiquidArea (or set it to true). Sorry about the confusion.

Link to comment
Share on other sites

I see, I'd assumed that if I was going to set them myself there was no point in the area doing it itself first. I've actually switched to using an AutoFitArea and one pinpoint for the time being as the project needed to be submitted, but I'll revisit this at some point. Thanks for your help!

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.
×