如何在 WPF 中将动画设置为半透明颜色?

问题描述 投票:0回答:1

简化(!)示例:

<Window Background="Black">

    <Button Background="#ff272727"
            Content="Whatever"
            Foreground="White"
            Padding="16,8"
            HorizontalAlignment="Center"
            VerticalAlignment="Center">
        <Button.Template>
            <ControlTemplate TargetType="{x:Type Button}">
                <Border x:Name="container" Background="{TemplateBinding Background}">
                    <ContentPresenter Margin="{TemplateBinding Padding}" />

                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualStateGroup.Transitions>
                                <VisualTransition GeneratedDuration="0:0:2" />
                            </VisualStateGroup.Transitions>
                            <VisualState x:Name="Normal" />
                            <VisualState x:Name="MouseOver">
                                <Storyboard>
                                    <ColorAnimation Storyboard.TargetName="container"
                                                    Storyboard.TargetProperty="Background.Color"
                                                    To="#33ff8000" />
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                </Border>
            </ControlTemplate>
        </Button.Template>
    </Button>

</Window>

将鼠标悬停在按钮上时,我希望颜色在 2 秒的时间内从

#ff272727
(不透明深灰色)过渡到
#33ff8000
(半透明橙色)。然而,实际发生的情况是,它首先非常快速地(我估计大约四分之一秒)过渡到看起来像
#ffff8000
的样子,然后在剩下的 2 秒内继续
#33ff8000
。 从本质上讲,它似乎是一个接一个地对颜色和 alpha 分量进行动画处理,而不是同时对两者进行动画处理。

有趣的是,如果我交换两种颜色的 alpha 值,即当我从半透明颜色设置动画为完全不透明颜色时,不会发生同样的事情。似乎只有当

To
颜色不透明时才会发生。

对我来说另一个有趣的观察是,即使使用这个故事板也会发生完全相同的现象:

<Storyboard>
    <DoubleAnimation Storyboard.TargetName="container"
                     Storyboard.TargetProperty="Background.Opacity"
                     To="0.2" />
    <ColorAnimation Storyboard.TargetName="container"
                    Storyboard.TargetProperty="Background.Color"
                    To="#ffff8000" />
</Storyboard>

这也将首先对颜色进行动画处理,然后对不透明度进行动画处理...

我做错了什么还是这是一个已知问题?如果是这样,是否有任何已知的解决方法?

wpf animation colors
1个回答
0
投票

这其实是你的眼睛欺骗了你。光是一件棘手的事情,它的强度不是线性的(对数或接近平方取决于我们正在讨论的光强度/颜色的哪个方面)。此外,从灰色到橙色的步骤比减少不透明度要短得多,因此您的眼睛比不透明度变化更快地察觉到这种情况发生。

这里有几个深入探讨该主题的链接:

为了用您的示例说明这种现象,我更改了您的模板以显示动画正在做什么。在下面的结果中,您可以看到它确实线性地穿过两个值。

<Button Background="#FF272700" Foreground="White" Padding="16,8" HorizontalAlignment="Center" VerticalAlignment="Center">
    <Button.Template>
        <ControlTemplate TargetType="{x:Type Button}">
            <Border x:Name="container" Background="{TemplateBinding Background}" Padding="16,8">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition />
                        <RowDefinition />
                    </Grid.RowDefinitions>
                    <TextBlock Text="{Binding Background.Color, ElementName=container}" />
                    <TextBlock Grid.Row="1" Text="{Binding Background.Opacity, ElementName=container}" />
                </Grid>
                <!--<ContentPresenter Margin="{TemplateBinding Padding}" />-->

                <VisualStateManager.VisualStateGroups>
                    <VisualStateGroup x:Name="CommonStates">
                        <VisualStateGroup.Transitions>
                            <VisualTransition GeneratedDuration="0:0:05" />
                        </VisualStateGroup.Transitions>
                        <VisualState x:Name="Normal" />
                        <VisualState x:Name="MouseOver">
                            <Storyboard Changed="Storyboard_Changed">
                                <DoubleAnimation Storyboard.TargetName="container" Storyboard.TargetProperty="Background.Opacity" To="0.2" />
                                <ColorAnimation Storyboard.TargetName="container" Storyboard.TargetProperty="Background.Color" To="#ff8000" />
                            </Storyboard>
                        </VisualState>
                    </VisualStateGroup>
                </VisualStateManager.VisualStateGroups>
            </Border>
        </ControlTemplate>
    </Button.Template>
</Button>

解决方法是分别更改动画的速度和/或起点,让它们按照您想要的方式显示。

© www.soinside.com 2019 - 2024. All rights reserved.