WPF 按钮悬停动画效果实现

WPF 按钮悬停动画效果实现

下面我将实现一个专业的按钮悬停动画效果:当鼠标悬停在按钮上时,按钮上的文字由黑色变为白色,同时加粗并变大。

完整实现方案

MainWindow.xaml

xml 复制代码
<Window x:Class="ButtonHoverEffect.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ButtonHoverEffect"
        mc:Ignorable="d"
        Title="按钮悬停动画效果" 
        Height="400" 
        Width="600"
        WindowStartupLocation="CenterScreen"
        Background="#FF1E1E1E">
    
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        
        <!-- 标题 -->
        <TextBlock Text="专业按钮悬停动画效果" 
                   Grid.Row="0"
                   FontSize="28"
                   FontWeight="Bold"
                   Foreground="White"
                   HorizontalAlignment="Center"
                   VerticalAlignment="Bottom"
                   Margin="0,0,0,40"/>
        
        <!-- 按钮容器 -->
        <StackPanel Grid.Row="1" 
                    Orientation="Horizontal" 
                    HorizontalAlignment="Center"
                    VerticalAlignment="Center"
                    Margin="20">
            
            <!-- 示例按钮 1 -->
            <Button Content="主页" 
                    Style="{StaticResource HoverButtonStyle}"
                    Margin="20,0"
                    Padding="30,15"/>
            
            <!-- 示例按钮 2 -->
            <Button Content="产品" 
                    Style="{StaticResource HoverButtonStyle}"
                    Margin="20,0"
                    Padding="30,15"/>
            
            <!-- 示例按钮 3 -->
            <Button Content="关于我们" 
                    Style="{StaticResource HoverButtonStyle}"
                    Margin="20,0"
                    Padding="30,15"/>
            
            <!-- 示例按钮 4 -->
            <Button Content="联系我们" 
                    Style="{StaticResource HoverButtonStyle}"
                    Margin="20,0"
                    Padding="30,15"/>
        </StackPanel>
        
        <!-- 页脚说明 -->
        <TextBlock Grid.Row="2"
                   Text="鼠标悬停在按钮上查看动画效果"
                   FontSize="16"
                   Foreground="#AAAAAA"
                   HorizontalAlignment="Center"
                   VerticalAlignment="Top"
                   Margin="0,40,0,0"/>
    </Grid>
</Window>

App.xaml (添加全局样式)

xml 复制代码
<Application x:Class="ButtonHoverEffect.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <!-- 按钮悬停动画样式 -->
        <Style x:Key="HoverButtonStyle" TargetType="Button">
            <!-- 基本样式设置 -->
            <Setter Property="Background" Value="#FF252526"/>
            <Setter Property="Foreground" Value="Black"/>
            <Setter Property="BorderBrush" Value="#FF3F3F46"/>
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="FontSize" Value="18"/>
            <Setter Property="FontWeight" Value="Normal"/>
            <Setter Property="Cursor" Value="Hand"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Button">
                        <!-- 按钮视觉结构 -->
                        <Border x:Name="border" 
                                Background="{TemplateBinding Background}"
                                BorderBrush="{TemplateBinding BorderBrush}"
                                BorderThickness="{TemplateBinding BorderThickness}"
                                CornerRadius="8">
                            
                            <!-- 内容容器 -->
                            <ContentPresenter x:Name="contentPresenter"
                                              HorizontalAlignment="Center"
                                              VerticalAlignment="Center"
                                              Margin="{TemplateBinding Padding}"/>
                        </Border>
                        
                        <!-- 触发器 -->
                        <ControlTemplate.Triggers>
                            <!-- 鼠标悬停触发器 -->
                            <Trigger Property="IsMouseOver" Value="True">
                                <!-- 文字颜色变为白色 -->
                                <Setter TargetName="contentPresenter" Property="TextElement.Foreground" Value="White"/>
                                
                                <!-- 文字加粗 -->
                                <Setter TargetName="contentPresenter" Property="TextElement.FontWeight" Value="Bold"/>
                                
                                <!-- 文字变大 -->
                                <Setter TargetName="contentPresenter" Property="TextElement.FontSize" Value="20"/>
                                
                                <!-- 背景色变化 -->
                                <Setter Property="Background" Value="#FF4A90E2"/>
                                
                                <!-- 边框变化 -->
                                <Setter Property="BorderBrush" Value="#FF3A80D2"/>
                                
                                <!-- 阴影效果 -->
                                <Setter Property="Effect">
                                    <Setter.Value>
                                        <DropShadowEffect BlurRadius="10" 
                                                          ShadowDepth="0" 
                                                          Color="#FF4A90E2" 
                                                          Opacity="0.7"/>
                                    </Setter.Value>
                                </Setter>
                            </Trigger>
                            
                            <!-- 鼠标按下效果 -->
                            <Trigger Property="IsPressed" Value="True">
                                <Setter Property="Background" Value="#FF2A70C2"/>
                                <Setter Property="BorderBrush" Value="#FF1A60B2"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        
        <!-- 平滑动画版本 -->
        <Style x:Key="AnimatedHoverButtonStyle" TargetType="Button" BasedOn="{StaticResource HoverButtonStyle}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Button">
                        <!-- 按钮视觉结构 -->
                        <Border x:Name="border" 
                                Background="{TemplateBinding Background}"
                                BorderBrush="{TemplateBinding BorderBrush}"
                                BorderThickness="{TemplateBinding BorderThickness}"
                                CornerRadius="8">
                            
                            <!-- 内容容器 -->
                            <ContentPresenter x:Name="contentPresenter"
                                              HorizontalAlignment="Center"
                                              VerticalAlignment="Center"
                                              Margin="{TemplateBinding Padding}"/>
                        </Border>
                        
                        <!-- 触发器 -->
                        <ControlTemplate.Triggers>
                            <!-- 鼠标悬停触发器(带平滑动画) -->
                            <EventTrigger RoutedEvent="MouseEnter">
                                <BeginStoryboard>
                                    <Storyboard>
                                        <!-- 文字颜色动画 -->
                                        <ColorAnimation Storyboard.TargetName="contentPresenter"
                                                         Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)"
                                                         To="White"
                                                         Duration="0:0:0.3"/>
                                        
                                        <!-- 文字加粗动画(使用FontWeightConverter) -->
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="contentPresenter"
                                                                       Storyboard.TargetProperty="(TextElement.FontWeight)">
                                            <DiscreteObjectKeyFrame KeyTime="0:0:0.3" Value="Bold"/>
                                        </ObjectAnimationUsingKeyFrames>
                                        
                                        <!-- 文字大小动画 -->
                                        <DoubleAnimation Storyboard.TargetName="contentPresenter"
                                                         Storyboard.TargetProperty="(TextElement.FontSize)"
                                                         To="20"
                                                         Duration="0:0:0.3"/>
                                        
                                        <!-- 背景色动画 -->
                                        <ColorAnimation Storyboard.TargetName="border"
                                                        Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)"
                                                        To="#FF4A90E2"
                                                        Duration="0:0:0.3"/>
                                        
                                        <!-- 边框色动画 -->
                                        <ColorAnimation Storyboard.TargetName="border"
                                                        Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)"
                                                        To="#FF3A80D2"
                                                        Duration="0:0:0.3"/>
                                        
                                        <!-- 阴影效果动画 -->
                                        <DoubleAnimation Storyboard.TargetProperty="Effect.(DropShadowEffect.Opacity)"
                                                         To="0.7"
                                                         Duration="0:0:0.3"/>
                                    </Storyboard>
                                </BeginStoryboard>
                            </EventTrigger>
                            
                            <!-- 鼠标离开动画 -->
                            <EventTrigger RoutedEvent="MouseLeave">
                                <BeginStoryboard>
                                    <Storyboard>
                                        <!-- 文字颜色恢复 -->
                                        <ColorAnimation Storyboard.TargetName="contentPresenter"
                                                         Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)"
                                                         To="Black"
                                                         Duration="0:0:0.3"/>
                                        
                                        <!-- 文字加粗恢复 -->
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="contentPresenter"
                                                                       Storyboard.TargetProperty="(TextElement.FontWeight)">
                                            <DiscreteObjectKeyFrame KeyTime="0:0:0.3" Value="Normal"/>
                                        </ObjectAnimationUsingKeyFrames>
                                        
                                        <!-- 文字大小恢复 -->
                                        <DoubleAnimation Storyboard.TargetName="contentPresenter"
                                                         Storyboard.TargetProperty="(TextElement.FontSize)"
                                                         To="18"
                                                         Duration="0:0:0.3"/>
                                        
                                        <!-- 背景色恢复 -->
                                        <ColorAnimation Storyboard.TargetName="border"
                                                        Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)"
                                                        To="#FF252526"
                                                        Duration="0:0:0.3"/>
                                        
                                        <!-- 边框色恢复 -->
                                        <ColorAnimation Storyboard.TargetName="border"
                                                        Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)"
                                                        To="#FF3F3F46"
                                                        Duration="0:0:0.3"/>
                                        
                                        <!-- 阴影效果恢复 -->
                                        <DoubleAnimation Storyboard.TargetProperty="Effect.(DropShadowEffect.Opacity)"
                                                         To="0"
                                                         Duration="0:0:0.3"/>
                                    </Storyboard>
                                </BeginStoryboard>
                            </EventTrigger>
                            
                            <!-- 鼠标按下效果 -->
                            <Trigger Property="IsPressed" Value="True">
                                <Setter Property="Background" Value="#FF2A70C2"/>
                                <Setter Property="BorderBrush" Value="#FF1A60B2"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Application.Resources>
</Application>

效果说明

基础效果(使用触发器)

  • 默认状态

    • 文字颜色:黑色
    • 字体粗细:正常
    • 字体大小:18
    • 背景色:深灰(#FF252526)
    • 边框色:深灰(#FF3F3F46)
  • 鼠标悬停状态

    • 文字颜色:白色
    • 字体粗细:加粗
    • 字体大小:20
    • 背景色:蓝色(#FF4A90E2)
    • 边框色:深蓝色(#FF3A80D2)
    • 添加蓝色阴影效果
  • 鼠标按下状态

    • 背景色:深蓝色(#FF2A70C2)
    • 边框色:更深蓝色(#FF1A60B2)

平滑动画效果(使用Storyboard动画)

  • 所有属性变化都有0.3秒的平滑过渡
  • 颜色变化使用ColorAnimation实现渐变
  • 字体大小变化使用DoubleAnimation实现平滑缩放
  • 字体粗细变化使用ObjectAnimationUsingKeyFrames实现

使用说明

1. 基本使用

xml 复制代码
<Button Content="基本按钮" 
        Style="{StaticResource HoverButtonStyle}"
        Padding="20,10"/>

2. 带平滑动画的按钮

xml 复制代码
<Button Content="平滑动画按钮" 
        Style="{StaticResource AnimatedHoverButtonStyle}"
        Padding="20,10"/>

3. 自定义按钮内容

xml 复制代码
<Button Style="{StaticResource AnimatedHoverButtonStyle}"
        Padding="20,10">
    <StackPanel Orientation="Horizontal" Spacing="10">
        <Path Data="M13,3V9H21V3M13,21H21V11H13M3,21H11V15H3M3,13H11V3H3V13Z" 
              Fill="Black" 
              Stretch="Uniform"
              Width="20"
              Height="20"/>
        <TextBlock Text="自定义内容" VerticalAlignment="Center"/>
    </StackPanel>
</Button>

高级效果:3D变换和光效

添加3D旋转效果

xml 复制代码
<!-- 在App.xaml的AnimatedHoverButtonStyle中添加 -->
<EventTrigger RoutedEvent="MouseEnter">
    <BeginStoryboard>
        <Storyboard>
            <!-- 其他动画... -->
            
            <!-- 3D旋转效果 -->
            <DoubleAnimation Storyboard.TargetName="transform3D"
                              Storyboard.TargetProperty="RotationX"
                              From="0" To="5" Duration="0:0:0.3"/>
            <DoubleAnimation Storyboard.TargetName="transform3D"
                              Storyboard.TargetProperty="RotationY"
                              From="0" To="5" Duration="0:0:0.3"/>
        </Storyboard>
    </BeginStoryboard>
</EventTrigger>

<EventTrigger RoutedEvent="MouseLeave">
    <BeginStoryboard>
        <Storyboard>
            <!-- 其他动画... -->
            
            <!-- 3D旋转恢复 -->
            <DoubleAnimation Storyboard.TargetName="transform3D"
                              Storyboard.TargetProperty="RotationX"
                              To="0" Duration="0:0:0.3"/>
            <DoubleAnimation Storyboard.TargetName="transform3D"
                              Storyboard.TargetProperty="RotationY"
                              To="0" Duration="0:0:0.3"/>
        </Storyboard>
    </BeginStoryboard>
</EventTrigger>

在按钮模板中添加3D变换:

xml 复制代码
<Border x:Name="border" ...>
    <Border.RenderTransform>
        <TransformGroup>
            <ScaleTransform/>
            <SkewTransform/>
            <RotateTransform/>
            <TranslateTransform/>
        </TransformGroup>
    </Border.RenderTransform>
    
    <Border.Projection>
        <PlaneProjection x:Name="transform3D"/>
    </Border.Projection>
    
    <ContentPresenter .../>
</Border>

添加光晕效果

xml 复制代码
<!-- 在按钮模板中添加 -->
<Border x:Name="glowEffect" 
        Opacity="0"
        Background="#60FFFFFF"
        CornerRadius="8"
        Margin="-5">
    <Border.Effect>
        <BlurEffect Radius="10"/>
    </Border.Effect>
</Border>

在动画中添加光晕效果:

xml 复制代码
<EventTrigger RoutedEvent="MouseEnter">
    <BeginStoryboard>
        <Storyboard>
            <!-- 其他动画... -->
            
            <!-- 光晕效果 -->
            <DoubleAnimation Storyboard.TargetName="glowEffect"
                              Storyboard.TargetProperty="Opacity"
                              To="1" Duration="0:0:0.3"/>
        </Storyboard>
    </BeginStoryboard>
</EventTrigger>

<EventTrigger RoutedEvent="MouseLeave">
    <BeginStoryboard>
        <Storyboard>
            <!-- 其他动画... -->
            
            <!-- 光晕消失 -->
            <DoubleAnimation Storyboard.TargetName="glowEffect"
                              Storyboard.TargetProperty="Opacity"
                              To="0" Duration="0:0:0.3"/>
        </Storyboard>
    </BeginStoryboard>
</EventTrigger>

专业建议

1. 性能优化

  • 使用硬件加速:

    csharp 复制代码
    // 在窗口构造函数中
    public MainWindow()
    {
        InitializeComponent();
        RenderOptions.ProcessRenderMode = System.Windows.Interop.RenderMode.Default;
    }
  • 简化动画元素:

    • 避免在动画中使用复杂效果
    • 限制同时进行的动画数量

2. 响应式设计

  • 使用Viewbox包裹按钮内容:

    xml 复制代码
    <Button Style="{StaticResource AnimatedHoverButtonStyle}">
        <Viewbox>
            <TextBlock Text="响应式按钮"/>
        </Viewbox>
    </Button>

3. 主题支持

xml 复制代码
<Application.Resources>
    <!-- 主题颜色 -->
    <Color x:Key="PrimaryColor">#FF4A90E2</Color>
    <Color x:Key="PrimaryDarkColor">#FF3A80D2</Color>
    <Color x:Key="PrimaryDarkerColor">#FF2A70C2</Color>
    
    <!-- 在样式中使用主题颜色 -->
    <Style x:Key="HoverButtonStyle" TargetType="Button">
        <Setter Property="Background" Value="{StaticResource PrimaryColor}"/>
        <!-- 悬停时 -->
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="Background" Value="{StaticResource PrimaryDarkColor}"/>
        </Trigger>
    </Style>
</Application.Resources>

4. 无障碍支持

xml 复制代码
<Style TargetType="Button">
    <!-- 添加键盘焦点样式 -->
    <Setter Property="FocusVisualStyle">
        <Setter.Value>
            <Style>
                <Setter Property="Control.Template">
                    <Setter.Value>
                        <ControlTemplate>
                            <Rectangle Stroke="White" 
                                       StrokeThickness="2"
                                       StrokeDashArray="2 2"
                                       Margin="2"
                                       SnapsToDevicePixels="true"/>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Setter.Value>
    </Setter>
    
    <!-- 高对比度支持 -->
    <Style.Triggers>
        <Trigger Property="SystemParameters.HighContrast" Value="true">
            <Setter Property="Background" Value="WindowText"/>
            <Setter Property="Foreground" Value="Window"/>
        </Trigger>
    </Style.Triggers>
</Style>

这个实现提供了专业且美观的按钮悬停动画效果,完全满足您的需求:鼠标悬停时文字颜色由黑变白、加粗并变大。您可以根据需要选择基本触发器效果或平滑动画效果,还可以添加额外的3D变换和光效来增强用户体验。

相关推荐
TA远方2 小时前
【C#】一个简单的http服务器项目开发过程详解
服务器·http·c#·wpf·web·winform·console
陈奕昆9 小时前
2.1HarmonyOS NEXT开发工具链进阶:DevEco Studio深度实践
华为·wpf·harmonyos
Dr.多喝热水11 小时前
WPF prism
windows·wpf
Hare_bai1 天前
WPF响应式UI的基础:INotifyPropertyChanged
ui·c#·wpf·xaml
上元星如雨1 天前
WPF 全局加载界面、多界面实现渐变过渡效果
wpf
Hare_bai1 天前
WPF的布局核心:网格布局(Grid)
ui·c#·wpf·交互·xaml
Hare_bai1 天前
WPF的基础控件:布局控件(StackPanel & DockPanel)
ui·c#·wpf·交互·xaml·visual studio
菜长江1 天前
WPF-Prism学习笔记之 “导航功能和依赖注入“
笔记·wpf
keke101 天前
WPF【09】WPF基础入门 (三层架构与MVC架构)
wpf