动画: 缓动动画
演示缓动(easing)的应用
Animation/EasingAnimation.xaml
<Page x:Class="Windows10.Animation.EasingAnimation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:Windows10.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="10 0 10 10"> <StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal"> <TextBlock FontSize="24" Text="Easing Function:" VerticalAlignment="Top" /> <!-- 用于选择 Easing Function --> <ComboBox x:Name="cboEasingFunction" SelectionChanged="cboEasingFunction_SelectionChanged" 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="24" Text="Easing Mode:" VerticalAlignment="Top" /> <ComboBox x:Name="cboEasingMode" SelectionChanged="cboEasingMode_SelectionChanged" 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.Shapes; namespace Windows10.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(object sender, SelectionChangedEventArgs e) { EasingChanged(); } private void cboEasingMode_SelectionChanged(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); } } }