Search code examples
actionscript-3apache-flexzoomingscale

Zoom to and from point


I'm trying to zoom a DisplayObject into a certain point. I figured it would be easy, but I've spent a day now trying to figure it out.

Basically, I think this should work. Emphasis on should.

//newPoint is the point being centered. There is no initial scaling, so I do not need to compensate for that (yet)
//scale is the zoom level
//container is the parent of the obj
//obj is the object being scaled/panned
var p:Point = new Point(
    ( this.container.width - this.obj.width * scale + newPoint.x * scale ) / 2, 
    ( this.container.height - this.obj.height * scale + newPoint.y * scale ) / 2 
);

this.obj.scaleX = this.obj.scaleY = scale;
this.obj.x = p.x;
this.obj.y = p.y;

It centers the point if scale is 1, but it gets further and further away from center as you increase the scale. I've tried dozens of different methods. This method, which I have seen on several sites, produced the same exact results. Anyone have any idea how to get this to work?

EDIT 10-1-12: As a followup, I took the code snippet that LondonDrugs_MediaServices provided as a basis for my original issue. I needed to be able to zoom to a specific point at a specific scale relative to the unscaled image (think how Google Maps zooms to a specific location). To do this, I had to center my image on the point before running the translation code. I've posted the additional code below. For other uses (pinch to zoom, scrolling, and double click), I used the code provided by Vesper, which worked quite well.

//obj is the object being translated
//container is its parent
//x and y are the coordinates to be zoomed to, in untranslated scaling
//obj.scaleX and obj.scaleY are always identical in my class, so there is no need to account for that


//calculates current center point, with scaling
var center:Point = new Point( ( this.container.width - this.obj.width * this.obj.scaleX ) / 2, ( this.container.height - this.obj.height * this.obj.scaleX ) / 2 );

//calulcates the distance from center the point is, with scaling
var distanceFromCenter:Point = new Point( this.obj.width * this.obj.scaleX / 2 - x * this.obj.scaleX, this.obj.height * this.obj.scaleX / 2 - y * this.obj.scaleX );

//center the object on that specific point
this.obj.x = center.x + distanceFromCenter.x;
this.obj.y = center.y + distanceFromCenter.y;

Solution

  • var mat:Matrix=new Matrix();
    mat.translate(-p.x,-p.y);
    mat.scale(desiredScale,desiredScale);
    mat.translate(p.x,p.y);
    yourObject.transform.matrix=mat;
    

    The core point is that scaling is done around (0,0), but you can do it with matrix that describes affine transformations. You first make an empty matrix (that is, a matrix that doesn't transform), then apply a set of transformations to it. First, place a desired point at (0,0) by translating by -1*coordinates, then scale, then translate back.