So I’m trying to add zoom functionality to Lex Talkington’s great Panning Class
http://www.lextalkington.com/blog/2009/08/auto-pan-class-for-panning-an-image-on-mouse-movement/
, and have run into the following issue: I cannot seem to get the image to scale without also scaling the container _rectangle. Any thoughts on this would be greatly appreciated.
Here’s my code
package com.lextalkington.autopan {
import flash.display.*;
import flash.events.*;
import flash.geom.Rectangle;
public class AutoPan extends Sprite {
private var _clip:DisplayObject;
private var _xp:Number;
private var _yp:Number;
private var _aw:Number = 500;
private var _ah:Number = 500;
private var _offsetx:Number;
private var _offsety:Number;
private var _ease:Number;
private var _easeSlideTo:Number;
private var _cache:Boolean;
private var _rectangle:Rectangle;
private var _clipParent:DisplayObject;
private var _clipW:Number;
private var _clipH:Number;
private var _yRatio:Number;
private var _yPos:Number;
private var _xRatio:Number;
private var _xPos:Number;
private var _motionActive:Boolean;
private var _toX:Number = 0;
private var _toY:Number = 0;
public function AutoPan(clip:DisplayObject, xp:Number, yp:Number, aw:Number, ah:Number, offsetx:Number, offsety:Number, ease:Number=0.7, cache:Boolean=true) {
_clip = clip;
_xp = xp;
_yp = yp;
_aw = aw;
_ah = ah;
_offsetx = offsetx;
_offsety = offsety;
_ease = ease;
_cache = cache;
init();
}
private function init():void {
_clip.x = _xp;
_clip.y = _yp;
_clipW = _clip.width;
_clipH = _clip.height;
try {
_clipParent = _clip.parent;
} catch(e:*) {
throw new Error("The clip ("+_clip+") you passed to AutoPan does not have a parent - it is probably not on the display list which is necessary for AutoPan to work");
return;
}
// set cache
if(_cache) _clip.cacheAsBitmap = true;
// create rectangle for scrollrect
_rectangle = new Rectangle(_offsetx, _offsety, 500, 500);
// set scrollrect on displayObject
_clip.scrollRect = _rectangle;
// set mouse event to start movement
_clip.addEventListener(MouseEvent.MOUSE_OVER, initiateMovement, false, 0, true);
// allow motion
_motionActive = true;
}
private function initiateMovement(e:Event):void {
if(hasEventListener(Event.ENTER_FRAME)) {
removeEventListener(Event.ENTER_FRAME, move);
}
_clip.removeEventListener(MouseEvent.MOUSE_OVER, initiateMovement);
addEventListener(Event.ENTER_FRAME, move);
}
private function move(e:Event):void {
var xm:int = _clipParent.mouseX;
var ym:int = _clipParent.mouseY;
// This catches a firefox issue where if the clip is in motion, and if you commmand-n open a new window, the ENTER_FRAME continues to fire.
if(checkMouseLeave(xm,ym)) return;
_clip.scrollRect = getXY(xm,ym);
// check if the mouse is over the visible clip area
if(!_clip.hitTestPoint(mouseX,mouseY,true)) {
killMovement();
}
}
//-----------------------------------
// check if the mouse has left the stage - added as a FireFox catch
//-----------------------------------
private function checkMouseLeave(xp:int,yp:int):Boolean {
if(xp<0) xp = -xp;
if(yp<0) yp = -yp;
if(xp>10000 || xp>10000) {
killMovement();
return true;
}
return false;
}
private function getXY(xp:Number,yp:Number):Rectangle {
// calculate the X offset / positions
_xRatio = (xp-_clip.x)/_rectangle.width;
_xPos = _xRatio*(_clipW-_rectangle.width);
// calculate the Y offset / positions
_yRatio = (yp-_clip.y)/_rectangle.height;
_yPos = _yRatio*(_clipH-_rectangle.height);
// set the rectangles offsets
_rectangle.x = _xPos-(_xPos-_rectangle.x)*_ease;
_rectangle.y = _yPos-(_yPos-_rectangle.y)*_ease;
return _rectangle;
}
private function killMovement():void {
if(hasEventListener(Event.ENTER_FRAME)) {
removeEventListener(Event.ENTER_FRAME, move);
}
if(_motionActive) {
if(!_clip.hasEventListener(MouseEvent.MOUSE_OVER)) {
_clip.addEventListener(MouseEvent.MOUSE_OVER, initiateMovement, false, 0, true);
}
} else {
if(_clip.hasEventListener(MouseEvent.MOUSE_OVER)) _clip.removeEventListener(MouseEvent.MOUSE_OVER, initiateMovement);
}
}
}
}
and here’s the document class to go with:
package com.lextalkington.autopan {
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.text.*;
import flash.display.MovieClip;
import com.lextalkington.autopan.AutoPan;
public class AutoPanDocument extends Sprite {
private var _autoPan:AutoPan;
public function AutoPanDocument() {
createAutoPan();
}
private function createAutoPan():void {
var xPos:Number = 55;
var yPos:Number = 55;
var visibleWidth:Number = 500;
var visibleHeight:Number = 500;
var startingViewableX:Number = (mc.width-visibleWidth)/2; // this will align the clip to be centered within the visible area
var startingViewableY:Number = (mc.height-visibleHeight)/2; // this will align the clip to be centered within the visible area
var ease:Number = 0.7; // easeing amount
var cacheIt:Boolean = true; // cached as bitmap, recommended
// mc is a MovieClip on the stage
_autoPan = new AutoPan(mc, xPos, yPos, visibleWidth, visibleHeight, startingViewableX, startingViewableY, ease, cacheIt);
ZOOM.addEventListener(MouseEvent.CLICK, zoom);
UNZOOM.addEventListener(MouseEvent.CLICK, unzoom);
}
public function zoom(e:MouseEvent):void {
mc.scaleX += 1;
mc.scaleY += 1;
}
public function unzoom(e:MouseEvent):void {
mc.scaleX -= 1;
mc.scaleY -= 1;
}
}
}