簡體   English   中英

使用#wpf 獲得流暢的動畫?

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM