浏览代码

Delegated the animation clock to the Animatable objects so that we can control their Play State individually.

Jumar Macato 7 年之前
父节点
当前提交
99e9f9eed5

+ 4 - 4
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;
             }
         }

+ 53 - 11
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();
         }
 
         /// <summary>
-        /// Defines the <see cref="AnimationPlayState"/> property.
+        /// The specific animations timer for this control.
         /// </summary>
-        public static readonly DirectProperty<Animatable, PlayState> AnimationPlayStateProperty =
+        /// <returns></returns>
+        public IObservable<ulong> AnimatableTimer;
+
+        internal void PrepareAnimatableForAnimation()
+        {
+            if (!_animationsInitialized)
+            {
+
+
+                _animationsInitialized = true;
+            }
+        }
+
+        bool _animationsInitialized = false;
+
+        // internal ConcurrentDictionary<int, (int repeatCount, int direction)> _animationStates;
+
+        internal ulong _animationTime;
+        
+        // internal int _iterationTokenCounter;
+
+        // internal uint GetIterationToken()
+        // {
+        //     return (uint)Interlocked.Increment(ref _iterationTokenCounter);
+        // }
+
+        /// <summary>
+        /// Defines the <see cref="PlayState"/> property.
+        /// </summary>
+        public static readonly DirectProperty<Animatable, PlayState> PlayStateProperty =
             AvaloniaProperty.RegisterDirect<Animatable, PlayState>(
-                nameof(AnimationPlayState),
-                o => o.AnimationPlayState,
-                (o, v) => o.AnimationPlayState = v);
+                nameof(PlayState),
+                o => o.PlayState,
+                (o, v) => o.PlayState = v);
 
         /// <summary>
         /// Gets or sets the state of the animation for this
         /// control.
         /// </summary>
-        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;
 
         /// <summary>
         /// Defines the <see cref="Transitions"/> property.

+ 2 - 0
src/Avalonia.Animation/Animation.cs

@@ -64,6 +64,8 @@ namespace Avalonia.Animation
         /// <inheritdocs/>
         public IDisposable Apply(Animatable control, IObservable<bool> matchObs)
         {
+            control.PrepareAnimatableForAnimation();
+            
             foreach (IKeyFrames keyframes in Children)
             {
                 _subscription.Add(keyframes.Apply(this, control, matchObs));

+ 0 - 1
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;
 

+ 3 - 1
src/Avalonia.Animation/Keyframes/KeyFrames.cs

@@ -29,6 +29,7 @@ namespace Avalonia.Animation.Keyframes
 
         private bool IsVerfifiedAndConverted;
 
+
         /// <inheritdoc/>
         public virtual IDisposable Apply(Animation animation, Animatable control, IObservable<bool> 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);
                 });
         }

+ 2 - 2
src/Avalonia.Animation/PlayState.cs

@@ -6,7 +6,7 @@ namespace Avalonia.Animation
 {
     public enum PlayState
     {
-        Running,
-        Paused
+        Run,
+        Pause
     }
 }

+ 7 - 21
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;
 
         /// <summary>
         /// 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.
         /// </remarks>
-        /// <value>
-        /// The animation timer.
-        /// </value>
-        public static IObservable<ulong> AnimationTimer
+        internal static IObservable<PlayState> 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.
         /// </remarks>
-        /// <value>
-        /// The animation timer.
-        /// </value>
         public static IObservable<ulong> TransitionsTimer
         {
             get;
@@ -124,10 +110,10 @@ namespace Avalonia.Animation
         /// </remarks>
         public static IObservable<double> 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)