TransformManager (AS3) - Interactively Scale/Rotate/Move DisplayObjects
- Compatibility: Flash Player 9 and later (ActionScript 3.0)
DESCRIPTION
TransformManager makes it easy to add interactive scaling/rotating/moving of DisplayObjects to your Flash application. It uses an intuitive interface that's similar to most modern drawing applications. When the user clicks on a managed DisplayObject, a selection box will be drawn around it along with 8 handles for scaling/rotating. When the mouse is placed just outside of any of the scaling handles, the cursor will change to indicate that they're in rotation mode. Just like most other applications, the user can hold down the SHIFT key to select multiple items, to constrain scaling proportions, or to limit the rotation to 45 degree increments.
FEATURES
- (NEW!) Select multiple items and scale/rotate/move them all simultaneously.
- (NEW!) Includes a "FlexTransformManager" class that makes it simple to integrate into Flex applications.
- (NEW!) Optionally control everything (transformations, selections, etc.) through code.
- (NEW!) 4 extra handles for a total of 8
- (NEW!) Depth management which allows you to programmatically push the selected items forward or backward in the stacking order
- (NEW!) Optionally set minScaleX, maxScaleX, minScaleY, and maxScaleY properties on each item
- (NEW!) Arrow keys move the selection (optional)
- Define bounds within which the DisplayObjects must stay, and TransformManager will not let the user scale/rotate/move them beyond those bounds
- Automatically bring the selected item(s) to the front in the stacking order (optional)
- The DELETE and BACKSPACE keys can be used to delete the selected DisplayObjects (optional)
- Lock certain kinds of transformations like rotation, scale, and/or movement (optional)
- Lock the proportions of the DisplayObjects so that users cannot distort them when scaling
- Scale from the DisplayObject's center or from its corners
- Listen for Events like scale, move, rotate, select, deselect, click off, delete, depth change, and destroy
- Set the selection box line color and handle thickness
- Cursor will automatically change to indicate scale or rotation mode
- VERY easy to use. In fact, all it takes is one line of code to get it up and running with the default settings.
NOTES / LIMITATIONS
- All DisplayObjects that are managed by a particular TransformManager instance must have the same parent (you can create multiple TransformManager instances if you want)
- TextFields cannot be flipped (have negative scales).
- TextFields cannot be skewed. Therefore, when a TextField is part of a multi-selection, scaling will be disabled because it could skew the TextField (imagine if a TextField is at a 45 degree angle, and then you selected another item and scaled vertically - your TextField would end up getting skewed).
- Due to several bugs in the Flex framework (acknowledged by Adobe), TransformManager cannot accommodate scrollbars in its container, nor can TextFields be scaled disproportionately and scaleX/scaleY/width/height properties don't always report properly after updates are made with TransformManager (again, these are bugs in the Flex framework, NOT TransformManager). However, I created a "FlexTransformManager" class that extends Canvas and makes it easy to integrate into Flex applications. Just beware that the DisplayObjects in the FlexTransformManager will be contained within the bounds of the FlexTransformManager. Also non-native TextFields (like Labels) are treated as regular DisplayObjects meaning they'll scale/stretch.
- Due to a limitation in the way Flash reports bounds, items that are extremely close or exactly on top of a boundary (if you define bounds) will be moved about 0.1 pixel away from the boundary when you select them. If an item fills the width and/or height of the bounds, it will be scaled down very slightly (about 0.2 pixels total) to move it away from the bounds and allow accurate collision detection.
|
As always, there's a 30-day money-back guarantee included. If you don't like the class and would prefer to forfeit your license and get a refund within 30 days, no problem.
Other links: Forums | AS2 version (NOT identical feature set) | License
IMPORTANT PROPERTIES
- constrainScale : Boolean To constrain items to only scaling proportionally, set this to true [default:false]
- scaleFromCenter : Boolean To force all items to use the center of the selection as the origin for scaling, set this to true [default:false]
- lockScale : Boolean Prevents scaling [default:false]
- lockRotation : Boolean Prevents rotating [default:false]
- lockPosition : Boolean Prevents moving [default:false]
- arrowKeysMove : Boolean When true, the arrow keys on the keyboard move the selected items when pressed [default: false]
- autoDeselect : Boolean When the user clicks anywhere OTHER than on one of the TransformItems, all are deselected [default:true]
- allowDelete : Boolean When the user presses the delete (or backspace) key, the selected item(s) will be deleted (except TextFields) [default:false]
- allowMultiSelect : Boolean To prevent users from being able to select multiple items, set this to false [default:true]
- bounds : Rectangle Defines the boundaries for movement/scaling/rotation. [default:null]
- lineColor : Number Controls the line color of the selection box and handles [default:0x3399FF]
- handleSize : Number Controls the handle size (in pixels) [default:8]
- handleFillColor : Number Controls the fill color of the handle [default:0xFFFFFF]
- paddingForRotation : Number Sets the amount of space outside each of the four corner scale handles that will trigger rotation mode [default:12]
- enabled : Boolean Allows you to enable or disable the TransformManager [default:true]
- forceSelectionToFront : Boolean When true, new selections are forced to the front of the display list of the container DisplayObjectContainer [default:false]
- selectedTargetObjects : Array An easy way to get an Array of all selected targetObjects
- selectedItems : Array Similar to selectedTargetObjects, but returns the TransformItem and TransformItemTF instances of the selected items
- items : Array All of the TransformItem and TransformItemTF instances that are controlled by this TransformManager (regardless of whether they're selected or not)
- targetObjects : Array All of the targetObjects (DisplayObjects) that are controlled by this TransformManager (regardless of whether they're selected or not)
- ignoredObjects : Array Sometimes you want TransformManager to ignore clicks on certain DisplayObjects, like buttons, color pickers, etc. Those items should populate the ignoreObjects Array. The DisplayObject CANNOT be a child of a targetObject.
TRANSFORMMANAGER EVENTS
- TransformEvent.SELECTION_CHANGE (to determine which items are selected, check the TransformEvent's items Array. If the Array is empty, it obviously means all items have been deselected)
- TransformEvent.MOVE
- TransformEvent.SCALE
- TransformEvent.ROTATE
- TransformEvent.CLICK_OFF (only called when autoDeselect is false, otherwise the DESELECT event is called)
- TransformEvent.DELETE
- TransformEvent.DEPTH_CHANGE
- TransformEvent.DESTROY
All TransformEvents have an "items" property which is an Array populated by the affected TransformItem instances. TransformEvents also have a "mouseEvent" property that will be populated if there was an associted MouseEvent (like CLICK_OFF)
TRANSFORMITEM EVENTS
Every targetObject gets associated with a unique TransformItem instance (TransformManager creates them for you). If you prefer to listen for a particular TransformItem's events, you can do so. For example, maybe you want to know when a particular item is selected. To find the targetObject's TransformItem instance, you can use the TransformManager.getItem() method.
- TransformEvent.SELECT
- TransformEvent.DESELECT
- TransformEvent.MOVE
- TransformEvent.SCALE
- TransformEvent.ROTATE
- TransformEvent.DELETE
- TransformEvent.DESTROY
USAGE
- Description:Constructor.
- Parameters:
- vars : Object (optional) An Object containing the properties you'd like to set. See the list of "IMPORTANT PROPERTIES" above for options. An example would be:
-
var manager:TransformManager = new TransformManager({constrainScale:true, forceSelectionToFront:true, bounds:new Rectangle(0, 0, 500, 400)});
-
- vars : Object (optional) An Object containing the properties you'd like to set. See the list of "IMPORTANT PROPERTIES" above for options. An example would be:
- Description: Adds a DisplayObject to the TransformManager so that it can be interactively transformed.
- Parameters:
- targetObject : DisplayObject Target DisplayObject
- Description: Same as addItem() but accepts an Array containing multiple DisplayObjects. (retuns an Array of corresponding TransformItems that are created)
- Parameters:
- targetObjects : Array An Array of target DisplayObjects
- Description: Removes an item. Calling this on an item will NOT delete the DisplayObject - it just prevents it from being transformable by this TransformManager anymore.
- Parameters:
- item : * Either the DisplayObject or the TransformItem that you'd like to remove from the TransformManager.
- Description: Removes all items. This does NOT delete the DisplayObjects - it just prevents them from being transformable by this TransformManager anymore.
- Description: A quick way to select an item. You may pass in the item's TransformItem or the DisplayObject (targetObject).
- Parameters:
- item : * Either the DisplayObject or the TransformItem that you'd like to remove from the TransformManager.
- addToSelection : Boolean By default, selecting an item replaces the current selection. If you prefer to ADD to the current selection, set this value to true.
- Description: Same as selectItem() but accepts an Array of TransformItems (or DisplayObjects) so that you can select more than one at a time.
- Parameters:
- items : Array Either the DisplayObject or the TransformItem that you'd like to remove from the TransformManager.
- addToSelection : Boolean By default, selecting an item replaces the current selection. If you prefer to ADD to the current selection, set this value to true.
- Description: Deselects all items
- Description: Deletes any items that are selected.
- Description: An easy way to find the TransformItem that's associated with a particular DisplayObject (if one has been created)
- Parameters:
- targetObject : DisplayObject The DisplayObject that's associated with the TransformItem you're looking for.
- Description: Scales the selected items.
- Parameters:
- sx : Number Multiplier in the x direction
- sy : Number Multiplier in the y direction
- Description: Moves the selected items. x and y are pixel measurements in the x and y directions respectively
- Parameters:
- x : Number Number of pixels to move in the x direction
- y : Number Number of pixels to move in the y direction
- Description: Rotates the selected items. Angle is in radians, not degrees.
- Parameters:
- angle : Number Angle (in radians) to rotate
- Description: Redraws the selection around the selected items which can be useful if the items changed sizes/positions.
- Description: Moves each of the selected items down one in z order (stacking order).
- Description: Moves each of the selected items up one in z order (stacking order).
- Description: Returns the center point of the current selection
- Description: Returns the bounds of the current selection (not including the handles)
- Description: Returns the bounds of the current selection including the handles
- Description: Allows you to have TransformManager ignore clicks on a particular DisplayObject (handy for buttons, color pickers, etc.). The DisplayObject CANNOT be a child of a targetObject.
- Parameters:
- object : DisplayObject The DisplayObject that TransformManager should ignore
- Description: Remove a DisplayObject from the list of ignoredObjects.
- Parameters:
- object : DisplayObject The DisplayObject that should be removed from the list of objects that TransformManager ignores.
- Description: Deselects everything and destroys the TransformManager. This does NOT delete the associated targetObjects.
EXAMPLES
-
import gs.transform.TransformManager;
-
var manager:TransformManager = new TransformManager({targetObjects:[myClip1, myClip2]});
-
import gs.transform.TransformManager;
-
import gs.events.TransformEvent;
-
-
var manager:TransformManager = new TransformManager({targetObjects:[myClip1, myClip2], constrainScale:true, lockRotation:true, allowDelete:true, autoDeselect:true});
-
manager.addEventListener(TransformEvent.SCALE, onScale);
-
function onScale($e:TransformEvent):void {
-
trace("Scaled " + $e.items.length + " items");
-
}
-
import gs.transform.TransformManager;
-
import gs.events.TransformEvent;
-
-
var manager:TransformManager = new TransformManager();
-
-
var clip1Item:TransformItem = manager.addItem(myClip1);
-
var clip2Item:TransformItem = manager.addItem(myClip2);
-
clip2Item.setScaleConstraints(0.5, 1, 0.5, 1);
-
-
clip1Item.addEventListener(TransformEvent.SELECT, onSelectClip1);
-
-
function onSelectClip1($e:TransformEvent):void {
-
trace("selected myClip1");
-
}
FLEX EXAMPLE
-
<?xml version="1.0" encoding="utf-8"?>
-
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:transform="gs.transform.*">
-
<transform:FlexTransformManager id="myManager" width="500" height="500">
-
<mx:Image source="../libs/image1.png" id="myImage1" autoLoad="true" x="100" y="100" />
-
<mx:Image source="../libs/image2.png" id="myImage2" autoLoad="true" x="0" y="300" />
-
</transform:FlexTransformManager>
-
</mx:Application>
TIP
- I want autoDeselect on, but I don't want items deselected when the user clicks on certain buttons or form elements. How can I accomplish that?
You have several options. You could have TransformManager ignore particular DisplayObjects using the addIgnoredObject() method, or try this:- Set autoDeselect to false
- Add a background Sprite (it could have a transparent fill so that it's invisible but still clickable)
- Add an Event.CLICK listener to that background Sprite that calls your TransformManager’s deselectAll() function.
FAQ
- Why do you charge for the code? Why not go open source like you did with TweenLite/TweenFilterLite/TweenMax?
I've learned the hard way that it takes a LOT of work to create, enhance, document, distribute, and support open source code. The vast majority of visitors to my blog just take the code and run. It becomes difficult to justify all the time I invest in the open source stuff. TransformManager caters to a very specific audience, and I think that $299 is actually quite a bargain considering the fact that it represents well over $15,000 worth of my time. The current AS2 version is still free, but it is missing many of the features included in the AS3 version. - If I purchase TransformManager, do I get access to the raw source code files or just a SWC?
You get the raw source code. Feel free to tweak it if you want, (just don't redistribute it). - What if I purchase TransformManager but don't like it? Can I get my money back?
Of course. I always offer a 30-day money-back guarantee. If you'd like to forfeit your license and get your money back, just e-mail me and I'll promptly send you the refund. - Do you offer discounted pricing for charitable/educational projects?
Yes I do, depending on the project. Feel free to contact me about your request at info@greensock.com. - What are the terms of the license? Is there a multi-user/corporate license available?
Currently, the single user license is available for immediate purchase on this site. However, multi-user licenses are available for corporations. Please e-mail me at info@greensock.com for details. Please be sure to read the license agreement before purchasing TransformManager. - Can I use TransformManager to transform dynamically-loaded assets?
Absolutely. Just load your asset, make sure it is fully instantiated, and then use the addItem() method to add it to your TransformManager instance. Keep in mind that all of a TransformManager's items must share the same parent. - Can I use TransformManager in Flex 3?
Sure! In fact, I created a FlexTransformManager class to make it particularly easy to integrate into Flex applications. Please be aware of the limitations, though (see above). Also, Flex is not my specialty, so I have not been able to perform extensive testing inside Flex, but several developers are using it successfully in Flex 3. - I'm a "Shockingly Green" Club GreenSock member, so do I get a discount?
Yes you do. "Shockingly Green" Club GreenSock members get a 15% discount. If you haven't received instructions from me yet about how to receive your discount, just e-mail me and I'll send you a special link.
Need Help?
Feel free to e-mail me a question. Or post your question on the forums. I'd highly recommend joining Club GreenSock to get prioritized access to my time in answering your question, and get some free ActionScript classes. When you e-mail your question, please include a simplified FLA file (and any class files) that clearly demonstrates the problem and provide a brief explanation.
|
on August 22nd, 2008 at 11:44 am
Kevin Hoyt from Adobe talks about his experience with TransformManager here:
http://blog.kevinhoyt.org/2008/08/13/greensock-transform-manager-as3/
As does Matt Przybylski:
http://evolve.reintroducing.com/2008/10/02/as3/my-as3-transformmanager-experience/
And Erik Hallander:
http://www.erikhallander.com/blog/2008/greensock-releases-transformmanager-a-spectacular-as3-class.html
on September 23rd, 2008 at 10:56 am
Hey,
Just want to add a little support here. I think for a lot of developers your offering us a short cut for a very fair price. I haven’t bought it yet, however i make good use of your TweenLite and more recently TweenMax open source projects. Its not that we can’t write it ourselves but you’ve done an excellent job with it i on’t see why i should re invent the wheel. The above looks very powerful, when i need a decent transform suite i’l likely be back to pay for it but for now just leaving this as my thanks. Don’t want to be one of ‘those’ developers who take the code and run…. i was…. but now im not? :)
Kevin At Twisted
on November 15th, 2008 at 8:18 am
Jack,
As always I am blown away by your work.
Contributions by people like yourself to the state of this art we call ActionScripting push the boundaries of the field without a doubt.
Maximum kudos, man.