WPF 利用路徑動畫做一個環形加載動畫


2020年10月24日 增加緩動函數方式

我們保持代碼不變,直接使用緩動函數,緩動函數內置很多運動方式

關於函數運動方式可以參考之前給出的網址。或者自己試試,直接使用某個函數即可。

    <Window.Triggers>
        <EventTrigger RoutedEvent="Button.Click" SourceName="c1">
            <BeginStoryboard>
                <Storyboard>
                    <DoubleAnimationUsingKeyFrames BeginTime="0:0:0.1"  RepeatBehavior="Forever"   Storyboard.TargetProperty="Angle" Storyboard.TargetName="rt1" >
                        <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
                        <EasingDoubleKeyFrame KeyTime="0:0:2" Value="360">
                            <EasingDoubleKeyFrame.EasingFunction>
                                <ExponentialEase EasingMode="EaseInOut"/>
                            </EasingDoubleKeyFrame.EasingFunction>
                        </EasingDoubleKeyFrame>
                    </DoubleAnimationUsingKeyFrames>
                    <DoubleAnimationUsingKeyFrames BeginTime="0:0:0.2"   RepeatBehavior="Forever"   Storyboard.TargetProperty="Angle" Storyboard.TargetName="rt2" >
                        <EasingDoubleKeyFrame Value="0"  KeyTime="0:0:0" />
                        <EasingDoubleKeyFrame KeyTime="0:0:2" Value="360">
                            <EasingDoubleKeyFrame.EasingFunction>
                                <ExponentialEase EasingMode="EaseInOut"/>
                            </EasingDoubleKeyFrame.EasingFunction>
                        </EasingDoubleKeyFrame>
                    </DoubleAnimationUsingKeyFrames>
                    <DoubleAnimationUsingKeyFrames BeginTime="0:0:0.3"   RepeatBehavior="Forever"   Storyboard.TargetProperty="Angle" Storyboard.TargetName="rt3" >
                        <EasingDoubleKeyFrame Value="0"  KeyTime="0:0:0" />
                        <EasingDoubleKeyFrame KeyTime="0:0:2" Value="360">
                            <EasingDoubleKeyFrame.EasingFunction>
                                <ExponentialEase EasingMode="EaseInOut"/>
                            </EasingDoubleKeyFrame.EasingFunction>
                        </EasingDoubleKeyFrame>
                    </DoubleAnimationUsingKeyFrames>
                    <DoubleAnimationUsingKeyFrames BeginTime="0:0:0.4 "   RepeatBehavior="Forever"   Storyboard.TargetProperty="Angle" Storyboard.TargetName="rt4" >
                        <EasingDoubleKeyFrame Value="0"  KeyTime="0:0:0" />
                        <EasingDoubleKeyFrame KeyTime="0:0:2" Value="360">
                            <EasingDoubleKeyFrame.EasingFunction>
                                <ExponentialEase EasingMode="EaseInOut"/>
                            </EasingDoubleKeyFrame.EasingFunction>
                        </EasingDoubleKeyFrame>
                    </DoubleAnimationUsingKeyFrames>
                    <DoubleAnimationUsingKeyFrames BeginTime="0:0:0.5"     RepeatBehavior="Forever"   Storyboard.TargetProperty="Angle" Storyboard.TargetName="rt5" >
                        <EasingDoubleKeyFrame Value="0"  KeyTime="0:0:0" />
                        <EasingDoubleKeyFrame KeyTime="0:0:2" Value="360">
                            <EasingDoubleKeyFrame.EasingFunction>
                                <ExponentialEase EasingMode="EaseInOut"/>
                            </EasingDoubleKeyFrame.EasingFunction>
                        </EasingDoubleKeyFrame>
                    </DoubleAnimationUsingKeyFrames>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Window.Triggers>
    <Grid >
        <Button x:Name="c1" Height="40" Width="50" VerticalAlignment="Bottom"/>
        <ContentControl    Height="150" Width="150" RenderTransformOrigin="0.5 ,0.5">
            <ContentControl.RenderTransform>
                <RotateTransform  x:Name="rt1"/>
            </ContentControl.RenderTransform>
            <Ellipse Width="15" Height="15" Fill="Red"  VerticalAlignment="Bottom"/>
        </ContentControl>
        <ContentControl    Height="150" Width="150" RenderTransformOrigin="0.5 ,0.5">
            <ContentControl.RenderTransform>
                <RotateTransform  x:Name="rt2"/>
            </ContentControl.RenderTransform>
            <Ellipse Width="15" Height="15" Fill="Red"  VerticalAlignment="Bottom"/>
        </ContentControl>
        <ContentControl    Height="150" Width="150" RenderTransformOrigin="0.5 ,0.5">
            <ContentControl.RenderTransform>
                <RotateTransform  x:Name="rt3"/>
            </ContentControl.RenderTransform>
            <Ellipse Width="15" Height="15" Fill="Red"  VerticalAlignment="Bottom"/>
        </ContentControl>
        <ContentControl    Height="150" Width="150" RenderTransformOrigin="0.5 ,0.5">
            <ContentControl.RenderTransform>
                <RotateTransform  x:Name="rt4"/>
            </ContentControl.RenderTransform>
            <Ellipse Width="15" Height="15" Fill="Red"  VerticalAlignment="Bottom"/>
        </ContentControl>
        <ContentControl    Height="150" Width="150" RenderTransformOrigin="0.5 ,0.5">
            <ContentControl.RenderTransform>
                <RotateTransform  x:Name="rt5"/>
            </ContentControl.RenderTransform>
            <Ellipse Width="15" Height="15" Fill="Red"  VerticalAlignment="Bottom"/>
        </ContentControl>
    </Grid>

截圖

*************************************************************************************************************************************************

2020年10月22日 增加其他方法【樣條動畫】

在之前的的文章中用動畫速率來實現球的運行速度達到緩速的效果。

其實,WPF原生中自帶有此類的東西,通過某個曲線來模擬速度的快慢:MSDN網址

本文的球動畫,差不多直接使用一個三次方貝塞爾曲線差不多就能模擬。

但不能使用路徑動畫了,我們需要改變新的動畫方式。

首先確定關鍵詞BeginTime,KeyTime,Value,Duration:

在動畫中時間線中當時間為KeyTime時動畫所應用的值應該為KeyValue,

如果一個時間線內有多個運行對象,則每個對象BeginTime為當前時間線運行的時間某個時刻,並且當時間線的時刻符合BeginTime時啟動動畫。

此時每個對象的KeyValue是當前對象自開始運行時計算獨立的運行時間,當對象的運行時間符合KeyTime時所應用到對象的屬性的值

Duration則是規定的總運行時間長,也可以不用寫,默認為所有對象運行時長的和。

至於為什么用貝塞爾曲線模擬運行速度,

首先在WPF動畫中規定,貝塞爾的起點為(0,0),終點(1,1)其次貝塞爾是一個光滑的曲線,所以我們只用去控制第一個控制點和第二個控制點制造曲線就會產生光滑的曲線,

輸入兩個控制點和兩個默認點的后通過公式計算即可得到0~1的每一個時刻的值與終點(1,1)的比值,即為速度。當然也可以直接使用blend去拖動圖表的控制點快速得到想要的效果。

【blend貝塞爾曲線繪制工具】

 

 

但是我認為適當了解原理還是比較好的。

動畫是一個細心的活,慢慢調

下面是代碼

 <Window.Triggers>
        <EventTrigger RoutedEvent="Button.Click" SourceName="c1">
            <BeginStoryboard>
                <Storyboard>
                    <DoubleAnimationUsingKeyFrames BeginTime="0:0:0"  RepeatBehavior="Forever"   Storyboard.TargetProperty="Angle" Storyboard.TargetName="rt1" >
                        <SplineDoubleKeyFrame Value="0"  KeyTime="0:0:0" />
                        <SplineDoubleKeyFrame Value="360"  KeyTime="0:0:2" KeySpline="0.13,1,0.9,0.8"/>
                    </DoubleAnimationUsingKeyFrames>
                    <DoubleAnimationUsingKeyFrames BeginTime="0:0:0.2"   RepeatBehavior="Forever"   Storyboard.TargetProperty="Angle" Storyboard.TargetName="rt2" >
                        <SplineDoubleKeyFrame Value="0"  KeyTime="0:0:0" />
                        <SplineDoubleKeyFrame Value="360"  KeyTime="0:0:2" KeySpline="0.13,1,0.9,0.8"/>
                    </DoubleAnimationUsingKeyFrames>

                    <DoubleAnimationUsingKeyFrames BeginTime="0:0:0.3"   RepeatBehavior="Forever"   Storyboard.TargetProperty="Angle" Storyboard.TargetName="rt3" >
                        <SplineDoubleKeyFrame Value="0"  KeyTime="0:0:0" />
                        <SplineDoubleKeyFrame Value="360" KeyTime="0:0:2" KeySpline="0.13,1,0.9,0.8"/>
                    </DoubleAnimationUsingKeyFrames>
                    <DoubleAnimationUsingKeyFrames BeginTime="0:0:0.4 "   RepeatBehavior="Forever"   Storyboard.TargetProperty="Angle" Storyboard.TargetName="rt4" >
                        <SplineDoubleKeyFrame Value="0"  KeyTime="0:0:0" />
                        <SplineDoubleKeyFrame Value="360"  KeyTime="0:0:2" KeySpline="0.13,1,0.9,0.8"/>
                    </DoubleAnimationUsingKeyFrames>
                    <DoubleAnimationUsingKeyFrames BeginTime="0:0:0.5"     RepeatBehavior="Forever"   Storyboard.TargetProperty="Angle" Storyboard.TargetName="rt5" >
                        <SplineDoubleKeyFrame Value="0"  KeyTime="0:0:0" />
                        <SplineDoubleKeyFrame Value="360" KeyTime="0:0:2" KeySpline="0.13,1,0.9,0.8"/>
                    </DoubleAnimationUsingKeyFrames>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Window.Triggers>
    <Grid >
        <Button x:Name="c1" Height="40" Width="50" VerticalAlignment="Bottom"/>
        <ContentControl    Height="150" Width="150" RenderTransformOrigin="0.5 ,0.5">
            <ContentControl.RenderTransform>
                <RotateTransform  x:Name="rt1"/>
            </ContentControl.RenderTransform>
            <Ellipse Width="15" Height="15" Fill="Red"  VerticalAlignment="Bottom"/>
        </ContentControl>
        <ContentControl    Height="150" Width="150" RenderTransformOrigin="0.5 ,0.5">
            <ContentControl.RenderTransform>
                <RotateTransform  x:Name="rt2"/>
            </ContentControl.RenderTransform>
            <Ellipse Width="15" Height="15" Fill="Red"  VerticalAlignment="Bottom"/>
        </ContentControl>
        <ContentControl    Height="150" Width="150" RenderTransformOrigin="0.5 ,0.5">
            <ContentControl.RenderTransform>
                <RotateTransform  x:Name="rt3"/>
            </ContentControl.RenderTransform>
            <Ellipse Width="15" Height="15" Fill="Red"  VerticalAlignment="Bottom"/>
        </ContentControl>
        <ContentControl    Height="150" Width="150" RenderTransformOrigin="0.5 ,0.5">
            <ContentControl.RenderTransform>
                <RotateTransform  x:Name="rt4"/>
            </ContentControl.RenderTransform>
            <Ellipse Width="15" Height="15" Fill="Red"  VerticalAlignment="Bottom"/>
        </ContentControl>
        <ContentControl    Height="150" Width="150" RenderTransformOrigin="0.5 ,0.5">
            <ContentControl.RenderTransform>
                <RotateTransform  x:Name="rt5"/>
            </ContentControl.RenderTransform>
            <Ellipse Width="15" Height="15" Fill="Red"  VerticalAlignment="Bottom"/>
        </ContentControl>
    </Grid>

截圖

***************************************************************************************************************************************************************************************************************

簡單用一個路徑動畫做一個環形加載動畫

四個點,啟動時間各個不同,運行時間相同。啟動時圓形半徑為0,啟動后恢復正常半徑。

gif截圖略慢,實際運行還是可以的

 

 

 

 

  <Window.Resources>
        <PathGeometry x:Key="EllipesPath" Figures="M 5 10 a 35 35 0 1 1 1 1 Z"/>
    </Window.Resources>
    <Grid>
        <Canvas x:Name="cs">
            <Path Panel.ZIndex="1" x:Name="Geo" Visibility="Visible"  Canvas.Top="100" Canvas.Left="100"  Fill="Red" Stroke="Red" >
                <Path.Data>
                    <GeometryGroup x:Name="G1" FillRule="Nonzero"  >
                        <EllipseGeometry  x:Name="eg1" Center="05 10"    RadiusX="0" RadiusY="0" />
                        <EllipseGeometry  x:Name="eg2" Center="25 10"    RadiusX="0" RadiusY="0"/>
                        <EllipseGeometry  x:Name="eg3" Center="45 10"    RadiusX="0" RadiusY="0"/>
                        <EllipseGeometry  x:Name="eg4" Center="65 10"    RadiusX="0" RadiusY="0"/>
                    </GeometryGroup>
                </Path.Data>
                <Path.RenderTransform>
                    <RotateTransform/>
                </Path.RenderTransform>
                <Path.Triggers>
                    <EventTrigger RoutedEvent="Path.Loaded"    >
                        <BeginStoryboard x:Name="P1" >
                            <Storyboard>
                                <DoubleAnimation Storyboard.TargetName="eg1"  Storyboard.TargetProperty="RadiusX" To="5" BeginTime="0:0:0"    />
                                <DoubleAnimation Storyboard.TargetName="eg1"  Storyboard.TargetProperty="RadiusY" To="5" BeginTime="0:0:0" />
                                <PointAnimationUsingPath  Storyboard.TargetName="eg1"  Storyboard.TargetProperty="Center" RepeatBehavior="Forever"  PathGeometry="{DynamicResource EllipesPath}" Duration="0:0:4" BeginTime="0:0:0.1"  AccelerationRatio="0.7" SpeedRatio="1.2"/>
                            </Storyboard>
                        </BeginStoryboard>
                        <BeginStoryboard x:Name="P2">
                            <Storyboard>
                                <DoubleAnimation Storyboard.TargetName="eg2"  Storyboard.TargetProperty="RadiusX" To="5" BeginTime="0:0:0.5"    />
                                <DoubleAnimation Storyboard.TargetName="eg2"  Storyboard.TargetProperty="RadiusY" To="5" BeginTime="0:0:0.5" />
                                <PointAnimationUsingPath  Storyboard.TargetName="eg2"  Storyboard.TargetProperty="Center"  RepeatBehavior="Forever"  PathGeometry="{DynamicResource EllipesPath}" Duration="0:0:4" BeginTime="0:0:0.5" AccelerationRatio="0.7" SpeedRatio="1.2" />
                            </Storyboard>
                        </BeginStoryboard>
                        <BeginStoryboard x:Name="P3">
                            <Storyboard>
                                <DoubleAnimation Storyboard.TargetName="eg3"  Storyboard.TargetProperty="RadiusX" To="5" BeginTime="0:0:1"  />
                                <DoubleAnimation Storyboard.TargetName="eg3"  Storyboard.TargetProperty="RadiusY" To="5" BeginTime="0:0:1"   />
                                <PointAnimationUsingPath RepeatBehavior="Forever"  Storyboard.TargetName="eg3" Storyboard.TargetProperty="Center" PathGeometry="{DynamicResource EllipesPath}" Duration="0:0:4" BeginTime="0:0:1" AccelerationRatio="0.7" SpeedRatio="1.2"/>
                            </Storyboard>
                        </BeginStoryboard>
                        <BeginStoryboard x:Name="P4">
                            <Storyboard>
                                <DoubleAnimation Storyboard.TargetName="eg4"  Storyboard.TargetProperty="RadiusX" To="5" BeginTime="0:0:1.5"  />
                                <DoubleAnimation Storyboard.TargetName="eg4"  Storyboard.TargetProperty="RadiusY" To="5" BeginTime="0:0:1.5"   />
                                <PointAnimationUsingPath RepeatBehavior="Forever"  Storyboard.TargetName="eg4" Storyboard.TargetProperty="Center" PathGeometry="{DynamicResource EllipesPath}" Duration="0:0:4" BeginTime="0:0:1.5" AccelerationRatio="0.7" SpeedRatio="1.2"/>
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger>
                </Path.Triggers>
            </Path>
            <Path  Canvas.Top="100" Canvas.Left="100" Stroke="Red" Visibility="Visible" StrokeThickness="1" Data="{DynamicResource EllipesPath}"/>
        </Canvas>
    </Grid>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM