wpf - 高级 XAML 动画效果。脉搏,行进的 Ant ,旋转。警报

标签 wpf xaml animation

我有一个警报列表。当警报被激活时,它被要求使它们更引人注目。当警报状态发生变化时,我想在项目周围创建一个脉冲外发光几秒钟,然后让它消失。

我遇到的问题是我似乎无法让 DropShadowEffect 只在我需要的时候出现。我尝试将不透明度设置为 0,将颜色设置为透明,但似乎禁用了动画。我考虑过使用样式触发器添加效果,但是我不确定在动画完成后如何将其删除?

关于如何实现这一点的任何建议?

<Rectangle Grid.Column="1" Grid.Row="0">    
    <Rectangle.Effect>
        <DropShadowEffect ShadowDepth="0" BlurRadius="0" Opacity="0" Color="White"    /> 
    </Rectangle.Effect>   
<Rectangle.Style>
<Style>
    <Style.Triggers>
        <DataTrigger Binding="{Binding Value, Converter={StaticResource AlarmConverter}, IsAsync=True}" Value="true">
            <DataTrigger.EnterActions>
               <BeginStoryboard>
                   <Storyboard FillBehavior="Stop" >
                       <DoubleAnimation Storyboard.TargetProperty="Effect.Opacity" To="1" FillBehavior="Stop" />
                        <ColorAnimation Storyboard.TargetProperty="Effect.Color" To="White" FillBehavior="Stop" />
                        <DoubleAnimation Storyboard.TargetProperty="Effect.BlurRadius" From="0" To="20" RepeatBehavior="3x" FillBehavior="Stop" />                                                            
                   </Storyboard>
              </BeginStoryboard>
          </DataTrigger.EnterActions>
      </DataTrigger>

更新
下面是屏幕部分外观的示例。由于安全问题,我不得不从屏幕截图中删除文本和其他方面,我很抱歉。我替换了其中的大部分通用文本以仍然提供上下文。另一件要注意的事情是,通常这不会在普通显示器上运行。它通常与其他屏幕一起显示在一个非常长、非常大的视频墙上。

screenshot

带有 Binding Limits 字样的警报(第一个字已删除,Text 通常不会像那样坐下)具有合理的动画滚动渐变,取代了简单的闪烁。此外,案件中的警报状态会导致形状旋转。

反馈是当警报状态第一次改变时(从绿色到黄色或橙色到红色等),他们想要一些额外的指示。我有一些不同的想法。我的第一个尝试是尝试为文本设置动画,使其扩展得几乎是脉动的。然而,当我尝试时,它仅向右和向下扩展非常明显,并没有真正产生我所希望的“膨胀”效果。

我在这里问的另一个想法是可能为警报项目周围的发光边框设置动画。当状态改变时,它会变亮然后变暗 3 或 4 次。然而,我对其他想法持开放态度。我真的很喜欢 WPF 中的动画功能,但我发现用它来表达我的想法很困难。 (我认为会随着时间而来的东西)

更新
尝试为 Stroke 和 StrokeThickness 以及效果设置动画,虽然它有助于 Glow 突出边框,但边框太硬且太明显,尤其是当警报颜色为红色时。
<BeginStoryboard>
     <Storyboard FillBehavior="Stop">
         <DoubleAnimation Storyboard.TargetProperty="StrokeThickness" To="2"   />
         <ColorAnimation Storyboard.TargetProperty="Stroke.Color" To="White"  />
         <DoubleAnimation Storyboard.TargetProperty="Effect.Opacity" To="30"   />
         <ColorAnimation Storyboard.TargetProperty="Effect.Color" To="White"  />
         <DoubleAnimation Storyboard.TargetProperty="Effect.BlurRadius" From="0" To="100" AutoReverse="True"  Duration="00:00:02" RepeatBehavior="3x" />                                                            
     </Storyboard>
</BeginStoryboard>

更新
演示了整个警报的外部发光,它被认为太微妙了。在这一点上,我正在考虑跳舞 7up 点的想法......(不是真的)

最佳答案

好的, friend ,所以我今天早上花了大约 15-20 分钟继续将我过去用于通知类型内容的一些随机样式示例放在一起。我猜你展示的模拟只是一个真正的粗略例子,所以如果不更准确地知道它是什么样子,很难像设计师想要的那样匹配风格。

但是,我想您可以使用这些示例来让创意源源不断地流向如何/走哪条路线,并尝试一下您可以真正快速轻松地完成的一些事情。如果你想要一个更漂亮/更精确的例子,你必须分享真实的屏幕等。动画和东西可以应用于其他对象,比如图标和东西,但在这个例子中,我只是把它们扔到了一些盒子里。

这些来自我自己的技巧,可以自由使用它们,如果你愿意,我可以向你展示更多不同的技巧,但如果我们参与太多,那么这种深入的建议是我谋生的方式,所以可能至少要向你收取一箱啤酒之类的东西;)

无论如何,把它扔到一个窗口里,我只是用一个新的快速 wpf 项目来做的。所以你只需将它们粘贴进去并运行它,它们就会在加载时启动。

我发现要避免的主要事情是在大量动画中大量使用渐变和各种像素着色器。然而,像这样的东西似乎做得很好。

输出(对于视觉示例,无论如何都是断断续续的 .gif 动画样式。):

enter image description here

和魔法:

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" x:Class="MainWindow"
    Title="MainWindow" Height="450" Width="250">
    <Window.Resources>

        <!-- Marching Ants -->
        <Storyboard x:Key="MarchingAnts">
                <DoubleAnimation BeginTime="00:00:00"
                                Storyboard.TargetName="AlertBox"
                                Storyboard.TargetProperty="StrokeThickness"
                                To="4"
                                Duration="0:0:0.25" />
                           <!-- If you want to run counter-clockwise, just swap the 'From' and 'To' values. -->
                <DoubleAnimation BeginTime="00:00:00" RepeatBehavior="Forever" Storyboard.TargetName="AlertBox" Storyboard.TargetProperty="StrokeDashOffset" 
                                Duration="0:3:0" From="1000" To="0"/>
        </Storyboard>

        <!-- Pulse -->
        <Storyboard x:Key="Pulse" RepeatBehavior="Forever">
            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)" Storyboard.TargetName="PulseBox">
                <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="1.15"/>
                <EasingDoubleKeyFrame KeyTime="0:0:1" Value="1"/>
            </DoubleAnimationUsingKeyFrames>
            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)" Storyboard.TargetName="PulseBox">
                <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="1.15"/>
                <EasingDoubleKeyFrame KeyTime="0:0:1" Value="1"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>

        <!-- Flipper -->
        <Storyboard x:Key="Flipper" RepeatBehavior="Forever">
            <PointAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransformOrigin)" Storyboard.TargetName="FlipperBox">
                <EasingPointKeyFrame KeyTime="0:0:1" Value="0.5,0.5"/>
                <EasingPointKeyFrame KeyTime="0:0:2" Value="0.5,0.5"/>
            </PointAnimationUsingKeyFrames>
            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)" Storyboard.TargetName="FlipperBox">
                <EasingDoubleKeyFrame KeyTime="0:0:1" Value="-1"/>
                <EasingDoubleKeyFrame KeyTime="0:0:2" Value="1"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>


        <!-- Elasic Lines -->
        <Storyboard x:Key="ElasticLines" RepeatBehavior="Forever" AutoReverse="True">
            <PointAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(LinearGradientBrush.EndPoint)" Storyboard.TargetName="ElasticBox">
                <EasingPointKeyFrame KeyTime="0:0:4" Value="12,8"/>
            </PointAnimationUsingKeyFrames>
        </Storyboard>

        <!-- Knight Rider -->
        <Storyboard x:Key="KnightRider" RepeatBehavior="Forever" AutoReverse="True">
            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="KRBox">
                <EasingDoubleKeyFrame KeyTime="0:0:1" Value="-50"/>
                <EasingDoubleKeyFrame KeyTime="0:0:2" Value="50"/>
                <EasingDoubleKeyFrame KeyTime="0:0:3" Value="0"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>

    </Window.Resources>
    <Window.Triggers>
        <EventTrigger RoutedEvent="FrameworkElement.Loaded">
            <BeginStoryboard Storyboard="{StaticResource Pulse}"/>
            <BeginStoryboard Storyboard="{StaticResource MarchingAnts}"/>
            <BeginStoryboard Storyboard="{StaticResource Flipper}"/>
            <BeginStoryboard Storyboard="{StaticResource ElasticLines}"/>
            <BeginStoryboard Storyboard="{StaticResource KnightRider}"/>
        </EventTrigger>
    </Window.Triggers>

    <Grid HorizontalAlignment="Center" VerticalAlignment="Center">
        <Grid.Resources>
            <Style TargetType="{x:Type TextBlock}">
                <Setter Property="Foreground" Value="White"/>
                <Setter Property="FontWeight" Value="Bold"/>
                <Setter Property="FontSize" Value="35"/>
                <Setter Property="HorizontalAlignment" Value="Center"/>
                <Setter Property="VerticalAlignment" Value="Center"/>
                <Setter Property="Text" Value="ALERT"/>
            </Style>
            <Style TargetType="{x:Type Grid}">
                <Setter Property="Margin" Value="0,10"/>                
            </Style>
            <Style TargetType="{x:Type Rectangle}">
                <Setter Property="Height" Value="50"/>
                <Setter Property="Width" Value="150"/>
            </Style>
        </Grid.Resources>

        <StackPanel>

        <!-- Marching Ants -->
        <Grid>

            <Rectangle x:Name="AlertBox"
                      Stroke="Red" 
                       StrokeDashOffset="2" StrokeDashArray="5" Margin="5">
                <Rectangle.Fill>
                    <LinearGradientBrush StartPoint="0,0" EndPoint="6,4" MappingMode="Absolute" SpreadMethod="Repeat">
                        <GradientStop Color="Red" Offset="0.25"/>
                        <GradientStop Color="#00000000" Offset="0.15"/>
                    </LinearGradientBrush>
                </Rectangle.Fill>
            </Rectangle>

            <TextBlock/>

        </Grid>
        <!-- End Marching Ants -->


        <!-- Pulse : Will not skew other elements location like width/height animations would. -->
        <Grid>
            <Border x:Name="PulseBox"
                        Background="Red" RenderTransformOrigin="0.5,0.5">
                <Border.RenderTransform>
                    <TransformGroup>
                        <ScaleTransform/>
                        <SkewTransform/>
                        <RotateTransform/>
                        <TranslateTransform/>
                    </TransformGroup>
                </Border.RenderTransform>

                <TextBlock/>

            </Border>
        </Grid>
        <!-- End Pulse -->


        <!-- Flipper -->
        <Grid>
            <Border x:Name="FlipperBox"
                        Background="Red">
                <Border.RenderTransform>
                    <TransformGroup>
                        <ScaleTransform/>
                        <SkewTransform/>
                        <RotateTransform/>
                        <TranslateTransform/>
                    </TransformGroup>
                </Border.RenderTransform>

                <TextBlock/>

            </Border>
        </Grid>
        <!-- End Flipper -->


        <!-- Elastic Lines -->
        <Grid>
            <Rectangle x:Name="ElasticBox"
                      Stroke="Red" StrokeThickness="5" Margin="5">
                <Rectangle.Fill>
                    <LinearGradientBrush StartPoint="0,0" EndPoint="6,4" MappingMode="Absolute" SpreadMethod="Repeat">
                        <GradientStop Color="Red" Offset="0.25"/>
                        <GradientStop Color="#00000000" Offset="0.15"/>
                    </LinearGradientBrush>
                </Rectangle.Fill>
            </Rectangle>

            <TextBlock/>

        </Grid>
        <!-- End Elastic Box -->


        <!-- Knight Rider -->
        <Grid>
            <Rectangle Fill="Red"/>
            <Rectangle x:Name="KRBox" Width="50" Fill="White" RenderTransformOrigin="0.5,0.5">
                <Rectangle.RenderTransform>
                    <TransformGroup>
                        <ScaleTransform/>
                        <SkewTransform/>
                        <RotateTransform/>
                        <TranslateTransform/>
                    </TransformGroup>
                </Rectangle.RenderTransform>
            </Rectangle>

            <TextBlock Foreground="Red"/>

        </Grid>
        <!-- End Knight Rider -->

        </StackPanel>

    </Grid>
</Window>

关于wpf - 高级 XAML 动画效果。脉搏,行进的 Ant ,旋转。警报,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25877737/

相关文章:

android - notifyDataSetChanged() 上的动画 ListView 项目

html - css动画伪元素影响div

c# - 使用具有不同类型详细信息的主从 View

wpf - WPF 折线上的线性渐变

c# - Windows Phone 8.1 RT 在 C# 中更改图像源

wpf - 将 XPS 转换为 PDF(反之亦然)的最佳方法?

Swift 多维纹理数组

c# - 我的数据绑定(bind)怎么会写出 Length 属性?

wpf 重写 ContentControl 中的 getHashCode 和 Eqaul

xaml - ListView SelectedItem 与 Xamarin 表单和 ReactiveUI 问题绑定(bind)