WPF学习(动画)

文章目录

  • [一、图像变换 RenderTransform](#一、图像变换 RenderTransform)
      • 1、常见变换类型
      • [2、`RenderTransform` 的核心作用](#2、RenderTransform 的核心作用)
      • [3、`RenderTransform` 的使用方式](#3、RenderTransform 的使用方式)
      • [4、与 `LayoutTransform` 的对比](#4、与 LayoutTransform 的对比)
      • 5、在动画中的应用
  • [二、 滚动的椭圆](#二、 滚动的椭圆)
  • 三、Storyboard放置位置
      • [1. **元素的 `Resources` 集合**](#1. 元素的 Resources 集合)
      • [2. **控件模板(`ControlTemplate`)或数据模板(`DataTemplate`)中**](#2. 控件模板(ControlTemplate)或数据模板(DataTemplate)中)
      • [3. **窗口(`Window`)或页面(`Page`)的资源**](#3. 窗口(Window)或页面(Page)的资源)
      • [4. **应用程序资源(`App.xaml`)**](#4. 应用程序资源(App.xaml)
      • [5. **代码动态创建**](#5. 代码动态创建)
      • 选择建议
        • [示例代码: 旋转的按钮](#示例代码: 旋转的按钮)

一、图像变换 RenderTransform

在WPF中,RenderTransform 是一个重要的属性,用于对UI元素进行变换(Transformation) ,即在不改变元素实际位置和大小的情况下,改变其视觉呈现效果。常见的变换包括旋转、缩放、平移和倾斜
Render:使成为某种状态,使成为

1、常见变换类型

WPF提供了多种变换类,每种对应不同的效果:

变换类 作用 关键属性
RotateTransform 旋转元素 Angle(旋转角度,单位:度)
ScaleTransform 缩放元素 ScaleXScaleY(水平/垂直缩放比例)
TranslateTransform 平移元素(相对移动) XY(平移距离)
SkewTransform 倾斜元素 AngleXAngleY(水平/垂直倾斜角度)
MatrixTransform 自定义矩阵变换(高级用法) Matrix(变换矩阵)

2、RenderTransform 的核心作用

  1. 视觉效果增强

    通过变换可以创建动画、特效或调整元素的显示方式,而不影响布局系统。

    例如:旋转按钮、放大图像、倾斜文本等。

  2. 独立于布局

    变换只影响元素的渲染结果,不会改变元素在布局中的位置或占用空间。

    例如:将按钮旋转45度后,它仍占据原来的矩形区域。

  3. 组合多种变换

    可以通过 TransformGroup 组合多个变换,按顺序应用效果。

3、RenderTransform 的使用方式

  1. 单一变换示例(旋转)
xml 复制代码
<Button Content="旋转按钮" Width="100" Height="30">
    <Button.RenderTransform>
        <RotateTransform Angle="45" CenterX="50" CenterY="15" />
    </Button.RenderTransform>
</Button>
  • CenterXCenterY:指定旋转中心点(相对于元素左上角)。
  1. 组合变换示例(缩放 + 旋转)
xml 复制代码
<Ellipse Width="50" Height="50" Fill="Blue">
    <Ellipse.RenderTransform>
        <TransformGroup>
            <ScaleTransform ScaleX="1.5" ScaleY="0.8" />
            <RotateTransform Angle="30" />
        </TransformGroup>
    </Ellipse.RenderTransform>
</Ellipse>
  • 变换按顺序应用:先缩放,再旋转。

4、与 LayoutTransform 的对比

WPF中还有一个 LayoutTransform 属性,两者的区别如下:

属性 作用范围 对布局的影响 性能
RenderTransform 仅影响元素的渲染结果 不影响布局(占位不变) 较高(仅重绘)
LayoutTransform 影响元素的布局计算 改变元素占用空间 较低(触发布局更新)

5、在动画中的应用

RenderTransform 常与动画结合使用,实现动态效果。例如:

xml 复制代码
<Button Content="动画按钮" Width="100">
    <Button.RenderTransform>
        <RotateTransform x:Name="buttonRotate" Angle="0" />
    </Button.RenderTransform>
</Button>

<!-- 动画定义 -->
<Storyboard x:Key="RotateAnimation">
    <DoubleAnimation 
        Storyboard.TargetName="buttonRotate"
        Storyboard.TargetProperty="Angle"
        From="0" To="360" Duration="0:0:2"
        RepeatBehavior="Forever" />
</Storyboard>

六、注意事项

  1. 变换中心(Center)

    多数变换需要指定中心点(如旋转、缩放),默认值为 (0, 0)(元素左上角)。合理设置中心点可避免元素"漂移"。

  2. 性能考虑

    频繁使用复杂变换(尤其是 MatrixTransform)可能影响性能,建议适度使用。

  3. 坐标系

    变换基于元素自身的坐标系,而非父容器或全局坐标系。

总结
RenderTransform 是WPF中实现元素视觉变换的核心机制,通过它可以轻松创建旋转、缩放、平移等效果,为UI增添动态和交互性。结合动画系统,更能实现复杂的视觉过渡效果。

二、 滚动的椭圆

示例代码

xml 复制代码
<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Ellipse Center 动画示例" Height="300" Width="400">
    <Grid>
                <!-- 定义动画资源 -->
                <Grid.Resources>
                    <Storyboard x:Key="RollingAnimation" RepeatBehavior="Forever">
                        <!-- 水平移动动画 -->
                        <DoubleAnimation 
                    Storyboard.TargetName="MyEllipse"
                    Storyboard.TargetProperty="(Canvas.Left)"
                    From="0" To="300" Duration="0:0:5"
                    AutoReverse="True" />

                        <!-- 旋转动画 - 模拟滚动效果 -->
                        <DoubleAnimation 
                    Storyboard.TargetName="EllipseRotateTransform"
                    Storyboard.TargetProperty="Angle"
                    From="0" To="360" Duration="0:0:1"
                    RepeatBehavior="Forever" />
                    </Storyboard>
                </Grid.Resources>

                <!-- 触发动画 -->
                <Grid.Triggers>
                    <EventTrigger RoutedEvent="FrameworkElement.Loaded">
                        <BeginStoryboard Storyboard="{StaticResource RollingAnimation}" />
                    </EventTrigger>
                </Grid.Triggers>

                <!-- 椭圆路径 -->
                <Canvas>
                    <Path Grid.Row="1" Stroke="red" StrokeThickness="2" x:Name="MyEllipse" Canvas.Left="0" Canvas.Top="100">
                        <Path.RenderTransform>
                            <RotateTransform x:Name="EllipseRotateTransform" CenterX="100" CenterY="100" />
                        </Path.RenderTransform>
                        <Path.Data>
                            <EllipseGeometry Center="100,100" RadiusX="50" RadiusY="20"/>
                        </Path.Data>
                    </Path>
                </Canvas>
            </Grid>
        </Window>

三、Storyboard放置位置

在WPF(Windows Presentation Foundation)中,Storyboard 是用于定义和控制动画的对象。它可以放在多个不同的位置,具体取决于你的使用场景和动画的作用范围。以下是常见的几种放置位置及其适用情况:

1. 元素的 Resources 集合

Storyboard 定义在元素的资源字典中,使其仅对该元素及其子元素可用。这种方式适合局部动画,例如按钮点击效果、控件加载动画等。

示例(按钮悬停动画)

xml 复制代码
<Button Content="Hover Me">
    <Button.Resources>
        <Storyboard x:Key="HoverStoryboard">
            <DoubleAnimation
                Storyboard.TargetProperty="Opacity"
                From="1.0" To="0.7" Duration="0:0:0.3"
                AutoReverse="True"/>
        </Storyboard>
    </Button.Resources>
    <Button.Triggers>
        <EventTrigger RoutedEvent="Button.MouseEnter">
            <BeginStoryboard Storyboard="{StaticResource HoverStoryboard}"/>
        </EventTrigger>
    </Button.Triggers>
</Button>

2. 控件模板(ControlTemplate)或数据模板(DataTemplate)中

当需要为自定义控件或数据项定义动画时,可以将 Storyboard 放在模板的资源中。这种方式适合封装在控件内部的动画逻辑。

示例(自定义按钮模板动画)

xml 复制代码
<Style TargetType="Button">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <Border x:Name="border" Background="{TemplateBinding Background}">
                    <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
                </Border>
                <ControlTemplate.Resources>
                    <Storyboard x:Key="PressAnimation">
                        <ColorAnimation
                            Storyboard.TargetName="border"
                            Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"
                            To="LightBlue" Duration="0:0:0.2"/>
                    </Storyboard>
                </ControlTemplate.Resources>
                <ControlTemplate.Triggers>
                    <EventTrigger RoutedEvent="Button.PreviewMouseDown">
                        <BeginStoryboard Storyboard="{StaticResource PressAnimation}"/>
                    </EventTrigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

3. 窗口(Window)或页面(Page)的资源

Storyboard 定义在窗口或页面的资源字典中,使其对整个窗口或页面内的所有元素可用。这种方式适合应用于多个控件的共享动画。

示例(窗口级别的共享动画)

xml 复制代码
<Window.Resources>
    <Storyboard x:Key="FadeInStoryboard">
        <DoubleAnimation
            Storyboard.TargetProperty="Opacity"
            From="0" To="1" Duration="0:0:0.5"/>
    </Storyboard>
</Window.Resources>

<StackPanel>
    <Button Content="Animate" 
            Click="Button_Click"/>
    <TextBlock x:Name="message" Text="Hello"/>
</StackPanel>

在代码-behind中启动动画:

csharp 复制代码
private void Button_Click(object sender, RoutedEventArgs e) {
    Storyboard sb = (Storyboard)FindResource("FadeInStoryboard");
    Storyboard.SetTarget(sb, message);
    sb.Begin();
}

4. 应用程序资源(App.xaml

对于全局共享的动画(如全局过渡效果、应用程序启动动画),可以将 Storyboard 定义在应用程序的资源字典中。

示例(应用程序级别的动画)

xml 复制代码
<Application.Resources>
    <Storyboard x:Key="GlobalHighlightAnimation">
        <ColorAnimation
            Storyboard.TargetProperty="(Control.Background).(SolidColorBrush.Color)"
            To="Yellow" Duration="0:0:0.5" AutoReverse="True"/>
    </Storyboard>
</Application.Resources>

5. 代码动态创建

在某些情况下(如需要动态生成动画参数),可以在代码中动态创建 Storyboard 并应用到元素上。

示例(动态创建动画)

csharp 复制代码
// 创建动画
DoubleAnimation animation = new DoubleAnimation {
    From = 0,
    To = 100,
    Duration = TimeSpan.FromSeconds(1)
};

// 创建 Storyboard 并设置目标属性
Storyboard storyboard = new Storyboard();
storyboard.Children.Add(animation);
Storyboard.SetTargetProperty(animation, new PropertyPath(Button.WidthProperty));
Storyboard.SetTarget(animation, myButton);

// 启动动画
storyboard.Begin();

选择建议

  • 局部动画:放在元素资源或模板中。
  • 共享动画:放在窗口/页面资源或应用程序资源中。
  • 动态动画:在代码中创建。

无论放在何处,确保 Storyboard 的作用范围与动画的使用场景相匹配,以提高代码的可维护性和复用性。

示例代码: 旋转的按钮

鼠标放到上面会自动旋转

xml 复制代码
<Window x:Class="WpfApp1.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:WpfApp1"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Button Content="动画按钮" Width="100" Height="60">
            <Button.RenderTransform>
                <RotateTransform x:Name="buttonRotate" Angle="0" />
            </Button.RenderTransform>
            <Button.Resources>
                <Storyboard x:Key="RotateAnimation">
                    <DoubleAnimation 
        Storyboard.TargetName="buttonRotate"
        Storyboard.TargetProperty="Angle"
        From="0" To="360" Duration="0:0:6"
        RepeatBehavior="Forever" />
                </Storyboard>

            </Button.Resources>
            <Button.Triggers>
                <EventTrigger RoutedEvent="Button.MouseEnter">
                    <BeginStoryboard Storyboard="{StaticResource RotateAnimation}"/>
                </EventTrigger>
            </Button.Triggers>
        </Button>
    </Grid>
</Window>
相关推荐
DKPT3 小时前
Java桥接模式实现方式与测试方法
java·笔记·学习·设计模式·桥接模式
好好研究5 小时前
学习栈和队列的插入和删除操作
数据结构·学习
新中地GIS开发老师6 小时前
新发布:26考研院校和专业大纲
学习·考研·arcgis·大学生·遥感·gis开发·地理信息科学
SH11HF7 小时前
小菜狗的云计算之旅,学习了解rsync+sersync实现数据实时同步(详细操作步骤)
学习·云计算
Frank学习路上7 小时前
【IOS】XCode创建firstapp并运行(成为IOS开发者)
开发语言·学习·ios·cocoa·xcode
Chef_Chen8 小时前
从0开始学习计算机视觉--Day07--神经网络
神经网络·学习·计算机视觉
X_StarX10 小时前
【Unity笔记02】订阅事件-自动开门
笔记·学习·unity·游戏引擎·游戏开发·大学生
MingYue_SSS10 小时前
开关电源抄板学习
经验分享·笔记·嵌入式硬件·学习
weixin_4373982111 小时前
转Go学习笔记(2)进阶
服务器·笔记·后端·学习·架构·golang
慕y27411 小时前
Java学习第十六部分——JUnit框架
java·开发语言·学习