Drag panning with zoom on mouseclick location AS3 - actionscript-3

So, another post on here REALLY helped me prior from this link!
It got me to zoom in neatly, but what I'm really looking for in my panning is a mouse drag (I will be working with a touch screen, so dragging to move is important) No need to use Touch classes, I have done dragging events with Mouse classes before and find it easier to me.
My problem here is that my neat zoom is linked to this MOUSE_MOVE panning, and I want to know a clean way to change my panning to a drag event, and still not have my panning go past my image constraints.
bg_mc- is my background image to move and zoom.
My code:
import com.greensock.*;
bg_mc.doubleClickEnabled = true;
//Variables
var percX:Number;
var percY:Number;
var destX:Number;
var destY:Number;
//Image panned and masked
this.mask = mask_mc;
stage.addEventListener(MouseEvent.MOUSE_MOVE,mousemove);
function mousemove(e:MouseEvent) {
if (mask_mc.hitTestPoint(stage.mouseX,stage.mouseY,false)) {
if (bg_mc.width>mask_mc.width) {//Avoids Scrolling if image is under mask area width
percX = mask_mc.mouseX/mask_mc.width;
}
if (bg_mc.height>mask_mc.height) {
//Avoids Scrolling if image is under mask area height
percY = mask_mc.mouseY/mask_mc.height;
}
destX = -(bg_mc.width-mask_mc.width)*percX;
destY = -(bg_mc.height-mask_mc.height)*percY;
TweenMax.to(bg_mc,.5,{x:destX,y:destY});
}
}
//Add listeners for the imgLoader movie clip.
bg_mc.doubleClickEnabled = true;
bg_mc.addEventListener(MouseEvent.DOUBLE_CLICK, increaseSize);
bg_mc.addEventListener(MouseEvent.CLICK, decreaseSize);
function scaleAroundMouse(objectToScale:DisplayObject, scaleAmount:Number,
bounds:Rectangle = null, onComplete:Function = null):TweenLite {
// scaling will be done relatively
var relScaleX:Number = scaleAmount / objectToScale.scaleX;
var relScaleY:Number = scaleAmount / objectToScale.scaleY;
// map vector to centre point within parent scope
var scalePoint:Point = objectToScale.localToGlobal( new
Point(objectToScale.mouseX, objectToScale.mouseY));
scalePoint = objectToScale.parent.globalToLocal( scalePoint );
// current registered postion AB
var AB:Point = new Point( objectToScale.x, objectToScale.y );
// CB = AB - scalePoint, objectToScale vector that will scale as it runs from the centre
var CB:Point = AB.subtract( scalePoint );
CB.x *= relScaleX;
CB.y *= relScaleY;
// recaulate AB, objectToScale will be the adjusted position for the clip
AB = scalePoint.add( CB );
// set actual properties
if(bounds){
var limits:Rectangle = new Rectangle(
bounds.x + (bounds.width - (objectToScale.width * relScaleX)),
bounds.y + (bounds.height - (objectToScale.height * relScaleY)),
(objectToScale.width * relScaleX) - bounds.width,
(objectToScale.height * relScaleY) - bounds.height
);
if(AB.x < limits.x) AB.x = limits.x;
if(AB.x > limits.x + limits.width) AB.x = limits.x + limits.width;
if(AB.y < limits.y) AB.y = limits.y;
if(AB.y > limits.y + limits.height) AB.y = limits.y + limits.height;
}
return TweenLite.to(objectToScale,1,{onComplete: onComplete,
scaleX: scaleAmount, scaleY: scaleAmount, x: AB.x, y: AB.y});
}
function increaseSize(event:MouseEvent):void{
stopMouseMove();
scaleAroundMouse(bg_mc, 4, null, resumeMouseMove);
}
function decreaseSize(event:MouseEvent):void{
stopMouseMove();
scaleAroundMouse(bg_mc, 1, null, resumeMouseMove);
}
function stopMouseMove():void {
stage.removeEventListener(MouseEvent.MOUSE_MOVE,mousemove);
}
function resumeMouseMove():void {
stage.addEventListener(MouseEvent.MOUSE_MOVE,mousemove);
}
Any help I can get would be great!

On a mousedown or whatever listener you want to start dragging, use the MovieClip.StartDrag() function to allow dragging, and the StopDrag() to stop it.

While you could use the built in startDrag (or startTouchDrag) and stopDrag methods, it will not play nice with your zoom in/out function.
bg_mc.addEventListener(MouseEvent.MOUSE_DOWN,mouseDown); //add the listener to the bg directly
function mouseDown(e:MouseEvent) {
// if (mask_mc.hitTestPoint(stage.mouseX,stage.mouseY,false)) { //this isn't needed if you add the listener directly to bg_mc
stage.addEventListener(MouseEvent.MOUSE_UP,mouseUp);
bg_mc.startDrag(false, getBoundsRect()); //see the code below for the getBoundsRect() function
}
function mouseUp(e:MouseEvent):void {
bg_mc.stopDrag();
stage.removeEventListener(MouseEvent.MOUSE_UP,mouseUp);
}
You'd be better served to have a custom drag function, like below:
import com.greensock.*;
import flash.events.MouseEvent;
import flash.geom.Rectangle;
import flash.events.Event;
import flash.geom.Point;
bg_mc.doubleClickEnabled = true;
//Variables
var percX:Number;
var percY:Number;
var destX:Number;
var destY:Number;
//Image panned and masked
bg_mc.mask = mask_mc;
//this function generates a bounds rectangle that would keep bg_mc edges from going outside of mask_mc area
function getBoundsRect():Rectangle {
return new Rectangle((mask_mc.x + mask_mc.width) - bg_mc.width, (mask_mc.y + mask_mc.height) - bg_mc.height, bg_mc.width - mask_mc.width, bg_mc.height - mask_mc.height);
}
var isZoomed:Boolean = false; //a var to keep track of whether your zoomed in or out
var isDragging:Boolean = false; //a var to keep track of whether the bg is being dragged
var tmpMousePoint:Point = new Point(); //this stores the mouse coordinates on the mouse down, to compare later on the mouse up to see if the mouse moved
var decay:Number = .27; //make this lower for slower drag, make it 1 to turn off a smooth drag all together
var tmpMouseMoved:Boolean = false; //to keep track on mouse up whether the action was a drag or a click
var mouseMoveSensitivity:Number = 15; //how far does mouse need to move before you cancel the click event
var offset:Point = new Point(); //the offset of the initial mouse click relative to bg_mc's 0,0
bg_mc.addEventListener(MouseEvent.MOUSE_DOWN,mouseDown);
bg_mc.addEventListener(MouseEvent.CLICK,mouseClick, false, 99999); //listen with a higher priority than any other click listeners on bg_mc - this way if it's a drag, you can cancel the click event
function mouseDown(e:Event):void {
//reset these to default
isDragging = true;
tmpMouseMoved = false;
tmpMousePoint.x = mouseX; //capture the current mouse to check later if it moved (so you know the user intended to drag not click)
tmpMousePoint.y = mouseY;
offset.x = bg_mc.mouseX;
offset.y = bg_mc.mouseY;
bg_mc.addEventListener(Event.ENTER_FRAME,bgEnterFrame); //listen every frame until the mouse is released
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUp);
}
function bgEnterFrame(e:Event):void {
bg_mc.x += decay * (mouseX - offset.x - bg_mc.x);
bg_mc.y += decay * (mouseY - offset.y - bg_mc.y);
var bounds:Rectangle = getBoundsRect();
switch(true){
case (bg_mc.x < bounds.x):
bg_mc.x = bounds.x;
break;
case (bg_mc.x > bounds.x + bounds.width):
bg_mc.x = bounds.x + bounds.width;
}
switch(true){
case (bg_mc.y < bounds.y):
bg_mc.y = bounds.y;
break;
case (bg_mc.y > bounds.y + bounds.height):
bg_mc.y = bounds.y + bounds.height;
}
if(Math.abs(tmpMousePoint.x - mouseX) > mouseMoveSensitivity || Math.abs(tmpMousePoint.y - mouseY) > mouseMoveSensitivity){
tmpMouseMoved = true;
}
}
function mouseUp(e:Event):void {
isDragging = false;
//remove listeners
bg_mc.removeEventListener(Event.ENTER_FRAME,bgEnterFrame);
stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUp);
}
function mouseClick(e:MouseEvent):void {
trace("CLICK cap");
if(tmpMouseMoved){
trace("Kill");
e.stopImmediatePropagation(); //cancel the mouse event
}
}
//Add listeners for the imgLoader movie clip.
bg_mc.doubleClickEnabled = true;
bg_mc.addEventListener(MouseEvent.DOUBLE_CLICK, increaseSize);
bg_mc.addEventListener(MouseEvent.CLICK, decreaseSize,false,0,true);
function scaleAroundMouse(objectToScale:DisplayObject, scaleAmount:Number,
bounds:Rectangle = null, onComplete:Function = null):TweenLite {
// scaling will be done relatively
var relScaleX:Number = scaleAmount / objectToScale.scaleX;
var relScaleY:Number = scaleAmount / objectToScale.scaleY;
// map vector to centre point within parent scope
var scalePoint:Point = objectToScale.localToGlobal( new
Point(objectToScale.mouseX, objectToScale.mouseY));
scalePoint = objectToScale.parent.globalToLocal( scalePoint );
// current registered postion AB
var AB:Point = new Point( objectToScale.x, objectToScale.y );
// CB = AB - scalePoint, objectToScale vector that will scale as it runs from the centre
var CB:Point = AB.subtract( scalePoint );
CB.x *= relScaleX;
CB.y *= relScaleY;
// recaulate AB, objectToScale will be the adjusted position for the clip
AB = scalePoint.add( CB );
// set actual properties
if(bounds){
var limits:Rectangle = new Rectangle(
bounds.x + (bounds.width - (objectToScale.width * relScaleX)),
bounds.y + (bounds.height - (objectToScale.height * relScaleY)),
(objectToScale.width * relScaleX) - bounds.width,
(objectToScale.height * relScaleY) - bounds.height
);
if(AB.x < limits.x) AB.x = limits.x;
if(AB.x > limits.x + limits.width) AB.x = limits.x + limits.width;
if(AB.y < limits.y) AB.y = limits.y;
if(AB.y > limits.y + limits.height) AB.y = limits.y + limits.height;
}
TweenLite.killTweensOf(objectToScale); //need to add this so the click/double click don't compete with each other
return TweenLite.to(objectToScale,1,{onComplete: onComplete,
scaleX: scaleAmount, scaleY: scaleAmount, x: AB.x, y: AB.y});
}
function increaseSize(event:MouseEvent):void{
if(isZoomed){
scaleAroundMouse(bg_mc, 4, getBoundsRect());
isZoomed = false;
}
}
function decreaseSize(event:MouseEvent):void{
if(!isZoomed){
scaleAroundMouse(bg_mc, 1, getBoundsRect());
isZoomed = true;
}
}

Related

How to stop player from walking on walls

I'm building a test avatar chat... thingy in ActionScript3, but I've come across a problem, whenever I click the chatbar to say something, my avatar (which is currently a penguin) walks to it -- how can I prevent this from happening? In other words, how do I build a wall and keep the penguins out?
This is the code I'm using to make my penguin move.
stage.addEventListener(MouseEvent.CLICK, myClickReaction);
// speeds ALONG NYPOTENUSE
var v:Number = 7;
// vector of movement
var dir:int = 100;
// mouse click point
var clickPoint:Point = new Point();
// angle doesn't change metween clicks - so it can be global
var angle:Number;
function myClickReaction (e:MouseEvent):void {
clickPoint = new Point(mouseX, mouseY);
angle = Math.atan2(clickPoint.y - penguin.y, clickPoint.x - penguin.x);
dir = angle >= 0 ? -1 : 1;
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
function onEnterFrame(e:Event):void {
var projectedX:Number = penguin.x + v * Math.cos(angle);
var projectedY:Number = penguin.y + v * Math.sin(angle);
var diff:Number = clickPoint.y - projectedY;
if (diff / Math.abs(diff) == dir) {
penguin.x = clickPoint.x;
penguin.y = clickPoint.y;
removeEventListener(Event.ENTER_FRAME, onEnterFrame);
}
else {
penguin.x = projectedX;
penguin.y = projectedY;
}
}

Shaking Object With Swinging/Tilting Effect in AS3

I have an image of a bottle on the stage. I want to have it so that the user can click and drag the bottle around. I want the bottle to sway as it's dragged so tilt and rotate as if it's being pulled back and forth. I've Googled this and found nothing. How can I achieve this effect through code?
So far I've created a timer that tracks a start and end point during drag, calculates distance travelled to get a rough idea of speed and direction and then rotates the bottle within a range of 120 degrees using the Tween class (and then bounce back to 0 after). It's close but not quite as fluid looking as I'd like.. I feel like I need some kind of custom easing function but I'm not great with this type of math.
function distanceTimerBeat(e:TimerEvent):void
{//speed detection beat timer
distCounter++;
if(!distSwitch)
{
startX = product.x;
startY = product.y;
distSwitch = true;
}
else
{
endX = product.x;
endY = product.y;
distSwitch = false;
var newDistance = calculateDistance();
setRotation();
//trace('>> ('+distCounter+') distance travelled = '+newDistance);
//produceNewFirework()
}
}
function calculateDistance():Number
{//returns distance travelled over beat timer intervals
var rawDistance = (( startX - endX ) * (startX - endX )) + ((startY - endY ) * (startY - endY ));
var distance = Math.sqrt( rawDistance);
var xDistance = startX - endX;
if(xDistance < 0)
{
speedDirection = 'right';
directionModifier = -1;
}
else if(xDistance > 0)
{
speedDirection = 'left';
directionModifier = 1;
}
//trace('>> going '+speedDirection+' at '+xDistance);
return distance;
}
function setRotation():void
{ //once start & end values are detected, check speed and set the rotation.
var curSpeed = calculateDistance();
if(curSpeed > 4)
{
tweenLock = false;
var speedPercent = curSpeed/maxSpeed * 100;
var rotationDegree = (speedPercent*120)/300;
var newRotation = directionModifier*rotationDegree;
var reversePercent = 100 - speedPercent;
var tweenSpeedModifier = (speedPercent/100);
//trace(tweenSpeedModifier*1);
//if(!tweenLock)
//rotationTween = null;
if(rotationTween) rotationTween.stop();
rotationTween = new Tween(product, "rotation", Strong.easeInOut, product.rotation, newRotation, 0.25, true);
//rotationTween.resume();
rotationTween.addEventListener(TweenEvent.MOTION_FINISH, resetProductTween);
//trace('speed percet = '+speedPercent);
}
else
{
//tweenLock = true;
}
}
function resetProductTween(e:TweenEvent)
{//after the product rotates, snap it back to it's original position.
tweenLock = false;
if(!tweenLock)
{
rotationTween = new Tween(product, "rotation", Strong.easeOut, product.rotation, 0, 0.75, true);
rotationTween.addEventListener(TweenEvent.MOTION_FINISH, tweenUnlock);
}
}
http://code.tutsplus.com/tutorials/quick-tip-trigonometry-for-flash-game-developers--active-4458
stage.addEventListener(MouseEvent.CLICK, calculateAngle);
var myAtan2:Number;
function calculateAngle(e:MouseEvent):void
{
myAtan2 = Math.atan2(e.stageY - mCircle.y, e.stageX - mCircle.x);
trace(myAtan2);
}

rotating sprite from it's current angle as3

i created an object that is rotated with the mouse, however each time after rotating, when mouse is clicked again the object "jump" right to it's new angle i would like that the object will continue to rotate from it's current location no matter where the mouse being clicked.
this is my code that rotates the object.
public function _mouseclick(me:MouseEvent):void
{
addEventListener(Event.ENTER_FRAME, UpdateGame);
IsButtonClicked = true;
}
public function UpdateGame(e:Event):void
{
if (IsButtonClicked)
{
var dist_Y:Number = mouseY - PlayerSprite.y ;
var dist_X:Number = mouseX - PlayerSprite.x ;
var angle:Number = Math.atan2(dist_Y, dist_X);
var degrees:Number = angle * 180/ Math.PI;
PlayerSprite.rotation = degrees;
}
}
how can i reset the angle to the current sprite angle and prevent that "jump"?
It looks like maybe you are trying to make some sort of knob or dial. Finding the angle between the mouse and sprite and applying it the way you are, will always face that direction. I think you are looking for something a little more simple.
First I would set up 2 variables, one to be the amount to increment the rotation, the other to store the mouse position.
var increment:int = 5;
var mousePos:Point;
Then in your mouse click function:
mousePos = new Point( mouseX, mouseY );
Lastly in your UpdateGame():
private function UpdateGame( e:Event ):void {
if ( IsButtonClicked ) {
var increment:int = 5;
if ( mousePos.y < mouseY ) {
spr.rotation += increment;
}
else {
spr.rotation -= increment;
}
mousePos = new Point( mouseX, mouseY );
}
}
That seems to be more the effect you are looking for. In this case when you move the mouse up, the sprite rotates counter clockwise. Moving the mouse down, rotates it clockwise.
If you want to change the rotation smoothly, you want to base it on the change from last rotation as the delta.
The delta is based on the initial rotation from mouse click relative to the current rotation.
current_rotation += (atan2 - last_rotation);
last_rotation = atan2;
And the full pseudo example.
private var current_rotation:Number;
private var last_rotation:Number;
private var mouse_down:Boolean;
public function MouseClick(e:MouseEvent):void
{
var dX:Number = Mouse.X - 400;
var dY:Number = Mouse.Y - 300;
var atan2:Number = Math.atan2(dY, dX);
last_rotation = atan2;
mouse_down = true;
}
public function UpdateGame(e:Event):void
{
if (mouse_down)
{
var dX:Number = Mouse.X - 400;
var dY:Number = Mouse.Y - 300;
var atan2:Number = Math.atan2(dY, dX);
current_rotation += (atan2 - last_rotation);
last_rotation = atan2;
}
}

Mouse_leave cannot make movieclip snap back

I am trying to make a small drag and drop application in flash , i have been able to achieve the following -
1)Drag the movie clips
2)Make sure that two movieclips do not interchange positions when put over each other
3)Make sure the MC that is being dragged stays on top of other movieclips ..
4)Make the movieclip stay when its dropped at designated position
However there is one very important thing i am unable to achieve , when the cursor moves out of stage , the movie clips gets stuck to the cursor , i want that the moment the user goes out of stage the clip that is being dragged goes back to its original position ...
I have tried using the mouse_leave option for this but it does not work...
I am adding the code for drag and drop as below , please guide me here -
Drag Code -
Array to hold the target instances, the drop instances,
and the start positions of the drop instances.
var hitArray:Array = new Array(hitTarget1,hitTarget2,hitTarget3);
var dropArray:Array = new Array(drop1,drop2,drop3);
var positionsArray:Array = new Array();
This adds the mouse down and up listener to the drop instances
and add the starting x and y positions of the drop instances
into the array.
for (var i:int = 0; i < dropArray.length; i++) {
dropArray[i].buttonMode = true;
dropArray[i].addEventListener(MouseEvent.MOUSE_DOWN, mdown);
dropArray[i].addEventListener(MouseEvent.MOUSE_UP, mUp);
positionsArray.push({xPos:dropArray[i].x, yPos:dropArray[i].y});
}
This drags the object that has been selected and moves it
to the top of the display list. This means you can't drag
this object underneath anything.
function mdown(e:MouseEvent):void {
e.currentTarget.startDrag();
setChildIndex(MovieClip(e.currentTarget), numChildren - 1);
}
And here is the drop code
This stops the dragging of the selected object when the mouse is
released. If the object is dropped on the corresponding target
then it get set to the x and y position of the target. Otherwise
it returns to the original position.
function mUp(e:MouseEvent):void {
var dropIndex:int = dropArray.indexOf(e.currentTarget);
var target:MovieClip = e.currentTarget as MovieClip;
target.stopDrag();
if (target.hitTestObject(hitArray[dropIndex])) {
target.x = hitArray[dropIndex].x;
target.y = hitArray[dropIndex].y;
}else{
target.x = positionsArray[dropIndex].xPos;
target.y = positionsArray[dropIndex].yPos;
}
}
Please tell me how to use mouse_leave here and make the snap back,
used it in the both drag and drop section like this below
stage.addEventListener(Event.MOUSE_LEAVE, mouseLeave);
but always get some error like stage does not support property x etc. i add some code like equating the x and y but it does not work .. please guide
Jin
MOUSE_LEAVE shows if we are in or out of the stage, but doesn't detect the position of the mouse. You have to collect mouse's data on MOUSE_DOWN, to restrict the instance into the limits.
const LL:uint = 0;
const LT:uint = 0;
const LR:uint = stage.stageWidth;
const LB:uint = stage.stageHeight;
function EnterFrame(e:Event):void {
e.target.x = mouseX;
e.target.y = mouseY;
if (mouseX < LL) {e.target.x = LL;} else if (mouseX > LR) {e.target.x = LR;}
if (mouseY < LT) {e.target.y = LT;} else if (mouseY > LB) {e.target.y = LB;}
}
In your function 'mdown':
e.currentTarget.addEventListener(Event.ENTER_FRAME, EnterFrame);
In your function 'mUp':
target.removeEventListener(Event.ENTER_FRAME, EnterFrame);
General method
Here is the way this can be done. On MOUSE_UP outside the limits, the target is [object stage]. So you have to create a variable __last that will make you recognize the instance (p1 or another) clicked on MOUSE_DOWN. StartDrag() isn't needed:
const LL:uint = 0;
const LT:uint = 0;
const LR:uint = stage.stageWidth;
const LB:uint = stage.stageHeight;
function EnterFrame(e:Event):void {
e.target.x = mouseX;
e.target.y = mouseY;
if (mouseX < LL) {e.target.x = LL;} else if (mouseX > LR) {e.target.x = LR;}
if (mouseY < LT) {e.target.y = LT;} else if (mouseY > LB) {e.target.y = LB;}
}
var __last:*;
p1.addEventListener(MouseEvent.MOUSE_DOWN, OnMouseDown);
function OnMouseDown(e:MouseEvent):void {
__last = MovieClip(e.target);
__last.addEventListener(Event.ENTER_FRAME, EnterFrame);
}
this.stage.addEventListener(MouseEvent.MOUSE_UP, OnMouseUp);
function OnMouseUp(e:MouseEvent):void {
if(__last) __last.removeEventListener(Event.ENTER_FRAME, EnterFrame);
}
To snap it back to original position
const LL:uint = 0;
const LT:uint = 0;
const LR:uint = stage.stageWidth;
const LB:uint = stage.stageHeight;
var __last:*;
var dropIndex:int;
function EnterFrame(e:Event):void {
if (mouseX < LL || mouseX > LR || mouseY < LT || mouseY > LB) {
__last.x = positionsArray[dropIndex].xPos;
__last.y = positionsArray[dropIndex].yPos;
__last.stopDrag();
}
}
var hitArray:Array = new Array(hitTarget1, hitTarget2, hitTarget3);
var dropArray:Array = new Array(drop1, drop2, drop3);
var positionsArray:Array = [];
for (var i:int = 0; i < dropArray.length; i++) {
dropArray[i].buttonMode = true;
dropArray[i].addEventListener(MouseEvent.MOUSE_DOWN, mdown);
dropArray[i].addEventListener(MouseEvent.MOUSE_UP, mUp);
positionsArray.push({xPos:dropArray[i].x, yPos:dropArray[i].y});
}
function mdown(e:MouseEvent):void {
__last = e.currentTarget;
dropIndex = dropArray.indexOf(__last);
setChildIndex(MovieClip(__last), numChildren - 1);
__last.startDrag();
addEventListener(Event.ENTER_FRAME, EnterFrame);
}
function mUp(e:MouseEvent):void {
if (__last.hitTestObject(hitArray[dropIndex])) {
__last.x = hitArray[dropIndex].x;
__last.y = hitArray[dropIndex].y;
} else {
__last.x = positionsArray[dropIndex].xPos;
__last.y = positionsArray[dropIndex].yPos;
}
__last.stopDrag();
removeEventListener(Event.ENTER_FRAME, EnterFrame);
}

AS3 zooming in and out where mouse clicked not at registration

I am trying to have a masked mouse panned image zoom in and out with a click and a double click mouse event. I got the image to zoom but it always zooms in on the left edge registration point, not where I click. I have absolutely no idea how to code this and have spent the whole day on the internet trying to figure it out with no luck. I am hoping someone can help me to figure this out!
import com.greensock.*;//Greensock Tweening Platform.
//Variables
var percX:Number;
var percY:Number;
var destX:Number;
var destY:Number;
//Image panned and masked
this.mask = mask_mc;
stage.addEventListener(MouseEvent.MOUSE_MOVE,mousemove);
function mousemove(e:MouseEvent) {
if (mask_mc.hitTestPoint(stage.mouseX,stage.mouseY,false)) {
if (imgLoader.width>mask_mc.width) {//Avoids Scrolling if image is under mask area width
percX = mask_mc.mouseX/mask_mc.width;
}
if (imgLoader.height>mask_mc.height) {//Avoids Scrolling if image is under mask area height
percY = mask_mc.mouseY/mask_mc.height;
}
destX = -(imgLoader.width-mask_mc.width)*percX;
destY = -(imgLoader.height-mask_mc.height)*percY;
TweenMax.to(imgLoader,.5,{x:destX,y:destY});
}
}
//Add listeners for the imgLoader movie clip.
imgLoader.doubleClickEnabled = true;
imgLoader.addEventListener(MouseEvent.CLICK, increaseSize);
imgLoader.addEventListener(MouseEvent.DOUBLE_CLICK, decreaseSize);
//This function increases the scale of the image
function increaseSize(event:MouseEvent):void{
TweenLite.to(imgLoader, 1, {scaleX:2, scaleY:2});
}
//This function decreases the scale of the image
function decreaseSize(event:MouseEvent):void{
TweenLite.to(imgLoader, 1, {scaleX:1, scaleY:1});
}
This answer is derived from here
Add this function:
function scaleAroundMouse(objectToScale:DisplayObject, scaleAmount:Number, bounds:Rectangle = null, onComplete:Function = null):TweenLite {
// scaling will be done relatively
var relScaleX:Number = scaleAmount / objectToScale.scaleX;
var relScaleY:Number = scaleAmount / objectToScale.scaleY;
// map vector to centre point within parent scope
var scalePoint:Point = objectToScale.localToGlobal( new Point(objectToScale.mouseX, objectToScale.mouseY));
scalePoint = objectToScale.parent.globalToLocal( scalePoint );
// current registered postion AB
var AB:Point = new Point( objectToScale.x, objectToScale.y );
// CB = AB - scalePoint, objectToScale vector that will scale as it runs from the centre
var CB:Point = AB.subtract( scalePoint );
CB.x *= relScaleX;
CB.y *= relScaleY;
// recaulate AB, objectToScale will be the adjusted position for the clip
AB = scalePoint.add( CB );
// set actual properties
if(bounds){
var limits:Rectangle = new Rectangle(
bounds.x + (bounds.width - (objectToScale.width * relScaleX)),
bounds.y + (bounds.height - (objectToScale.height * relScaleY)),
(objectToScale.width * relScaleX) - bounds.width,
(objectToScale.height * relScaleY) - bounds.height
);
if(AB.x < limits.x) AB.x = limits.x;
if(AB.x > limits.x + limits.width) AB.x = limits.x + limits.width;
if(AB.y < limits.y) AB.y = limits.y;
if(AB.y > limits.y + limits.height) AB.y = limits.y + limits.height;
}
return TweenLite.to(objectToScale,1,{onComplete: onComplete, scaleX: scaleAmount, scaleY: scaleAmount, x: AB.x, y: AB.y);
}
Then update your sizing function to this:
function increaseSize(event:MouseEvent):void{
stopMouseMove();
scaleAroundMouse(imgLoader, 2, null, resumeMouseMove);
}
function decreaseSize(event:MouseEvent):void{
stopMouseMove();
scaleAroundMouse(imgLoader, 1, null, resumeMouseMove);
}
function stopMouseMove():void {
stage.removeEventListener(MouseEvent.MOUSE_MOVE,mousemove);
}
function resumeMouseMove():void {
stage.addEventListener(MouseEvent.MOUSE_MOVE,mousemove);
}
I also added a bounds parameter to the function. This is useful if you never want the edges of you content to be visible within the mask. So if you could use it by passing the bounds of your mask to the function:
scaleAroundMouse(imgLoader, 1, myMask.getBounds(this));
This example uses zoom effect classes that may help achieve the zoom effect you are looking for http://graphics-geek.blogspot.com/2010/06/video-image-zoom-effect-in-flex-4.html.
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;
That is taken from a question I posted about a month ago. You can see it here. While I didn't end up going with that specific snippet (I actually went with a modified version of the script LondongDrugs_MediaServ posted), it will work and is much easier to understand and implement.