Search code examples
wpfxamlanimation

WPF: How to smooth out a ColorAnimation with the starting point as Transparent?


I'm animating the background of a button at the control template level, but since the initial background color is set to Transparent, I'm noticing a weird effect where the transition jumps from Transparent => some white/gray intermediate => my desired color.

Here is a gif showing the effect: enter image description here

Button Style (XAML)

 <Style x:Key="btn-style"
         TargetType="Button">
    <Setter Property="Foreground"
            Value="Black" />
    <Setter Property="Background"
            Value="Transparent" />
    <Setter Property="Padding"
            Value="15,0,15,0" />
    <Setter Property="BorderBrush"
            Value="Transparent" />
    <Setter Property="BorderThickness"
            Value="0" />
    <Setter Property="Template">
      <Setter.Value>
        <ControlTemplate TargetType="{x:Type ButtonBase}">
          <Border x:Name="PART_Border"
                  Background="{TemplateBinding Background}"
                  BorderBrush="{TemplateBinding BorderBrush}"
                  BorderThickness="{TemplateBinding BorderThickness}"
                  Padding="{TemplateBinding Padding}">
            <ContentPresenter x:Name="PART_ContentHost"
                              HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                              VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
          </Border>
          <ControlTemplate.Triggers>
            <MultiTrigger>
              <MultiTrigger.Conditions>
                <Condition Property="IsMouseOver"
                           Value="True" />
              </MultiTrigger.Conditions>
              <MultiTrigger.EnterActions>
                <BeginStoryboard>
                  <Storyboard>

                    <ColorAnimation Duration="0:0:0.125"
                                    Storyboard.TargetProperty="(Button.Background).(SolidColorBrush.Color)"
                                    From="Transparent"
                                    To="#ff0000">
                      <ColorAnimation.EasingFunction>
                        <ExponentialEase EasingMode="EaseInOut"
                                         Exponent="2" />
                      </ColorAnimation.EasingFunction>
                    </ColorAnimation>
                  </Storyboard>
                </BeginStoryboard>
              </MultiTrigger.EnterActions>
              <MultiTrigger.ExitActions>
                <BeginStoryboard>
                  <Storyboard>
                    <ColorAnimation Duration="0:0:0.125"
                                    Storyboard.TargetProperty="(Button.Background).(SolidColorBrush.Color)"
                                    From="#ff0000"
                                    To="Transparent">
                      <ColorAnimation.EasingFunction>
                        <ExponentialEase EasingMode="EaseInOut"
                                         Exponent="2" />
                      </ColorAnimation.EasingFunction>
                    </ColorAnimation>

                  </Storyboard>
                </BeginStoryboard>
              </MultiTrigger.ExitActions>
            </MultiTrigger>
          </ControlTemplate.Triggers>
        </ControlTemplate>
      </Setter.Value>
    </Setter>
  </Style>

Things I've Tried

  • Setting the DesiredFrameRate="60" definitely makes it smoother, but the intermediate "Gray" flash is still present.

  • Not specifying the EasingFunction has the same behavior


Solution

  • You see some white because Colors.Transparent is defined as transparent white , i.e. #00FFFFFF.

    You may animate to/from a fully transparent red:

    <ColorAnimation Storyboard.TargetProperty="Background.Color"
                    From="#00ff0000" To="#ffff0000"
                    Duration="0:0:0.125">
        ...
    </ColorAnimation>