作者:webabcd
介绍
重新想象 Windows 8 Store Apps 之 动画
示例
1、演示线性动画的应用
Animation/LinearAnimation.xaml
<Page x:Class="XamlDemo.Animation.LinearAnimation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:XamlDemo.Animation" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid Background="Transparent"> <!-- 线性动画一共有 3 种:ColorAnimation, DoubleAnimation, PointAnimation, 它们均继承自 Timeline Storyboard.TargetName - 附加属性,要进行动画处理的对象的名称 Storyboard.TargetProperty - 附加属性,要进行动画处理的对象的属性 BeginTime - 时间线在被触发 BeginTime 的时间后才能开始播放 TimeSpan - [-][日.]时:分:秒[.1位到7为的秒后的小数](可为正;可为负;可为空;默认值为 0) From - 动画的起始值 To - 动画的结束值 By - 动画从起始值开始计算,所需变化的总量(To 优先于 By) Duration - 时间线的持续时间 TimeSpan - [-][日.]时:分:秒[.1位到7为的秒后的小数] Automatic - 自动确定 Forever - 无限长 AutoReverse - 动画完成后是否要原路返回。默认值为 false RepeatBehavior - 动画重复播放的时间、次数或类型 TimeSpan - [-][日.]时:分:秒[.1位到7为的秒后的小数] nx - 播放次数。1x, 2x, 3x Forever - 永久播放 SpeedRatio - 时间线的速率的倍数。默认值 1 FillBehavior - 动画结束后的行为(System.Windows.Media.Animation.FillBehavior 枚举) FillBehavior.HoldEnd - 动画结束后,UI 保留动画后的状态。默认值 FillBehavior.Stop - 动画结束后,UI 恢复为动画前的状态 注意: 1、在 WinRT 中为了流畅的体验,部分动画被优化成了“独立动画”,即动画不依赖于 UI 线程 2、但是也有一部分动画无法优化成“独立动画”,我们把这类动画称作“依赖动画”,其需要在 UI 线程上运行 3、通过将 EnableDependentAnimation 设置为 true(默认为 false),开启“依赖动画” 4、通过将 Timeline.AllowDependentAnimations 设置为 false(默认为 true),可以全局禁止开启“依赖动画” Independent Animation - 独立动画 Dependent Animation - 依赖动画 --> <Grid.Resources> <BeginStoryboard x:Name="storyboardColor"> <Storyboard> <!--Color 值线性动画--> <!-- 动画要修改的属性是 Ellipse.Fill,动画后的结果值会赋予 SolidColorBrush.Color,然后 SolidColorBrush 就是动画后 Fill 属性的值 类似的比如:(UIElement.RenderTransform).(CompositeTransform.TranslateY) 以及 (UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX) 等 --> <ColorAnimation Storyboard.TargetName="ellipse" Storyboard.TargetProperty="(Ellipse.Fill).(SolidColorBrush.Color)" BeginTime="00:00:00" From="Red" To="Yellow" Duration="0:0:3" AutoReverse="true" RepeatBehavior="3x"> </ColorAnimation> </Storyboard> </BeginStoryboard> <BeginStoryboard x:Name="storyboardDouble"> <Storyboard> <!--Double 值线性动画--> <!-- 动画要修改的属性是 Canvas.Left --> <DoubleAnimation Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(Canvas.Left)" From="100" By="100" BeginTime="0:0:0" Duration="00:00:03" AutoReverse="true" RepeatBehavior="Forever"> </DoubleAnimation> </Storyboard> </BeginStoryboard> <BeginStoryboard x:Name="storyboardPoint"> <Storyboard> <!--Point 值线性动画--> <PointAnimation EnableDependentAnimation="True" Storyboard.TargetName="ellipseGeometry" Storyboard.TargetProperty="Center" BeginTime="00:00:00" From="50,50" To="200,200" Duration="00:00:03" AutoReverse="true" RepeatBehavior="Forever"> </PointAnimation> </Storyboard> </BeginStoryboard> </Grid.Resources> <StackPanel Margin="120 0 0 0"> <Ellipse x:Name="ellipse" Fill="Orange" Width="200" Height="100" HorizontalAlignment="Left" /> <Canvas Width="400" Height="100" HorizontalAlignment="Left" Margin="0 10 0 0"> <Rectangle x:Name="rectangle" Fill="Orange" Width="200" Height="100" Canvas.Left="100" /> </Canvas> <Path Fill="Orange"> <Path.Data> <EllipseGeometry x:Name="ellipseGeometry" Center="50,50" RadiusX="15" RadiusY="15" /> </Path.Data> </Path> </StackPanel> </Grid> </Page>
2、演示关键帧动画的应用
Animation/KeyFrameAnimation.xaml
<Page x:Class="XamlDemo.Animation.KeyFrameAnimation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:XamlDemo.Animation" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid Background="Transparent"> <StackPanel Margin="120 0 0 0"> <!-- 关键帧动画一共有 4 种: ColorAnimationUsingKeyFrames, DoubleAnimationUsingKeyFrames, PointAnimationUsingKeyFrames, ObjectAnimationUsingKeyFrames 它们均继承自 Timeline ColorAnimationUsingKeyFrames, DoubleAnimationUsingKeyFrames, PointAnimationUsingKeyFrames 中的 KeyFrame 支持: LinearColorKeyFrame, DiscreteColorKeyFrame, SplineColorKeyFrame, EasingColorKeyFrame ObjectAnimationUsingKeyFrames 中的 KeyFrame 支持: DiscreteObjectKeyFrame Linear 代表线性,Discrete 代表离散,Spline 代表三次贝塞尔曲线,Easing 代表缓动 Value - 关键帧的目标值 KeyTime - 到达关键帧目标值的时间 KeySpline - 三次贝塞尔曲线的两个控制点:x1,y1 x2,y2(该三次贝塞尔曲线的起点为0,0,终点为1,1) --> <Grid Margin="5" HorizontalAlignment="Left"> <Grid.Resources> <BeginStoryboard x:Name="storyboardColor"> <Storyboard> <ColorAnimationUsingKeyFrames Storyboard.TargetName="solidColorBrush" Storyboard.TargetProperty="Color" Duration="0:0:10"> <LinearColorKeyFrame Value="Green" KeyTime="0:0:3" /> <DiscreteColorKeyFrame Value="Blue" KeyTime="0:0:4" /> <SplineColorKeyFrame Value="Red" KeySpline="0.6,0.0 0.9,0.00" KeyTime="0:0:6" /> <EasingColorKeyFrame Value="Orange" KeyTime="0:0:8"> <EasingColorKeyFrame.EasingFunction> <ElasticEase EasingMode="EaseInOut" /> </EasingColorKeyFrame.EasingFunction> </EasingColorKeyFrame> </ColorAnimationUsingKeyFrames> </Storyboard> </BeginStoryboard> </Grid.Resources> <Rectangle Width="100" Height="50"> <Rectangle.Fill> <SolidColorBrush x:Name="solidColorBrush" Color="Red" /> </Rectangle.Fill> </Rectangle> </Grid> <Grid Margin="5" HorizontalAlignment="Left"> <Grid.Resources> <BeginStoryboard x:Name="storyboardDouble"> <Storyboard> <DoubleAnimationUsingKeyFrames Storyboard.TargetName="translateTransform" Storyboard.TargetProperty="X" Duration="0:0:10"> <LinearDoubleKeyFrame Value="500" KeyTime="0:0:3" /> <DiscreteDoubleKeyFrame Value="400" KeyTime="0:0:4" /> <SplineDoubleKeyFrame Value="300" KeySpline="0.6,0.0 0.9,0.00" KeyTime="0:0:6" /> <EasingDoubleKeyFrame Value="200" KeyTime="0:0:8"> <EasingDoubleKeyFrame.EasingFunction> <ElasticEase EasingMode="EaseInOut" /> </EasingDoubleKeyFrame.EasingFunction> </EasingDoubleKeyFrame> </DoubleAnimationUsingKeyFrames> </Storyboard> </BeginStoryboard> </Grid.Resources> <Rectangle Fill="Red" Width="100" Height="50"> <Rectangle.RenderTransform> <TranslateTransform x:Name="translateTransform" X="0" Y="0" /> </Rectangle.RenderTransform> </Rectangle> </Grid> <Grid Margin="5" HorizontalAlignment="Left"> <Grid.Resources> <BeginStoryboard x:Name="storyboardPoint"> <Storyboard> <PointAnimationUsingKeyFrames Storyboard.TargetName="ellipseGeometry" Storyboard.TargetProperty="Center" Duration="0:0:10" EnableDependentAnimation="True"> <LinearPointKeyFrame Value="100,100" KeyTime="0:0:3" /> <DiscretePointKeyFrame Value="200,200" KeyTime="0:0:4" /> <SplinePointKeyFrame Value="300,300" KeySpline="0.6,0.0 0.9,0.00" KeyTime="0:0:6" /> <EasingPointKeyFrame Value="400,400" KeyTime="0:0:8"> <EasingPointKeyFrame.EasingFunction> <ElasticEase EasingMode="EaseInOut" /> </EasingPointKeyFrame.EasingFunction> </EasingPointKeyFrame> </PointAnimationUsingKeyFrames> </Storyboard> </BeginStoryboard> </Grid.Resources> <Path Fill="Red"> <Path.Data> <EllipseGeometry x:Name="ellipseGeometry" Center="50,50" RadiusX="15" RadiusY="15" /> </Path.Data> </Path> </Grid> <Grid Margin="5" HorizontalAlignment="Left"> <Grid.Resources> <BeginStoryboard x:Name="storyboardObject"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="textBlock" Storyboard.TargetProperty="Text" Duration="0:0:10"> <DiscreteObjectKeyFrame KeyTime="0:0:1" Value="w" /> <DiscreteObjectKeyFrame KeyTime="0:0:2" Value="we" /> <DiscreteObjectKeyFrame KeyTime="0:0:3" Value="web" /> <DiscreteObjectKeyFrame KeyTime="0:0:4" Value="weba" /> <DiscreteObjectKeyFrame KeyTime="0:0:5" Value="webab" /> <DiscreteObjectKeyFrame KeyTime="0:0:6" Value="webabc" /> <DiscreteObjectKeyFrame KeyTime="0:0:7" Value="webabcd" /> </ObjectAnimationUsingKeyFrames> </Storyboard> </BeginStoryboard> </Grid.Resources> <TextBlock x:Name="textBlock" Width="200" FontSize="26.667" Text="" /> </Grid> </StackPanel> </Grid> </Page>
3、演示缓动动画的应用
Animation/EasingAnimation.xaml
<Page x:Class="XamlDemo.Animation.EasingAnimation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:XamlDemo.Animation" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid Background="Transparent"> <StackPanel Margin="120 0 0 0"> <StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal"> <TextBlock FontSize="26.667" Text="Easing Function:" VerticalAlignment="Top" /> <!-- 用于选择 Easing Function --> <ComboBox x:Name="cboEasingFunction" SelectionChanged="cboEasingFunction_SelectionChanged_1" Margin="10 0 0 0"> <ComboBoxItem>BackEase</ComboBoxItem> <ComboBoxItem>BounceEase</ComboBoxItem> <ComboBoxItem>CircleEase</ComboBoxItem> <ComboBoxItem>CubicEase</ComboBoxItem> <ComboBoxItem>ElasticEase</ComboBoxItem> <ComboBoxItem>ExponentialEase</ComboBoxItem> <ComboBoxItem>PowerEase</ComboBoxItem> <ComboBoxItem>QuadraticEase</ComboBoxItem> <ComboBoxItem>QuarticEase</ComboBoxItem> <ComboBoxItem>QuinticEase</ComboBoxItem> <ComboBoxItem>SineEase</ComboBoxItem> </ComboBox> </StackPanel> <StackPanel Orientation="Horizontal" Margin="10 0 0 0"> <TextBlock FontSize="26.667" Text="Easing Mode:" VerticalAlignment="Top" /> <ComboBox x:Name="cboEasingMode" SelectionChanged="cboEasingMode_SelectionChanged_1" Margin="10 0 0 0"> <!-- 用于选择 Easing Mode --> <ComboBoxItem>EaseIn</ComboBoxItem> <ComboBoxItem>EaseOut</ComboBoxItem> <ComboBoxItem>EaseInOut</ComboBoxItem> </ComboBox> </StackPanel> </StackPanel> <StackPanel Orientation="Horizontal" Margin="0 30 0 0"> <StackPanel.Resources> <Storyboard x:Name="storyboard"> <!-- 用于演示缓动动画的效果 --> <DoubleAnimation x:Name="aniEasingDemo" Storyboard.TargetName="easingDemo" Storyboard.TargetProperty="(Canvas.Left)" Duration="0:0:3" RepeatBehavior="Forever" From="0" To="300" /> <!-- 用一个球显示缓动轨迹(X 轴代表时间) --> <DoubleAnimation x:Name="aniBallX" Storyboard.TargetName="ball" Storyboard.TargetProperty="(Canvas.Left)" Duration="0:0:3" RepeatBehavior="Forever" From="0" To="100" /> <!-- 用一个球显示缓动轨迹(Y 轴代表当前时间点的缓动结果值) --> <DoubleAnimation x:Name="aniBallY" Storyboard.TargetName="ball" Storyboard.TargetProperty="(Canvas.Top)" Duration="0:0:3" RepeatBehavior="Forever" From="0" To="100" /> </Storyboard> </StackPanel.Resources> <StackPanel> <Canvas Name="graphContainer" RenderTransformOrigin="0,0.5" Height="100" Width="100"> <Canvas.RenderTransform> <ScaleTransform ScaleY="-1" /> </Canvas.RenderTransform> <!-- 用于显示缓动曲线 --> <Canvas Name="graph" /> <!-- 缓动曲线的 X 轴和 Y 轴 --> <Line X1="0" Y1="0" X2="0" Y2="100" Stroke="Black" StrokeThickness="1" Width="1" Height="100" /> <Line X1="0" Y1="0" X2="100" Y2="1" Stroke="Black" StrokeThickness="1" Width="100" Height="1" /> <!-- 用一个球显示缓动轨迹 --> <Ellipse Name="ball" Fill="Orange" Width="5" Height="5" /> </Canvas> </StackPanel> <StackPanel Margin="30 0 0 0"> <Border BorderBrush="Black" BorderThickness="1"> <Canvas Width="400" Height="100"> <!-- 用于演示缓动动画的效果 --> <Rectangle Name="easingDemo" Width="100" Height="100" Fill="Blue" /> </Canvas> </Border> </StackPanel> </StackPanel> </StackPanel> </Grid> </Page>
Animation/EasingAnimation.xaml.cs
/* * 演示缓动(easing)的应用 * * WinRT 支持 11 种经典的缓动: * BackEase, BounceEase, CircleEase, CubicEase, ElasticEase, ExponentialEase, PowerEase, QuadraticEase, QuarticEase, QuinticEase, SineEase * * EasingMode 有 3 种: * EaseIn, EaseOut, EaseInOut */ using Windows.Foundation; using Windows.UI; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Media; using Windows.UI.Xaml.Media.Animation; using Windows.UI.Xaml.Navigation; using Windows.UI.Xaml.Shapes; namespace XamlDemo.Animation { public sealed partial class EasingAnimation : Page { public EasingAnimation() { this.InitializeComponent(); this.Loaded += EasingAnimation_Loaded; } void EasingAnimation_Loaded(object sender, Windows.UI.Xaml.RoutedEventArgs e) { cboEasingFunction.SelectedIndex = 0; cboEasingMode.SelectedIndex = 0; } private void cboEasingFunction_SelectionChanged_1(object sender, SelectionChangedEventArgs e) { EasingChanged(); } private void cboEasingMode_SelectionChanged_1(object sender, SelectionChangedEventArgs e) { EasingChanged(); } private void EasingChanged() { if (cboEasingFunction.SelectedIndex == -1 || cboEasingMode.SelectedIndex == -1) return; storyboard.Stop(); EasingFunctionBase easingFunction = null; // 确定 Easing Function switch ((cboEasingFunction.SelectedItem as ComboBoxItem).Content.ToString()) { case "BackEase": // Amplitude - 幅度,必须大于等于 0,默认值 1 easingFunction = new BackEase() { Amplitude = 1 }; break; case "BounceEase": // Bounces - 弹跳次数,必须大于等于 0,默认值 3 // Bounciness - 弹跳程度,必须是正数,默认值 2 easingFunction = new BounceEase() { Bounces = 3, Bounciness = 2 }; break; case "CircleEase": easingFunction = new CircleEase(); break; case "CubicEase": easingFunction = new CubicEase(); break; case "ElasticEase": // Oscillations - 来回滑动的次数,必须大于等于 0,默认值 3 // Springiness - 弹簧的弹度,必须是正数,默认值 3 easingFunction = new ElasticEase() { Oscillations = 3, Springiness = 3 }; break; case "ExponentialEase": easingFunction = new ExponentialEase(); break; case "PowerEase": easingFunction = new PowerEase(); break; case "QuadraticEase": easingFunction = new QuadraticEase(); break; case "QuarticEase": easingFunction = new QuarticEase(); break; case "QuinticEase": easingFunction = new QuinticEase(); break; case "SineEase": easingFunction = new SineEase(); break; default: break; } // 确定 Easing Mode switch ((cboEasingMode.SelectedItem as ComboBoxItem).Content.ToString()) { case "EaseIn": easingFunction.EasingMode = EasingMode.EaseIn; break; case "EaseOut": easingFunction.EasingMode = EasingMode.EaseOut; break; case "EaseInOut": easingFunction.EasingMode = EasingMode.EaseInOut; break; default: break; } // 用于演示缓动效果 aniEasingDemo.EasingFunction = easingFunction; // 用于演示缓动轨迹 aniBallY.EasingFunction = easingFunction; // 画出当前缓动的曲线图 DrawEasingGraph(easingFunction); storyboard.Begin(); } /// <summary> /// 绘制指定的 easing 的曲线图 /// </summary> private void DrawEasingGraph(EasingFunctionBase easingFunction) { graph.Children.Clear(); Path path = new Path(); PathGeometry pathGeometry = new PathGeometry(); PathFigure pathFigure = new PathFigure() { StartPoint = new Point(0, 0) }; PathSegmentCollection pathSegmentCollection = new PathSegmentCollection(); // 0 - 1 之间每隔 0.005 计算出一段 LineSegment,用于显示此 0.005 时间段内的缓动曲线 for (double i = 0; i < 1; i += 0.005) { double x = i * graphContainer.Width; double y = easingFunction.Ease(i) * graphContainer.Height; LineSegment segment = new LineSegment(); segment.Point = new Point(x, y); pathSegmentCollection.Add(segment); } pathFigure.Segments = pathSegmentCollection; pathGeometry.Figures.Add(pathFigure); path.Data = pathGeometry; path.Stroke = new SolidColorBrush(Colors.Black); path.StrokeThickness = 1; graph.Children.Add(path); } } }
OK
[源码下载]