[英]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.