如何平滑地向外设置径向渐变的动画

时间:2014-09-25 16:28:19

标签: c# wpf xaml animation

我想设置一个径向渐变的动画,该渐变从波浪中心点向外平滑移动。

以下是我尝试过的两个不同的故事板:

<Storyboard x:Key="RadialStoryBoard" RepeatBehavior="Forever">
        <DoubleAnimation Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[0].(GradientStop.Offset)" From=".1" To=".7" Duration="00:00:03" Storyboard.TargetName="RadialTest"  />
        <DoubleAnimation Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Offset)" From=".2" To=".8" Duration="00:00:03" Storyboard.TargetName="RadialTest"  />
        <DoubleAnimation Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[2].(GradientStop.Offset)" From=".3" To=".9" Duration="00:00:03" Storyboard.TargetName="RadialTest"  />
        <DoubleAnimation Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[3].(GradientStop.Offset)" From=".4" To="1" Duration="00:00:03" Storyboard.TargetName="RadialTest"  />
    </Storyboard>

    <Storyboard x:Key="RadialStory2Board" RepeatBehavior="Forever">
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[0].(GradientStop.Offset)" Storyboard.TargetName="RadialTest">
            <EasingDoubleKeyFrame KeyTime="0:0:3" Value=".5" />
        </DoubleAnimationUsingKeyFrames>

        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Offset)" Storyboard.TargetName="RadialTest">
            <EasingDoubleKeyFrame KeyTime="0:0:3" Value=".7" />
        </DoubleAnimationUsingKeyFrames>

        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[2].(GradientStop.Offset)" Storyboard.TargetName="RadialTest">
            <EasingDoubleKeyFrame KeyTime="0:0:3" Value=".9" />
        </DoubleAnimationUsingKeyFrames>

        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[3].(GradientStop.Offset)" Storyboard.TargetName="RadialTest">
            <EasingDoubleKeyFrame KeyTime="0:0:3" Value="1.1" />
        </DoubleAnimationUsingKeyFrames>
    </Storyboard>

<Window.Triggers>
    <EventTrigger RoutedEvent="FrameworkElement.Loaded"> 
        <BeginStoryboard Storyboard="{StaticResource RadialStory2}"/>
    </EventTrigger>
</Window.Triggers>

这是对象:

<Rectangle x:Name="RadialTest" Height="50" Width="150" Stroke="Blue" StrokeThickness="4" Margin="5">
                <Rectangle.Fill>
                    <RadialGradientBrush Center="0.5,0.5" RadiusX=".15" RadiusY=".15" GradientOrigin="0.5,0.5"  MappingMode="RelativeToBoundingBox" SpreadMethod="Repeat" >
                        <GradientStop Color="Yellow" Offset="0.1"/>
                        <GradientStop Color="Black" Offset="0.2"/>
                        <GradientStop Color="Yellow" Offset="0.3"/>
                        <GradientStop Color="Black" Offset="0.4"/>
                    </RadialGradientBrush>
                </Rectangle.Fill>
            </Rectangle>

我尝试了几种不同的变化,但这是关于我来的壁橱。建议?

1 个答案:

答案 0 :(得分:1)

我认为你 不能 在这里利用SpreadMethod="Repeat"创建圈子。因为我们必须为偏移设置动画,但是偏移(在每个圆圈中)已经填充范围0-1。这意味着动画偏移将显着改变径向并产生闪烁结果。因此,您必须定义多个GradientStop,而不是使用重复的SpreadMethod来创建效果。创建多个GradientStop时,您还必须将RadiusXRadiusY设置为1,以便我们有更多空间用于渐变停止。此处的规则是Black(或Yellow)的偏移量应设置为 下一个 Black的偏移量(或Yellow)GradientStop。这将实现 周期 ,之后转换几乎是平滑的,不会引起任何闪烁:

<Storyboard x:Key="RadialStoryBoard" RepeatBehavior="Forever">
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Offset)" Storyboard.TargetName="RadialTest">
            <EasingDoubleKeyFrame KeyTime="0:0:3" Value="0.125" />
        </DoubleAnimationUsingKeyFrames>

        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[2].(GradientStop.Offset)" Storyboard.TargetName="RadialTest">
            <EasingDoubleKeyFrame KeyTime="0:0:3" Value=".25" />
        </DoubleAnimationUsingKeyFrames>

        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[3].(GradientStop.Offset)" Storyboard.TargetName="RadialTest">
            <EasingDoubleKeyFrame KeyTime="0:0:3" Value=".375" />
        </DoubleAnimationUsingKeyFrames>

        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[4].(GradientStop.Offset)" Storyboard.TargetName="RadialTest">
            <EasingDoubleKeyFrame KeyTime="0:0:3" Value=".5" />
        </DoubleAnimationUsingKeyFrames>

        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[5].(GradientStop.Offset)" Storyboard.TargetName="RadialTest">
            <EasingDoubleKeyFrame KeyTime="0:0:3" Value=".625" />
        </DoubleAnimationUsingKeyFrames>

        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[6].(GradientStop.Offset)" Storyboard.TargetName="RadialTest">
            <EasingDoubleKeyFrame KeyTime="0:0:3" Value=".75" />
        </DoubleAnimationUsingKeyFrames>

        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[7].(GradientStop.Offset)" Storyboard.TargetName="RadialTest">
            <EasingDoubleKeyFrame KeyTime="0:0:3" Value=".875" />
        </DoubleAnimationUsingKeyFrames>

</Storyboard>

<RadialGradientBrush Center="0.5,0.5" RadiusX="1" RadiusY="1" GradientOrigin="0.5,0.5"  MappingMode="RelativeToBoundingBox">
      <GradientStop Color="Yellow" Offset="0"/>
      <GradientStop Color="Black" Offset="0"/>
      <GradientStop Color="Yellow" Offset="0"/>
      <GradientStop Color="Black" Offset=".125"/>
      <GradientStop Color="Yellow" Offset=".25"/>
      <GradientStop Color="Black" Offset=".375"/>
      <GradientStop Color="Yellow" Offset=".5"/>
      <GradientStop Color="Black" Offset=".625"/>   
</RadialGradientBrush>

请注意删除SpreadMethod以及我在上面发布的x:Key的{​​{1}}内的更改。另外我认为您可以使用Storyboard(线性)而不是上面的简单DoubleAnimation(当然,您可能希望将来使用这种动画进行复杂的计时)。