diff --git a/samples/RenderTest/Pages/AnimationsPage.xaml b/samples/RenderTest/Pages/AnimationsPage.xaml
index c57f0764f9..1dc924145a 100644
--- a/samples/RenderTest/Pages/AnimationsPage.xaml
+++ b/samples/RenderTest/Pages/AnimationsPage.xaml
@@ -40,81 +40,25 @@
-
-
-
-
-
+
diff --git a/samples/RenderTest/Pages/ClippingPage.xaml b/samples/RenderTest/Pages/ClippingPage.xaml
index 879da34615..a47d3e1bd2 100644
--- a/samples/RenderTest/Pages/ClippingPage.xaml
+++ b/samples/RenderTest/Pages/ClippingPage.xaml
@@ -7,14 +7,14 @@
diff --git a/src/Avalonia.Animation/Animation.cs b/src/Avalonia.Animation/Animation.cs
index 98c4961681..c91430c979 100644
--- a/src/Avalonia.Animation/Animation.cs
+++ b/src/Avalonia.Animation/Animation.cs
@@ -8,14 +8,18 @@ using Avalonia.Metadata;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
+using System.Reflection;
+using System.Linq;
namespace Avalonia.Animation
{
///
/// Tracks the progress of an animation.
///
- public class Animation : IDisposable, IAnimation
+ public class Animation : AvaloniaList, IDisposable, IAnimation
{
+
+ private bool _isChildrenChanged = false;
private List _subscription = new List();
public AvaloniaList _animators { get; set; } = new AvaloniaList();
@@ -54,23 +58,44 @@ namespace Avalonia.Animation
///
public Easing Easing { get; set; } = new LinearEasing();
- ///
- /// A list of objects.
- ///
- [Content]
- public AvaloniaList Children { get; set; } = new AvaloniaList();
public Animation()
{
- InterpretKeyframes();
+ this.CollectionChanged += delegate { _isChildrenChanged = true; };
+ }
+
+ public Animation(IEnumerable items) : base(items)
+ {
+ this.CollectionChanged += delegate { _isChildrenChanged = true; };
+ }
+
+ public Animation(params KeyFrame[] items) : base(items)
+ {
+ this.CollectionChanged += delegate { _isChildrenChanged = true; };
}
private void InterpretKeyframes()
{
- foreach (var keyframe in Children)
+ var handlerList = new List();
+
+ foreach (var keyframe in this)
{
-
+ foreach (var setter in keyframe)
+ {
+
+ var custAttr = setter.GetType()
+ .GetCustomAttributes()
+ .Where(p => p.GetType() == typeof(AnimatorAttribute));
+
+ if (!custAttr.Any())
+ throw new InvalidProgramException($"Type {setter.GetType()} doesn't have Animator attribute.");
+
+ var match = (AnimatorAttribute)custAttr.First();
+ if (!handlerList.Contains(match.HandlerType))
+ handlerList.Add(match.HandlerType);
+ }
}
+
}
///
@@ -87,6 +112,12 @@ namespace Avalonia.Animation
///
public IDisposable Apply(Animatable control, IObservable matchObs)
{
+ if (_isChildrenChanged)
+ {
+ InterpretKeyframes();
+ _isChildrenChanged = false;
+ }
+
foreach (IAnimator keyframes in _animators)
{
_subscription.Add(keyframes.Apply(this, control, matchObs));
diff --git a/src/Avalonia.Animation/Animator`1.cs b/src/Avalonia.Animation/Animator`1.cs
index 83e32c7739..89da918ec3 100644
--- a/src/Avalonia.Animation/Animator`1.cs
+++ b/src/Avalonia.Animation/Animator`1.cs
@@ -14,7 +14,7 @@ namespace Avalonia.Animation
///
/// Base class for KeyFrames objects
///
- public abstract class Animator : AvaloniaList, IAnimator
+ public abstract class Animator : AvaloniaList, IAnimator
{
///
/// List of type-converted keyframes.
@@ -117,7 +117,7 @@ namespace Avalonia.Animation
{
var typeConv = TypeDescriptor.GetConverter(type);
- foreach (KeyFrame k in this)
+ foreach (InternalKeyFrame k in this)
{
if (k.Value == null)
{
diff --git a/src/Avalonia.Animation/IAnimationSetter.cs b/src/Avalonia.Animation/IAnimationSetter.cs
index 28f6f911c4..f2a94c9ed6 100644
--- a/src/Avalonia.Animation/IAnimationSetter.cs
+++ b/src/Avalonia.Animation/IAnimationSetter.cs
@@ -4,6 +4,5 @@ namespace Avalonia.Animation
{
AvaloniaProperty Property { get; set; }
object Value { get; set; }
-
}
}
\ No newline at end of file
diff --git a/src/Avalonia.Animation/KeyFrame.cs b/src/Avalonia.Animation/KeyFrame.cs
index 07af6b406c..3ffd38e9b4 100644
--- a/src/Avalonia.Animation/KeyFrame.cs
+++ b/src/Avalonia.Animation/KeyFrame.cs
@@ -12,12 +12,24 @@ namespace Avalonia.Animation
/// Stores data regarding a specific key
/// point and value in an animation.
///
- public class KeyFrame
+ public class KeyFrame : AvaloniaList
{
internal bool timeSpanSet, cueSet;
private TimeSpan _ktimeSpan;
private Cue _kCue;
+ public KeyFrame()
+ {
+ }
+
+ public KeyFrame(IEnumerable items) : base(items)
+ {
+ }
+
+ public KeyFrame(params IAnimationSetter[] items) : base(items)
+ {
+ }
+
///
/// Gets or sets the key time of this .
///
@@ -60,13 +72,15 @@ namespace Avalonia.Animation
}
}
- ///
- /// The keyframe's target value.
- ///
- public object Value { get; set; }
- [Content]
- public AvaloniaList Children { get; set; } = new AvaloniaList();
+ }
+ public class InternalKeyFrame
+ {
+ public Cue Cue { get; set; }
+ public TimeSpan KeyTime { get; set; }
+ internal bool timeSpanSet, cueSet;
+ public object Value { get; set; }
}
+
}
diff --git a/src/Avalonia.Visuals/Animation/TransformAnimator.cs b/src/Avalonia.Visuals/Animation/TransformAnimator.cs
index 9f2138225f..7c3966ce93 100644
--- a/src/Avalonia.Visuals/Animation/TransformAnimator.cs
+++ b/src/Avalonia.Visuals/Animation/TransformAnimator.cs
@@ -84,7 +84,7 @@ namespace Avalonia.Animation
{
childKeyFrames = new DoubleAnimator();
- foreach (KeyFrame keyframe in this)
+ foreach (InternalKeyFrame keyframe in this)
{
childKeyFrames.Add(keyframe);
}
diff --git a/src/Avalonia.Visuals/Animation/TransformSetter.cs b/src/Avalonia.Visuals/Animation/TransformSetter.cs
new file mode 100644
index 0000000000..f8b8d588fc
--- /dev/null
+++ b/src/Avalonia.Visuals/Animation/TransformSetter.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Linq;
+using System.Reactive.Linq;
+using System.Diagnostics;
+using Avalonia.Animation.Utils;
+using Avalonia.Data;
+
+namespace Avalonia.Animation
+{
+ [Animator(typeof(TransformAnimator))]
+ public class TransformSetter : Setter
+ {
+
+ }
+}