Browse Source

Fix #11819

pull/11821/head
Jumar Macato 3 years ago
parent
commit
634ccedd0c
  1. 119
      src/Avalonia.Base/Animation/AnimationInstance`1.cs

119
src/Avalonia.Base/Animation/AnimationInstance`1.cs

@ -58,6 +58,9 @@ namespace Avalonia.Animation
if (_animation.Duration < TimeSpan.Zero) if (_animation.Duration < TimeSpan.Zero)
throw new InvalidOperationException("Duration value cannot be negative."); throw new InvalidOperationException("Duration value cannot be negative.");
if (_animation.Delay < TimeSpan.Zero)
throw new InvalidOperationException("Delay value cannot be negative.");
_easeFunc = _animation.Easing; _easeFunc = _animation.Easing;
_speedRatioConv = 1d / _animation.SpeedRatio; _speedRatioConv = 1d / _animation.SpeedRatio;
@ -151,72 +154,74 @@ namespace Avalonia.Animation
var iterDelay = _iterationDelay.Ticks * _speedRatioConv; var iterDelay = _iterationDelay.Ticks * _speedRatioConv;
var initDelay = _initialDelay.Ticks * _speedRatioConv; var initDelay = _initialDelay.Ticks * _speedRatioConv;
if (indexTime > 0 & indexTime <= initDelay) // This conditional checks if the time given is the very start/zero
// and when we have an active delay time.
if (initDelay > 0 && indexTime <= initDelay)
{ {
DoDelay(); DoDelay();
return;
} }
else
// Calculate timebases.
var iterationTime = iterDuration + iterDelay;
var opsTime = indexTime - initDelay;
var playbackTime = opsTime % iterationTime;
_currentIteration = (ulong)(opsTime / iterationTime);
// Stop animation when the current iteration is beyond the iteration count or
// when the duration is set to zero while animating and snap to the last iterated value.
if (_currentIteration + 1 > _iterationCount || _duration == TimeSpan.Zero)
{ {
// Calculate timebases. var easedTime = _easeFunc!.Ease(_playbackReversed ? 0.0 : 1.0);
var iterationTime = iterDuration + iterDelay; _lastInterpValue = _interpolator(easedTime, _neutralValue);
var opsTime = indexTime - initDelay; DoComplete();
var playbackTime = opsTime % iterationTime; }
_currentIteration = (ulong)(opsTime / iterationTime); if (playbackTime <= iterDuration)
{
// Normalize time for interpolation.
var normalizedTime = playbackTime / iterDuration;
// Stop animation when the current iteration is beyond the iteration count or // Check if normalized time needs to be reversed according to PlaybackDirection
// when the duration is set to zero while animating and snap to the last iterated value.
if (_currentIteration + 1 > _iterationCount || _duration == TimeSpan.Zero)
{
var easedTime = _easeFunc!.Ease(_playbackReversed ? 0.0 : 1.0);
_lastInterpValue = _interpolator(easedTime, _neutralValue);
DoComplete();
}
if (playbackTime <= iterDuration) switch (_playbackDirection)
{
// Normalize time for interpolation.
var normalizedTime = playbackTime / iterDuration;
// Check if normalized time needs to be reversed according to PlaybackDirection
switch (_playbackDirection)
{
case PlaybackDirection.Normal:
_playbackReversed = false;
break;
case PlaybackDirection.Reverse:
_playbackReversed = true;
break;
case PlaybackDirection.Alternate:
_playbackReversed = _currentIteration % 2 != 0;
break;
case PlaybackDirection.AlternateReverse:
_playbackReversed = _currentIteration % 2 == 0;
break;
default:
throw new InvalidOperationException($"Animation direction value is unknown: {_playbackDirection}");
}
if (_playbackReversed)
normalizedTime = 1 - normalizedTime;
// Ease and interpolate
var easedTime = _easeFunc!.Ease(normalizedTime);
_lastInterpValue = _interpolator(easedTime, _neutralValue);
PublishNext(_lastInterpValue);
}
else if (playbackTime > iterDuration &
playbackTime <= iterationTime &
iterDelay > 0)
{ {
// The last iteration's trailing delay should be skipped. case PlaybackDirection.Normal:
if (_currentIteration + 1 < _iterationCount) _playbackReversed = false;
DoDelay(); break;
else case PlaybackDirection.Reverse:
DoComplete(); _playbackReversed = true;
break;
case PlaybackDirection.Alternate:
_playbackReversed = _currentIteration % 2 != 0;
break;
case PlaybackDirection.AlternateReverse:
_playbackReversed = _currentIteration % 2 == 0;
break;
default:
throw new InvalidOperationException(
$"Animation direction value is unknown: {_playbackDirection}");
} }
if (_playbackReversed)
normalizedTime = 1 - normalizedTime;
// Ease and interpolate
var easedTime = _easeFunc!.Ease(normalizedTime);
_lastInterpValue = _interpolator(easedTime, _neutralValue);
PublishNext(_lastInterpValue);
}
else if (playbackTime > iterDuration &&
playbackTime <= iterationTime &&
iterDelay > 0)
{
// The last iteration's trailing delay should be skipped.
if (_currentIteration + 1 < _iterationCount)
DoDelay();
else
DoComplete();
} }
} }

Loading…
Cancel
Save