Jump to content
GreenSock

mhigley

AS3 combining TweenLite and MOUSE_LEAVE

Recommended Posts

Hey everyone.

 

I'm just starting to take user leaving the stage into consideration for current and all future projects and I've got the basic idea... so I figured I'd start weaving some GS love into the recipe and I'm having mixed results. The code seems simple enough, but I can't figure out what's not being calculated correctly.

 

Roll over the stage and the box tracks the x, and y position of the mouse...

Roll out of the stage and the square re-centers itself.

Should the user roll back onto the stage, I'm wanting the square to tween over 0.5 seconds back to the x and y of the mouse.

 

But it's that last part that's causing my headache. I just can't find any reason the code shouldn't work. :|

 

The code is below and I've also put it on my test site since the IDE doesn't register rolling off the stage. Thanks for all the help.

 

-JR

 

import com.greensock.TweenLite;
import com.greensock.easing.*;

function init():void
{
stage.addEventListener(Event.MOUSE_LEAVE, boxHide);
stage.addEventListener(MouseEvent.MOUSE_MOVE, cursorFollow);
}

function boxHide(e:Event):void
{
TweenLite.to(box_mc, 1, {x: stage.stageWidth/2, y:stage.stageHeight/2});
}

function cursorFollow(e:MouseEvent):void
{
if (box_mc.x == stage.stageWidth/2 && box_mc.y == stage.stageHeight/2)
{
	TweenLite.to(box_mc, 1, {x:mouseX, y:mouseY});
}
box_mc.x = mouseX;
box_mc.y = mouseY;
}
init();

Link to comment
Share on other sites

There are a few problems with your code:

 

1) You are setting box_mc.x and box_mc.y inside the cursorFollow() function no matter what, so when you have a tween going, you're fighting with the tween for control. Whichever code executes last wins.

 

2) You're only starting the tween if the box_mc is in the center of the screen, but what if the mouse leaves and then comes back within 0.5 seconds? box_mc won't be in the center yet, so that tween will continue to run and again, you'll have competing code.

 

There are several ways to accomplish this, but there's one (untested):

 

var mouseLeft:Boolean = false;
var findingMouse:Boolean = false;
var tween:TweenMax;

function init():void {
  stage.addEventListener(Event.MOUSE_LEAVE, boxHide);
  stage.addEventListener(MouseEvent.MOUSE_MOVE, cursorFollow);
}

function boxHide(e:Event):void {
  TweenLite.to(box_mc, 1, {x:stage.stageWidth/2, y:stage.stageHeight/2});
  mouseLeft = true;
}

function cursorFollow(e:MouseEvent):void {
  if (mouseLeft) {
   tween = new TweenMax(box_mc, 1, {x:mouseX, y:mouseY, onComplete:onFindMouse});
   mouseLeft = false;
   findingMouse = true;
  } else if (findingMouse) {
   tween.updateTo({x:mouseX, y:mouseY}, false);
  } else {
     box_mc.x = mouseX;
     box_mc.y = mouseY
  }
}

function onFindMouse():void {
findingMouse = false;
}

 

It could be a bit more elegant with the dynamicProps plugin but that's a membership benefit of Club GreenSock so I'm not sure if you have it. There's an interactive example of dynamicProps in the Plugin Explorer and it's doing almost exactly what you're trying to do here (tweening to the mouse position). But TweenMax's new updateTo() method will accomplish this sort of thing as well.

 

Hope that helps.

Link to comment
Share on other sites

I'm still having a few issues controlling my tweens with a mouse_leave.

 

Now I'm having the square rotate based on the location of the mouse which all works fine, but I'm trying now to completely kill the tween when the user has rolled off the stage, and only respond again until the mouse rolls over the stage again. The problem is most apparent when testing in Safari... roll off the stage and the tween falls to a set position but if anywhere outside of the stage is clicked the movieclip still responds to the mouse input. And god forbid the user click on another open window, cuz that makes the movieclip completely wig out!! :x

 

Any recommendations?

 

Here's a live demo to check out.

 

Thanks

-JR

 

import com.greensock.TweenLite;
import com.greensock.easing.*;

var rotateBox:TweenLite;

function init():void
{
stage.addEventListener(Event.MOUSE_LEAVE, boxReset);
stage.addEventListener(MouseEvent.MOUSE_MOVE, cursorFollow);
}
init();

function boxReset(e:Event):void
{
removeEventListener(Event.ENTER_FRAME, loop);
TweenLite.to(box_mc, 2, {rotationY:-25,
                    rotationX:-10,
                    ease:Strong.easeOut
                    });
rotateBox.kill();
}

function cursorFollow(e:MouseEvent):void
{
addEventListener(Event.ENTER_FRAME, loop);
}
function loop(e:Event):void
{
  var distX:Number = mouseX / stage.stageWidth;
  var distY:Number = mouseY / stage.stageHeight;
  rotateBox = new TweenLite(box_mc, 2, {rotationY:(-30 + (70 * distX)), 			
												rotationX:(30 - (70 * distY)),
                    								ease:Strong.easeOut
                    								});
}

Link to comment
Share on other sites

Why do you have a MOUSE_MOVE handler that adds an ENTER_FRAME listener every single time the mouse moves?! That's a huge waste.

 

I'm not sure why you're doing some of the stuff you're doing in the code, but it seems to me like this would probably work:

 

function init():void {
  stage.addEventListener(Event.MOUSE_LEAVE, boxReset);
  stage.addEventListener(MouseEvent.MOUSE_MOVE, loop);
}
init();

function boxReset(e:Event):void {
  TweenLite.to(box_mc, 2, {rotationY:-25, rotationX:-10, ease:Strong.easeOut});
}

function loop(e:Event):void {
  var distX:Number = mouseX / stage.stageWidth;
  var distY:Number = mouseY / stage.stageHeight;
  rotateBox = new TweenLite(box_mc, 2, {rotationY:(-30 + (70 * distX)), rotationX:(30 - (70 * distY)), ease:Strong.easeOut});
}

 

You may be seeing the functions called in Safari because of a bug in either Safari or the Flash Player that's built for Safari (maybe it continues to dispatch MOUSE_MOVE events even after the mouse has left the stage). In that case, you'd probably need to check the mouseX and mouseY and see if maybe they're reporting outside of (or directly on top of) the stage's edges/boundaries and if so, ignore them. Just an idea.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×