How can you prevent both jumpiness, and interrupting tweens with animated Flash buttons?
This is something I've never been able to figure out.
You've got a button offscreen you want to animate in. We'll call it 'btn.' You've got a hit area that serves as the proximity sensor to trigger btn's animation. We'll call it 'hitZone' (as to not cause confusion with the hitArea property of display objects).
Both btn and hitZone are MovieClips. The listeners go something like this.
import com.greensock.*;
import com.greensock.easing.*;
import flash.events.MouseEvent;
var endPoint:Number = 31;
hitZone.addEventListener(MouseEvent.ROLL_OVER, onHitZoneOver);
hitZone.addEventListener(MouseEvent.ROLL_OUT, onHitZoneOut);
hitZone.addEventListener(MouseEvent.CLICK, onHitZoneClick);
btn.addEventListener(MouseEvent.ROLL_OVER, onBtnOver);
btn.addEventListener(MouseEvent.ROLL_OUT, onBtnOut);
btn.addEventListener(MouseEvent.CLICK, onBtnClick);
btn.mouseChildren = false;
function onHitZoneOver(e:MouseEvent):void
{
TweenLite.to(btn, 0.75, {x:endPoint, ease:开发者_StackOverflow中文版Expo.easeOut});
trace("over hitZone");
}
function onHitZoneOut(e:MouseEvent):void
{
TweenLite.to(btn, 0.75, {x:-1, ease:Expo.easeOut});
trace("out hitZone");
}
function onBtnOver(e:MouseEvent):void
{
hitZone.mouseEnabled = false;
hitZone.removeEventListener(MouseEvent.ROLL_OVER, onHitZoneOver);
hitZone.removeEventListener(MouseEvent.ROLL_OUT, onHitZoneOut);
trace("over BTN");
// This line is the only thing keeping the btn animation from being fired continuously
// causing jumpiness. However, calling this allows the animation to be interrupted
// at any point.
TweenLite.killTweensOf(btn);
}
function onBtnOut(e:MouseEvent):void
{
hitZone.mouseEnabled = true;
hitZone.addEventListener(MouseEvent.ROLL_OVER, onHitZoneOver);
hitZone.addEventListener(MouseEvent.ROLL_OUT, onHitZoneOut);
trace("out BTN");
}
function onBtnClick(e:MouseEvent):void
{
trace("click BTN");
}
function onHitZoneClick(e:MouseEvent):void
{
trace("click hitZone");
}
The issue is when your mouse is over both the hitZone and btn. The button continuously jumps unless you call TweenLite.killAllTweensOf(). This fixes the jumpiness, but it introduces a new problem. Now, it's very easy to interrupt the animation of the btn at any point, stopping it before it's totally visible on the stage.
I've seen similar posts, but even they suffer from the same issue. Perhaps it's a problem with how Flash detects edges, because I've never once seen a workaround for this.
IIRC to fix this issue, when dealing with proximity zones, I used the mouse position to show/hide the content (the button). I would use the hitZone to trigger a mouse move listener. Once the mouse position is outside the hitZone: hide the button and remove the mouse move listener.
import com.greensock.*;
import com.greensock.easing.*;
import flash.events.MouseEvent;
var endPoint:Number = 31;
hitZone.addEventListener(MouseEvent.ROLL_OVER, onHitZoneOver);
hitZone.addEventListener(MouseEvent.CLICK, onHitZoneClick);
btn.addEventListener(MouseEvent.ROLL_OVER, onBtnOver);
btn.addEventListener(MouseEvent.ROLL_OUT, onBtnOut);
btn.addEventListener(MouseEvent.CLICK, onBtnClick);
btn.mouseChildren = false;
function onHitZoneOver(e:MouseEvent):void
{
TweenLite.to(btn, 0.75, {x:endPoint, ease:Expo.easeOut});
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMoved);
hitZone.removeEventListener(MouseEvent.ROLL_OVER, onHitZoneOver);
trace("over hitZone");
}
function onHitZoneOut(e:MouseEvent):void
{
TweenLite.to(btn, 0.75, {x:-1, ease:Expo.easeOut});
trace("out hitZone");
}
function onBtnOver(e:MouseEvent):void
{
trace("over BTN");
}
function onBtnOut(e:MouseEvent):void
{
trace("out BTN");
}
function onBtnClick(e:MouseEvent):void
{
trace("click BTN");
}
function onHitZoneClick(e:MouseEvent):void
{
trace("click hitZone");
}
function onMouseMoved(e:MouseEvent):void
{
if( !hitZone.hitTestPoint(mouseX, mouseY) )
{
trace("Sacrebleu!");
TweenLite.to(btn, 0.75, {x:-41, ease:Expo.easeOut});
stage.removeEventListener( MouseEvent.MOUSE_MOVE, onMouseMoved );
hitZone.addEventListener(MouseEvent.ROLL_OVER, onHitZoneOver);
}
}
Don't know if I got it right, but perhaps you should remove the onHitZoneOver listener right away and wait until the button tween is complete so you can trigger it again;
Something like this:
hitZone.addEventListener(MouseEvent.MOUSE_OVER, hitAreaOver);
hitZone.addEventListener(MouseEvent.MOUSE_OUT, hitAreaOut);
function onHitZoneOver(event:MouseEvent):void
{
hitZone.removeEventListener(MouseEvent.MOUSE_OVER, hitAreaOver);
TweenLite.to(btn, 0.75, {x:endPoint, ease:Expo.easeOut});
trace("over hitZone");
}
function onHitZoneOut(e:MouseEvent):void
{
TweenLite.to(btn, 0.75, {x:-1, ease:Expo.easeOut});
trace("out hitZone");
hitZone.addEventListener(MouseEvent.MOUSE_OVER, hitAreaOver);
}
精彩评论