开发者

XAML Heartbeat Animation - How to ensure heart beats at least twice

开发者 https://www.devze.com 2023-01-30 04:43 出处:网络
Greetings, I would like to visually show when a background pr开发者_如何转开发ocess is working. This process happens at a regular intervals (say every 30 seconds), and might take 10ms or 1000ms+ to c

Greetings,

I would like to visually show when a background pr开发者_如何转开发ocess is working. This process happens at a regular intervals (say every 30 seconds), and might take 10ms or 1000ms+ to complete. I'm using MVVM-Light framework so have created a data trigger wired up to a view model property on an image of a heart fading in and out.

My amateur animation technique is working when the process takes a second or more, but I would also like it to complete a full heartbeat (2 repeats) when the process takes a short period of time (<100ms), otherwise the animation is over too quickly and you can't (visually) tell that the process is working.

The problem is that the heart should remain beating for the duration of the process, so I can't just set the repeat behaviour to 2. A XAML solution is preferred, but I will not cringe if some code behind is needed :)

<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>

And if anyone has any tips on how to improve the heartbeat animation, I'm open to suggestions, thanks!


I think you're gonna have to specify RepeatBehavior="2x" and subscribe to the Completed event for the StoryBoard and if IsHeartBeating is still true then you restart it.

<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>

Code behind event handler.
Update
Added boolean flag to only Stop the Storyboard when is has been re-started

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;
    }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消