Odd Behavior with ScaleTransform.CenterXY in SilverLight 3
Lately I’ve been working on an AI project, parts of which might get turned into a Boise Code Camp presentation, hopefully. Rather than just debugging via Console.Write, I want to see what the AI is up to using one of those new-fangled Graphical User Interfaces that I’ve heard so much about, specifically via Silverlight. A major requirement is to be able to zoom in and out of a canvas, along with the ability to pan around the canvas. If you’ve played an RTS like Starcraft, you’ll know what I mean. I thought that this would be easy, certainly far easier than debugging A* pathfinding. As usual, I was wrong.
To zoom in or out, use the mouse wheel while hovering over the map. Zooming In should bring you into the point you are hovering over – “zoom in here.” This is implemented via a ScaleTransform, plus an animation to keep things nice and smooth. The ScaleTransform exposes two properties, CenterX and CenterY, to make this happen.
And in fact, when you first zoom in to a section of the map, the zoom does exactly that. The problem is – zoom back out, now move to a different section of the map and attempt to zoom in – the animation completely ignores the new CenterX and Y values and will always use the previous Center value. This problem was also confirmed using the latest release of Silverlight 4.
If I remove the animation completely and just alter the ScaleTransform directly, the CenterXY code works fine. However this was causing other problems…
The Pan and Zoom functionality seemed like it was much easier to get working in WPF however – and since I didn’t have a strict requirement to be using Silverlight… I will post a working Pan/Zoom Canvas example, largely based on code from this article on Joe Wood’s blog.
Update! December 6th 2010, from Václav Jedli?ka:
I found how to fix your solution of the zoom example you put here … It is necessary to animate the CenterX and CenterY properties of the
scaling, not just the ScaleX and ScaleY properties. It is because
after the animation ends, the values set by the animation take
precendense of the regular properties of the transformation.
With this fix it works fine, but only for the image size you used. It
does not work with larger images, because there is no pan feature.
Thanks for the fix, Václav!
Three different sample sln’s showing the problem available over here: