Archive for the 'Flash' Category

Zooming & centering using Flash’s annoying ScrollPane

May 11, 2006

In the old Flash (the first version of MX) the FScrollPane component had a nice setScrollPosition function, with which one could set the position of the movie clip inside. This function no longer exists in the whizzy Flash 8 environment; it’s been replaced with ScrollPane, which has a much more obscure functionality, with the properties hPosition and vPosition. The documentation for hPosition states:

Property; the pixel position of the scroll pane’s horizontal scroll box (thumb). The 0 position is at the extreme left end of the scroll track, which causes the left edge of the scroll pane content to be visible in the scroll pane.

Liars! It’s nothing of the sort. hPosition does not descibe the scroll bars, it describes the horizontal position of the movieclip inside the pane; it is the amount the top-left corner of the clip is displaced to the left of the top-left corner of the pane. This is slightly confusing: Flash works on a rightwards-positive co-ordinate system, yet hPosition is always positive. Similarly, vPosition described displacement upwards, not downwards.

Anyway, with that confusion over, we can get something done. Let’s say we’re zooming into the clip by doubling its size, but we want to keep the display currently centered upon where we are. In the co-ordinate space of the movie clip (not the pane), where (0,0) is the top left corner of the clip, and the clip is currently displaced to the left by hPosition, then the x co-ordinate of the centre of the pane XC can be found by:

XC = hPosition + pane_mc.width/2

Doubling the clip in size will result in the co-ordinate of the new centre XC’ being twice that of the original. So we need to find the new displacement hPosition’

XC’ = 2XC
hPosition’ + pane_mc.width/2 = 2*(hPosition + pane_mc.width/2)
hPosition’ = 2*hPosition + pane_mc.width/2

Which means the following code will successfully zoom & center our clip:

// Scale our object
clip._xscale *= 2;
clip._yscale *= 2;

// New offset
var hPos = 2*scrollPane.hPosition + scrollPane.width/2;
var vPos = 2*scrollPane.vPosition + scrollPane.height/2;

// Refresh the pane to auto-add scrollbars
scrollPane.setSize(scrollPane.width, scrollPane.height);

// Set the new positions
scrollPane.hPosition = hPos;
scrollPane.vPosition = vPos;

You’ll need some extra code to deal with the clip not shifting outside the pane when you zoom back out again (which can happen) but this is trivial checking of bounds. Now you can use Flash’s ScrollPane to display zoomable clips (such as maps…)