首页 > 解决方案 > 改进win2d线条动画UWP

问题描述

我创建了一个频率的音频频谱,并为我使用 CanvasAnimatedControl 的线条动画制作了线条动画。

绘制事件代码:

    private void OnDraw(Microsoft.Graphics.Canvas.UI.Xaml.ICanvasAnimatedControl 
        sender, Microsoft.Graphics.Canvas.UI.Xaml.CanvasAnimatedDrawEventArgs args)
    {
        double height = sender.Size.Height;
        double width = sender.Size.Width;

        for (int a = 0; a < nBands; a++)
        {
            _data.Add(new List<double>());
            for (int i = 0; i < DataPointsPerFrame; i++)
            {
                _lastValue = Math.Max(0d, Math.Min(1d, _lastValue + (list[a] * 0.00001)));
                _data[a].Add(list[a]);
            }
        }

        for (int a = 0; a < nBands; a++)
        {
            double total = 0;
            double range = 0;

            double widthBand = (width - 120 - ((nBands - 1) * 1)) / nBands;
            var padding = 60 + (a * widthBand) + (a * 1);
            for (int start = 0; start < _data[a].Count; start += ColumnAvgDataRange)
            {
                total = 0;
                range = Math.Min(ColumnAvgDataRange, _data[a].Count - start);

                for (int i = start; i < start + range; i++)
                {
                    total += _data[a][i];
                }
            }

            total = total * 0.0008;

            var point1 = new Vector2((float)padding, (float)height);
            var point2 = new Vector2((float)padding, (float)height - (float)(height * (total / range)));
            args.DrawingSession.DrawLine(point1, point2, Colors.Green, (float)widthBand);
        }
        canvasBands.Invalidate();
    }

我将项目上传到此链接

如何改善线条的动画以避免出现镜头?

提前致谢。

更新

    private void canvasBands_Update(Microsoft.Graphics.Canvas.UI.Xaml.ICanvasAnimatedControl sender, 
        Microsoft.Graphics.Canvas.UI.Xaml.CanvasAnimatedUpdateEventArgs args)
    {
        double height = sender.Size.Height;
        double width = sender.Size.Width;

        point2 = new Vector2((float)padding, (float)height - (float)(height * (total / range)));
    }

我尝试按照您所说的进行修改,但无法获得良好的结果,因为更新事件仅更改一次并且仅返回一点二。我在这里上传了文件。我怎样才能变得更好?

永远感谢。

标签: c#canvasuwplinewin2d

解决方案


您不需要在画布上调用 invalidate 。
您需要分离您的代码:您应该在控件的 Update 事件处理程序中更新几何图形,然后在 Draw 事件处理程序中进行绘制。

这是一个使用随机数生成器创建值的示例。您可以根据自己的用途进行调整。请注意,Draw 函数中没有进行任何计算:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using Windows.UI;
using Windows.UI.Xaml.Controls;

namespace Test_One_Bar_UWP
{
    public sealed partial class MainPage : Page
    {
        private List<double> _values = new List<double>();
        private List<Vector2> _points = new List<Vector2>();
        private Random _random = new Random();
        private float _barWidth = 30.0f;

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

        private void canvas_Draw(Microsoft.Graphics.Canvas.UI.Xaml.ICanvasAnimatedControl sender, Microsoft.Graphics.Canvas.UI.Xaml.CanvasAnimatedDrawEventArgs args)
        {
            lock (_points)
            {
                double height = sender.Size.Height;

                foreach (var point in _points)
                {
                    args.DrawingSession.DrawLine(
                        point.X * _barWidth,
                        Convert.ToSingle(height),
                        point.X * _barWidth,
                        Convert.ToSingle(height) - point.Y,
                        Colors.Green, 1);
                }
            }
        }

        private void canvas_Update(Microsoft.Graphics.Canvas.UI.Xaml.ICanvasAnimatedControl sender, Microsoft.Graphics.Canvas.UI.Xaml.CanvasAnimatedUpdateEventArgs args)
        {
            _values.Add(_random.NextDouble());

            double width = sender.Size.Width;

            var lastPoints = _values.TakeLast(Convert.ToInt32(width / _barWidth));

            lock (_points)
            {
                _points.Clear();

                for (var i = 0; i < lastPoints.Count(); i++)
                {
                    _points.Add(new Vector2(i, Convert.ToSingle(sender.Size.Height * lastPoints.ElementAt(i))));
                }
            }
        }
    }
}

推荐阅读