diff --git a/samples/RenderTest/ViewModels/AnimationsPageViewModel.cs b/samples/RenderTest/ViewModels/AnimationsPageViewModel.cs
index b7f6086d0f..17eee547a1 100644
--- a/samples/RenderTest/ViewModels/AnimationsPageViewModel.cs
+++ b/samples/RenderTest/ViewModels/AnimationsPageViewModel.cs
@@ -17,14 +17,14 @@ namespace RenderTest.ViewModels
{
switch (Timing.GetGlobalPlayState())
{
- case PlayState.Running:
+ case PlayState.Run:
PlayStateText = "Resume all animations";
- Timing.SetGlobalPlayState(PlayState.Paused);
+ Timing.SetGlobalPlayState(PlayState.Pause);
break;
- case PlayState.Paused:
+ case PlayState.Pause:
PlayStateText = "Pause all animations";
- Timing.SetGlobalPlayState(PlayState.Running);
+ Timing.SetGlobalPlayState(PlayState.Run);
break;
}
}
diff --git a/src/Avalonia.Animation/Animatable.cs b/src/Avalonia.Animation/Animatable.cs
index 8359d22c51..f88c25fd0e 100644
--- a/src/Avalonia.Animation/Animatable.cs
+++ b/src/Avalonia.Animation/Animatable.cs
@@ -8,6 +8,8 @@ using System.Reactive.Linq;
using Avalonia.Collections;
using Avalonia.Animation.Transitions;
using System.Collections.Generic;
+using System.Threading;
+using System.Collections.Concurrent;
namespace Avalonia.Animation
{
@@ -22,29 +24,69 @@ namespace Avalonia.Animation
public Animatable()
{
Transitions = new Transitions.Transitions();
+ AnimatableTimer = Timing.AnimationStateTimer
+ .Select(p =>
+ {
+ if (p == PlayState.Run
+ && this._playState == PlayState.Run)
+ return _animationTime++;
+ else
+ return _animationTime;
+ })
+ .Publish()
+ .RefCount();
}
///
- /// Defines the property.
+ /// The specific animations timer for this control.
///
- public static readonly DirectProperty AnimationPlayStateProperty =
+ ///
+ public IObservable AnimatableTimer;
+
+ internal void PrepareAnimatableForAnimation()
+ {
+ if (!_animationsInitialized)
+ {
+
+
+ _animationsInitialized = true;
+ }
+ }
+
+ bool _animationsInitialized = false;
+
+ // internal ConcurrentDictionary _animationStates;
+
+ internal ulong _animationTime;
+
+ // internal int _iterationTokenCounter;
+
+ // internal uint GetIterationToken()
+ // {
+ // return (uint)Interlocked.Increment(ref _iterationTokenCounter);
+ // }
+
+ ///
+ /// Defines the property.
+ ///
+ public static readonly DirectProperty PlayStateProperty =
AvaloniaProperty.RegisterDirect(
- nameof(AnimationPlayState),
- o => o.AnimationPlayState,
- (o, v) => o.AnimationPlayState = v);
+ nameof(PlayState),
+ o => o.PlayState,
+ (o, v) => o.PlayState = v);
///
/// Gets or sets the state of the animation for this
/// control.
///
- public PlayState AnimationPlayState
- {
- get { return _animationPlayState; }
- set { SetAndRaise(AnimationPlayStateProperty, ref _animationPlayState, value); }
-
+ public PlayState PlayState
+ {
+ get { return _playState; }
+ set { SetAndRaise(PlayStateProperty, ref _playState, value); }
+
}
- private PlayState _animationPlayState;
+ private PlayState _playState = PlayState.Run;
///
/// Defines the property.
diff --git a/src/Avalonia.Animation/Animation.cs b/src/Avalonia.Animation/Animation.cs
index eb97093b06..c3a31d05fa 100644
--- a/src/Avalonia.Animation/Animation.cs
+++ b/src/Avalonia.Animation/Animation.cs
@@ -64,6 +64,8 @@ namespace Avalonia.Animation
///
public IDisposable Apply(Animatable control, IObservable matchObs)
{
+ control.PrepareAnimatableForAnimation();
+
foreach (IKeyFrames keyframes in Children)
{
_subscription.Add(keyframes.Apply(this, control, matchObs));
diff --git a/src/Avalonia.Animation/Keyframes/KeyFrame.cs b/src/Avalonia.Animation/Keyframes/KeyFrame.cs
index e4a8e59ab1..9a9f9ba940 100644
--- a/src/Avalonia.Animation/Keyframes/KeyFrame.cs
+++ b/src/Avalonia.Animation/Keyframes/KeyFrame.cs
@@ -13,7 +13,6 @@ namespace Avalonia.Animation.Keyframes
public class KeyFrame
{
internal bool timeSpanSet, cueSet;
-
private TimeSpan _ktimeSpan;
private Cue _kCue;
diff --git a/src/Avalonia.Animation/Keyframes/KeyFrames.cs b/src/Avalonia.Animation/Keyframes/KeyFrames.cs
index 34576beb7d..a6dee814c1 100644
--- a/src/Avalonia.Animation/Keyframes/KeyFrames.cs
+++ b/src/Avalonia.Animation/Keyframes/KeyFrames.cs
@@ -29,6 +29,7 @@ namespace Avalonia.Animation.Keyframes
private bool IsVerfifiedAndConverted;
+
///
public virtual IDisposable Apply(Animation animation, Animatable control, IObservable obsMatch)
{
@@ -38,11 +39,12 @@ namespace Avalonia.Animation.Keyframes
return obsMatch
.Where(p => p == true)
// Ignore triggers when global timers are paused.
- .Where(p=> Timing.GetGlobalPlayState() != PlayState.Paused)
+ .Where(p=> Timing.GetGlobalPlayState() == PlayState.Run)
.Subscribe(_ =>
{
var interp = DoInterpolation(animation, control)
.Select(p => (object)p);
+
control.Bind(Property, interp, BindingPriority.Animation);
});
}
diff --git a/src/Avalonia.Animation/PlayState.cs b/src/Avalonia.Animation/PlayState.cs
index ae2890cce1..a76a680eb8 100644
--- a/src/Avalonia.Animation/PlayState.cs
+++ b/src/Avalonia.Animation/PlayState.cs
@@ -6,7 +6,7 @@ namespace Avalonia.Animation
{
public enum PlayState
{
- Running,
- Paused
+ Run,
+ Pause
}
}
diff --git a/src/Avalonia.Animation/Timing.cs b/src/Avalonia.Animation/Timing.cs
index 0714b9e201..95fc0328c2 100644
--- a/src/Avalonia.Animation/Timing.cs
+++ b/src/Avalonia.Animation/Timing.cs
@@ -16,7 +16,7 @@ namespace Avalonia.Animation
public static class Timing
{
static ulong _animationsFrameCount, _transitionsFrameCount;
- static PlayState _globalState = PlayState.Running;
+ static PlayState _globalState = PlayState.Run;
///
/// The number of frames per second.
@@ -35,18 +35,10 @@ namespace Avalonia.Animation
{
var globalTimer = Observable.Interval(Tick, AvaloniaScheduler.Instance);
- AnimationTimer = globalTimer
+ AnimationStateTimer = globalTimer
.Select(_ =>
{
- switch (_globalState)
- {
- case PlayState.Paused:
- break;
- default:
- _animationsFrameCount ++;
- break;
- }
- return _animationsFrameCount;
+ return _globalState;
})
.Publish()
.RefCount();
@@ -85,10 +77,7 @@ namespace Avalonia.Animation
/// The parameter passed to a subsciber is the number of frames since the animation system was
/// initialized.
///
- ///
- /// The animation timer.
- ///
- public static IObservable AnimationTimer
+ internal static IObservable AnimationStateTimer
{
get;
}
@@ -102,9 +91,6 @@ namespace Avalonia.Animation
/// The parameter passed to a subsciber is the number of frames since the animation system was
/// initialized.
///
- ///
- /// The animation timer.
- ///
public static IObservable TransitionsTimer
{
get;
@@ -124,10 +110,10 @@ namespace Avalonia.Animation
///
public static IObservable GetAnimationsTimer(Animatable control, TimeSpan duration, TimeSpan delay)
{
- var startTime = _animationsFrameCount;
- var _duration = (ulong)(duration.Ticks/Tick.Ticks);
+ var startTime = control._animationTime;
+ var _duration = (ulong)(duration.Ticks / Tick.Ticks);
var endTime = startTime + _duration;
- return AnimationTimer
+ return control.AnimatableTimer
.TakeWhile(x => x < endTime)
.Select(x => (double)(x - startTime) / _duration)
.StartWith(0.0)