先看效果圖:
最直觀的,這是4個圓點在移動,就用一個橫向的StackPanel表示這四個點吧。
<StackPanel Orientation="Horizontal"> <StackPanel.Resources> <Style TargetType="{x:Type Border}"> <Setter Property="BorderBrush" Value="Transparent"/> <Setter Property="BorderThickness" Value="0"/> <Setter Property="Background" Value="{Binding RelativeSource={RelativeSource AncestorType=UserControl, AncestorLevel=1}, Path= Foreground}"/> <Setter Property="CornerRadius" Value="100"/> <Setter Property="Height" Value="4"/> <Setter Property="Width" Value="4"/> </Style> </StackPanel.Resources> <Border x:Name="border4" Margin="0,0,5,0" RenderTransformOrigin="0.5,0.5"> <Border.RenderTransform> <TransformGroup> <ScaleTransform/> <SkewTransform/> <RotateTransform/> <TranslateTransform/> </TransformGroup> </Border.RenderTransform> </Border> <Border x:Name="border3" Margin="0,0,5,0" RenderTransformOrigin="0.5,0.5"> <Border.RenderTransform> <TransformGroup> <ScaleTransform/> <SkewTransform/> <RotateTransform/> <TranslateTransform/> </TransformGroup> </Border.RenderTransform> </Border> <Border x:Name="border2" Margin="0,0,5,0" RenderTransformOrigin="0.5,0.5"> <Border.RenderTransform> <TransformGroup> <ScaleTransform/> <SkewTransform/> <RotateTransform/> <TranslateTransform/> </TransformGroup> </Border.RenderTransform> </Border> <Border x:Name="border1" RenderTransformOrigin="0.5,0.5"> <Border.RenderTransform> <TransformGroup> <ScaleTransform/> <SkewTransform/> <RotateTransform/> <TranslateTransform/> </TransformGroup> </Border.RenderTransform> </Border> </StackPanel>
圓點的顏色綁定在用戶控件的Foreground上面。在調用控件的時候記得對其Foreground賦值以便顯示適合的顏色。
這個動畫實際上很簡單,分為5個部分:
1.准備部分:准備向前移動
2.正向加速度部分:移動速度越來越快
3.勻速部分:慢速勻速移動
4.負向加速度部分:移動速度越來越慢
5.等待部分:等待所有動畫完成
動畫代碼如下:
<Storyboard x:Key="sbKey" Completed="Storyboard_Completed" > <!--最右邊--> <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="border1"> <EasingDoubleKeyFrame KeyTime="0:0:0" Value="0"/> <EasingDoubleKeyFrame KeyTime="0:0:0.8"> <EasingDoubleKeyFrame.EasingFunction> <CircleEase EasingMode="EaseOut"/> </EasingDoubleKeyFrame.EasingFunction> </EasingDoubleKeyFrame> <EasingDoubleKeyFrame KeyTime="0:0:1.2"/> <EasingDoubleKeyFrame KeyTime="0:0:2"> <EasingDoubleKeyFrame.EasingFunction> <CircleEase EasingMode="EaseIn"/> </EasingDoubleKeyFrame.EasingFunction> </EasingDoubleKeyFrame> <EasingDoubleKeyFrame KeyTime="0:0:2.6"/> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="border2"> <EasingDoubleKeyFrame KeyTime="0:0:0.1" Value="0" x:Name="_2_1"> <EasingDoubleKeyFrame.EasingFunction> <CircleEase EasingMode="EaseOut"/> </EasingDoubleKeyFrame.EasingFunction> </EasingDoubleKeyFrame> <EasingDoubleKeyFrame KeyTime="0:0:0.9" Value="190" x:Name="_2_2"> <EasingDoubleKeyFrame.EasingFunction> <CircleEase EasingMode="EaseOut"/> </EasingDoubleKeyFrame.EasingFunction> </EasingDoubleKeyFrame> <EasingDoubleKeyFrame KeyTime="0:0:1.3" Value="210" x:Name="_2_3"/> <EasingDoubleKeyFrame KeyTime="0:0:2.1" Value="400" x:Name="_2_4"> <EasingDoubleKeyFrame.EasingFunction> <CircleEase EasingMode="EaseIn"/> </EasingDoubleKeyFrame.EasingFunction> </EasingDoubleKeyFrame> <EasingDoubleKeyFrame KeyTime="0:0:2.6" Value="400" x:Name="_2_5"/> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="border3"> <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="0" x:Name="_3_1"> <EasingDoubleKeyFrame.EasingFunction> <CircleEase EasingMode="EaseOut"/> </EasingDoubleKeyFrame.EasingFunction> </EasingDoubleKeyFrame> <EasingDoubleKeyFrame KeyTime="0:0:1.0" Value="190" x:Name="_3_2"> <EasingDoubleKeyFrame.EasingFunction> <CircleEase EasingMode="EaseOut"/> </EasingDoubleKeyFrame.EasingFunction> </EasingDoubleKeyFrame> <EasingDoubleKeyFrame KeyTime="0:0:1.4" Value="210" x:Name="_3_3"/> <EasingDoubleKeyFrame KeyTime="0:0:2.2" Value="400" x:Name="_3_4"> <EasingDoubleKeyFrame.EasingFunction> <CircleEase EasingMode="EaseIn"/> </EasingDoubleKeyFrame.EasingFunction> </EasingDoubleKeyFrame> <EasingDoubleKeyFrame KeyTime="0:0:2.6" Value="400" x:Name="_3_5"/> </DoubleAnimationUsingKeyFrames> <!--最左邊--> <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="border4"> <EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="0" x:Name="_4_1"> <EasingDoubleKeyFrame.EasingFunction> <CircleEase EasingMode="EaseOut"/> </EasingDoubleKeyFrame.EasingFunction> </EasingDoubleKeyFrame> <EasingDoubleKeyFrame KeyTime="0:0:1.1" Value="190" x:Name="_4_2"> <EasingDoubleKeyFrame.EasingFunction> <CircleEase EasingMode="EaseOut"/> </EasingDoubleKeyFrame.EasingFunction> </EasingDoubleKeyFrame> <EasingDoubleKeyFrame KeyTime="0:0:1.5" Value="210" x:Name="_4_3"/> <EasingDoubleKeyFrame KeyTime="0:0:2.3" Value="400" x:Name="_4_4"> <EasingDoubleKeyFrame.EasingFunction> <CircleEase EasingMode="EaseIn"/> </EasingDoubleKeyFrame.EasingFunction> </EasingDoubleKeyFrame> <EasingDoubleKeyFrame KeyTime="0:0:2.6" Value="400" x:Name="_4_5"/> </DoubleAnimationUsingKeyFrames> </Storyboard>
由於動畫需要自適應寬度,所以部分關鍵幀的值無法在XAML中表現出來,只有在后台進行動態處理。
當控件的寬度發生變化時需要更新動畫部分關鍵幀:
/// <summary> /// 當控件的大小發生變化時 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void UserControl_SizeChanged(object sender, SizeChangedEventArgs e) { //當控件的寬度發生變化時 if(e.WidthChanged) { isNeedUpdateStoryboard = true; } }
當動畫每一次執行完畢后,下一次執行之前,判斷是否需要更新部分關鍵幀,所以響應動畫的Completed事件:
/// <summary> /// 動畫執行完畢 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Storyboard_Completed(object sender, EventArgs e) { //每次動畫執行完畢后判斷是否需要更新動畫 if(isNeedUpdateStoryboard) { UpdateStoryboard(); } isNeedUpdateStoryboard = false; storyboard.Begin(this); }
/// <summary> /// 更新動畫部分關鍵幀 /// </summary> private void UpdateStoryboard() { //獲取控件的實際寬度,減去4個點占用的寬度 double realWidth = this.ActualWidth - 36; //正向加速度占比47.5% double _0Width = realWidth * 0.475; //勻速部分占比5% double _1Width = _0Width + realWidth * 0.05; //根據控件的實際大小動態更改動畫 #region 右邊第一個 var _0 = storyboard.Children[0] as DoubleAnimationUsingKeyFrames; var _0_1 = _0.KeyFrames[1] as EasingDoubleKeyFrame; var _0_2 = _0.KeyFrames[2] as EasingDoubleKeyFrame; var _0_3 = _0.KeyFrames[3] as EasingDoubleKeyFrame; var _0_4 = _0.KeyFrames[4] as EasingDoubleKeyFrame; _0_1.Value = _0Width; _0_2.Value = _1Width; _0_3.Value = realWidth; _0_4.Value = realWidth; #endregion #region 右邊倒數第二個 var _1 = storyboard.Children[1] as DoubleAnimationUsingKeyFrames; var _1_1 = _1.KeyFrames[1] as EasingDoubleKeyFrame; var _1_2 = _1.KeyFrames[2] as EasingDoubleKeyFrame; var _1_3 = _1.KeyFrames[3] as EasingDoubleKeyFrame; var _1_4 = _1.KeyFrames[4] as EasingDoubleKeyFrame; _1_1.Value = _0Width; _1_2.Value = _1Width; _1_3.Value = realWidth; _1_4.Value = realWidth; #endregion #region 右邊倒數第三個 var _2 = storyboard.Children[2] as DoubleAnimationUsingKeyFrames; var _2_1 = _2.KeyFrames[1] as EasingDoubleKeyFrame; var _2_2 = _2.KeyFrames[2] as EasingDoubleKeyFrame; var _2_3 = _2.KeyFrames[3] as EasingDoubleKeyFrame; var _2_4 = _2.KeyFrames[4] as EasingDoubleKeyFrame; _2_1.Value = _0Width; _2_2.Value = _1Width; _2_3.Value = realWidth; _2_4.Value = realWidth; #endregion #region 右邊倒數第四個 var _3 = storyboard.Children[3] as DoubleAnimationUsingKeyFrames; var _3_1 = _3.KeyFrames[1] as EasingDoubleKeyFrame; var _3_2 = _3.KeyFrames[2] as EasingDoubleKeyFrame; var _3_3 = _3.KeyFrames[3] as EasingDoubleKeyFrame; var _3_4 = _3.KeyFrames[4] as EasingDoubleKeyFrame; _3_1.Value = _0Width; _3_2.Value = _1Width; _3_3.Value = realWidth; _3_4.Value = realWidth; #endregion }
最后提供動畫的開始和結束調用:
/// <summary> /// 使進度條開始滾動 /// </summary> public void Start() { this.Visibility = System.Windows.Visibility.Visible; UpdateStoryboard(); storyboard.Begin(this, true); } /// <summary> /// 使進度條停止滾動 /// </summary> public void Stop() { this.Visibility = System.Windows.Visibility.Collapsed; storyboard.Stop(this); }
源代碼下載:http://download.csdn.net/detail/lyclovezmy/7598897