让你的XAML运动起来

最近开始接触到.NET3.5的东西,看了一些老外的文章,觉得不错的也顺手翻译了一下,希望对跟我一样刚刚接触.NET3.0/3.5的朋友有所帮助。水平有限,欢迎拍砖。

下面这篇是关于WPF的,想学Silverlight的朋友也不妨一看。已经是人家1年多以前的作品了,我们的技术还是比较滞后的。

原文地址:http://www.c-sharpcorner.com/UploadFile/mgold/XAMLAnimation04042007191109PM/XAMLAnimation.aspx

原作者:

 
介绍
XAML在描述表单上的控件时非常有用,但并不仅限于此。XAML还提供了在窗口中绘图的途径。这些图像可以是静态的或者运动的,而且都是通过XML来描述。在这篇文章中我们将会看到使用XML在XAML画布上绘图的部分功能。
在XAML中绘图
让我们从在窗口中绘制一个简单的多边形开始。多边形的属性包括:名称(多边形变量名),描边(边缘颜色),描边粗细(类似于画笔粗细),点(描述多边形的实际点),以及Polygon.Fill(怎样填充多边形)
清单1 - XAML 中描述的多边形

<Windowx:Class="XAMLAnimation.Window1"
   
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   
Title="XAML Animation - Spinning Stars"Height="300"Width="355">

    <GridName="myGrid">
      <
CanvasMargin="15,18,18,26"MinHeight="50"MinWidth="50"Name="canvas1">
        <!--
Draw a star shape  -->
        <
Polygon
          
Name ="mypolygon1"
           Stroke="Blue"
          
StrokeThickness="1.0"     
          
Points="176.5,50 189.2,155.003 286.485,113.5 201.9,177 286.485,240.5
                      189.2,198.997 176.5,304 163.8,198.997 66.5148,240.5 151.1,177
                      66.5148,113.5 163.8,155.003
">

           <Polygon.Fill>
              <
SolidColorBrushColor="Blue" />
            </
Polygon.Fill>

          </Polygon>
      </
Canvas>
  </
Grid>
</
Window>

.NET 3.0同时给予了使用XAML或者C#描述的灵活性。以下是在代码中描述多边形的等价形式。
列表2 使用C# 绘制多边形

myPolygon1 = new Polygon();
myPolygon.Stroke = Brushes.Blue;
myPolygon.Fill = Brushes.Blue;
myPolygon.StrokeThickness = 1;
Point Point1 = new Point(176, 50);
Point Point2 = new Point(190,155);
Point Point3 = new Point(286,113);

...
PointCollection myPointCollection = new PointCollection();
myPointCollection.Add(Point1);
myPointCollection.Add(Point2);
myPointCollection.Add(Point3);
myPolygon.Points = myPointCollection;
myGrid.Children.Add(myPolygon1);

现在我们画出了我们的蓝星星,如果能够移动、旋转它或者改变它的尺寸,将会很有趣。让我们试试使用XAML变换我们的多边形。
在XAML的变换图形
XAML为所有图形提供了一组变换描述方式,包括平移、旋转、缩放、拉伸。以下表格描述了这些变换。
表1 - XMAL 图形的2D 变换
变换方式
XAML
XAML 示例
旋转
RotateTransform

 <RotateTransformx:Name="rotateIt"CenterX="176"CenterY="145" Angle="45" />

平移
TranslateTransform
< TranslateTransform x:Name = "translateIt"X ="-50"Y="50" />
拉伸
SkewTransform

<SkewTransform CenterX="50" CenterY="50" AngleX="30" AngleY="0" />

缩放
ScaleTransform
< ScaleTransform x:Name = "scaleIt"ScaleX=".25"ScaleY=".25" />
如果你想在一个图形上使用多种变换,你需要将这些变换包装在一个TransformationGroup中。以下是让我们的蓝星星在画布中收缩、移动和旋转的变换方式。RotateTransform告诉多边形绕点(176, 145)旋转90度。TranslateTransform将多边形向上和向左各移动了50像素。ScaleTransform将多边形收缩到它目前尺寸的1/4。
清单3 使用3 种变换来展现多边形

<Polygon.RenderTransform>
<
TransformGroup>
 <
RotateTransformx:Name="xformRotate"CenterX="176"CenterY="145" Angle="90" />
 <
TranslateTransformx:Name="xformTranslate"X ="-50"Y="-50" />
 <
ScaleTransformx:Name ="xformScale"ScaleX=".25"ScaleY=".25" />
</
TransformGroup>

</ Polygon.RenderTransform >
为了使用这些变换在画布上展现多边形,我们在多边形的RenderRansform标签中插入了变换组。
既然我们已经知道了怎样在多边形上进行这些很cool的变换,就让它开始在窗口中移动吧!
XAML中的运动

XAML使用了故事板(Stroyboard)的概念来提供一个框架,在这个框架中你可以使你的图形运动起来。故事板中的元素被称为运动对象。2D XAML中一共有4种类型的运动:DoubleAnimation, ColorAnimation, VectorAnimation和PointAnimation。基本上每种运动都会在指定的时间段内改变图形的一种属性。例如,DoubleAnimation可以在一段时间内改变一个Double类型的属性,而ColorAnimation将会在一段时间内改变Color属性。你只需要指定你要改变的属性、时间轴、改变区间以及运动类型!对于运动,你可以指定这个多边形对象中你想改变的那个变换(指TransformGroup中的变换),然后改变变换的相关属性,就可以在指定的时间轴内得到需要的运动效果。对于颜色变换,你可以指定你要改变的画刷(brush)。(注意,你需要确保你为图形中的XAML变换或画刷取了名字,这样你才能在Storyboard.TargetName中引用它)

表2 - XAML 中的不同运动
XAML
描述
XAML 示例
DoubleAnimation
在指定时间内改变图形的一个 Double 属性

<DoubleAnimationStoryboard.TargetName="KennyRotateIt"
Storyboard.TargetProperty="Angle"
From="0"To="360"Duration="0:0:01"
RepeatBehavior="Forever" />

DoubleAnimationUsingKeyFrames
允许你在一组时间间隔内改变一个 Double 属性。图形的运动会被解析成从一个位置到下一个位置的线性运动。例如,它会在开始的 3 秒内移动到第 10 个位置。在下 2 秒内移动到第 100 个位置,而在最终 5 秒内移动到第 200 个位置。

<DoubleAnimationUsingKeyFrames
Storyboard.TargetName="KennyTranslateIt"
Storyboard.TargetProperty="X"
Duration="0:0:10">
 <
LinearDoubleKeyFrameValue="10"KeyTime="0:0:3" />
  <
LinearDoubleKeyFrameValue="100"KeyTime="0:0:5" />
  <
LinearDoubleKeyFrameValue="200"KeyTime="0:0:10" />
</
DoubleAnimationUsingKeyFrames>

ColorAnimation
在一定时间内将图形的 Color 属性从一种颜色改变到一种新的颜色。
< ColorAnimation Storyboard.TargetName = "mybrush"Storyboard.TargetProperty="Color"From="Red"To="Blue"Duration="0:0:7"
 
VectorAnimation
允许你在一定时间内改变图形的 Vector 属性。
 
VectorAnimationUsingKeyFrames
允许你在一组时间间隔内使用向量改变一个图形。
                 
 
PointAnimation
允许你在一段时间内改变图形的一个点属性。例如图形的中心。
 < PointAnimation Storyboard.TargetProperty = "Center"Storyboard.TargetName="MyAnimatedEllipseGeometry"Duration="0:0:2"From="200,100"To="450,250"RepeatBehavior="Forever" />
 
像上面提到的那样,故事板是一组改变某些属性的运动对象。清单4展示了在屏幕上移动一个多边形的XAML运动。这里我们只改变TranslationTransform,为此我们使用DoubleAnimation来改变平移的X属性。在这个示例中,我们在14秒中将X从1改变到750像素。设置AutoReverse属性为True使我们可以让这个运动的星星原路返回(从750到1)。
清单4 在屏幕上使一个星星前后运动

<Polygon.Triggers>
<
EventTriggerRoutedEvent="Polygon.Loaded">
 <
EventTrigger.Actions>
    <
BeginStoryboard>
   <
Storyboard>
   <!--
Translate from 1 to 750 pixels, repeated, back-and-forth  -->
    <
DoubleAnimationStoryboard.TargetName="xformTranslate"
      
Storyboard.TargetProperty="X"
      
From="1"To="750"Duration="0:0:14"
       
AutoReverse ="True"RepeatBehavior="Forever" />

     </Storyboard>
    </
BeginStoryboard>
    </
EventTrigger.Actions>
 </
EventTrigger>
</
Polygon.Triggers>

如果我们想使这个星星在屏幕中移动的同时旋转,我们需要为旋转变换增加一个DoubleAnimation。清单5列出的是使多边形星星在表单中前后移动的同时作360度旋转的代码。
清单5 使星星旋转

<Polygon.Triggers>
<
EventTriggerRoutedEvent="Polygon.Loaded">
 <
EventTrigger.Actions>
    <
BeginStoryboard>
    <
Storyboard>
      <!--
RotateTransform angle from 0 to 360 in 1 second, repeated forever -->
      <
DoubleAnimationStoryboard.TargetName="xformRotate"
      
Storyboard.TargetProperty="Angle"
      
From="0"To="360"Duration="0:0:01"
       
RepeatBehavior="Forever" />

     <
DoubleAnimationStoryboard.TargetName="xformTranslate"
      
Storyboard.TargetProperty="X"
       
From="1"To="750"Duration="0:0:14"
       
AutoReverse ="True"RepeatBehavior="Forever" />
      </
Storyboard>
    </
BeginStoryboard>
 </
EventTrigger.Actions>
</
EventTrigger>
</
Polygon.Triggers>

最后我们可以通过使它的填充颜色从蓝到红作一个平滑的变换。我们只需要在ColorAnimation标签中驾驭颜色变化。我们可以像清单7展示的那样通过指定持续时间来控制颜色的改变和颜色的改变速率。注意,我们必须给我们要改变的画刷一个名字,像清单6展示的那样,这样我们才能在清单7的颜色变换中引用它:
清单6 在XAML 中命名画刷

<Polygon.Fill>
     <
SolidColorBrushx:Name ="mybrush"Color="Red" />
</Polygon.Fill>

清单7 在XAML 中改变颜色

<Polygon.Triggers>
              <
EventTriggerRoutedEvent="Polygon.Loaded">
                <
EventTrigger.Actions>
                  <
BeginStoryboard>
                  <
Storyboard>
                    <!--
Animate the color from red to blue, and from blue to red in 7 seconds -->
                     <
ColorAnimationStoryboard.TargetName="mybrush"
                        Storyboard.TargetProperty
="Color"
                        From
="Red"To="Blue"Duration="0:0:7"
                       
RepeatBehavior="Forever"AutoReverse="True"/>

                    <
DoubleAnimationStoryboard.TargetName="xformRotate"
                                    
Storyboard.TargetProperty="Angle"
                                    
From="0"To="360"Duration="0:0:01"
                                    
RepeatBehavior="Forever" />

                    <
DoubleAnimationStoryboard.TargetName="xformTranslate"
                                    
Storyboard.TargetProperty="X"
                                    
From="1"To="750"Duration="0:0:14"
                                    
AutoReverse ="True"RepeatBehavior="Forever" />

                  </Storyboard>
                  </
BeginStoryboard>
                </
EventTrigger.Actions>
              </
EventTrigger>
              </
Polygon.Triggers>

让一个位图运动
使多边形运动很有意思,下面让我们看看如何使一个位图运动。实际上使图形和位图运动的区别很小。这张Kenny的位图在XAML中和多边形使用了同样的定义方式。唯一的不同在于定义图像的那些属性(比如Source属性定义了位图的文件名)。图像的变换和多边形的变换采用了完全相同的方式。
清单8 在XAML 中描述一张Kenny 的图像

<ImageMargin="75,61,0,119"Name="image1"Source="Images/KENNY.bmp"HorizontalAlignment="Left"Width="72">
          <
Image.RenderTransform>
            <
TransformGroup>
              <
RotateTransformx:Name="KennyRotateIt"   CenterX="50"CenterY="50"Angle="45"  />
              <
ScaleTransformx:Name="KennyScaleIt"ScaleX=".75"ScaleY=".75" />
              <
TranslateTransform x:Name="KennyTranslateIt"X="0"Y="100" />
            </
TransformGroup>
          </
Image.RenderTransform>

...
在从多边开到位图改变的过程中,故事板的结构并未改变。清单9的示例中,我们通过使用关键帧加速了Kenny在屏幕中的移动,达到一个盘旋的效果。关键帧达到了在表单中在不同时间段内摇晃Kenny的效果。(或许我们应该在他身后表示一个闪电动画,这样更符合Kenny的人物特点)。
清单9 使用关键帧在屏幕中摇晃Kenny

<Image.Triggers>
            <
EventTriggerRoutedEvent="Image.Loaded">
              <
EventTrigger.Actions>
                <
BeginStoryboard>
                  <
Storyboardx:Name="myStoryBoard1"Completed="OnCompletedAnimation">
                    <
DoubleAnimationStoryboard.TargetName="KennyRotateIt"
                                    
Storyboard.TargetProperty="Angle"
                                    
From="0"To="360"Duration="0:0:01"
                                    
RepeatBehavior="Forever" />
 

                    <!-- Jolt Kenny across the screen at different time frames -->
                    <
DoubleAnimationUsingKeyFrames
                        
Storyboard.TargetName="KennyTranslateIt"
                        
Storyboard.TargetProperty="X"
                        
Duration="0:0:10"AutoReverse="True"RepeatBehavior="Forever">
                      <!--
These KeyTime properties are specified as TimeSpan values
                 which are in the form of "hours:minutes:seconds".
-->
                      <
LinearDoubleKeyFrameValue="10"KeyTime="0:0:3" />
                      <
LinearDoubleKeyFrameValue="100"KeyTime="0:0:5" />
                      <
LinearDoubleKeyFrameValue="200"KeyTime="0:0:10" />
                    </
DoubleAnimationUsingKeyFrames>
                  </
Storyboard>
                </
BeginStoryboard>
              </
EventTrigger.Actions>
            </
EventTrigger>
 </
Image.Triggers>

结束语
XAML引入了一种通过在故事板中插入一组简单规则来实现运动的方法。通过这些规则你可以创建有趣的2D和3D运动场景来添加到你的软件中。希望在将来我们还可以向你展示怎么利用这些特性来制作一些简单的游戏。同时,请不要害怕跟大家分享你的动画故事,这样他们才能更好地利用XAML和.NET的力量。
 

你可能感兴趣的:(运动)