AnimationExample综合动画实例
功能说明:
- 主界面显示各页动画缩略按钮,点击后加载对应页的动画,按钮界面隐藏
- 主界面显示页动画,并有退出按钮实现返回到前者。
- 各页动画实现
文件组织:
具体设计、实现说明:
主窗口界面设计:
1、界面缩略选择按钮为自定义RadioButton.一个特定是选中后不能再点击选中,私认为还是使用自定义Button更适合。另外示例未设置好Tab按钮,在播放动画时,背后使用Tab选择另一页动画替换播放。
- 内容为Frame,直接设置Source,直接在小框里显示了,这性能。。。
<RadioButton Grid.Column="2" Grid.Row="0" Style="{StaticResource GlassRadioButtonStyle}">
<Frame
Name="SkewTextAnimationExampleFrame"
Source="text\SkewTextAnimationExample.xaml"
NavigationUIVisibility="Visible" />
</RadioButton>
2、RadioButton的玻璃效果,细节不解释了,看代码:
<Style TargetType="{x:Type RadioButton}" x:Key="GlassRadioButtonStyle">
<Setter Property="Margin" Value="1" />
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
<LinearGradientBrush.GradientStops>
<GradientStop Offset="0.0" Color="#CCCCFF" />
<GradientStop Offset="1.0" Color="DarkGray" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RadioButton}">
<Grid Width="{TemplateBinding Width}" Height="{TemplateBinding Height}"
ClipToBounds="true">
<Rectangle x:Name="outerRectangle"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Stroke="{TemplateBinding Background}"
StrokeThickness="1" Fill="Transparent" />
<Rectangle x:Name="glassCube" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
StrokeThickness="2" RadiusX="10" RadiusY="10" Opacity="0"
Fill="{StaticResource MyGlassBrushResource}"
RenderTransformOrigin="0.5,0.5"
>
<Rectangle.Stroke>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
<LinearGradientBrush.GradientStops>
<GradientStop Offset="0.0" Color="LightBlue" />
<GradientStop Offset="1.0" Color="Gray" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Rectangle.Stroke>
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform x:Name="cubeScaleTransform" />
<RotateTransform x:Name="cubeRotateTransform" />
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
<DockPanel Margin="10">
<Viewbox Stretch="Uniform">
<ContentPresenter x:Name="myContentPresenter"
Content="{TemplateBinding Content}"
TextBlock.Foreground="Black" />
</Viewbox>
</DockPanel>
<Rectangle Fill="Transparent" />
</Grid>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true" />
<Condition Property="IsChecked" Value="false" />
</MultiTrigger.Conditions>
<Setter Property ="Rectangle.Stroke" Value="Black" TargetName="outerRectangle" />
<Setter Property="Rectangle.Opacity" Value="1" TargetName="glassCube" />
</MultiTrigger>
<Trigger Property="IsChecked" Value="true">
<Setter Property="Rectangle.Opacity" Value="1" TargetName="glassCube" />
</Trigger>
<Trigger Property="IsFocused" Value="true">
<Setter Property="Rectangle.Stroke" Value="Black" TargetName="outerRectangle" />
<Setter Property="Rectangle.Opacity" Value="1" TargetName="glassCube" />
</Trigger>
<EventTrigger RoutedEvent="Mouse.MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard Name="mouseEnterBeginStoryboard">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="cubeScaleTransform"
Storyboard.TargetProperty="ScaleX"
By="-0.1" Duration="0:0:0.5" />
<DoubleAnimation
Storyboard.TargetName="cubeScaleTransform"
Storyboard.TargetProperty="ScaleY"
By="-0.1" Duration="0:0:0.5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="Mouse.MouseLeave">
<EventTrigger.Actions>
<StopStoryboard BeginStoryboardName="mouseEnterBeginStoryboard" />
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="RadioButton.Checked">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="cubeRotateTransform"
Storyboard.TargetProperty="Angle"
By="360" Duration="0:0:0.5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
3、主界面容器为Grid,除了包含一个上面的缩略按钮的Grid,还有个Border层:DockPanel容器右侧有一个退出按钮,左侧为主Frame区,平时Border.Visibility=“Collapsed”隐藏。
- 点击退出按钮触发:之前的Grid.Opacity=1动画显示出来,并且其移动变换的X,To=0执行动画.
- Border层的移动变换的X,To值绑定到窗口ActualWidth执行动画。(此处就有缺陷了,如下)此处的解决方法是在添加动画完成后事件,清除属性上的动画,重新设值。
增加修改的代码,及加个动画是否完成的判断:
private void xSampleDisplayBorderDoubleAnimation_Completed(object sender, EventArgs e)
{
SampleDisplayBorderTranslateTransform.ApplyAnimationClock(TranslateTransform.XProperty, null);
SampleDisplayBorderTranslateTransform.X = ActualWidth;
}
//判断动画已完成x=0状态,若>0,此时若动画未解除,以下的设置可以无效,一举两得。
private void PageSizeChanged(object sender, SizeChangedEventArgs args)
{
if (SampleDisplayBorderTranslateTransform.X>0)
{
SampleDisplayBorderTranslateTransform.X = ActualWidth;
}
}
主界面退出按钮Border层代码:
<Border Name="SampleDisplayBorder" BorderBrush="Gray" BorderThickness="1"
Visibility="Collapsed"
Background="Black">
<DockPanel
Margin="10" HorizontalAlignment="Stretch">
<Button
DockPanel.Dock="Right"
Height="50" Width="50" Click="Button_Click">
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard HandoffBehavior="SnapshotAndReplace">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="SampleGrid"
Storyboard.TargetProperty="Opacity"
From="0"
To="1" BeginTime="0:0:0" />
<DoubleAnimation
Storyboard.TargetName="SampleGridTranslateTransform"
Storyboard.TargetProperty="X"
To="0"
BeginTime="0:0:0" />
<DoubleAnimation Name="xSampleDisplayBorderDoubleAnimation"
Storyboard.TargetName="SampleDisplayBorderTranslateTransform"
Storyboard.TargetProperty="X"
BeginTime="0:0:0"
Duration="0:0:1"
From="0"
To="{Binding ElementName=SampleDisplayBorder, Path=ActualWidth,Mode=OneWay}"
Completed="xSampleDisplayBorderDoubleAnimation_Completed"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>
<Frame Name="SampleDisplayFrame" Background="White"
ContentRendered="SampleDisplayFrameLoaded"
NavigationUIVisibility="Hidden" >
</Frame>
</DockPanel>
<Border.RenderTransform>
<TranslateTransform x:Name="SampleDisplayBorderTranslateTransform"
X="0" />
</Border.RenderTransform>
</Border>
4、 RadioButton选中后切换页
- 确定RadioButton对应的Frame.Source,加载到主Frame中。
private void SelectedSampleChanged(object sender, RoutedEventArgs args)
{
if (args.Source is RadioButton)
{
var theButton = (RadioButton) args.Source;
var theFrame = (Frame) theButton.Content;
if (theFrame.HasContent)
{
var source = theFrame.CurrentSource;
if ((source != null) && !source.IsAbsoluteUri)
{
source = new Uri(PackUri, source);
}
SampleDisplayFrame.Source = source;
//未报错,但会造成RadioButtond的内容不显示。
//SampleDisplayFrame.Content= theFrame.Content;
}
//此处设置 为不管是否已加载Frame, 都显示此Border及退出按钮
SampleDisplayBorder.Visibility = Visibility.Visible;
}
}
在主Frame加载n内容执行对应的切换动画
private void SampleDisplayFrameLoaded(object sender, EventArgs args)
{
SampleGrid.BeginAnimation(OpacityProperty, _sampleGridOpacityAnimation);
SampleGridTranslateTransform.BeginAnimation(TranslateTransform.XProperty,
_sampleGridTranslateTransformAnimation);
SampleDisplayBorderTranslateTransform.BeginAnimation(TranslateTransform.XProperty,
_borderTranslateDoubleAnimation);
//可省略,加载Frame时已设置。
//SampleDisplayBorder.Visibility = Visibility.Visible;
}
简单分析:以上的退出按钮代码的演示板动画可放在Xaml里设置,后台代码就只实现选择加载页、优化窗口改变事件、清除属性动画的功能代码即可。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。