WPF:动画不流畅

2024-05-23

我正在制作一个动画TextBlock。 60秒后增加FontSize从 8 点到 200 点。一切工作正常,除了我的动画随着文本的增长而上下移动。为什么会发生这种情况?是否可以避免这种情况?

我有一个非常简单的 XAML 文件:

<Window x:Class="Timer.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Width="800" 
        Height="500"
        Title="MainWindow" 
        Loaded="Window_Loaded">

    <Grid>

        <TextBlock 
            Name="TimerTextBlock" 
            HorizontalAlignment="Center" 
            VerticalAlignment="Center" 
            Text="00h : 00m : 00.000s" />

    </Grid>

</Window>

同样简单的代码隐藏:

public partial class MainWindow : Window
{
    private const string timerFormat = "{0:hh'h : 'mm'm : 'ss'.'fff's'}";
    private DispatcherTimer dispatcherTimer;
    private DateTime targetTime;

    public MainWindow()
    {
        InitializeComponent();
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        targetTime = DateTime.Now.AddSeconds(60);
        double totalTime = targetTime.Subtract(DateTime.Now).TotalMilliseconds;

        DoubleAnimation animation = new DoubleAnimation();
        animation.From = TimerTextBlock.FontSize;
        animation.To = 200;
        animation.Duration = new Duration(targetTime.Subtract(DateTime.Now));
        TimerTextBlock.BeginAnimation(TextBlock.FontSizeProperty, animation);

        dispatcherTimer = new DispatcherTimer();
        dispatcherTimer.Interval = TimeSpan.FromMilliseconds(1);
        dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
        dispatcherTimer.Start();
    }

    private void dispatcherTimer_Tick(object sender, EventArgs e)
    {
        if (DateTime.Compare(targetTime, DateTime.Now) > 0)
        {
            TimerTextBlock.Text = 
                string.Format(timerFormat, targetTime.Subtract(DateTime.Now));
        }
    }
}

感谢您的所有澄清。


您的垂直跳跃问题是由于字体渲染舍入造成的。具体来说,WPF 将避免亚像素字体高度,以实现字体平滑。避免这种情况的一种方法是将文本转换为路径几何图形,然后使用比例变换对其进行动画处理。

这是示例的替代版本,没有跳转。新的 XAML 是:

<Grid>
    <Path Name="Path" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>

以及加载窗口时的新代码:

SetText("");
var transform = new ScaleTransform(1, 1);
Path.LayoutTransform = transform;
var animationX = new DoubleAnimation(1, 10, new Duration(TimeSpan.FromSeconds(60)));
transform.BeginAnimation(ScaleTransform.ScaleXProperty, animationX);
var animationY = new DoubleAnimation(1, 10, new Duration(TimeSpan.FromSeconds(60)));
transform.BeginAnimation(ScaleTransform.ScaleYProperty, animationY);

以及设置动画文本的新方法:

private void SetText(string text)
{
    var formatted = new FormattedText(text, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface("Lucida Console"), 12, Brushes.Black);
    Path.Data = formatted.BuildGeometry(new Point(0, 0));
    Path.Fill = Brushes.Black;
}

并且您已从计时器事件处理程序中调用 SetText。

请注意,为了避免水平跳跃,您必须使用固定长度的文本字符串和恒定宽度的字体。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

WPF:动画不流畅 的相关文章

随机推荐

  • 是否可以在 opengrok 中搜索包含大括号的短语?

    我尝试过使用 struct a 和 struct a 之类的东西来查找 a 的声明 但 opengrok 似乎只是忽略了大括号 有没有办法搜索短语 struct a Grok 支持转义查询语法中的特殊字符 当前的特殊字符列表是 To esc
  • 寻找一种从 C++ 调用 Java 的便捷方法

    似乎大多数与 JNI Java 本机接口 相关的文档或帮助程序库都与从 Java 调用本机代码有关 这似乎是它的主要用途 尽管它还有更多功能 我主要想朝相反的方向工作 通过添加一些 Java 库来修改现有的 相当大的 可移植 C 程序 例如
  • 表格外的标题?

    我试图在乳胶中向表格添加标题 但它会抛出此错误 乳胶错误 标题位于浮动之外 从错误中我猜测这意味着它在表之外 但我已经清楚地把它放在里面了 begin tabular c c c c c c caption Table1 Potentiom
  • 无法使用 Runtime.getRuntime().exec 从 jsp 执行 java 程序

    我正在尝试通过 jsp 运行 jar 文件 我使用命令Runtime getRuntime exec java jar file jar 我收到错误Unable to access jarfile file jar当我打印错误流时 我尝试将
  • 如何用 C 语言编写 gRPC 客户端/服务器?

    我有一个用 C 编写的程序 想在其中包含 gRPC 然而 gRPC 的 API 是用 C 编写的 我查看了这里并让 foo client 和 foo server 正常工作 https github com Juniper grpc c t
  • 从 Facebook Account Kit 获取电话号码

    Account Kit 文档指出 如果您使用 AccountKitActivity ResponseType TOKEN 开始登录会话 则可以通过调用 getCurrentAccount 来访问当前帐户的 Account Kit ID 电话
  • 设置 pyodbc 搜索 odbcinst.ini 文件的位置

    我正在尝试使用查询 ODBC 兼容数据库pyodbc in ubuntu 为此 我已经安装了驱动程序 例如 mysql odbc driver 安装后odbcinst ini在该位置创建包含配置的文件 usr share libmyodbc
  • Swift 中的 @autoreleasepool 相当于什么?

    在 Swift 中 我注意到没有 autoreleasepool 构造 尽管 Swift 确实使用了 ARC 在 Swift 中管理自动释放池的正确方法是什么 或者它是否因某种原因被删除 语法如下 autoreleasepool code
  • 从 iOS 设备向 Google App Engine 进行身份验证

    我正在开发一个 iPhone 应用程序 它使用 Google 应用程序引擎来托管后端 我需要通过 Google 进行身份验证 但我似乎无法找到从我的应用程序中执行此操作的方法 看来我要做一个UIWebView让用户登录到我从 Google
  • java.lang.NoSuchMethodError:没有虚拟方法 setTag(Ljava/lang/Object;)

    我刚刚完成使用登录和注册屏幕与齐射的代码 但在模拟器中运行时我收到此错误 java lang NoSuchMethodError No virtual method setTag Ljava lang Object Lcom android
  • 使用 Twitter Bootstrap 将 4 列变为 2 列

    我有一个 4 列流体布局 div class container fluid div class row fluid div class span3 A div div class span3 B div div class span3 C
  • pyspark:聚合列中最常见的值

    aggregrated table df input groupBy city income bracket agg count suburb alias suburb sum population alias population sum
  • 带有 CSS 过渡的 Meteor 模板

    当通过模板助手触发 CSS 转换时 Meteor 似乎会跳过这些转换 有办法解决这个问题吗 Example
  • EKS Fargate Fluent-Bit 多输出

    我正在 Fargate 上运行 K8 集群并使用 FluentBit 将日志发送到 cloudwatchhttps docs aws amazon com eks latest userguide fargate logging html
  • 是否可以限制 asyncio 中同时运行的协程数量?

    我已经使用 asyncio 编写了脚本 但发现同时运行的协程数量太大 并且经常会挂起 所以我想限制并发协程的数量 一旦达到限制 我想等待任何协程完成后再执行另一个协程 我当前的代码如下所示 loop asyncio get event lo
  • Facebook 使用开放图协议 ID 作为地点 ID 进行签到

    我用的是FB页面linter http developers facebook com tools lint url http www foodtrucksmap com facebook html验证我使用的所有元信息是否正确 根据图表网
  • Retrofit/Moshi:平台类 java.util.Date 需要显式注册 JsonAdapter

    我是 Android Retrofit 和 Moshi 的新手 我正在尝试对 API 进行 POST 调用 但在序列化方面遇到问题Date 如果您发现任何其他需要纠正的地方 请指出 因为我仍在学习 谢谢 interface ApiInter
  • iphone - 如何读取麦克风输入?

    如何从麦克风读取声音数据 我不想录制然后访问数据 我希望能够实时访问声音输入 您可以将麦克风中的声音 PCM 样本 录制到非常短的内存缓冲区 持续时间短至几毫秒 这与使用 iOS API 一样接近 实时 查看 aurioTouch 示例 了
  • 查找一个二维矩阵是否是另一个二维矩阵的子集

    最近我参加了一个黑客马拉松 我了解到一个问题 试图在 2d 矩阵中找到网格形式的模式 模式可以是 U H 和 T 并由 3 3 矩阵表示 假设我想展示 H 和 U 1 0 1 1 0 1 1 1 1 gt H 1 0 1 gt U 1 0
  • WPF:动画不流畅

    我正在制作一个动画TextBlock 60秒后增加FontSize从 8 点到 200 点 一切工作正常 除了我的动画随着文本的增长而上下移动 为什么会发生这种情况 是否可以避免这种情况 我有一个非常简单的 XAML 文件