[WPF] 實現兩個任天堂 Switch 的載入動畫
寫了兩個 Switch 的載入動畫,第一個是 Swtich 最常見那個 Loading 動畫:
其中拆分文字用到了 之前一篇文章 裡提到的用 ItemsControl 拆分的方案,文字逐個反轉的動畫也用了那篇文章裡提到的 TimeSpanIncreaser
來控制 BeginTime:
<Storyboard BeginTime="{Binding Next, Source={StaticResource TimeSpanIncreaser}}" RepeatBehavior="Forever"> <DoubleAnimationUsingKeyFrames Storyboard.TargetName="TextElement" Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)" Duration="0:0:4"> <LinearDoubleKeyFrame KeyTime="0:0:0.4" Value="-1" /> <LinearDoubleKeyFrame KeyTime="0:0:0.6" Value="1" /> <LinearDoubleKeyFrame KeyTime="0:0:0.8" Value="-1" /> </DoubleAnimationUsingKeyFrames> </Storyboard>
另一個是 eShop 的載入動畫,看起來簡單,實現過程反而更有趣。
要實現這個動畫,第一步要先把每行都拆分成一個獨立的部分,然後還是使用 TimeSpanIncreaser
控制每個部分的開始動畫的時間:
<local:NintendoEShopLoadingRow Delay="{Binding Next, Source={StaticResource TimeSpanIncreaser}}" /> <local:NintendoEShopLoadingRow Grid.Row="1" Delay="{Binding Next, Source={StaticResource TimeSpanIncreaser}}" /> <local:NintendoEShopLoadingRow Grid.Row="2" Delay="{Binding Next, Source={StaticResource TimeSpanIncreaser}}" /> <local:NintendoEShopLoadingRow Grid.Row="3" Delay="{Binding Next, Source={StaticResource TimeSpanIncreaser}}" /> <local:NintendoEShopLoadingRow Grid.Row="4" Delay="{Binding Next, Source={StaticResource TimeSpanIncreaser}}" /> <local:NintendoEShopLoadingRow Grid.Row="5" Delay="{Binding Next, Source={StaticResource TimeSpanIncreaser}}" />
然後實現 NintendoEShopLoadingRow
,先在裡面放上四個顏色由淺到深的 Grid。為了不寫死顏色,我做了個 LightenConverter
,具體用法如下:
<Grid Background="{Binding Foreground, ElementName=Row, Converter={StaticResource LightenConverter}, ConverterParameter=.8}" /> <Grid Background="{Binding Foreground, ElementName=Row, Converter={StaticResource LightenConverter}, ConverterParameter=.6}" /> <Grid Background="{Binding Foreground, ElementName=Row, Converter={StaticResource LightenConverter}, ConverterParameter=.4}" /> <Grid Background="{Binding Foreground, ElementName=Row}" />
LightenConverter
的程式碼如下,先實現一個 HslColor
類,HSL即色相、飽和度、亮度(英語:Hue, Saturation, Lightness)。LightenConverter
將原本的 SolidColorBrush 中的 Color 轉換成 HslColor,然後修改亮度後再轉換回來:
public class LightenConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var brush = value as SolidColorBrush;
if (brush == null)
return value;
var amount =System.Convert.ToDouble(parameter);
return new SolidColorBrush(new HslColor(brush.Color).Lighten(amount).ToRgb());
}
public HslColor Lighten(HslColor source, double amount)
{
return new HslColor(source.h, source.s, source.l + (1 - source.l) * amount, source.a);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotImplementedException();
}
這樣就實現了 4 個 Grid 使用同一個顏色,但亮度不同。
最後要讓這四個 Grid 動起來(其實只是動前面三個)。雖然說”動起來“,但並不是做移動的動畫,而是用 ScaleTransform 做拉伸,同樣是做 ScaleX 從 1 到 0 的動畫,如果 RenderTransformOrigin="0,0.5"
就是以左邊界為中心,即從右往左縮小;反之 RenderTransformOrigin="1,0.5"
就是從左往右縮小。通過設定 RenderTransformOrigin
實現了各層往不同的方向縮小,實現了左右往返的動畫:
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="L1" Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)">
<LinearDoubleKeyFrame KeyTime="00:00:1" Value="0" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="L2" Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)">
<LinearDoubleKeyFrame KeyTime="00:00:1" Value="1" />
<LinearDoubleKeyFrame KeyTime="00:00:2" Value="0" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="L3" Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)">
<LinearDoubleKeyFrame KeyTime="00:00:2" Value="1" />
<LinearDoubleKeyFrame KeyTime="00:00:3" Value="0" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="L1" Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)">
<LinearDoubleKeyFrame KeyTime="00:00:3" Value="0" />
<LinearDoubleKeyFrame KeyTime="00:00:4" Value="1" />
</DoubleAnimationUsingKeyFrames>
可惜的是,這個動畫對 WPF 來說有些勉強,偶爾會有卡頓的現象。反正只是玩玩,正式產品不要在這麼大的元素上做動畫。
原始碼:https://github.com/DinoChan/wpf_design_and_animation_lab
作者:dino.c
出處:http://www.cnblogs.com/dino623/
說明:歡迎轉載並請標明來源和作者。如有錯漏請指出,謝謝。