Zooming
in Flash & Flex
Have you ever tried to implement zooming that works like Google Maps where you can use your mouse wheel to zoom to a particular point on the map?
Well, I did and it took me quite some time to get zooming to work like that. Typically, in Flash or Flex, if you scale an object it uses the upper left corner as reference point and this can lead to akward results like the ones in the following example:
Example: Zooming Broken
To zoom, use your mouse wheel or the arrow keys on your Keyboard, especially if you're on a Mac where Flash Player is (still) missing mouse wheel support.
To rotate the object, press and hold theAltkey while scrolling.
Panning works with drag and drop or, again, with the arrow keys on your keyboard.
Basically, any transformation that you apply to a DisplayObject has its origin at the object's registration point. The registration point of an object is typically the upper left corner and cannot be changed directly in ActionScript.
While working on tandem, I tried to implement the behavior that normal mapping applications have where you can zoom to the coordinates your mouse points at by scrolling. Oh my, how long it took me. To work around the issue, I nested two Sprites and moved the inner object in such a way that the registration point of the outer one was at the coordinates of the mouse. This way to dynamically change the registration point was a hack at best.
However, the revelation came soon: zooming (or scaling) is a linear transformation. This means I can scale an object and readjust its position afterwards so that it appears as if it has never moved but rather scaled right from the origin I pointed at.
At this point I successfully wrote a function to scale from an arbitrary point on an object. This code was not too long, actually pretty sweet after all my previous, fruitless endeavours. But yesterday, after looking at the source code of Piccolo, a powerful framework for building Zoomable User Interfaces (ZUI) in Java or C#, I came across an even more elegant solution:
AffineTransform is the name of the class where the magic lies in Java.
What Are Affine Transformations?
Affine transformations are part of the mathematics of linear algebra. Simply put, they are a way to mathematically describe transformations such as scale, rotation, skew and translation. An interesting property of affine transformations is that they preserve the straightness of lines while transforming, so that parallel lines stay parallel.
I won't go into deeper discussion of this topic at this point but if you have time, I recommend you to read the theory behind affine transformations and linear algebra in general. Before this enlightening experience I am about to share here, linear algebra and I were not very close. I took a linear algebra course in first semester computer science but unfortunately the professors never got around using 2D or 3D as basis for their examples which would have been great. They didn't do it because it seemed that they only got excited about n-dimensional vector spaces where n > 5. Too bad.
Affine Transformations & Flash
When I made my discovery in the source code of Piccolo, I was about to port the Java AffineTransform class to ActionScript. Then I discovered that ActionScript had a similar class called Matrix.
Basically, any visible object in Flash has a transformation attached to it which can be accessed through a property called transform. What you'll get is a Transform object that gives you, through its matrix property, access to the transformation matrix of a DisplayObject.
Usually, we change the appearance of a Sprite or MovieClip (both inherit from DisplayObject) through properties such as x, y, width, height, scaleX, scaleY or rotation. These properties can be seen as a high-level abstraction of the underlying transformation matrix of a DisplayObject.
Basically, if you need more low-level access, for example to implement zooming or rotating around a particular point, use the Transform and Matrix class.
Enough theory, let's see how it's done.
Example: Zooming Done Right
Code Walk-Trough
Let us go step by step through the code of the example class called
ZoomCanvasthat you'll find in the source of the example above.Let's say you have an object you want to scale at a certain point.
First, you get its transformationMatrix:
44affineTransform = transform.matrixThen you move the object to the origin of the point you want to scale from:
49 affineTransform.translate( -originX, -originY )After that, you are safe to scale the object:
52 affineTransform.scale( scale, scale )Then, you simply move the object back to its original position:
55 affineTransform.translate( originX, originY )In the end, you apply the new transformation to the object
59transform.matrix = affineTransform
Since I love clear and simple code, I was very pleased with the result.
From my observations this method for transforming an object seems at least as fast as the conventional way of doing it.
I hope this helps you as much as it did help me.
Further Reading
- Senocular.com: Understanding the Transformation Matrix in Flash
- ActionScript Documentation:
Matrixclass - Piccolo: Geometric Transformations
- Piccolo: Download Source
- Lawrence Kesteloot: Homogeneous Coordinates



06.02.2008
10:44
If you had been in my Linear Algebra HS2007 lessons, you would have known this before fiddling around with it.

A classical matrix application
Cheers
06.02.2008
10:52
Dominik: Thanks, you are probably right. As I said, there’s room for improvement in ETH’s linear algebra curriculum.
06.02.2008
11:20
You might also be interested in how this is done in an n-dimensional vector space where n = 3
http://msdn2.microsoft.com/en-us/library/bb206260.aspx
29.02.2008
6:43
Daniel,
Fantastic post! This has cleared up a lot of my frustrations, as I’ve been struggling with the exact same issues that you describe in the post. As I was reading your explanation, it all started to make sense for the first time. Great work and thank you!
24.04.2008
10:08
thats just bomb man, i was looking around and asking for zoom. but almost no one know this technique lol …. so thax u so much for such a great help
04.05.2008
0:56
believe it or not, i was making a map with zoom and scale function, and reading this, wow, i have to quote:
Fantastic post! This has cleared up a lot of my frustrations, as I’ve been struggling with the exact same issues that you describe in the post. As I was reading your explanation, it all started to make sense for the first time. Great work and thank you!
04.05.2008
1:28
btw
if you’re on a Mac where Flash Player is (still) missing mouse wheel support.
solution:
http://blog.pixelbreaker.com/flash/swfmacmousewheel/
08.05.2008
15:52
Awesome! I am working on a map tool, and this is exactly what I was looking for. Do you know if tweening can be introduced to this?
30.05.2008
4:50
[...] Zooming in Flash & Flex [...]
14.07.2008
20:16
GREAT stuff
This was big help for this: http://nuigroup.com/forums/viewthread/2125/
07.08.2008
15:17
but does it displays when you scale it over 8191 x 8191?
19.08.2008
18:29
Deus: You’re right, there are limitations when dealing with large objects. Just today, I found this article which states that Flash Player 10 will raise the bar for it, though:
Large bitmap support
— Justin Everett-Church (Adobe): Introducing Flash Player 10 beta
04.11.2008
7:52
A little late to the party
Very nice blog! I am really enjoying your take on Deep Zoom.
Anyway, for visitors reading this post: you might also be interested in the following, to keep on adding to this very nice explanation:
http://blog.aldobucchi.com/2008/08/decomposing-regular-transformation.html
Eigenvalue decomposition to the rescue… part of bigflexlib.com
08.11.2008
19:53
Aldo: Thanks for the link to the very interesting article on your blog.
22.11.2008
15:50
Thanks bro, been looking for this technique for some time
08.01.2009
23:34
Its amazing how you can take the concept of 3×3 matrix for 2D graphics and 4×4 for 3D graphics.
15.07.2009
5:48
I love you. You are the only normal person on the internets. This shit is HARD. Sure it’s easy, but if you dropped out of Maths at 15, like any normal person, its like beating yourself in the face with a shoe. I have been a relatively successful programmer for 11 years and this shit has always freaked me out, YOUR ARTICLE IS LIKE NAKED NIPPLY SUPER HAPPY TO ME!!1! I totally got that. First! Why cants I find any other resources like this, the rest of this place is rubbish. Going home now, you made someone in New Zealand pretty fucking happy and that happiness my friend will be translated into a good boning for the missus. You made 2 people happy! ! At least she says she likes it. Maybe just one, but thats one happy mother fucker! whoopwhoopwhopwhooop thanks bro!
15.07.2009
10:36
Steve: You’ve made my day! Say hi to your missus from me.
If you have any other questions around this subject, please join our community at http://getsatisfaction.com/openzoom
17.09.2009
19:56
HI Steve,
I know that the topic its already old but I couldn’t just click the next link without saying thanks for the research!
Although I like to crack my head up with complex code to create better and simple classes, it really makes me happy to know that AS3, Flash and Flex community are one of the best, less spam and friendly on the whole web (specially for AS3 noobs like me -__-).
Again, thanks and keep up with the good work!
17.09.2009
19:59
By the way, its HI DANIEL and not STEVE
sorry 
cheers from Japan!
02.10.2009
14:05
Hi Daniel,
First, it looks really great!!! This is exactly what i’ve been looking for!!
Ive managed to put it into my document class so i can scale the whole stage. Unfortunately it wil only scale between two sizes?? And theres no really smooth effect as in your perfect example
Any ideas on why thats so? Ive been looking for a good and useable zoom effect for three days now, so im really exited finally to come accross such a nice one!!
Any help appreciated!
Cheers
02.10.2009
14:25
No worries i got it figured out
I simply forgot to address my_mc
in the beginning of scaleAt like affineTransform = my_mc.transform.matrix.
Again thanks for this!!!! When im finished with this never ending project, im gonna go all in with the Flex environment and openZoom!!!
Have a great weekend!!
10.11.2009
15:01
Hi Daniel,
I had some troubles of my homework, need to zoom all Sprites.
I got your idea about transform.matrix and solved the problem.
Thank you very much!
13.11.2009
21:25
Extremely helpful! Wonder if there’s any way to get the mouse wheel working when the map is in a non-full-screen Flash embed?
15.11.2009
2:38
Ken: In this example, the mousewheel only doesn’t work on Mac OS. This is a known bug of the Flash Player for Mac. In order to make it work, check out the following topic in the OpenZoom community: http://getsatisfaction.com/openzoom/topics/using_externalmousewheel
09.12.2009
15:45
Hi Daniel,
Awesome blog and really helpfull!!
Is there any way of tweening the transistions so the scaling will go a bit more smoothly? Ive tried for days with TweenLite , and cant seem to figure out how to pull this one off.
Cheers!
10.12.2009
19:34
For those asking about how to tween this type of effect, it is exactly what the transformAroundPoint plugin is for in TweenLite/Max – check out the interactive example in the Plugin Explorer at http://www.TweenLite.com (click “EXAMPLE” next to transformAroundPoint). One line of code is all you need. (note: the plugin is a membership benefit of Club GreenSock, so it isn’t included in the free downloads)
10.12.2009
20:18
Steffen: If you’re already using TweenLite then Jack’s suggestion is the way to go. If not, simply omit the last step of applying the transform to the target object and tween it to the property values of the affineTransform.
16.01.2010
19:46
[...] is a brilliant post ‘Zooming in Flash & Flex’ on how to use the transform Matrix to zoom and rotate DisplayObjects. Daniel Gasienica writes well [...]
24.03.2010
11:19
hi Daniel,
nice work ^_^ !!
i would like to signal a little bug in the zoom. when we zoom deeply, it seems that the zoomCanvas is no longer visible, can you explain that and try to solve it?
i have the same problem and i didn’t understand it.
Thanks.
Kamal
24.03.2010
12:09
Kamal: This is a limitation of the Flash Player. There’s no simple fix for that.
24.03.2010
18:04
Daniel
yes, I did realize that there is UIComponent.DEFAULT_MAX_WIDTH & …HEIGHT, i guess that these constants are the limitations.
Thanks,
Kamal
10.05.2010
7:40
Dude, After implementing your code in like 5 minutes flat, I gotta say: Thanks bro, you rock ..
you REALLY rock
You do and let no one tell you different
you rock
hard
11.06.2010
13:28
I wrote a similar article on this subject but you nailed it here.
23.07.2010
7:54
Daniel, its great work….
I want to know how to add scroll bar feature???
28.07.2010
9:35
Hi Daniel,
Ive been looking for something like this for about 2 months, all the other approaches i saw were lengthy involved external classes and as you say were not very elegant. I was beginning to lose hope.
Ive just added 6 lines to my picture scaling and panning app and now it works great.
You should expand your tutorial here with more examples and post links on other forums. Also add a bit more about rotation too! It took me too long to find this page.
thanks,
/S