From 8132bdc162705394e7a9dad115ad3727f690f30b Mon Sep 17 00:00:00 2001 From: ahopper Date: Wed, 31 Oct 2018 09:49:43 +0000 Subject: [PATCH 1/5] end animation cleanly with correct value --- src/Avalonia.Animation/AnimationInstance`1.cs | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/Avalonia.Animation/AnimationInstance`1.cs b/src/Avalonia.Animation/AnimationInstance`1.cs index 1ad609bce8..04c91ced99 100644 --- a/src/Avalonia.Animation/AnimationInstance`1.cs +++ b/src/Avalonia.Animation/AnimationInstance`1.cs @@ -141,9 +141,6 @@ namespace Avalonia.Animation } else if (time > iterationEndpoint) { - //Subtract first iteration to properly get the subsequent iteration time - time -= iterationEndpoint; - if (!_iterationDelay & delayEndpoint > TimeSpan.Zero) { delayEndpoint = TimeSpan.Zero; @@ -151,27 +148,32 @@ namespace Avalonia.Animation } //Calculate the current iteration number - _currentIteration = (int)Math.Floor((double)((double)time.Ticks / iterationEndpoint.Ticks)) + 2; + _currentIteration = (int)Math.Floor((double)((double)time.Ticks / iterationEndpoint.Ticks))+1; } else { return; } - time = TimeSpan.FromTicks((long)(time.Ticks % iterationEndpoint.Ticks)); - - if (!_isLooping) - { - if ((_currentIteration > _repeatCount) || (time > iterationEndpoint)) - DoComplete(); - } - - // Determine if the current iteration should have its normalized time inverted. + // Determine if the current iteration should have its normalized time inverted. bool isCurIterReverse = _animationDirection == PlaybackDirection.Normal ? false : _animationDirection == PlaybackDirection.Alternate ? (_currentIteration % 2 == 0) ? false : true : _animationDirection == PlaybackDirection.AlternateReverse ? (_currentIteration % 2 == 0) ? true : false : _animationDirection == PlaybackDirection.Reverse ? true : false; - + + if (!_isLooping) + { + if ((_currentIteration > _repeatCount) || (time >= iterationEndpoint)) + { + var easedTime = _easeFunc.Ease(isCurIterReverse?0.0:1.0); + _lastInterpValue = _interpolator(easedTime, _neutralValue); + + DoComplete(); + return; + } + } + time = TimeSpan.FromTicks((long)(time.Ticks % iterationEndpoint.Ticks)); + if (delayEndpoint > TimeSpan.Zero & time < delayEndpoint) { DoDelay(); From 8864dc8e10e4ac36e6222451176ab93980c005ac Mon Sep 17 00:00:00 2001 From: ahopper Date: Wed, 31 Oct 2018 11:36:01 +0000 Subject: [PATCH 2/5] Fix repeating animations --- src/Avalonia.Animation/AnimationInstance`1.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Avalonia.Animation/AnimationInstance`1.cs b/src/Avalonia.Animation/AnimationInstance`1.cs index 04c91ced99..273c59df0a 100644 --- a/src/Avalonia.Animation/AnimationInstance`1.cs +++ b/src/Avalonia.Animation/AnimationInstance`1.cs @@ -163,7 +163,8 @@ namespace Avalonia.Animation if (!_isLooping) { - if ((_currentIteration > _repeatCount) || (time >= iterationEndpoint)) + var totalTime = _repeatCount * _duration.Ticks + _delay.Ticks; + if (time.Ticks >= totalTime) { var easedTime = _easeFunc.Ease(isCurIterReverse?0.0:1.0); _lastInterpValue = _interpolator(easedTime, _neutralValue); From 29aad6bc9a35839fc2718ab1b6ec61844b554b1b Mon Sep 17 00:00:00 2001 From: ahopper Date: Wed, 31 Oct 2018 12:09:06 +0000 Subject: [PATCH 3/5] allow for Delay --- src/Avalonia.Animation/AnimationInstance`1.cs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/Avalonia.Animation/AnimationInstance`1.cs b/src/Avalonia.Animation/AnimationInstance`1.cs index 273c59df0a..5f8e33b09a 100644 --- a/src/Avalonia.Animation/AnimationInstance`1.cs +++ b/src/Avalonia.Animation/AnimationInstance`1.cs @@ -133,6 +133,7 @@ namespace Avalonia.Animation DoPlayStates(); var delayEndpoint = _delay; var iterationEndpoint = delayEndpoint + _duration; + var iterationTime = time; //determine if time is currently in the first iteration. if (time >= TimeSpan.Zero & time <= iterationEndpoint) @@ -141,6 +142,9 @@ namespace Avalonia.Animation } else if (time > iterationEndpoint) { + //Subtract first iteration to properly get the subsequent iteration time + iterationTime -= iterationEndpoint; + if (!_iterationDelay & delayEndpoint > TimeSpan.Zero) { delayEndpoint = TimeSpan.Zero; @@ -148,7 +152,7 @@ namespace Avalonia.Animation } //Calculate the current iteration number - _currentIteration = (int)Math.Floor((double)((double)time.Ticks / iterationEndpoint.Ticks))+1; + _currentIteration = Math.Max(_repeatCount,(int)Math.Floor((double)((double)iterationTime.Ticks / iterationEndpoint.Ticks)) + 2); } else { @@ -173,20 +177,20 @@ namespace Avalonia.Animation return; } } - time = TimeSpan.FromTicks((long)(time.Ticks % iterationEndpoint.Ticks)); + iterationTime = TimeSpan.FromTicks((long)(iterationTime.Ticks % iterationEndpoint.Ticks)); - if (delayEndpoint > TimeSpan.Zero & time < delayEndpoint) + if (delayEndpoint > TimeSpan.Zero & iterationTime < delayEndpoint) { DoDelay(); } else { // Offset the delay time - time -= delayEndpoint; + iterationTime -= delayEndpoint; iterationEndpoint -= delayEndpoint; // Normalize time - var interpVal = (double)time.Ticks / iterationEndpoint.Ticks; + var interpVal = (double)iterationTime.Ticks / iterationEndpoint.Ticks; if (isCurIterReverse) interpVal = 1 - interpVal; From d82a25ea5f72fd51b344c7accff9360e76abddf1 Mon Sep 17 00:00:00 2001 From: ahopper Date: Wed, 31 Oct 2018 12:25:17 +0000 Subject: [PATCH 4/5] fix reversing --- src/Avalonia.Animation/AnimationInstance`1.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Avalonia.Animation/AnimationInstance`1.cs b/src/Avalonia.Animation/AnimationInstance`1.cs index 5f8e33b09a..ea033d8cc9 100644 --- a/src/Avalonia.Animation/AnimationInstance`1.cs +++ b/src/Avalonia.Animation/AnimationInstance`1.cs @@ -152,7 +152,7 @@ namespace Avalonia.Animation } //Calculate the current iteration number - _currentIteration = Math.Max(_repeatCount,(int)Math.Floor((double)((double)iterationTime.Ticks / iterationEndpoint.Ticks)) + 2); + _currentIteration = Math.Min(_repeatCount,(int)Math.Floor((double)((double)iterationTime.Ticks / iterationEndpoint.Ticks)) + 2); } else { From bb0bb392821eefde12ef9fc985c93c2665038e2a Mon Sep 17 00:00:00 2001 From: ahopper Date: Wed, 31 Oct 2018 15:25:42 +0000 Subject: [PATCH 5/5] respect FillMode=Forward if animation stopped part way through --- src/Avalonia.Animation/AnimationInstance`1.cs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/Avalonia.Animation/AnimationInstance`1.cs b/src/Avalonia.Animation/AnimationInstance`1.cs index ea033d8cc9..8184e68d42 100644 --- a/src/Avalonia.Animation/AnimationInstance`1.cs +++ b/src/Avalonia.Animation/AnimationInstance`1.cs @@ -72,10 +72,13 @@ namespace Avalonia.Animation _onCompleteAction = OnComplete; _interpolator = Interpolator; _baseClock = baseClock; - } + } protected override void Unsubscribed() { + //Animation may have been stopped before it has finished + ApplyFinalFill(); + _timerSubscription?.Dispose(); _clock.PlayState = PlayState.Stop; } @@ -98,11 +101,15 @@ namespace Avalonia.Animation } } - private void DoComplete() + private void ApplyFinalFill() { if (_fillMode == FillMode.Forward || _fillMode == FillMode.Both) _targetControl.SetValue(_parent.Property, _lastInterpValue, BindingPriority.LocalValue); + } + private void DoComplete() + { + ApplyFinalFill(); _onCompleteAction?.Invoke(); PublishCompleted(); } @@ -167,10 +174,10 @@ namespace Avalonia.Animation if (!_isLooping) { - var totalTime = _repeatCount * _duration.Ticks + _delay.Ticks; + var totalTime = _iterationDelay ? _repeatCount * ( _duration.Ticks + _delay.Ticks) : _repeatCount * _duration.Ticks + _delay.Ticks; if (time.Ticks >= totalTime) { - var easedTime = _easeFunc.Ease(isCurIterReverse?0.0:1.0); + var easedTime = _easeFunc.Ease(isCurIterReverse ? 0.0 : 1.0); _lastInterpValue = _interpolator(easedTime, _neutralValue); DoComplete();