feathersui / feathersui-starling

User interface components for Starling Framework and Adobe AIR
https://feathersui.com/learn/as3-starling/
Other
914 stars 386 forks source link

Possible minor tweening issue in `BaseEffectContext` @ `playReverse()` #1826

Closed 2jfw closed 7 months ago

2jfw commented 7 months ago

I was playing around with the StackScreenNavigator and added a popTransition like = Slide.createSlideRightTransition(.3, Transitions.EASE_OUT);

Scenario: Two screens in the navigator, currently being on the second screen right to the initial screen 1.

Action: Touch-Slide back to the left to go back to screen 1 but not finishing the action so that handleDragEnd with _dragCancelled = true gets called, which is calling _dragEffectContext.playReverse();.

Observation: The effect does not tween back in the given duration but resets kind of immediately due to the low calculated duration (var duration:Number = this._duration * this._position;) which is ~0.0x s.

Workaround: Similar to the play function's determination of duration, adding a "1" like the following:

Old/Before: var duration:Number = this._duration * this._position;

New/After:

var duration:Number = this._duration * (1 + this._position);

will resolve the issue and slide back on cancel tweens as expected. Unsure if this is the correct solution or just a workaround though.

In the case this is an actual issue and the correct way to fix it, I can create a pull request for the fix

joshtynjala commented 7 months ago

I'm not sure that I understand your proposal.

Let's assume that a Slide transition's duration is 2 seconds. Here are some scenarios that explain how it should behave with the current behavior when playing in reverse (this._duration * this._position):

  1. The starting position is 1.0 (at the end). Playing in reverse will require the entire duration: 2 seconds.
  2. The starting position is 0.5. Playing in reverse should require sliding half the x/y distance, so the reverse duration is calculated as half the original duration too: 1 second.
  3. The starting position is 0.0 (at the beginning). It is already fully reversed. No animation needs to play because the final x/y is the same as the starting x/y: 0 seconds duration.

Here's how it would behave with your proposed new behavior when playing in reverse (this._duration * (1 + this._position)):

  1. The starting position is 1.0 (at the end). Playing in reverse will require 4 seconds (2 * (1 + 1)). That's twice as long as the original duration, for the same distance. It should never be more than 2 seconds.
  2. The starting position is 0.5. Playing in reverse will require 3 seconds (2 * (1 + 0.5)). It will slide only half the x/y distance, but the duration is (again), over 2 seconds.
  3. The starting position is 0.0 (at the beginning). Playing in reverse will require 2 seconds (2 * (1 + 0)), but there is nothing to see because the starting x/y is the same as the final x/y.
2jfw commented 7 months ago

Thanks for the input on this - seems I was on the wrong track with the workaround, which actually worked quite well in my scenario to fix the very short resulting duration, but it's obviously wrong. I will probably need to check more in depth regarding the position property. I set the distance (/ratio) to perform the successful drag to a lower value as the default and I will have to check if this is causing the low duration.