繁体   English   中英

Win2d UWP 流体动画画布线

[英]Win2d UWP fluid animation canvas line

我必须获得用 Win2d 绘制的线条的流畅动画。 下面是模拟我的问题的代码。

主页.xaml:

     <canvas:CanvasAnimatedControl x:Name="animatedControl" 
                                   Margin="0,30,0,0"
                                   Height="500"
                                   Draw="OnDraw"/>

MainPage.xaml.cs:

    private void OnDraw(Microsoft.Graphics.Canvas.UI.Xaml.ICanvasAnimatedControl sender, Microsoft.Graphics.Canvas.UI.Xaml.CanvasAnimatedDrawEventArgs args)
    {
        CanvasDrawingSession ds = args.DrawingSession;

        double height = sender.Size.Height;
        double width = sender.Size.Width;

        Random random = new Random();

        double pointHeigth = random.Next(0, 300);

        var point1 = new Vector2((float)(width / 2), (float)height);
        var point2 = new Vector2((float)(width / 2), (float)height - (float)pointHeigth);

        CanvasSolidColorBrush brush = new CanvasSolidColorBrush(sender, Colors.Green);

        ds.DrawLine(point1, point2, brush, (float)10);
    }

这样我得到了一个荷叶边动画我怎样才能得到线条的平滑动画?

我声明我必须在 win2d 中使用画布。

提前致谢。

更新(我的代码不起作用)

    private Vector2 _point1;
    private Vector2 _point2;
    private Vector2 _targetPoint;
    private TimeSpan _animationElapsedTime = TimeSpan.FromMilliseconds(100);

    public MainPage()
    {
        this.InitializeComponent();
    }

    private void OnDraw(Microsoft.Graphics.Canvas.UI.Xaml.ICanvasAnimatedControl sender, Microsoft.Graphics.Canvas.UI.Xaml.CanvasAnimatedDrawEventArgs args)
    {
        CanvasDrawingSession ds = args.DrawingSession;

        double height = sender.Size.Height;
        double width = sender.Size.Width;


        Random random = new Random();

        double pointHeigth = random.Next(0, 300);

        var _point1 = new Vector2((float)(width / 2), (float)height);

        var _point2 = new Vector2((float)(width / 2), (float)height - (float)pointHeigth);

        CanvasSolidColorBrush brush = new CanvasSolidColorBrush(sender, Colors.Green);

        ds.DrawLine(_point1, _point2, brush, (float)10);
    }

    private Vector2 Tween(Vector2 sourcePoint, Vector2 targetPoint, float percentage)
    {
        return new Vector2(targetPoint.X + (targetPoint.X - sourcePoint.X) * percentage, targetPoint.Y + (targetPoint.Y - sourcePoint.Y) * percentage);
    }

    private void OnUpdate(Microsoft.Graphics.Canvas.UI.Xaml.ICanvasAnimatedControl sender, Microsoft.Graphics.Canvas.UI.Xaml.CanvasAnimatedUpdateEventArgs args)
    {
        _animationElapsedTime += args.Timing.ElapsedTime;
        var percentage = Math.Min(_animationElapsedTime.TotalSeconds / 5.0f, 1f);
        _point2 = Tween(_point1, _targetPoint, (float)percentage);
    }

更新 2 我的代码:

    double previuosData = 0;
    bool isDraw = false;

    public MainPage()
    {
        this.InitializeComponent();
    }

    private void OnDraw(Microsoft.Graphics.Canvas.UI.Xaml.ICanvasAnimatedControl sender, Microsoft.Graphics.Canvas.UI.Xaml.CanvasAnimatedDrawEventArgs args)
    {
        if (isDraw)
            return;

        CanvasDrawingSession ds = args.DrawingSession;

        double height = sender.Size.Height;
        double width = sender.Size.Width;

        CanvasSolidColorBrush brush = new CanvasSolidColorBrush(sender, Colors.Green);

        Random random = new Random();

        double pointHeigth = random.Next(0, 500);

        var point1 = new Vector2((float)(width / 2), (float)height);

        if (pointHeigth > previuosData)
        {
            for (double a = previuosData; a <= pointHeigth; a++)
            {
                isDraw = true;
                var point2 = new Vector2((float)(width / 2), (float)height - (float)a);
                ds.DrawLine(point1, point2, brush, (float)10);
            }
            isDraw = false;
        }
        else
        {
            for (double a = previuosData; a >= pointHeigth; a--)
            {
                isDraw = true;
                var point2 = new Vector2((float)(width / 2), (float)height - (float)a);
                ds.DrawLine(point1, point2, brush, (float)10);
            }
            isDraw = false;
        }

        previuosData = pointHeigth;
    }

通过这种方式,我使动画更加流畅,但是使用 for 循环还不够,我该如何改进?

您似乎正在使用 Random 并从每个单帧中的给定范围生成一个随机数。 所以这意味着每秒60次第二个点会随机上下跳跃。

与以下内容进行比较:

private bool _adding = true;
private int _currentHeightOffset = 0;
private void OnDraw(Microsoft.Graphics.Canvas.UI.Xaml.ICanvasAnimatedControl sender, Microsoft.Graphics.Canvas.UI.Xaml.CanvasAnimatedDrawEventArgs args)
{
    CanvasDrawingSession ds = args.DrawingSession;

    double height = sender.Size.Height;
    double width = sender.Size.Width;

    var point1 = new Vector2((float)(width / 2), (float)height);
    var point2 = new Vector2((float)(width / 2), (float)height - (float)_currentHeight);

    CanvasSolidColorBrush brush = new CanvasSolidColorBrush(sender, Colors.Green);

    ds.DrawLine(point1, point2, brush, (float)10);
    if (_adding)
    {
       _currentHeightOffset++;
    }
    else
    {
       _currentHeightOffset--;
    }
    if (_currentHeightOffset == 0 || _currentHeightOffset == 300 )
    {
       _adding = !_adding;
    }        
}

现在在这个例子中,我在每一帧中逐个像素地移动点,直到它达到 300,然后回到 0。所以结果应该是一条线,它似乎固定在point1 ,并且上下移动和拉伸。

关键是,这些值不再是随机的,而是可以逐帧预测的。

更新

正如我在评论中所讨论的,您可以在两点之间进行“补间”效果。

我们将使用以下方法:

private Vector2 Tween(Vector2 sourcePoint, Vector2 targetPoint, float percentage)
{
   return new Vector2( 
       targetPoint.X + (targetPoint.X - sourcePoint.X)*percentage,
       targetPoint.Y + (targetPoint.Y - sourcePoint.Y)*percentage)  
}

现在,如果您想在这两个点之间设置动画 5 秒,您可以执行以下操作:

private Vector2 _point2;
private TimeSpan _animationElapsedTime = TimeSpan.Zero;

private void OnUpdate(Microsoft.Graphics.Canvas.UI.Xaml.ICanvasAnimatedControl sender, 
      Microsoft.Graphics.Canvas.UI.Xaml.CanvasAnimatedUpdateEventArgs args)
{
    _animationElapsedTime += args.Timing.ElapsedTime;
    var percentage = Math.Min(_animationElapsedTime.TotalSeconds / 5.0f, 1f);
    _point2 = Tween(_point1, _targetPoint, percentage);
}

这只是代码外观的快速草图,但是,它是重要的点 - 一旦您选择了目标点(例如使用随机),您需要决定动画需要多长时间然后移动第二点越来越接近目标,直到时间结束。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM