5

我正在尝试弄清楚如何在 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);
                }
            }
        }

如何使用代码在 Avalonia 中做同样的事情?我尝试过使用 PathTransition 但 PathFigure 和 LineSegments 都不是动画的。

4

1 回答 1

3

我不认为有内置的动画师,但在 Avalonia 你可以做这样的自定义动画师:

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

并注册

Animation.RegisterAnimator<MorphAnimator>(prop => typeof(Geometry).IsAssignableFrom(prop.PropertyType));

示例代码:https ://github.com/wieslawsoltes/MorphingDemo

您还可以从 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>

动画师:

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;
        }
    }
}
于 2021-12-01T08:02:50.473 回答