Stuck on panning/Zooming an Image

It’s been a long while since i’ve been around here, so I’m currently trying to get to grips with AS3, and what i’m trying to do is driving me nuts!

What I want to end up with is an image viewer where i can zoom in and out of the image and pan around it.

I’ve got so far, and have now got fairly stuck and i’ve googled for ages trying to find answers but don’t seem to be able to find anything.

Problems:

  • Zooming in on the centre of the viewing area
  • Limiting the panning so you cant pull the images out of the viewing area

THE LINKS:
View Swf
Source Files

THE CODE:

package {
    
    import flash.display.*;
    import flash.events.*;
    import flash.text.TextField;
      import flash.text.TextFieldAutoSize;
    import flash.net.URLRequest;
    import flash.filters.BitmapFilterQuality;
    import flash.filters.GlowFilter;
    import flash.geom.Rectangle;
    
    public class ImageViewer { 
        
        private var imgLoader:Loader;
        private var container:Sprite = new Sprite();
        private var frame:Sprite = new Sprite();
        private var picMask:Sprite = new Sprite();
        private var picTemp:Sprite = new Sprite();
        private var picHolder:Sprite = new Sprite();
        private var pic:Bitmap;
        private var dragRect:Rectangle;
        
        private var loadStatus_txt:TextField;
        private var picWidth:int;
        private var picHeight:int;
        private var frameWidth:Number;
        private var frameColor:Number;
        private var initPicScale:*;
        private var curPicScale:*;
        
        private var btnZoomIn:myButton;
        private var btnZoomOut:myButton;
        /*var btnPanUp:myButton = new myButton(20,20,4,0xFFFFFF,0.7);
        var btnPanDown:myButton = new myButton(20,20,4,0xFFFFFF,0.7);
        var btnPanLeft:myButton = new myButton(20,20,4,0xFFFFFF,0.7);
        var btnPanRight:myButton = new myButton(20,20,4,0xFFFFFF,0.7);*/
        
        // The constructor function 
        public function ImageViewer ( sprite, w:int, h:int, frameWidth:Number, frameColor:Number) { 
            this.container = sprite;
            this.picWidth = w;
            this.picHeight = h;
            this.frameWidth = frameWidth;
            this.frameColor = frameColor;
            
            buildViewer(w,h);
        } 
        
        // The loadImage( ) method 
        public function loadImage (picURL:String) { 
            var picLdr:Loader = new Loader();
            var picURLReq:URLRequest = new URLRequest(picURL);
            picLdr.load(picURLReq);
            picLdr.contentLoaderInfo.addEventListener(Event.COMPLETE, imgLoaded); 
            function imgLoaded(event:Event):void {
                trace('image loaded');
                
                var pic:Bitmap = new Bitmap(event.target.content.bitmapData);
                
                resizePic(pic);
            }
        } 

        private function buildViewer( w:int, h:int) {
            
            createFrame(w,h);
            createMask(w,h);
            container.addChild(picHolder);

        }

        private function createFrame(w:int, h:int) {
            frame.graphics.beginFill(frameColor);
            frame.graphics.drawRect(0, 0, w, h );    
            var glow:GlowFilter = new GlowFilter();
            glow.color = 0x666666;
            glow.alpha = 0.8;
            glow.blurX = 10;
            glow.blurY = 10;
            glow.quality = BitmapFilterQuality.MEDIUM;
            frame.filters = [glow];
            container.addChild(frame)
        }
        
        private function createMask(w,h) {
            var maskW:int = (w-(2*frameWidth));
            var maskH:int = (h-(2*frameWidth));
            picMask.graphics.beginFill(0xff0000);
            picMask.graphics.drawRect(frameWidth, frameWidth, maskW, maskH );
            //var dragRect:Rectangle = new Rectangle(frameWidth,frameWidth,picWidth,picHeight);
            
        }

        private function resizePic(picture) {
            
            picture.width=picWidth;
            picture.scaleY=picture.scaleX;
            initPicScale=1;
            trace('initScale='+initPicScale)
            curPicScale=initPicScale;
            trace('curScale='+curPicScale);
            picture.x=frameWidth;
            picture.y=frameWidth;
            picHolder.addChild(picture);
            picHolder.addEventListener(MouseEvent.MOUSE_DOWN, startDragging);
            picHolder.addEventListener(MouseEvent.MOUSE_UP, stopDragging);
            addDisplayItems()
        }
        
        private function addDisplayItems(){
            
            container.addChild(picMask);
            picHolder.mask=picMask;
        }
        
        private function createDragRect() {
            var dragRect:Rectangle = new Rectangle(0,0,100,100);
        }
        
        // This function is called when the mouse button is pressed.
        private function startDragging(event:MouseEvent):void {
            createDragRect();
            picHolder.startDrag(false, dragRect );
        }

        // This function is called when the mouse button is released.
        private function stopDragging(event:MouseEvent):void {
            picHolder.stopDrag();
        }

        public function createControls(size:int,padding:int,margin:int,zoom:Boolean,pan:Boolean){
            
            var buttonSize:int = size;
            var buttonMargin:int = padding;
            var zoomX:Number = margin;
            var zoomInY:Number = picHeight-margin-(buttonSize*2)-padding;
            var zoomOutY:Number = picHeight-margin-buttonSize;
            if(zoom){
                addZoomControls(zoomX,zoomInY,zoomOutY,buttonSize);
            }
        }
        
        private function addZoomControls(zoomX:int,zoomInY:int,zoomOutY:int,buttonSize:int) {
            var btnZoomIn:myButton = new myButton(zoomX,zoomInY,buttonSize,buttonSize,4,0xffffff,0.7,true);
            var btnZoomOut:myButton = new myButton(zoomX,zoomOutY,buttonSize,buttonSize,4,0xffffff,0.7,true);
            container.addChild(btnZoomIn);
            container.addChild(btnZoomOut);
            btnZoomIn.addEventListener(MouseEvent.CLICK, zoomIn);
            btnZoomOut.addEventListener(MouseEvent.CLICK, zoomOut);
        }
            
        
        private function zoomIn(event:MouseEvent){

            trace('*************************************')
            curPicScale = curPicScale+0.1
            trace ('newScaler='+curPicScale);
            
            trace('initX='+picHolder.x)
                        
            var centreX:Number = (frame.width/2)
            trace('framecentreX='+frame.width/2)
            trace('centreX='+centreX);
            var centreY:Number = (frame.height/2)
            
            var prevPointX:Number = (picMask.x-picHolder.x)+centreX
            trace('prevPointX='+prevPointX);
            var prevPointY:Number = (picMask.y-picHolder.y)+centreY
                        
            var newPointX:Number = prevPointX*curPicScale;
            trace('newPointX='+newPointX)
            var newPointY:Number = prevPointY*curPicScale;
            
            var newWidth:Number = picHolder.width*curPicScale
            trace('newWidth='+newWidth);
            var newHeight:Number = picHolder.height*curPicScale
            
            var difX:Number = newPointX-prevPointX;
            trace('difX='+difX)
            var difY:Number = newPointY-prevPointY;
            
            var newX:Number = picHolder.x-difX;
            trace('newX='+newX)
            var newY:Number = picHolder.y-difY;
            trace('newY='+newY)
            
            picHolder.scaleX=curPicScale;
            picHolder.scaleY=curPicScale;
            
            
            
            picHolder.x=newX;
            picHolder.y=newY;
            trace('*************************************')
        }
        
        private function zoomOut(event:MouseEvent){
        
            if(curPicScale>initPicScale){
                
                curPicScale = (curPicScale-0.1)
                trace ('newScale='+curPicScale);
                if(curPicScale<1){
                    curPicScale=1
                }
                
                pic.scaleX=curPicScale;
                pic.scaleY=curPicScale;
            }
        }
        
    }

}

Please help if you can, I seem to have hit a brick wall with this - the maths on the zoom repositioning looks right to me, but it still veers off to the left!! and the bounds for the panning just don’t seem to do anything! Argh!

Thanks in advance

Chris