AnimationTiming动画时机

RepeatBehaviorExample重复行为动画

clipboard.png

<StackPanel.Triggers>
  <EventTrigger SourceName="restartButton" RoutedEvent="Button.Click">
    <BeginStoryboard Name="myBeginStoryboard">
      <Storyboard>
      
        <!-- Create an animation that repeats indefinitely. -->
        <DoubleAnimation 
          Storyboard.TargetName="foreverRepeatingRectangle" Storyboard.TargetProperty="(Rectangle.Width)" 
          From="50" To="300" Duration="0:0:2" RepeatBehavior="Forever" />
  
        <!-- Create an animation that repeats for four seconds. As a result, the
             animation repeats twice. -->          
        <DoubleAnimation Storyboard.TargetName="fourSecondsRepeatingRectangle" Storyboard.TargetProperty="(Rectangle.Width)"
          From="50" To="300" Duration="0:0:2" RepeatBehavior="0:0:4" />

        <!-- Create an animation that repeats twice. -->
        <DoubleAnimation Storyboard.TargetName="twiceRepeatingRectangle" Storyboard.TargetProperty="(Rectangle.Width)" 
          From="50" To="300" Duration="0:0:2" RepeatBehavior="2x" />     
  
        <!-- Create an animation that repeats 0.5 times. The resulting animation
             plays for one second, half of its Duration. It animates from 50 to 150. -->
        <DoubleAnimation Storyboard.TargetName="halfRepeatingRectangle" Storyboard.TargetProperty="(Rectangle.Width)" 
          From="50" To="300" Duration="0:0:2" RepeatBehavior="0.5x" />
  
        <!-- Create an animation that repeats for one second. The resulting animation
             plays for one second, half of its Duration. It animates from 50 to 150. -->
        <DoubleAnimation Storyboard.TargetName="oneSecondRepeatingRectangle" Storyboard.TargetProperty="(Rectangle.Width)" 
          From="50" To="300" Duration="0:0:1" RepeatBehavior="0:0:1" />          
      </Storyboard>
    </BeginStoryboard>
  </EventTrigger>        
  <EventTrigger SourceName="stopButton" RoutedEvent="Button.Click">
    <StopStoryboard BeginStoryboardName="myBeginStoryboard" />
  </EventTrigger>
</StackPanel.Triggers>
  </StackPanel>

Timeline.RepeatBehavior 属性:获取或设置此时间线的重复行为。

  1. 一个迭代 Count,指定时间线将要播放的次数;一个 TimeSpan 值,指定此时间线活动周期的总长度;或者特殊值 Forever,指定时间线应该无限重复。 默认值是 RepeatBehavior 的 Count 为 1,该值指示时间线播放一次。
  2. 如果指定了一个迭代 Count 且将时间线的 AutoReverse 属性设置为 true,则一次重复包含一次向前迭代和一次向后迭代。
  3. 除了指定时间线播放的次数,还可以指定希望时间线播放的总时间长度。 对于要重复的时间线,此 RepeatBehavior.Duration 值应该大于时间线的 Duration。 例如, Duration 为 2 秒且 RepeatBehavior.Duration 为 4 秒的时间线将播放两次。如果 RepeatBehavior.Duration 小于时间线的 Duration,则时间线的活动周期将缩短。

AutoReverseExample自动反转

注意:AutoReverse 属性如何在嵌套时间线上工作:最后一个AutoReverse设置在父并行时间线ParallelTimeline 此时为向前2次,再向后2次,若设置在具体动画DoubleAnimation,则会正常来回重复两次。
clipboard.png

<!-- Create an animation that automatically reverses at the end of each iteration.
       Set the animation to repeat twice. As a result, then animation plays forward,
       the backward, then forward, and then backward again. -->
  <DoubleAnimation Storyboard.TargetName="autoReverseRectangleWithRepeats" 
    Storyboard.TargetProperty="(Rectangle.Width)"
    Duration="0:0:2" From="100" To="400" AutoReverse="True" RepeatBehavior="2x" />  
    
  <!-- Set the parent timeline's AutoReverse property to True and set the animation's
       RepeatBehavior to 2x. As a result, the animation plays forward twice and then
       backwards twice. -->                
  <ParallelTimeline AutoReverse="True">
    <DoubleAnimation Storyboard.TargetName="complexAutoReverseExample" Storyboard.TargetProperty="(Rectangle.Width)"
      Duration="0:0:2" From="100" To="400" RepeatBehavior="2x"  />  
  </ParallelTimeline>
</Storyboard>

Timeline.AutoReverse 属性:获取或设置一个值,该值指示时间线在完成向前迭代后是否按相反的顺序播放。

  1. 如果时间线在每次迭代结束时按相反的顺序播放,则为 true;否则为 false。 默认值为 false。 如果将 AutoReverse 属性设置为 true,则时间线播放的时间长度是其 Duration 属性指定时间长度的二倍。
  2. 当时间线的 AutoReverse 属性设置为 true 并且它的 RepeatBehavior 属性使它重复时,每个向前迭代都跟有一个向后迭代。 这样就产生了一次重复。 例如,AutoReverse 值为 true 且迭代 Count 为 2 的时间线将向前播放一次,然后向后播放一次,再向前播放一次,然后再向后播放一次。

BeginTimeExample开始动画时间

clipboard.png

<Button.Triggers>
    <EventTrigger RoutedEvent="Button.Click">
      <BeginStoryboard>
        <Storyboard>

          <DoubleAnimation 
            Storyboard.TargetName="defaultBeginTimeRectangle" Storyboard.TargetProperty="(Rectangle.Width)"
            BeginTime="0:0:0" From="20" To="400" Duration="0:0:2"  FillBehavior="HoldEnd" /> 

          <DoubleAnimation Storyboard.TargetName="delayedBeginTimeRectangle" 
            Storyboard.TargetProperty="(Rectangle.Width)"  
            BeginTime="0:0:5" From="20" To="400" Duration="0:0:2" FillBehavior="HoldEnd" />
            
          <ParallelTimeline BeginTime="0:0:5">  
            <DoubleAnimation  
              Storyboard.TargetName="delayedAnimationWithDelayedParentRectangle" Storyboard.TargetProperty="(Rectangle.Width)" 
              BeginTime="0:0:5" From="20" To="400" Duration="0:0:2" FillBehavior="HoldEnd" />
          </ParallelTimeline>
          
        </Storyboard>
      </BeginStoryboard>
    </EventTrigger>
  </Button.Triggers>  

Timeline.BeginTime 属性:获取或设置此 Timeline 将要开始的时间。

  1. 创建在序列中播放的时间线时,BeginTime 属性非常有用:通过增加共享同一个父级的连续时间线的 BeginTime,可以错开它们的播放时间。
  2. 负的 BeginTime 值使 Timeline 的行为如同在过去某个时间开始一样。 例如,BeginTime 为 - 2.5 秒且 Duration 为 5 秒的 Timeline 将看起来像是一开始就已完成了一半。
  3. 由 BeginTime 属性描述的时间以时间线父级的时间为单位进行度量。 例如,BeginTime 为 5 且其父级的 SpeedRatio 为 2 的时间线,实际将是在 2.5 秒后开始。
  4. 时间线自己的 SpeedRatio 设置将不影响其 BeginTime。 例如,BeginTime 为 5 秒、 SpeedRatio 为 2 且其父级时间线的 SpeedRatio 为 1 的时间线将在 5 秒(而不是 2.5 秒)后开始。

FillBehaviorExample填充行为

注意:当父时间线的FillBehavior为Stop时,子时间线都为Stop,当父时间线的FillBehavior为HoldEnd时,子时间线的由自身的为准。
clipboard.png

Button.Triggers>
    <EventTrigger RoutedEvent="Button.Click">
      <BeginStoryboard>
        <Storyboard>

          <!-- The animated rectangle's width reverts back to its non-animated value
               after the animation ends. -->
          <DoubleAnimation 
            Storyboard.TargetName="deactiveAnimationRectangle" 
            Storyboard.TargetProperty="(Rectangle.Width)" 
            From="100" To="400" Duration="0:0:2" FillBehavior="Stop" />

          <DoubleAnimation Storyboard.TargetName="holdEndAnimationRectangle" 
            Storyboard.TargetProperty="(Rectangle.Width)"  
            From="100" To="400" Duration="0:0:2" FillBehavior="HoldEnd" />     
        </Storyboard>
      </BeginStoryboard>
    </EventTrigger>
  </Button.Triggers> 

Timeline.FillBehavior 属性:获取或设置一个值,该值指定 Timeline 在活动周期结束后的行为方式。

  1. 一个值,用于指定时间线在其活动周期结束后但其父时间线仍处于活动周期或填充周期时的行为方式。 默认值为 HoldEnd。
  2. 如果希望动画在活动周期结束时保留其值,则将动画 FillBehavior 属性设置为 HoldEnd。 如果动画的活动周期已结束且 FillBehavior 的设置为 HoldEnd,则说明动画进入填充周期。 如果不希望动画在其活动周期结束时保留其值,则将其FillBehavior 属性设置为 Stop。
  3. 因为处于填充周期的动画将继续重写其目标属性值,所以尝试通过其他方法设置目标属性的值似乎不起任何作用。
  4. 当父时间线停止播放和填充时,子时间线也将停止;如果希望子时间线进行填充,请确保其父时间线的 FillBehavior 为 HoldEnd。

SpeedExample速度示例

注意:父时间线的SpeedRatio影响到子时间线,值为相乘
clipboard.png

<DoubleAnimation
    Storyboard.TargetName="slowerRectangle" Storyboard.TargetProperty="(Rectangle.Width)" 
    From="20" To="400" Duration="0:0:2" SpeedRatio="0.5"  /> 

Timeline.SpeedRatio 属性:获取或设置此 Timeline 的时间相对于其父级的前进速率。

  1. 一个大于 0 的有限值,表示此时间线的时间相对于其父级的前进速率;如果此时间线为根时间线,则为默认时间线速度。 默认值为 1。
  2. 某个时间线的 SpeedRatio 设置对其 BeginTime 没有影响。如果该时间线为根时间线,则该时间为时间线的时钟开始时刻,否则该时间相对于该时间线的父级。
  3. 如果指定了 AccelerationRatio 或 DecelerationRatio,则 SpeedRatio 是整个时间线自然长度的平均速率。

Acceleration and DecelerationExample加速减速动画

注意:一个介于 0 和 1 之间的值(包括 0 和 1),用于指定在将时间消逝从其最大速率减速到零所占用时间线的 Duration 的百分比。 如果同时设置时间线的 AccelerationRatio 属性,则 DecelerationRatio 和 AccelerationRatio 之和必须小于等于 1。 默认值为 0。
clipboard.png

 <!-- Creates an animation that accelerates through 40% of its duration and
           decelerates through the 60% of its duration. -->
  <DoubleAnimation 
    Storyboard.TargetName="acceleratedAndDeceleratedRectangle" 
    Storyboard.TargetProperty="(Rectangle.Width)"
    AccelerationRatio="0.4" DecelerationRatio="0.6" Duration="0:0:10" From="20" To="400" />
  
</Storyboard>  
</BeginStoryboard>
  </EventTrigger>      
</Button.Triggers>    

HandoffVersusComposeExample

clipboard.png

<Page.Resources>
  <Storyboard x:Key="FadeToHalf">
   <DoubleAnimation To="0.5" Duration="0:0:1.0"
Storyboard.TargetProperty="Fill.Opacity" />
   <DoubleAnimation To="45" Duration="0:0:1.0"
Storyboard.TargetProperty="Height" />
  </Storyboard>  
  <Storyboard x:Key="FadeToFull">
   <DoubleAnimation Duration="0:0:1.0"
Storyboard.TargetProperty="Fill.Opacity" />
   <DoubleAnimation Duration="0:0:1.0"
Storyboard.TargetProperty="Height" />
  </Storyboard>  
  <Style x:Key="Compose" TargetType="{x:Type Rectangle}">
   <Setter Property="Fill" Value="Red" />
   <Setter Property="Width" Value="90" />
   <Setter Property="Height" Value="90" />
   <Style.Triggers>
<EventTrigger RoutedEvent="Mouse.MouseEnter">
 <EventTrigger.Actions>
  <BeginStoryboard Storyboard="{StaticResource FadeToHalf}" HandoffBehavior="Compose"/>
 </EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="Mouse.MouseLeave">
 <EventTrigger.Actions>
  <BeginStoryboard Storyboard="{StaticResource FadeToFull}" HandoffBehavior="Compose"/>
 </EventTrigger.Actions>
</EventTrigger>
   </Style.Triggers>
  </Style>
  <Style x:Key="Handoff" TargetType="{x:Type Rectangle}">
   <Setter Property="Fill" Value="Blue" />
   <Setter Property="Width" Value="90" />
   <Setter Property="Height" Value="90" />
   <Style.Triggers>
<EventTrigger RoutedEvent="Mouse.MouseEnter">
 <EventTrigger.Actions>
  <BeginStoryboard Storyboard="{StaticResource FadeToHalf}" HandoffBehavior="SnapshotAndReplace"/>
 </EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="Mouse.MouseLeave">
 <EventTrigger.Actions>
  <BeginStoryboard Storyboard="{StaticResource FadeToFull}" HandoffBehavior="SnapshotAndReplace"/>
 </EventTrigger.Actions>
</EventTrigger>
   </Style.Triggers>
  </Style>
 </Page.Resources>
<Canvas Background="White">
  <TextBlock Canvas.Top="50" Canvas.Left="100" Foreground="Red">Compose</TextBlock>
  <TextBlock Canvas.Top="50" Canvas.Left="200" Foreground="Blue">SnapshotAndReplace</TextBlock>
  <Rectangle Style="{StaticResource Handoff}" Canvas.Top="100" Canvas.Left="100" />
  <Rectangle Style="{StaticResource Compose}" Canvas.Top="100" Canvas.Left="200" />

BeginStoryboard.HandoffBehavior 属性:获取或设置正确的提交行为以启动此演示图板中的动画时钟周期。一般指定演示图板动画之间的切换行为。默认值为 SnapshotAndReplace。

  1. 当通过使用 HandoffBehavior.Compose 将 Storyboard、 AnimationTimeline 或 AnimationClock 应用于属性时,任何以前与该属性关联的 Clock 对象都会继续占用系统资源,计时系统不会自动移除这些时钟周期。
  2. 在使用 Compose 应用大量时钟时,若要避免出现性能问题,应在时钟应用完成后从经过动画处理的属性中移除组合时钟。 用来移除时钟的方法有以下几种:ApplyAnimationClock(,null)或BeginAnimation(,null).这主要是生存期很长的对象上的动画所具有的问题。将对象作为垃圾回收时,同时会断开其时钟的连接并将其时钟作为垃圾回收。
  3. 如果值为 Compose,在出现动画重叠时,动画之间的过渡将较为平滑,而如果值为 SnapshotAndReplace,则会使新动画立即取代之前的重叠动画。

DatabindingExample动画绑定值

clipboard.png

<Page.Triggers>
    <EventTrigger RoutedEvent="Button.Click"  SourceName="myButton">
      <EventTrigger.Actions>
        <BeginStoryboard >

          <Storyboard FillBehavior="HoldEnd" >
            <DoubleAnimation 
              FillBehavior="HoldEnd" 
              BeginTime="00:00:00" 
              Storyboard.TargetName="MyAnimatedRectangle" 
              Storyboard.TargetProperty="Width" 
              Duration="00:00:03"
              To="{Binding ElementName=AnimationDestinationValueSlider, Path=Value}"
              From="0" />
          </Storyboard>
        </BeginStoryboard >
      </EventTrigger.Actions>
    </EventTrigger>
  </Page.Triggers>

<TextBlock Margin="0,30,0,0">Animated Rectangle</TextBlock>
    <Rectangle Width="50" Height="50" Fill="Red" Name="MyAnimatedRectangle"
      HorizontalAlignment="Left"
      Margin="0,10,0,0" />
    <Button Content="Trigger animation" Width="150" Height="40" Name="myButton"/>

对动画数To值进行绑定,值为开始动画时候已设置的值

IsCumulativeExample是否累计值

clipboard.png

<Button.Triggers>
    <EventTrigger RoutedEvent="Button.Click">
      <BeginStoryboard>
        <Storyboard>

          <!-- Animation with IsCumulative set to "True". -->
          <DoubleAnimation 
            Storyboard.TargetName="withIsCumulative" 
            Storyboard.TargetProperty="(Rectangle.Width)" 
            Duration="0:0:1" From="100" By="100" IsCumulative="True" RepeatBehavior="4x" AutoReverse="True" />

          <!-- Animation with IsCumulative set to "False". -->
          <DoubleAnimation 
            Storyboard.TargetName="withoutIsCumulative" 
            Storyboard.TargetProperty="(Rectangle.Width)" 
            Duration="0:0:1" From="100" By="100" IsCumulative="False" RepeatBehavior="4x" AutoReverse="True" />
        </Storyboard>

      </BeginStoryboard>
    </EventTrigger>
  </Button.Triggers>

DoubleAnimation.IsCumulative 属性:该值指定动画重复时是否累计该动画的值。默认值为 false

  1. 如果将该属性设置为 true,则只在该动画的 RepeatBehavior 属性使其简单重复时累计该动画的输出值。 该动画在重新启动时不累计其值,这是因为已重复该动画的父级,或者是因为已从 Begin 调用中重新启动该动画的时钟。

IsAdditiveExample

注意:当正在进行动画时,再次开始动画,当前值会累计基值。

clipboard.png

<Button.Triggers>
    <EventTrigger RoutedEvent="Button.Click">
      <BeginStoryboard>
        <Storyboard>

          <!-- Animation with IsCumulative set to "True". -->
          <DoubleAnimation 
            Storyboard.TargetName="withIsAdditive" 
            Storyboard.TargetProperty="(Rectangle.Width)" 
            Duration="0:0:1" From="100" By="100" IsAdditive="True" />

          <!-- Animation with IsCumulative set to "False". -->
          <DoubleAnimation 
            Storyboard.TargetName="withoutIsAdditive" 
            Storyboard.TargetProperty="(Rectangle.Width)" 
            Duration="0:0:1" From="100" By="100" IsAdditive="False" />
        </Storyboard>

      </BeginStoryboard>
    </EventTrigger>
  </Button.Triggers>

DoubleAnimation.IsAdditive 属性:该值指示是否应将目标属性的当前值与此动画的起始值相加。默认值为 false。

  1. 如果动画仅设置了其 From、 To 或 By 属性之一,则设置此属性将无效。
  2. IsAdditive 属性指定是否将动画的输出值添加到已进行动画处理的属性的起始值(基值)。 您可以将 IsAdditive 属性用于大多数基本动画和大多数关键帧动画。

扩展:
尺码Path的代码数据:

<!-- This rectangle is animated with IsAdditive set to "True". -->
<Rectangle Name="withIsAdditive"
  Width="100" Height="20" Margin="12,0,0,5" Fill="#AA3333FF" HorizontalAlignment="Left" />
<!-- Measuring Stick -->
<Path Stroke="Black" StrokeThickness="2"  
Data="M 12,0 L 112,0" />
<Path Stroke="Black" StrokeThickness="2"  
Data="M 112,0 L 112,8" />
<Path Stroke="Black" StrokeThickness="2"  
Data="M 112,-9 L 212,-9" />
<Path Stroke="Black" StrokeThickness="2"  
Data="M 212,-9 L 212,0" />
<Path Stroke="Black" StrokeThickness="2"  
Data="M 212,-9 L 312,-9" />
<Path Stroke="Black" StrokeThickness="2"  
Data="M 312,-9 L 312,0" />
<Path Stroke="Black" StrokeThickness="2"  
Data="M 312,-9 L 412,-9" />
<Path Stroke="Black" StrokeThickness="2"  
Data="M 412,-9 L 412,0" />
<Path Stroke="Black" StrokeThickness="2"  
Data="M 412,-9 L 512,-9" />
<Path Stroke="Black" StrokeThickness="2"  
Data="M 512,-9 L 512,0" />
<!-- End of Measuring Stick -->

李志玮
22 声望34 粉丝

求索~~


引用和评论

0 条评论