原文:Silverlight & Blend动画设计系列五:故事板(StoryBoards)和动画(Animations)

  正如你所看到的,Blend是一个非常强大的节约时间的设计工具,在Blend下能够设计出很多满意的动画作品,或许他具体是怎么实现的,通过什么方式实现的我们还是一无所知。本篇将续前面几篇基础动画之上,详细介绍Silverlight里提供故事板(StoryBorards)的属性和各种不同类型的动画(Animations)的详细知识点,揭晓在Blend下设计动画的内幕故事。

一、故事板(StoryBoard)属性

  Silvelight中的故事板(StoryBoard)提供了管理时间线的功能接口,可以用来控制一个或多个Silverlight动画进程,故我也称其为动画时间线容器。如下XAML代码块演示了通过StoryBoard来管理了名为GreenBall的元素在X坐标方向上的偏移变换动画。

<Storyboard x:Name="MoveBall">
    <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="GreenBall" 
        Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">
        <EasingDoubleKeyFrame KeyTime="00:00:02" Value="540"/>
    </DoubleAnimationUsingKeyFrames>
</Storyboard>

  StoryBoard提供了六个常用的动画属性选项,它们分别是:AutoReverse,BeginTime,Duration,FillBehavior,RepeatBehavior,SpeedRatio。通过这六个属性可以用来控制动画的基本行为动作,比如想要实现动画的缓冲时间,就需要用到Duration属性;设置动画的开始时间则用BeginTime;如果动画执行完后根据执行路线反向执行到原始状态则需要使用AutoReverse;如果需要设置动画的运行速度则使用SpeedRatio就可以完成。以下代码块演示了AutoReverse属性的使用,动画运行完后将按着原来的运行路线进行反向运行。更多详细可参考这篇博文介绍:《动画基础快速入门Animation》或者MSDN。

<Storyboard x:Name="MoveBall" AutoReverse="True">
    <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="GreenBall" 
        Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">
        <EasingDoubleKeyFrame KeyTime="00:00:02" Value="540"/>
    </DoubleAnimationUsingKeyFrames>
</Storyboard>

  Storyboard的属性是可以组合应用的,如上代码块给动画设置了AutoReverse属性,使其在动画执行完后通过原来的运行路径进行回滚动画,可以给该动画时间线容器添加一个BeginTime属性,使其在程序加载后5秒钟才开始执行动画,这样就使用到了两个属性,如下代码块:

<Storyboard x:Name="MoveBall" AutoReverse="True" BeginTime="00:00:05">
    ......
</Storyboard>

二、动画类型(Types of animation)

  Silverlight中的动画主要分From/To/By关键帧动画两种类型。

  From/To/By动画也称为线性插值动画(Linear Interpolation),是Silverlight类型中最简单的一种动画,只需要设置开始(From)、结束(To)和动画值(By)就可以完成动画的创建,Silverlight 3中提供了三种基础的From/To/By动画类型:DoubleAnimation、ColorAnimation和PointAnimation.

  关键帧动画比From/To/By动画更加强大,无需指定动画的开始、结束以及动画缓冲时间等相关参数,只需要关注关键帧和如何去控制动画就行了。Silverlight 3中提供了四种基本的关键帧动画:缓和(Easing)、线性(Linear)、样条(Spline)和离散(discreet)。

  DoubleAnimation的使用是非常简单的,只需要搞清楚From/To/By三要素就基本掌握了该类型动画的使用,下面是一个简单的通过DoubleAnimation实现的圆形移动的示例。

<UserControl x:Class="DoubleByAnimation.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Width="800" Height="600">
    <UserControl.Resources>
        <Storyboard x:Name="Storyboard1">
            <DoubleAnimation Storyboard.TargetName="Ellipse" 
                Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" 
                From="0" 
                By="150" 
                Duration="00:00:01"/>
        </Storyboard>
    </UserControl.Resources>

<Canvas x:Name="LayoutRoot" Background="White" >
        <Ellipse Height="200" Width="200" Fill="#FFFF0000" Canvas.Top="181" Canvas.Left="92" RenderTransformOrigin="0.5,0.5" x:Name="Ellipse">
            <Ellipse.RenderTransform>
                <TransformGroup>
                    <ScaleTransform/>
                    <SkewTransform/>
                    <RotateTransform/>
                    <TranslateTransform/>
                </TransformGroup>
            </Ellipse.RenderTransform>
        </Ellipse>
    </Canvas>
</UserControl>

  下面通过一个稍复杂的示例来演示DoubleAnimation动画的使用,如下动画代码块实现了名称为Slider对象的X坐标方向的移动动画:

<Storyboard x:Name="SlideOut">
    <DoubleAnimation Storyboard.TargetName="Slider" 
        Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" 
    Duration="00:00:00.50" To="150"/>
</Storyboard>
<Storyboard x:Name="SlideIn">
    <DoubleAnimation Storyboard.TargetName="Slider" 
        Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" 
    Duration="00:00:00.50" To="0"/>
</Storyboard>

  如上动画定义代码块中定义了两个动画,一个实现将对象Slider向X坐标方向移动到150像素点的位置,第二个动画实现将名为Silder的对象向X方向移动到0像素点的坐标位置,这样其实就实现了一个呈现与不呈现的效果。这里我们发挥大脑的潜力想象一下,如果Slider是一个面板对象,通过鼠标指向和离开的事件使用上面两个动画进行控制其不就实现了面板的鼠标指向就显示,离开就退回到原来的位置了?答案却是如此,详细见下代码块:

public partial class MainPage : UserControl
{
    public MainPage()
    {
        InitializeComponent();

Slider.MouseEnter += new MouseEventHandler(Slider_MouseEnter);
        Slider.MouseLeave += new MouseEventHandler(Slider_MouseLeave);
    }

private void Slider_MouseLeave(object sender, MouseEventArgs e)
    {
        SlideIn.Begin();
    }

private void Slider_MouseEnter(object sender, MouseEventArgs e)
    {
        SlideOut.Begin();
    }
}

        

  通过上面的示例,是否觉得要在Silverlight中实现一个动画是非常简单的?上面的示例就是掩饰了如何使用From/To/By的DoubleAnimation实现了对象的移动动画,同样也可以使用关键帧动画(DoubleUsingKeyframes)来实现这一功能。如下代码片段演示了元素Silder向X坐标方向移动到150像素点。

Storyboard MoveRight = new Storyboard();

DoubleAnimationUsingKeyFrames Anim = new DoubleAnimationUsingKeyFrames();
Storyboard.SetTargetName(Anim, "Slider");
Anim.SetValue(Storyboard.TargetPropertyProperty, 
    new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)"));
Anim.BeginTime = new TimeSpan(0, 0, 0);
SplineDoubleKeyFrame SKeyFrame = new SplineDoubleKeyFrame();
SKeyFrame.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0.5));
SKeyFrame.Value = 150;
Anim.KeyFrames.Add(SKeyFrame);
MoveRight.Children.Add(Anim);

......

  ColorAnimation类型动画主要应用于颜色上的变换动画效果,比如有一个圆,默认的填充颜色是红色(Red),设计一个动画通过2秒钟的动画换成将圆的填充颜色变换为蓝色。

<Ellipse Height="218" Width="218" Canvas.Left="294" Canvas.Top="195" Fill="#FFFF0000" Cursor="Hand" x:Name="RedEllipse"/>

  可以通过Blend的设计器来完成这样的动画的创建,在对象和时间轴面板里新建动画容器时间线,然后选中RadEllipse圆形对象在0秒的时间线上填充其颜色为红色,2秒的时间线上填充其颜色为蓝色,详细设计如下图:

        

  Blend最终生成的XAML代码如下:

<Storyboard x:Name="Storyboard1">
    <ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="RedEllipse" 
        Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
        <EasingColorKeyFrame KeyTime="00:00:00" Value="Red"/>
        <EasingColorKeyFrame KeyTime="00:00:02" Value="Blue"/>
    </ColorAnimationUsingKeyFrames>
</Storyboard>

  有Blend这样强大的设计工具是很幸运的,对于设计人员来说要实现一些动画需求直接通过界面设计就完成了。对于程序员来说就烦恼了,由于不熟悉设计工具,要实现某种动画只能通过编写程序代码来完成,这将是一个很庞大的工程,比如说当鼠标指向一圆的时候其填充颜色慢慢的向蓝色(Blue)渐变,鼠标离开的时候慢慢的恢复其默认颜色红色。实现这动画效果则需要写上如下长篇的程序代码:

private Storyboard TurnBlue = new Storyboard();
private Storyboard TurnRed = new Storyboard();
private ColorAnimation BlueColor = new ColorAnimation();
private ColorAnimation RedColor = new ColorAnimation();

public MainPage()
{
    InitializeComponent();

BlueColor.SetValue(Storyboard.TargetNameProperty, "RedEllipse");
    BlueColor.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath("(Shape.Fill).(SolidColorBrush.Color)"));
    BlueColor.To = Colors.Blue;
    TurnBlue.Children.Add(BlueColor);
    LayoutRoot.Resources.Add("TurnBlue", TurnBlue);

RedColor.SetValue(Storyboard.TargetNameProperty, "RedEllipse");
    RedColor.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath("(Shape.Fill).(SolidColorBrush.Color)"))
    RedColor.To = Colors.Red;
    TurnRed.Children.Add(RedColor);
    LayoutRoot.Resources.Add("TurnRed", TurnRed);

RedEllipse.MouseEnter += (senderRed, eRed) =>
        {
            TurnRed.Begin();
        };
    RedEllipse.MouseLeave += (senderBlue, eBlue) =>
        {
            TurnBlue.Begin();
        };
}

  这样的代码实现其实就是用程序代码创建了两个动画,一个由红色变换到蓝色,一个则由蓝色变换到红色,按照前面的方法直接在Blend中设计也是可以的。最终的运行效果如下图:

        

  PointAnimation类型动画更好理解,也就是动画效果是通过不同的坐标点来控制的。比如说浪涛的效果,下面就以浪涛为示例来演示PointAnimation类型动画的使用。

代码

<Storyboard x:Name="Storyboard1" RepeatBehavior="Forever" FillBehavior="HoldEnd">
    <PointAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="water" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[1].(BezierSegment.Point2)">
        <EasingPointKeyFrame KeyTime="00:00:00" Value="351.732116699219,36.4064197540283"/>
        <EasingPointKeyFrame KeyTime="00:00:03" Value="415.732116699219,84.4064178466797"/>
    </PointAnimationUsingKeyFrames>
    <PointAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="water" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[1].(BezierSegment.Point3)">
        <EasingPointKeyFrame KeyTime="00:00:00" Value="425.502014160156,32.8349914550781"/>
        <EasingPointKeyFrame KeyTime="00:00:03" Value="489.502014160156,80.8349914550781"/>
    </PointAnimationUsingKeyFrames>
    <PointAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="water" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[2].(BezierSegment.Point1)">
        <EasingPointKeyFrame KeyTime="00:00:00" Value="499.271911621094,29.2635669708252"/>
        <EasingPointKeyFrame KeyTime="00:00:03" Value="563.271911621094,77.2635650634765"/>
    </PointAnimationUsingKeyFrames>
    <PointAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="water" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[0].(BezierSegment.Point2)">
        <EasingPointKeyFrame KeyTime="00:00:00" Value="112.729011535644,80.834991455078"/>
        <EasingPointKeyFrame KeyTime="00:00:03" Value="104.729011535645,32.8349914550781"/>
    </PointAnimationUsingKeyFrames>
    <PointAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="water" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[0].(BezierSegment.Point3)">
        <EasingPointKeyFrame KeyTime="00:00:00" Value="185.502014160156,80.834991455078"/>
        <EasingPointKeyFrame KeyTime="00:00:03" Value="177.502014160156,32.8349914550781"/>
    </PointAnimationUsingKeyFrames>
    <PointAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="water" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[1].(BezierSegment.Point1)">
        <EasingPointKeyFrame KeyTime="00:00:00" Value="258.275024414062,80.834991455078"/>
        <EasingPointKeyFrame KeyTime="00:00:03" Value="250.275024414063,32.8349914550781"/>
    </PointAnimationUsingKeyFrames>
    <PointAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="water" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[2].(BezierSegment.Point2)">
        <EasingPointKeyFrame KeyTime="00:00:00" Value="600.704162597656,72.7879943847655"/>
        <EasingPointKeyFrame KeyTime="00:00:03" Value="608.704162597656,32.8349229097365"/>
    </PointAnimationUsingKeyFrames>
    <PointAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="water" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[2].(BezierSegment.Point3)">
        <EasingPointKeyFrame KeyTime="00:00:00" Value="665.502014160156,72.7879943847655"/>
        <EasingPointKeyFrame KeyTime="00:00:03" Value="673.502014160156,32.8349229097365"/>
    </PointAnimationUsingKeyFrames>
    <PointAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="water" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[3].(BezierSegment.Point1)">
        <EasingPointKeyFrame KeyTime="00:00:00" Value="730.299926757813,72.7879943847655"/>
        <EasingPointKeyFrame KeyTime="00:00:03" Value="738.299926757813,32.8349229097365"/>
    </PointAnimationUsingKeyFrames>
    <PointAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="water" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[3].(BezierSegment.Point2)">
        <EasingPointKeyFrame KeyTime="00:00:00" Value="801.502014160156,40.8349914550781"/>
        <EasingPointKeyFrame KeyTime="00:00:03" Value="801.502014160156,56.8349229097366"/>
    </PointAnimationUsingKeyFrames>
    <PointAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="water" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[3].(BezierSegment.Point3)">
        <EasingPointKeyFrame KeyTime="00:00:00" Value="801.502014160156,40.8349914550781"/>
        <EasingPointKeyFrame KeyTime="00:00:03" Value="801.502014160156,56.8349229097366"/>
    </PointAnimationUsingKeyFrames>
    <PointAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="water" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[4].(BezierSegment.Point1)">
        <EasingPointKeyFrame KeyTime="00:00:00" Value="801.502014160156,40.8349914550781"/>
        <EasingPointKeyFrame KeyTime="00:00:03" Value="801.502014160156,56.8349229097366"/>
    </PointAnimationUsingKeyFrames>
    <PointAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="water" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.StartPoint)">
        <EasingPointKeyFrame KeyTime="00:00:00" Value="1.50201416015619,32.834991455078"/>
        <EasingPointKeyFrame KeyTime="00:00:03" Value="1.50201416015625,88.8349914550779"/>
    </PointAnimationUsingKeyFrames>
    <PointAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="water" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[0].(BezierSegment.Point1)">
        <EasingPointKeyFrame KeyTime="00:00:00" Value="1.50201416015619,32.834991455078"/>
        <EasingPointKeyFrame KeyTime="00:00:03" Value="1.50201416015625,88.8349914550779"/>
    </PointAnimationUsingKeyFrames>
</Storyboard>

        

  关于Silverlight中的动画相关的理论概论暂时就介绍这些,希望上面的简单介绍能帮助大家深入的理解和使用Blend进行各种不同的动画功能设计。更多信息可查阅下面的推资源连接。

推荐资源:

  MSDN:http://msdn.microsoft.com/zh-cn/library/cc189090(VS.95).aspx

  http://www.silverlight.net/learn/quickstarts/animations/

  http://blog.csdn.net/ghj1976/archive/2009/12/22/5056916.aspx

  Silverlight & Blend动画设计系列一:偏移动画(TranslateTransform)

  Silverlight & Blend动画设计系列二:旋转动画(RotateTransform)

  Silverlight & Blend动画设计系列三:缩放动画(ScaleTransform)

  Silverlight & Blend动画设计系列四:倾斜动画(SkewTransform)

  

版权说明

本文属原创文章,欢迎转载且注明文章出处,其版权归作者和博客园共有。

作      者:Beniao

文章出处:http://beniao.cnblogs.com/  或  http://www.cnblogs.com/

Silverlight Blend动画设计系列五:故事板(StoryBoards)和动画(Animations)相关推荐

  1. Silverlight Blend动画设计系列六:动画技巧(Animation Techniques)之对象与路径转化、波感特效...

    原文:Silverlight & Blend动画设计系列六:动画技巧(Animation Techniques)之对象与路径转化.波感特效 当我们在进行Silverlight & Bl ...

  2. Silverlight Blend动画设计系列四:倾斜动画(SkewTransform)

    Silverlight中的倾斜变化动画(SkewTransform)能够实现对象元素的水平.垂直方向的倾斜变化动画效果.我们现实生活中的倾斜变化效果是非常常见的,比如翻书的纸张效果,关门开门的时候门缝 ...

  3. Silverlight Blend动画设计系列八:拖放(Drag-Drop)操作与拖放行为(DragBehavior)

    Silverlight & Blend动画设计系列八:拖放(Drag-Drop)操作与拖放行为(DragBehavior) 原文:Silverlight & Blend动画设计系列八: ...

  4. Silverlight Blend动画设计系列十二:三角函数(Trigonometry)动画之自由旋转(Free-form rotation)...

    说到对象的旋转,或许就会联想到对象角度的概念.对象的旋转实现实际上就是利用对象的角度改变来实现的位置变换,在<Silverlight & Blend动画设计系列二:旋转动画(Rotate ...

  5. Silverlight Blend动画设计系列七:模糊效果(BlurEffect)与阴影效果(DropShadowEffect)...

    模糊效果(BlurEffect)与阴影效果(DropShadowEffect)是两个非常实用和常用的两个特效,比如在开发相册中,可以对照片的缩略图添加模糊效果,在放大照片的过程中动态改变照片的大小和模 ...

  6. Silverlight Blend动画设计系列三:缩放动画(ScaleTransform)

    原文:Silverlight & Blend动画设计系列三:缩放动画(ScaleTransform) 在Silverlight的动画框架中,ScaleTransform类提供了在二维空间中的坐 ...

  7. Silverlight Blend动画设计系列二:旋转动画(RotateTransform)

    原文:Silverlight & Blend动画设计系列二:旋转动画(RotateTransform) Silverlight的基础动画包括偏移.旋转.缩放.倾斜和翻转动画,这些基础动画毫无疑 ...

  8. 基于Montgomery算法的高速、可配置 RSA密码IP核硬件设计系列(五)——模幂模块(抵抗侧信道攻击)模块的设计实现方案

    基于Montgomery算法的高速.可配置RSA密码IP核硬件设计系列(五) 2.2 模幂模块设计(抵抗测信道攻击模块) 2.2.1 模幂模块及内部模块的功能 2.2.3 模幂各模块的实现方案 2.2 ...

  9. Silverlight Blend动画设计系列

    第一至三章地址:http://www.silverlightchina.net/plus/search.php?keyword=Silverlight+Blend%B6%AF%BB%AD%C9%E8% ...

最新文章

  1. linux grep 例子,Linux中Grep常用的15个例子
  2. 求马鞍点java_二维数组马鞍点求解算法
  3. 科大星云诗社动态20210310
  4. 工作47:继续理解父子组件
  5. magento网站建设_跨境自建站Magento麦进斗代打包代贴单代发货
  6. C++_你真的知道++i 和 i++的区别吗?_左值/右值/右值引用
  7. Access数据类型备忘
  8. dda算法_计算机图形学中的DDA(数字差分分析仪)算法
  9. 计算机制图的基本知识和技能,《计算机绘图基础》制图的基本知识和技能精讲.ppt...
  10. 2022哈尔滨工程大学软件工程上岸经验贴
  11. C#进阶高级程序员开发必知必会:泛型的定义实操案例: 实现堆栈的后进先出功能
  12. 程序员如何写简历?程序员写出牛逼简历的5大技巧
  13. 融合定位技术(FLP)介绍
  14. 怎样利用闲鱼赚差价?教你在闲鱼卖货赚钱!
  15. mysql sql 隐藏信息
  16. WWW 2015 | LINE:大规模信息网络的嵌入
  17. 一喝到威士忌真是什么烦恼都忘了
  18. 大型网站前端使用图片格式的正确姿势
  19. JSS-22 DC220V【时间继电器】
  20. VRTK4.0 学习Day4

热门文章

  1. Google Play服务中的条码扫描识别
  2. 使用Android Studio新建Project并建立多个module
  3. linux命令速查手册_值得收藏!Linux系统常用命令速查手册
  4. 【Android UI】图片 + 文字展示by SpannableStringBuilder
  5. Swift String字符串版本更新特性
  6. (0029) iOS 开发之API HTTP 请求调试网站
  7. (iOS-框架封装)AFN3.x 网络请求封装
  8. python 错误与异常
  9. git分支合并(包含学习git命令的方法)
  10. 【BZOJ 4832】 [Lydsy2017年4月月赛] 抵制克苏恩 期望概率dp