XAML心跳动画 - 如何确保心脏跳动至少两次

时间:2010-12-14 00:11:35

标签: wpf xaml mvvm-light

问候,

我希望直观地显示后台进程何时起作用。此过程定期发生(例如每30秒),可能需要10ms或1000ms +才能完成。我正在使用MVVM-Light框架,所以创建了一个数据触发器连接到心脏图像上的视图模型属性淡入淡出。

我的业余动画技术在此过程需要一秒钟或更长时间时正在工作,但我还希望它在过程需要很短的时间(<100ms)时完成完整的心跳(2次重复),否则动画过快,你不能(在视觉上)告诉过程正在发挥作用。

问题是心脏应该在整个过程中保持跳动,所以我不能将重复行为设置为2.首选XAML解决方案,但如果需要一些代码,我不会畏缩: )

<Image 
    Height="60" Width="60" Margin="0,6,6,6"
    Name="Heartbeat" Source="/Resources/Heartbeat.png"
    VerticalAlignment="Bottom" HorizontalAlignment="Right" 
    Opacity=".05" Stretch="UniformToFill">
    <Image.Style>
        <Style>
            <Style.Triggers>
                <DataTrigger Binding="{Binding IsHeartBeating}" Value="True">
                    <DataTrigger.EnterActions>
                        <BeginStoryboard Name="HeartbeatStoryboard">
                            <Storyboard RepeatBehavior="Forever">
                                <DoubleAnimation
                                    Storyboard.TargetProperty="Opacity"
                                    From="0.05" To="0.8" Duration="0:0:0.100">
                                </DoubleAnimation>
                                <DoubleAnimation
                                    Storyboard.TargetProperty="Opacity"
                                    From="0.8" To="0.05" Duration="0:0:0.300">
                                    <DoubleAnimation.EasingFunction>
                                        <PowerEase EasingMode="EaseOut" Power="6" />
                                    </DoubleAnimation.EasingFunction>
                                </DoubleAnimation>
                            </Storyboard>
                        </BeginStoryboard>
                    </DataTrigger.EnterActions>
                    <DataTrigger.ExitActions>
                        <StopStoryboard BeginStoryboardName="HeartbeatStoryboard" />
                    </DataTrigger.ExitActions>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Image.Style>
</Image>

如果有人对如何改善心跳动画有任何提示,我愿意接受建议,谢谢!

1 个答案:

答案 0 :(得分:4)

我认为您必须指定RepeatBehavior =“2x”并订阅StoryBoard的Completed事件,如果IsHeartBeating仍为true,则重新启动它。

<Image Height="60" Width="60" Margin="0,6,6,6"   
       Name="Heartbeat" Source="/Resources/Heartbeat.png"   
       VerticalAlignment="Bottom" HorizontalAlignment="Right"    
       Opacity=".05" Stretch="UniformToFill">
    <Image.Resources>
        <Storyboard x:Key="HeartbeatStoryboard2x"
                    RepeatBehavior="2x"
                    Completed="Storyboard_Completed">
            <DoubleAnimation Storyboard.TargetProperty="Opacity"
                             Storyboard.Target="{Binding ElementName=Heartbeat}"
                             From="0.05" To="0.8" Duration="0:0:0.500">
            </DoubleAnimation>
            <DoubleAnimation Storyboard.TargetProperty="Opacity"
                             Storyboard.Target="{Binding ElementName=Heartbeat}"
                             From="0.8" To="0.05" Duration="0:0:1.500">
                <DoubleAnimation.EasingFunction>
                    <PowerEase EasingMode="EaseOut" Power="6" />
                </DoubleAnimation.EasingFunction>
            </DoubleAnimation>
        </Storyboard>
    </Image.Resources>
    <Image.Style>
        <Style>
            <Style.Triggers>
                <DataTrigger Binding="{Binding IsHeartBeating}" Value="True">
                    <DataTrigger.EnterActions>
                        <BeginStoryboard Name="HeartbeatStoryboard">
                            <StaticResource ResourceKey="HeartbeatStoryboard2x"/>
                        </BeginStoryboard>
                    </DataTrigger.EnterActions>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Image.Style>
</Image>

事件处理程序背后的代码 的更新
添加布尔标志仅在重新启动时停止故事板

private bool m_restartedAnimation = false;
private void Storyboard_Completed(object sender, EventArgs e)
{
    ClockGroup clockGroup = sender as ClockGroup;
    Storyboard heartbeatStoryboard = clockGroup.Timeline as Storyboard;
    if (IsHeartBeating == true)
    {
        m_restartedAnimation = true;
        heartbeatStoryboard.Begin();
    }
    else
    {
        if (m_restartedAnimation == true)
        {
            heartbeatStoryboard.Stop();
        }
        m_restartedAnimation = false;
    }
}