Avalonia:如何使用代码对路径中的点进行动画处理

Nie*_*sma 7 c# avaloniaui avalonia

我正在尝试弄清楚如何在 Avalonia 中制作动画。

我有一条包含 4 条线段的路径,我想将每个点设置为新位置的动画。在 WPF 中我是这样做的:

        public void AnimatePoints(PointCollection pts, TimeSpan timespan, bool randomized = true, Action onFinished = null)
        {
            Points = PointCollection.Parse(PathString);

            //PathFigure needs an animation too (for the start point), otherwise the first point always stays in one place
            var pfa = new PointAnimation(pts[0], timespan);

            if (onFinished != null)
            {
                pfa.Completed += (sender, args) => onFinished();
            }

            PathFigure.BeginAnimation(PathFigure.StartPointProperty, pfa);

            for (int i = 0; i < pts.Count; i++)
            {
                var pa = new PointAnimation(pts[i], timespan);
                if (randomized)
                {
                    LineSegments[i].BeginAnimation(LineSegment.PointProperty, pa);
                }
                else
                {
                    LineSegments[i].BeginAnimation(LineSegment.PointProperty, pa);
                }
            }
        }
Run Code Online (Sandbox Code Playgroud)

我如何使用代码在 Avalonia 中执行相同操作?我尝试过使用 PathTransition,但 PathFigure 和 LineSegments 都不可设置动画。

Wie*_*tés 4

I don't think there is built-in animator, but in Avalonia you can do custom animators like that:

public class MorphAnimator : Animator<Geometry>
{
    public override Geometry Interpolate(double progress, Geometry oldValue, Geometry newValue)
    {
        var clone = (oldValue as PathGeometry).ClonePathGeometry();

        Morph.To(clone, newValue as PathGeometry, progress);

        return clone;
    }
}
Run Code Online (Sandbox Code Playgroud)

and register

Animation.RegisterAnimator<MorphAnimator>(prop => typeof(Geometry).IsAssignableFrom(prop.PropertyType));
Run Code Online (Sandbox Code Playgroud)

Example code: https://github.com/wieslawsoltes/MorphingDemo

You can also do custom animators from Xaml:

<UserControl 
  xmlns="https://github.com/avaloniaui" 
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
  xmlns:pages="clr-namespace:RenderDemo.Pages"
  x:Class="RenderDemo.Pages.CustomAnimatorPage"
  MaxWidth="600">
  <Grid>
    <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center">
      <TextBlock.Styles>
        <Style Selector="TextBlock">
          <Style.Animations>
            <Animation Duration="0:0:1" IterationCount="Infinite">
              <KeyFrame Cue="0%">
                <Setter Property="Text" Value="" Animation.Animator="{x:Type pages:CustomStringAnimator}"/>
              </KeyFrame>
              <KeyFrame Cue="100%">
                <Setter Property="Text" Value="0123456789" Animation.Animator="{x:Type pages:CustomStringAnimator}"/>
              </KeyFrame>
            </Animation>
          </Style.Animations>
        </Style>
      </TextBlock.Styles>
    </TextBlock>
  </Grid>
</UserControl>
Run Code Online (Sandbox Code Playgroud)

Animator:

using Avalonia.Animation.Animators;

namespace RenderDemo.Pages
{
    public class CustomStringAnimator : Animator<string>
    {
        public override string Interpolate(double progress, string oldValue, string newValue)
        {
            if (newValue.Length == 0) return "";
            var step = 1.0 / newValue.Length;
            var length = (int)(progress / step);
            var result = newValue.Substring(0, length + 1);
            return result;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)