如何在WPF故事板动画中暂停一秒钟后继续播放?

8
我们有一个从红色到白色的颜色动画。目前,这是一种线性渐变。我们知道可以使用Storyboard类的BeginTime等来调整,但那只会延迟整个动画的开始时间。我们也看了缓入/缓出的方面,但它们似乎也不起作用。
具体地说,我们想将红色值保持1秒钟,然后在接下来的时间内从红色渐变到白色。这是否可以在纯XAML中完成?如果不能,在代码后台手动设置Storyboard是否可以实现?还是我们必须使用两个单独的storyboard并按顺序播放它们?
2个回答

20

有几种方法可以实现这个目标。

使用关键帧:

<Storyboard>
    <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="Background.Color">
        <DiscreteColorKeyFrame Value="Red" KeyTime="0:0:0" />
        <DiscreteColorKeyFrame Value="Red" KeyTime="0:0:1" />
        <LinearColorKeyFrame Value="White" KeyTime="0:0:2" />
    </ColorAnimationUsingKeyFrames>
</Storyboard>

连续播放两个动画:

<Storyboard>
    <ColorAnimation Storyboard.TargetProperty="Background.Color"
                    From="Red" To="Red" Duration="0:0:1" />
    <ColorAnimation Storyboard.TargetProperty="Background.Color"
                    To="White" BeginTime="0:0:1" Duration="0:0:1" />
</Storyboard>

使用自定义缓动函数:

<Storyboard>
    <ColorAnimation Storyboard.TargetProperty="Background.Color"
                    From="Red" To="White" Duration="0:0:2">
        <ColorAnimation.EasingFunction>
            <local:CustomEasingFunction />
        </ColorAnimation.EasingFunction>
    </ColorAnimation>
</Storyboard>
在这种情况下,这个函数在持续时间的前半段展示过渡效果并保持值在后半段。因为默认的 EasingMode 是 EaseOut,所以该函数将会“倒播”。
public class CustomEasingFunction : EasingFunctionBase
{
    public CustomEasingFunction() : base()
    { }

    protected override double EaseInCore(double normalizedTime)
    {
        return (normalizedTime < 0.5)
            ? normalizedTime * 2
            : 1;
    }

    protected override Freezable CreateInstanceCore()
    {
        return new CustomEasingFunction();
    }
}

非常详细,正是我所需要的。这也是一个很棒的S.O.答案,因为我知道其他人会对你提供的详细程度感到满意。非常感谢! - Mark A. Donohoe
有一个问题...你确定Easing Function示例中的评论是正确的吗?根据MSDN,标准化时间从0到1,而不是你所说的从1到0,因此返回值应该对于小于0.5的值为0(持续时间的前半部分),然后对于第二半部分应该是'(normalizedTime * 2) - 1'(与'(normalizedTime - 0.5) * 2'相同),对吗?我从这里得到的信息...http://msdn.microsoft.com/en-us/library/system.windows.media.animation.easingfunctionbase.easeincore.aspx - Mark A. Donohoe
2
啊!我明白你为什么认为它从1到0了。你将EasingMode设置为默认值EaseOut,这意味着从“Ease”返回的值应该是100%插值减去EaseInCore函数的结果,因此你认为它从1到0了。这是一个双重否定。然而,由于函数被称为EaseInCore,为了保持一致性,它应该写成时间从0到1,然后必须显式设置EasingMode为EaseIn,但是,这样会更清晰,因为函数将正确表示经过的时间。 - Mark A. Donohoe
1
感谢澄清。我在开始创建时就已经想到了这个问题。再次感谢。 - LPL
1
没问题。这就是这个网站的目的。我们互相帮助!就像你现在要通过给我的评论点赞来帮助我一样,对吧?[傻笑] - Mark A. Donohoe
经过进一步的思考,我编辑了我的答案以添加您的发现。我现在认为它仍然简单而一致。 - LPL

1
根据您的动画编写方式,您可以在开头添加一个持续一秒钟的从红色到红色的过渡,这样技术上动画正在运行,但它并没有做任何事情。这可以在纯XAML中完成。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接