Skip to content

Commit

Permalink
ScreenNavigator, StackScreenNavigator: added an experimental workarou…
Browse files Browse the repository at this point in the history
…nd for the issue where the first few frames of a transition can be skipped. the full animation is now visible even on slow mobile devices.
  • Loading branch information
joshtynjala committed Dec 18, 2014
1 parent 9c26e3c commit b37b803
Showing 1 changed file with 50 additions and 2 deletions.
52 changes: 50 additions & 2 deletions source/feathers/controls/supportClasses/BaseScreenNavigator.as
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,16 @@ package feathers.controls.supportClasses
this.invalidate(INVALIDATION_FLAG_SIZE);
}

/**
* @private
*/
protected var _waitingTransition:Function;

/**
* @private
*/
private var _waitingForTransitionFrameCount:int = 1;

/**
* @private
*/
Expand Down Expand Up @@ -602,7 +612,14 @@ package feathers.controls.supportClasses
}
if(transition != null)
{
transition(this._previousScreenInTransition, this._activeScreen, transitionComplete);
//temporarily make the active screen invisible because the
//transition doesn't start right away.
this._activeScreen.visible = false;
this._waitingForTransitionFrameCount = 0;
this._waitingTransition = transition;
//this is a workaround for an issue with transition performance.
//see the comment in the listener for details.
this.addEventListener(Event.ENTER_FRAME, waitingForTransition_enterFrameHandler);
}
else
{
Expand Down Expand Up @@ -646,7 +663,12 @@ package feathers.controls.supportClasses
{
this.dispatchEventWith(FeathersEventType.TRANSITION_START);
this._previousScreenInTransition.dispatchEventWith(FeathersEventType.TRANSITION_OUT_START);
transition(this._previousScreenInTransition, null, transitionComplete);

this._waitingForTransitionFrameCount = 0;
this._waitingTransition = transition;
//this is a workaround for an issue with transition performance.
//see the comment in the listener for details.
this.addEventListener(Event.ENTER_FRAME, waitingForTransition_enterFrameHandler);
}
this.invalidate(INVALIDATION_FLAG_SELECTED);
}
Expand Down Expand Up @@ -764,5 +786,31 @@ package feathers.controls.supportClasses
{
this.invalidate(INVALIDATION_FLAG_SIZE);
}

/**
* @private
*/
private function waitingForTransition_enterFrameHandler(event:Event):void
{
//we need to wait a couple of frames before we can start the
//transition to make it as smooth as possible. this feels a little
//hacky, to be honest, but I can't figure out why waiting only one
//frame won't do the trick. the delay is so small though that it's
//virtually impossible to notice.
if(this._waitingForTransitionFrameCount < 2)
{
this._waitingForTransitionFrameCount++;
return;
}
this.removeEventListener(Event.ENTER_FRAME, waitingForTransition_enterFrameHandler);
if(this._activeScreen)
{
this._activeScreen.visible = true;
}

var transition:Function = this._waitingTransition;
this._waitingTransition = null;
transition(this._previousScreenInTransition, this._activeScreen, transitionComplete);
}
}
}

7 comments on commit b37b803

@harry248
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes a big difference. Thanks!

@harry248
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But now sometimes an exception is thrown because item equals null in line 734 of BaseScreenNavigator.

@joshtynjala
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know how to reproduce that issue. Are you removing a screen? If so, when?

@apellerano-kong
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This commit causes my very first frame of stage3d drawing to be invisible. I was doing the trick where you draw a flash.display.Bitmap to the flash stage and then listen for Starling's Event.ROOT_CREATED to convert it into a starling.textures.Texture. The effect is a seamless transition from preloader image to the game's background image. With this commit there is exactly 1 frame of white flash while it waits for the ENTER_FRAME, which ruins the effect.

I could try and avoid the visibility toggle if I could set myScreenNavigator.transition = null, but if you try to set transition to null in ScreenNavigator it detects the null and assigns it defaultTransition() instead (which does nothing).

So there's not really a workaround for this right now other than to rollback to a previous commit.

@joshtynjala
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. I'll see what I can do.

@joshtynjala
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I just pushed some changes that should clear this up. If the transition is null, the ScreenNavigator won't wait for Event.ENTER_FRAME. There is no animation to optimize in that case, so it just shows the new screen instantly. That should once again allow for a preloader image while Starling initializes.

@apellerano-kong
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works perfectly

Please sign in to comment.