Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
Guest mcc36

Horizontal Contrained Scaling & Flipping Problem

Recommended Posts

I'm using the latest release of TransformManager AS3 with constrained proportional scaling enabled. I'm having two issues currently. The first is that setting minScaleX and minScaleY don't seem to be having any effect for me (with or without bounds being set). The object remains flippable to a negative scale no matter what. Looking at the code, I think that MatrixTools.getScaleX() and MatrixTools.getScaleY() may be returning positive values in some cases where they should be negative.

 

My second issue is this: If I do allow flipping, if I scale down from one of the horizontal handles (the handles on the left and right at the vertical center of the TransformItem), when the image is mirrored, the y-scale is also inverted. Both axes are similarly affected when I scale using the vertical handles. Even if the scaling is proportional, I would expect the horizontal handles to cause the image to mirror across the x-axis, and the y-axis scaling to be encased in a Math.abs() so as to remain upright. Does TransformManager know which handle is being used for the transform? Is there some way I can override this so that the image doesn't end up inverted on both axes?

 

Thanks in advance for your help, and for your continued work on improving this great tool.

 

-Matt

Link to comment
Share on other sites

Any chance you could post (or send me) a simple example of the problem? That always makes troubleshooting much more efficient. One or two other users have mentioned something similar and it turned out their code was incorrect (not that yours is - I'm just saying that was the case with the other users).

Link to comment
Share on other sites

Thanks for the quick reply. I'll post a simple example of the first issue (minScale not restricting) as soon as I get a few minutes to whip things up. As for the second issue, this can easily be seen by going to the TransformManager AS3 homepage: On your live demo, check "Force proportional scale" and then scale a object across a single axis (that is, any handle except those at the corners). The image will invert on both axes instead of just one. This does not occur in unconstrained transformations.

 

Again, thanks for your help with this. I will definitely create a clean-room test case for my minScale problem to try and figure out what's causing it. In the meantime, a fix for the above (or advice on how you'd tackle it so I can make an emergency patch for now) would be great.

 

-Matt

Link to comment
Share on other sites

The 2nd issue is actually working properly - forcing a proportional scale basically means that you scale both axis the same amount all the time. So if you scale on the x-axis, the y-axis gets scaled by the same amount too, etc. So if you flip into the negative scaleX direction, scaleY would also get flipped negatively. See what I mean?

Link to comment
Share on other sites

Thanks again for your quick feedback. We were really hoping to have this operate similar to the interactive scaling in the Flash IDE and Photoshop. How would you suggest we achieve this behavior? Our main concern is that, as it stands, there doesn't seem to be any way to mirror an object across a single axis (using the handles on the object itself, not a call to flipSelectedHorizontal, etc.) with constrained scaling enabled. Any advice would be very much appreciated. Thanks.

 

-Matt

Link to comment
Share on other sites

  • 8 months later...

I think i've got a fix for this after creating a sub-class of TransformManager, and exposing some of the private properties, and one private method by changing their access modifier to protected..

 

Here's the props i needed to change from private to protected to subClass the TransformManager.as class:

 

Props:

protected var _selConstrainScale:Boolean;

protected var _bounds:Rectangle;

protected var _parent:DisplayObjectContainer;

protected var _origin:Point;

protected var _trackingInfo:Object;

protected var _prevScaleX:Number = 0;

protected var _prevScaleY:Number = 0;

 

Method:

protected function updateScale($x:Boolean = true, $y:Boolean = true):void

 

Here's my sub-class that will constrain proportions, and allow flipping.

package com.greensock.transform
{
import flash.ui.Keyboard;

public class CustomTransformManager extends TransformManager
{
	public function CustomTransformManager($vars:Object=null)
	{
		super($vars);
	}

	override protected function updateScale($x:Boolean = true, $y:Boolean = true):void
	{
		var ti:Object = _trackingInfo; //to speed things up
		var mx:Number = _parent.mouseX - ti.mouseOffsetX, my:Number = _parent.mouseY - ti.mouseOffsetY;

		if (_bounds != null) {
			if (mx >= _bounds.right) {
				mx = _bounds.right - 0.02;
			} else if (mx <= _bounds.left) {
				mx = _bounds.left + 0.02;
			}
			if (my >= _bounds.bottom) {
				my = _bounds.bottom - 0.02;
			} else if (my <= _bounds.top) {
				my = _bounds.top + 0.02;
			}
		}

		var dx:Number = mx - _origin.x; //Distance from mouse to origin (x)
		var dy:Number = _origin.y - my; //Distance from mouse to origin (y)
		var d:Number = Math.sqrt(dx * dx + dy * dy); //Distance from mouse to origin (total).
		var angleToMouse:Number = Math.atan2(dy, dx);
		var constrain:Boolean = (_selConstrainScale || isKeyDown(Keyboard.SHIFT));
		var newScaleX:Number, newScaleY:Number, xFactor:Number, yFactor:Number;
		if (constrain) {
			var angleDif:Number = (angleToMouse - ti.angleToMouse + Math.PI * 3.5) % (Math.PI * 2);

			var xDelta:Number = ( dx > 0 ? dx : -( dx ) );
			var yDelta:Number = ( dy > 0 ? dy : -( dy ) );
			var changeAxis:String = xDelta > yDelta ? "x" : "y";

			if ( angleDif < Math.PI )
			{
				d *= -1; //flip it when necessary to make the scaleX & scaleY negative.
			}

			switch ( changeAxis )
			{
				case "x":

					if ( d < 0 )
					{
						newScaleX = d * ti.scaleRatioXConst;
						newScaleY = -(d) * ti.scaleRatioYConst;

					} else
					{
						newScaleX = d * ti.scaleRatioXConst;
						newScaleY = d * ti.scaleRatioYConst;
					}


				break;

				case "y":
					if ( d < 0 )
					{
						newScaleX = -(d) * ti.scaleRatioXConst;
						newScaleY = d * ti.scaleRatioYConst;

					} else
					{
						newScaleX = d * ti.scaleRatioXConst;
						newScaleY = d * ti.scaleRatioYConst;
					}
				break;
			}

		} else
		{
			angleToMouse += ti.angle;
			newScaleX = ti.scaleRatioX * Math.cos(angleToMouse) * d;
			newScaleY = ti.scaleRatioY * Math.sin(angleToMouse) * d;
		}

		if (($x || constrain) && (newScaleX > 0.001 || newScaleX < -0.001)) {
			xFactor = newScaleX / _prevScaleX;
		} else {
			xFactor = 1;
		}
		if (($y || constrain) && (newScaleY > 0.001 || newScaleY < -0.001)) {
			yFactor = newScaleY / _prevScaleY;
		} else {
			yFactor = 1;
		}

		scaleSelection(xFactor, yFactor);
	}
}
}

 

Ideally a new version of the TransformManager would have a constrainProportions prop, and a allowFlip prop to get around this grafted on possible solution.

Link to comment
Share on other sites

  • 6 months later...

If anyone decides to use eketch's solution, make sure you also set each TransformItem's constrainScale prop to false (TransformManager.constrainScale should be set to true, or SHIFT key held, of course)

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