[英]Get smooth animations using #wpf?
我正在开发一个简单的图形查看器。 我在 canvas 上使用简单的椭圆和线条很好地渲染了它。
现在,我想让一些点在图表中导航。 你可以把它想象成穿过城市街道的汽车。
为了拥有可以以一定速率运行 animation 逻辑的东西,我设置了一个 DispatcherTimer 并在那里执行了所有 animation 逻辑。 它有效,但它真的很不稳定。 说实话,我并不感到惊讶。 我知道,这种在 canvas 上渲染并使用事件系统制作动画的方式并不像 2D 游戏引擎那样运行流畅。
所以,我的问题是,作为 WPF 的新手,我能做些什么来提高性能/准确性吗? 我已经看到存在一个可用于 c# (SkiaSharp) 的 Skia package,我认为它可以提高渲染性能,但是以“准确”(这里没有实时操作系统)帧速率运行逻辑呢?
性能不是 WPF 的主要设计目标之一。 如果您需要无法使用 WPF animation 系统实现的高速自定义动画,那么您最好直接从 FrameworkElement 派生并覆盖 OnRender:
public class CustomControl : FrameworkElement
{
public CustomControl()
{
// leave this line in to force a render of the control for each frame
CompositionTarget.Rendering += (s, e) => InvalidateVisual();
}
protected override void OnRender(DrawingContext drawingContext)
{
var angle = Math.PI * DateTime.Now.Ticks / 10000000;
var xoffset = 100 + (int)(50 * Math.Sin(angle));
var yoffset = 100 + (int)(50 * Math.Cos(angle));
drawingContext.DrawEllipse(Brushes.Red, null, new Point(xoffset, yoffset), 50, 50);
}
}
需要使用 Animatios 以所需的方式显示数据。 WPF 动画旨在用于平滑渲染并在调度程序时展示更好的性能。
在最简单的情况下,您需要启动 Double animation 来更新视图 model 的单个属性。 然后根据该值重新计算不同对象的属性(大小、位置等)。
另一种可能的解决方案是定义自定义 animation class。 此解决方案在WPF 教程 - 第 2 部分:编写自定义 animation class中进行了演示。 此解决方案提供了更大的灵活性,但通常您将获得可用于计算对象设置的类似值(您可以将其视为“经过时间”)。
WPF 中有一个特殊机制仅适用于您的情况 - 动画。 我建议您阅读这篇文章: 如何:沿路径为 Object 设置动画。
下面是一个遍历简单图的例子。 另请注意,在示例中,我使用了一个预定义的路径(为简单起见)。 在实践中,您可以从代码隐藏动态创建此类路径和动画。
<Canvas>
<Canvas.Resources>
<PathGeometry x:Key="AnimationPath" Figures="M 100,100 L 200,150 L 230,250 L 150,300 L 100,100"/>
</Canvas.Resources>
<Line X1="115" X2="215" Y1="115" Y2="165" Stroke="Green" StrokeThickness="5"/>
<Line X1="215" X2="245" Y1="165" Y2="265" Stroke="Green" StrokeThickness="5"/>
<Line X1="245" X2="165" Y1="265" Y2="315" Stroke="Green" StrokeThickness="5"/>
<Line X1="165" X2="115" Y1="315" Y2="115" Stroke="Green" StrokeThickness="5"/>
<Ellipse Width="30" Height="30" Canvas.Left="100" Canvas.Top="100" Fill="Red"/>
<Ellipse Width="30" Height="30" Canvas.Left="200" Canvas.Top="150" Fill="Red"/>
<Ellipse Width="30" Height="30" Canvas.Left="230" Canvas.Top="250" Fill="Red"/>
<Ellipse Width="30" Height="30" Canvas.Left="150" Canvas.Top="300" Fill="Red"/>
<Ellipse x:Name="traveller" Width="30" Height="30" Fill="Blue">
<Ellipse.RenderTransform>
<TranslateTransform x:Name="transform"/>
</Ellipse.RenderTransform>
</Ellipse>
<Canvas.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<Storyboard RepeatBehavior="Forever">
<DoubleAnimationUsingPath PathGeometry="{StaticResource AnimationPath}"
Storyboard.TargetName="transform"
Storyboard.TargetProperty="X"
Source="X"
Duration="0:0:10"/>
<DoubleAnimationUsingPath PathGeometry="{StaticResource AnimationPath}"
Storyboard.TargetName="transform"
Storyboard.TargetProperty="Y"
Source="Y"
Duration="0:0:10"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Canvas.Triggers>
</Canvas>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.