Silverlight:以编程方式使用动画 -电脑资料

电脑资料 时间:2019-01-01 我要投稿
【www.unjs.com - 电脑资料】

有时您可能要动态(即时)更改动画的属性,

Silverlight:以编程方式使用动画

。例如,您可能要调整应用到对象 的动画行为,这取决于对象当前在布局中的位置、对象包含何种内容等等。可以 通过使用程序代码(例如 C# 或 Visual Basic)动态操作动画。

先决条件

您应熟悉 Silverlight 动画。有关简介,请参见动画概述。

通过名称访问动画

访问动画对象以更改其属性的最直接方法是:命名该动画对象,然后在代码中 通过该名称引用它。下面的示例包含一个 Ellipse,当您在屏幕上单击时它将显 示动画效果。为了实现此动画,在单击 Canvas 时,事件处理程序更改 PointAnimation 对象的 To 属性,然后启动动画。

运行此示例:http://go.microsoft.com/fwlink/? LinkId=139798&sref=change_animation_properties_1

XAML

   Background="Gray" Width="600" Height="500">
    
      
        
                    x:Name="myPointAnimation"
           Storyboard.TargetProperty="Center"
           Storyboard.TargetName="MyAnimatedEllipseGeometry"
           Duration="0:0:2"/>
      
    

    
      
        
                   Center="200,100" RadiusX="15"  RadiusY="15" />
      

    

VB

Private Sub Handle_MouseDown(ByVal sender As Object,  ByVal e As MouseButtonEventArgs)
     ' Retrieve current mouse coordinates.
     Dim newX As Double = e.GetPosition(Nothing).X
     Dim newY As Double = e.GetPosition(Nothing).Y
     Dim myPoint As Point = New Point
     myPoint.X = newX
     myPoint.Y = newY
     myPointAnimation.To = myPoint
     myStoryboard.Begin()
End Sub

C#

private void Handle_MouseDown(object sender, MouseButtonEventArgs 

e)<br />{<br />    // Retrieve current mouse coordinates.<br />    double 

newX = e.GetPosition(null).X;<br />    double newY = e.GetPosition

(null).Y;<br />    Point myPoint = new Point();<br />    myPoint.X = 

newX;<br />    myPoint.Y = newY;<br />    myPointAnimation.To = 

myPoint;<br />    myStoryboard.Begin();<br />}

使所有动画具有唯一的名称有时不易做到。这时您可以使用集合来访问动画或 动画的关键帧。例如,如果要以编程方式访问 DoubleAnimationUsingKeyFrames 对象中的所有关键帧,可以使用与以下代码类似的代码:

XAML

   Width="600" Height="500" Background="Gray">
  
    
                x:Name="myPointAnimationUsingKeyFrames"
         Storyboard.TargetProperty="Center"
         Storyboard.TargetName="MyAnimatedEllipseGeometry"
         Duration="0:0:3">
          
          
          
          
      
    
  

  
    
      
                Center="200,100" RadiusX="15"  RadiusY="15" />
    

  

C#

public void Handle_MouseDown(object sender, MouseEventArgs e)<br />

{<br />    int i;<br />    for (i = 0; i < 

myPointAnimationUsingKeyFrames.KeyFrames.Count; i++)<br />    {<br />       

 // Do something with each keyframe; for example, set values.<br />    }

<br />}

下面的示例与上一个示例类似,即在用户单击屏幕的地方出现椭圆,只是此示 例中使用了关键帧。对关键帧的集合进行迭代并为关键帧动态设置值,以便使椭 圆动画出现在合适的位置。

运行此示例:http://go.microsoft.com/fwlink/? LinkId=139798&sref=access_keyframe_collection

XAML

   Width="600" Height="500" Background="Gray">
  
    
                x:Name="myPointAnimationUsingKeyFrames"
         Storyboard.TargetProperty="Center"
         Storyboard.TargetName="MyAnimatedEllipseGeometry"
         Duration="0:0:3">
        
        
        
      
    
  

  
    
      
                Center="200,100" RadiusX="15"  RadiusY="15" />
    

  

C#

' Global variables that keep track of the end  point
' of the last animation.
Private lastX As Double = 200
Private lastY As Double = 100
Private Sub Handle_MouseDown(ByVal sender As Object, ByVal e  As MouseEventArgs)
     ' Retrieve current mouse coordinates.
     Dim newX As Double = e.GetPosition(Nothing).X
     Dim newY As Double = e.GetPosition(Nothing).Y
     Dim i As Integer
     i = 0
     Do While (i <  myPointAnimationUsingKeyFrames.KeyFrames.Count)
         Dim keyFrame. As PointKeyFrame. =  myPointAnimationUsingKeyFrames.KeyFrames(i)
         If (keyFrame.GetType.Name =  "DiscretePointKeyFrame") Then
             keyFrame.SetValue (DiscretePointKeyFrame.ValueProperty, New Point(lastX, lastY))
         ElseIf (keyFrame.GetType.Name =  "LinearPointKeyFrame") Then
             ' The LinearKeyFrame. has a value that  is part way to the 
             ' final end point. In addition, this  value has to be on
             ' the correct line, therefore, you  need to use the line 
             ' formula y = mx + b to find the  values of x and y.
             ' Calculate the slope
             Dim m As Double = ((newY - lastY) /  (newX - lastX))
             ' Calculate the y-intercept.
             Dim b As Double = (newY - (m *  newX))
             ' Set X to a third of the way to  the end point.
             Dim intermediateX As Double = (lastX +  ((newX - lastX) / 3))
             ' Find the value Y from X and the  line formula.
             Dim intermediateY As Double = ((m *  intermediateX) + b)
             ' Set the keyframe. value to the  intermediate x and y value.
             keyFrame.SetValue (LinearPointKeyFrame.ValueProperty, New Point(intermediateX,  intermediateY))
         ElseIf (keyFrame.GetType.Name =  "SplinePointKeyFrame") Then
             keyFrame.SetValue (SplinePointKeyFrame.ValueProperty, New Point(newX, newY))
         End If
         i = (i + 1)
     Loop
     myStoryboard.Stop()
     myStoryboard.Begin()
     lastX = newX
     lastY = newY
End Sub

注意说明:

Storyboard 具有 Children 属性,该属性允许您访问指定 Storyboard 中的 所有动画对象。

动态更改 TargetName

动态更改 Storyboard.TargetName 属性最常见的情况是您想将同一动画应用 到多个对象。当具有要应用相似动画的大量对象时,这特别有用。例如,您可能 要显示几行图像并使用动画突出显示鼠标当前所指示的图像。为每个图像创建单 独的 Storyboard 对象非常麻烦。重用同一 Storyboard 更为合适。

下面的示例涉及很多矩形,当您单击这些矩形时,它们会逐渐消失,接着重新 显示。所有这些矩形使用同一 Storyboard,因为呈现 Opacity 动画效果的 DoubleAnimation 将 TargetName 更改为所单击的矩形。

运行此示例:http://go.microsoft.com/fwlink/? LinkId=139798&sref=change_targetname_1

XAML


  
    
                Storyboard.TargetProperty="Opacity"
         From="1.0" To="0.0" Duration="0:0:2"
         AutoReverse="True" />
    
  

        x:Name="MyAnimatedRectangle1"
     Margin="3" Width="100" Height="100" Fill="Blue"
     MouseLeftButtonDown="Start_Animation" />
        x:Name="MyAnimatedRectangle2"
     Margin="3" Width="100" Height="100" Fill="Blue"
     MouseLeftButtonDown="Start_Animation" />
        x:Name="MyAnimatedRectangle3"
     Margin="3" Width="100" Height="100" Fill="Blue"
     MouseLeftButtonDown="Start_Animation" />
        x:Name="MyAnimatedRectangle4"
     Margin="3" Width="100" Height="100" Fill="Blue"
     MouseLeftButtonDown="Start_Animation" />

VB

Private Sub Start_Animation(ByVal sender As Object,  ByVal e As MouseEventArgs)
     ' If the Storyboard is running and you try to  change
     ' properties of its animation objects  programmatically, 
     ' an error will occur.
     myStoryboard.Stop()
     ' Get a reference to the rectangle that was  clicked.
     Dim myRect As Rectangle = CType(sender, Rectangle)
     ' Change the TargetName of the animation to the  name of the
     ' rectangle that was clicked.
     myDoubleAnimation.SetValue(Storyboard.TargetNameProperty,  myRect.Name)
     ' Begin the animation.
     myStoryboard.Begin()
End Sub

在前面的代码中,请注意您在动态更改动画对象的属性前必须停止 Storyboard,否则将出错,

电脑资料

Silverlight:以编程方式使用动画》(https://www.unjs.com)。在此示例中,可能不希望只有停止一个矩形的动画才 能启动另一个矩形的动画。可能您想同时运行这两个动画。但是,您不能使用同 一个动画对象同时运行两个独立的动画,因为只有一个 TargetName。这并不意味 着您不得不重新为每个对象创建单独的 Storyboard。您只需要为并发(同步)运 行的每个动画提供一个 Storyboard。下面的示例与上一个示例类似,只是它包含 三个而不是一个 Storyboard 对象。您单击矩形时,事件处理程序查找当前未使 用的 Storyboard 并使用它来创建动画。

运行此示例:http://go.microsoft.com/fwlink/? LinkId=139798&sref=change_targetname_2

XAML


  
    
                Storyboard.TargetProperty="Opacity"
         From="1.0" To="0.0" Duration="0:0:2"  AutoReverse="True" />
    
    
                Storyboard.TargetProperty="Opacity"
         From="1.0" To="0.0" Duration="0:0:2"
         AutoReverse="True" />
    
    
                Storyboard.TargetProperty="Opacity"
         From="1.0" To="0.0" Duration="0:0:2"
         AutoReverse="True" />
    
  

        Margin="3" Width="100" Height="100" Fill="Blue"
     MouseLeftButtonDown="Start_Animation" />
        Margin="3" Width="100" Height="100" Fill="Blue"
     MouseLeftButtonDown="Start_Animation" />
        Margin="3" Width="100" Height="100" Fill="Blue"
     MouseLeftButtonDown="Start_Animation" />
        Margin="3" Width="100" Height="100" Fill="Blue"
     MouseLeftButtonDown="Start_Animation" />

VB

Private storyboard1Active As Boolean = False
Private storyboard2Active As Boolean = False
Private storyboard3Active As Boolean = False
Private Sub Start_Animation(ByVal sender As Object, ByVal e  As MouseEventArgs)
     ' Get a reference to the rectangle that was  clicked.
     Dim myRect As Rectangle = CType(sender, Rectangle)
     If Not storyboard1Active Then
         myStoryboard1.Stop()
         myDoubleAnimation1.SetValue (Storyboard.TargetNameProperty, myRect.Name)
         myStoryboard1.Begin()
         storyboard1Active = True
     ElseIf Not storyboard2Active Then
         myStoryboard2.Stop()
         myDoubleAnimation2.SetValue (Storyboard.TargetNameProperty, myRect.Name)
         myStoryboard2.Begin()
         storyboard2Active = True
     ElseIf Not storyboard3Active Then
         myStoryboard3.Stop()
         myDoubleAnimation3.SetValue (Storyboard.TargetNameProperty, myRect.Name)
         myStoryboard3.Begin()
         storyboard3Active = True
     End If
End Sub
Private Sub Storyboard_Completed(ByVal sender As Object, ByVal  e As EventArgs)
     Dim myStoryboard As Storyboard = CType(sender,  Storyboard)
     Select Case (myStoryboard.GetValue (NameProperty).ToString)
         Case "myStoryboard1"
             storyboard1Active = False
         Case "myStoryboard2"
             storyboard2Active = False
         Case "myStoryboard3"
             storyboard3Active = False
     End Select
End Sub

在上面的示例中,同时只能运行三个动画(等于 Storyboard 对象的数目)。 如果您不需要同时运行更多动画,这个示例就可以满足要求了,否则将需要更多 的 Storyboard 对象。如果要同时运行很多独立的动画,可能要动态创建 Storyboard 对象。有关在代码中创建演示图板对象的示例,请参见下一节。

在程序代码中创建动画

您还可以完全在程序代码中创建动画。下面的示例演示如何创建一个动画,在 其中用动画呈现矩形的 Canvas.Top 和 Canvas.Left 附加属性。

运行此示例:http://go.microsoft.com/fwlink/? LinkId=139798&sref=programmatic_animation

VB

Private Sub Create_And_Run_Animation(ByVal sender As  Object, ByVal e As EventArgs)
     ' Create a red rectangle that will be the  target
     ' of the animation.
     Dim myRectangle As Rectangle = New Rectangle
     myRectangle.Width = 200
     myRectangle.Height = 200
     Dim myColor As Color = Color.FromArgb(255, 255, 0,  0)
     Dim myBrush As SolidColorBrush = New  SolidColorBrush
     myBrush.Color = myColor
     myRectangle.Fill = myBrush
     ' Add the rectangle to the tree.
     LayoutRoot.Children.Add(myRectangle)
     ' Create a duration of 2 seconds.
     Dim duration As Duration = New Duration (TimeSpan.FromSeconds(2))
     ' Create two DoubleAnimations and set their  properties.
     Dim myDoubleAnimation1 As DoubleAnimation = New  DoubleAnimation
     Dim myDoubleAnimation2 As DoubleAnimation = New  DoubleAnimation
     myDoubleAnimation1.Duration = duration
     myDoubleAnimation2.Duration = duration
     Dim sb As Storyboard = New Storyboard
     sb.Duration = duration
     sb.Children.Add(myDoubleAnimation1)
     sb.Children.Add(myDoubleAnimation2)
     Storyboard.SetTarget(myDoubleAnimation1, myRectangle)
     Storyboard.SetTarget(myDoubleAnimation2, myRectangle)
     ' Set the attached properties of Canvas.Left and  Canvas.Top
     ' to be the target properties of the two respective  DoubleAnimations
     Storyboard.SetTargetProperty(myDoubleAnimation1, New  PropertyPath("(Canvas.Left)"))
     Storyboard.SetTargetProperty(myDoubleAnimation2, New  PropertyPath("(Canvas.Top)"))
     myDoubleAnimation1.To = 200
     myDoubleAnimation2.To = 200
     ' Make the Storyboard a resource.
     LayoutRoot.Resources.Add("unique_id", sb)
     ' Begin the animation.
     sb.Begin()
End Sub

注意说明:

不要试图在页面的构造函数中调用 Storyboard 成员(例如 Begin 方法)。 这将导致动画失败,且无任何提示。

最新文章