Browse Source

More syntax rework

pull/1461/head
Jumar Macato 8 years ago
parent
commit
1b416690eb
  1. 84
      samples/RenderTest/Pages/AnimationsPage.xaml
  2. 4
      samples/RenderTest/Pages/ClippingPage.xaml
  3. 49
      src/Avalonia.Animation/Animation.cs
  4. 4
      src/Avalonia.Animation/Animator`1.cs
  5. 1
      src/Avalonia.Animation/IAnimationSetter.cs
  6. 28
      src/Avalonia.Animation/KeyFrame.cs
  7. 2
      src/Avalonia.Visuals/Animation/TransformAnimator.cs
  8. 17
      src/Avalonia.Visuals/Animation/TransformSetter.cs

84
samples/RenderTest/Pages/AnimationsPage.xaml

@ -40,81 +40,25 @@
<Setter Property="Height" Value="100"/> <Setter Property="Height" Value="100"/>
<Setter Property="Child" Value="{StaticResource Acorn}"/> <Setter Property="Child" Value="{StaticResource Acorn}"/>
</Style> </Style>
<Style Selector="Border.Rect1:pointerover"> <Style Selector="Border.Rect1">
<Style.Animations> <Style.Animations>
<Animation Duration="0:0:2.5" <Animation Duration="0:0:2.5"
RepeatBehavior="Repeat" RepeatBehavior="Repeat"
RepeatCount="4" FillMode="None" PlaybackDirection="AlternateReverse" Easing="SineEaseInOut"> RepeatCount="4" FillMode="None"
<TransformKeyFrames Property="RotateTransform.Angle"> PlaybackDirection="AlternateReverse"
<KeyFrame Cue="0%" Value="0"/> Easing="SineEaseInOut">
<KeyFrame Cue="100%" Value="0"/> <KeyFrame Cue="0%">
<KeyFrame Cue="20%" Value="45"/> <DoubleSetter Property="Opacity" Value="0"/>
<KeyFrame Cue="80%" Value="120"/> </KeyFrame>
</TransformKeyFrames> <KeyFrame Cue="0%">
<TransformKeyFrames Property="ScaleTransform.ScaleX"> <TransformSetter Property="RotateTransform.Angle" Value="360"/>
<KeyFrame Cue="0%" Value="1"/> </KeyFrame>
<KeyFrame Cue="50%" Value="1.5"/> <KeyFrame Cue="100%">
<KeyFrame Cue="100%" Value="1"/> <DoubleSetter Property="Opacity" Value="1"/>
</TransformKeyFrames> </KeyFrame>
</Animation> </Animation>
</Style.Animations> </Style.Animations>
</Style> </Style>
<Style Selector="Border.Rect2:pointerover">
<Style.Animations>
<Animation Duration="0:0:0.5" Easing="SineEaseInOut">
<TransformKeyFrames Property="ScaleTransform.ScaleX">
<KeyFrame Cue="0%" Value="1"/>
<KeyFrame Cue="50%" Value="0.8"/>
<KeyFrame Cue="100%" Value="1"/>
</TransformKeyFrames>
<TransformKeyFrames Property="ScaleTransform.ScaleY">
<KeyFrame Cue="0%" Value="1"/>
<KeyFrame Cue="50%" Value="0.8"/>
<KeyFrame Cue="100%" Value="1"/>
</TransformKeyFrames>
</Animation>
</Style.Animations>
</Style>
<Style Selector="Border.Rect3">
<Setter Property="Child" Value="{StaticResource Heart}"/>
<Style.Animations>
<Animation Duration="0:0:0.5" Easing="QuadraticEaseInOut" RepeatBehavior="Loop">
<TransformKeyFrames Property="ScaleTransform.ScaleX">
<KeyFrame Cue="0%" Value="1"/>
<KeyFrame Cue="50%" Value="0.8"/>
<KeyFrame Cue="100%" Value="1"/>
</TransformKeyFrames>
<TransformKeyFrames Property="ScaleTransform.ScaleY">
<KeyFrame Cue="0%" Value="1"/>
<KeyFrame Cue="50%" Value="0.8"/>
<KeyFrame Cue="100%" Value="1"/>
</TransformKeyFrames>
</Animation>
</Style.Animations>
</Style>
<Style Selector="Border.Rect4:pointerover">
<Style.Animations>
<Animation Duration="0:0:3" Easing="BounceEaseInOut">
<TransformKeyFrames Property="TranslateTransform.Y">
<KeyFrame Cue="0%" Value="0"/>
<KeyFrame Cue="48%" Value="-100"/>
<KeyFrame Cue="100%" Value="0"/>
</TransformKeyFrames>
</Animation>
</Style.Animations>
</Style>
<Style Selector="Border.Rect5:pointerover">
<Style.Animations>
<Animation Duration="0:0:3" Easing="CircularEaseInOut">
<TransformKeyFrames Property="SkewTransform.AngleX">
<KeyFrame Cue="0%" Value="0"/>
<KeyFrame Cue="25%" Value="-20"/>
<KeyFrame Cue="75%" Value="20"/>
<KeyFrame Cue="100%" Value="0"/>
</TransformKeyFrames>
</Animation>
</Style.Animations>
</Style>
</Styles> </Styles>
</UserControl.Styles> </UserControl.Styles>
<Grid> <Grid>

4
samples/RenderTest/Pages/ClippingPage.xaml

@ -7,14 +7,14 @@
<Setter Property="Border.Background" Value="Crimson"/> <Setter Property="Border.Background" Value="Crimson"/>
</Style> </Style>
<Style Selector="Border#clipChild"> <Style Selector="Border#clipChild">
<Style.Animations> <!-- <Style.Animations>
<Animation Duration="0:0:2" RepeatBehavior="Loop"> <Animation Duration="0:0:2" RepeatBehavior="Loop">
<TransformKeyFrames Property="RotateTransform.Angle"> <TransformKeyFrames Property="RotateTransform.Angle">
<KeyFrame Cue="0%" Value="0"/> <KeyFrame Cue="0%" Value="0"/>
<KeyFrame Cue="100%" Value="360"/> <KeyFrame Cue="100%" Value="360"/>
</TransformKeyFrames> </TransformKeyFrames>
</Animation> </Animation>
</Style.Animations> </Style.Animations> -->
</Style> </Style>
</Styles> </Styles>
</Grid.Styles> </Grid.Styles>

49
src/Avalonia.Animation/Animation.cs

@ -8,14 +8,18 @@ using Avalonia.Metadata;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.Reflection;
using System.Linq;
namespace Avalonia.Animation namespace Avalonia.Animation
{ {
/// <summary> /// <summary>
/// Tracks the progress of an animation. /// Tracks the progress of an animation.
/// </summary> /// </summary>
public class Animation : IDisposable, IAnimation public class Animation : AvaloniaList<KeyFrame>, IDisposable, IAnimation
{ {
private bool _isChildrenChanged = false;
private List<IDisposable> _subscription = new List<IDisposable>(); private List<IDisposable> _subscription = new List<IDisposable>();
public AvaloniaList<IAnimator> _animators { get; set; } = new AvaloniaList<IAnimator>(); public AvaloniaList<IAnimator> _animators { get; set; } = new AvaloniaList<IAnimator>();
@ -54,23 +58,44 @@ namespace Avalonia.Animation
/// </summary> /// </summary>
public Easing Easing { get; set; } = new LinearEasing(); public Easing Easing { get; set; } = new LinearEasing();
/// <summary>
/// A list of <see cref="KeyFrame"/> objects.
/// </summary>
[Content]
public AvaloniaList<KeyFrame> Children { get; set; } = new AvaloniaList<KeyFrame>();
public Animation() public Animation()
{ {
InterpretKeyframes(); this.CollectionChanged += delegate { _isChildrenChanged = true; };
}
public Animation(IEnumerable<KeyFrame> items) : base(items)
{
this.CollectionChanged += delegate { _isChildrenChanged = true; };
}
public Animation(params KeyFrame[] items) : base(items)
{
this.CollectionChanged += delegate { _isChildrenChanged = true; };
} }
private void InterpretKeyframes() private void InterpretKeyframes()
{ {
foreach (var keyframe in Children) var handlerList = new List<Type>();
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);
}
} }
} }
/// <summary> /// <summary>
@ -87,6 +112,12 @@ namespace Avalonia.Animation
/// <inheritdocs/> /// <inheritdocs/>
public IDisposable Apply(Animatable control, IObservable<bool> matchObs) public IDisposable Apply(Animatable control, IObservable<bool> matchObs)
{ {
if (_isChildrenChanged)
{
InterpretKeyframes();
_isChildrenChanged = false;
}
foreach (IAnimator keyframes in _animators) foreach (IAnimator keyframes in _animators)
{ {
_subscription.Add(keyframes.Apply(this, control, matchObs)); _subscription.Add(keyframes.Apply(this, control, matchObs));

4
src/Avalonia.Animation/Animator`1.cs

@ -14,7 +14,7 @@ namespace Avalonia.Animation
/// <summary> /// <summary>
/// Base class for KeyFrames objects /// Base class for KeyFrames objects
/// </summary> /// </summary>
public abstract class Animator<T> : AvaloniaList<KeyFrame>, IAnimator public abstract class Animator<T> : AvaloniaList<InternalKeyFrame>, IAnimator
{ {
/// <summary> /// <summary>
/// List of type-converted keyframes. /// List of type-converted keyframes.
@ -117,7 +117,7 @@ namespace Avalonia.Animation
{ {
var typeConv = TypeDescriptor.GetConverter(type); var typeConv = TypeDescriptor.GetConverter(type);
foreach (KeyFrame k in this) foreach (InternalKeyFrame k in this)
{ {
if (k.Value == null) if (k.Value == null)
{ {

1
src/Avalonia.Animation/IAnimationSetter.cs

@ -4,6 +4,5 @@ namespace Avalonia.Animation
{ {
AvaloniaProperty Property { get; set; } AvaloniaProperty Property { get; set; }
object Value { get; set; } object Value { get; set; }
} }
} }

28
src/Avalonia.Animation/KeyFrame.cs

@ -12,12 +12,24 @@ namespace Avalonia.Animation
/// Stores data regarding a specific key /// Stores data regarding a specific key
/// point and value in an animation. /// point and value in an animation.
/// </summary> /// </summary>
public class KeyFrame public class KeyFrame : AvaloniaList<IAnimationSetter>
{ {
internal bool timeSpanSet, cueSet; internal bool timeSpanSet, cueSet;
private TimeSpan _ktimeSpan; private TimeSpan _ktimeSpan;
private Cue _kCue; private Cue _kCue;
public KeyFrame()
{
}
public KeyFrame(IEnumerable<IAnimationSetter> items) : base(items)
{
}
public KeyFrame(params IAnimationSetter[] items) : base(items)
{
}
/// <summary> /// <summary>
/// Gets or sets the key time of this <see cref="KeyFrame"/>. /// Gets or sets the key time of this <see cref="KeyFrame"/>.
/// </summary> /// </summary>
@ -60,13 +72,15 @@ namespace Avalonia.Animation
} }
} }
/// <summary>
/// The keyframe's target value.
/// </summary>
public object Value { get; set; }
[Content] }
public AvaloniaList<IAnimationSetter> Children { get; set; } = new AvaloniaList<IAnimationSetter>();
public class InternalKeyFrame
{
public Cue Cue { get; set; }
public TimeSpan KeyTime { get; set; }
internal bool timeSpanSet, cueSet;
public object Value { get; set; }
} }
} }

2
src/Avalonia.Visuals/Animation/TransformAnimator.cs

@ -84,7 +84,7 @@ namespace Avalonia.Animation
{ {
childKeyFrames = new DoubleAnimator(); childKeyFrames = new DoubleAnimator();
foreach (KeyFrame keyframe in this) foreach (InternalKeyFrame keyframe in this)
{ {
childKeyFrames.Add(keyframe); childKeyFrames.Add(keyframe);
} }

17
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
{
}
}
Loading…
Cancel
Save