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

7

我正在尝试弄清楚如何在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都不能进行动画处理。
1个回答

4

我认为没有内置的动画程序,但是在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;
        }
    }
}

太棒了,谢谢!我应该能够使用这个来弄清楚如何做到这一点。 - Niels Bosma
在Avalonia 11中,Animator<T>不再可访问(internal),那么现在应该如何实现这个功能呢? - mmix
@mmix 尝试使用 InterpolatingAnimator<T> - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接