zoukankan      html  css  js  c++  java
  • 重新想象 Windows 8 Store Apps (19) 动画: 线性动画, 关键帧动画, 缓动动画

    [源码下载]


    重新想象 Windows 8 Store Apps (19) - 动画: 线性动画, 关键帧动画, 缓动动画



    作者:webabcd


    介绍
    重新想象 Windows 8 Store Apps 之 动画

    • 线性动画 - 共有 3 种: ColorAnimation, DoubleAnimation, PointAnimation, 它们均继承自 Timeline
    • 关键帧动画 - 共有 4 种:ColorAnimationUsingKeyFrames, DoubleAnimationUsingKeyFrames, PointAnimationUsingKeyFrames, ObjectAnimationUsingKeyFrames 它们均继承自 Timeline
    • 缓动动画 - easing



    示例
    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
    [源码下载]

  • 相关阅读:
    Asp.net2.0 中自定义过滤器对Response内容进行处理 dodo
    自动化测试工具 dodo
    TestDriven.NET 2.0——单元测试的好助手(转) dodo
    JS弹出窗口的运用与技巧 dodo
    ElasticSearch 简介 规格严格
    修改PostgreSQL字段长度导致cached plan must not change result type错误 规格严格
    Linux系统更改时区(转) 规格严格
    mvn编译“Cannot find matching toolchain definitions for the following toolchain types“报错解决方法 规格严格
    ElasticSearch 集群 & 数据备份 & 优化 规格严格
    Elasticsearch黑鸟教程22:索引模板的详细介绍 规格严格
  • 原文地址:https://www.cnblogs.com/webabcd/p/3021400.html
Copyright © 2011-2022 走看看