当动画在屏幕上不可见时,WPF 停止动画



我正在使用AvalonEdit创建一个ANSI终端,该终端可以正确进行颜色编码并实现一些样式,例如下划线和反向(它对此非常有效,这不是完整的VT100之类的东西(。

在 AvalonEdit 中,DocumentColorizingTransformer将 ANSI 颜色代码转换为彩色文本或样式文本。昨晚我正在努力实施ANSI Blink。我在处理这部分代码时眨了眨眼:

else if (color.AnsiColor is Blink)
{
// The color animation of the pulse, use the opacity to simulate blinking
var da = new DoubleAnimation
{
Duration = new Duration(TimeSpan.FromMilliseconds(500)),
From = 0,
To = 1,
AutoReverse = true
RepeatBehavior = RepeatBehavior.Forever
};
// Get the foreground
var foreground = element.TextRunProperties.ForegroundBrush;
// Clone the foreground so it's not frozen and we can run animations on it.
var blinkForeground = foreground.Clone();
// Set the new foreground.
element.TextRunProperties.SetForegroundBrush(blinkForeground);
// Blink Blink Blink Blink
blinkForeground.BeginAnimation(SolidColorBrush.OpacityProperty, da);
}

显然,我希望此文本在屏幕上时永远闪烁,这就是我将"重复行为"设置为"永远"的原因。但是,即使它滚动出屏幕的可见部分(它可能没有渲染,但动画似乎仍在运行(,它也会继续使用 CPU。

我的问题:

当一段文本滚动出可见视图时,如何停止一段文本上的动画(不必在 AvalonEdit 框中遍历 - 所有内容,这可能非常非常大并且不可行性能明智(。如果我可以在动画离开屏幕时停止动画,然后在ColorizeLine(DocumentLine line)触发时重新启动它,那将是理想的。 使用AvalonEdit,我知道当某些东西通过时ColorizeLine它是可见的,但我不一定知道在这一点上什么是不可见的。 我考虑过保留所有双重动画的引用列表,但我仍然不知道它们何时在屏幕上可见。

关于我如何处理这个问题还有其他想法或想法吗?

如果有任何动画正在运行,WPF 将以每秒 60 帧的速度呈现。如果没有实际更改,则呈现速度相对较快,但是当应用程序应该处于空闲状态时,它仍然会导致明显的 CPU 使用率。AvalonEdit 的插入符号是打开和关闭的(带有计时器(,而不是使用动画来避免渲染不必要的帧。


DocumentColorizingTransformer中,您可以使用this.CurrentContext.VisualLine访问正在处理的VisualLineVisualLine有一个IsDisposed属性,一旦 AvalonEdit 丢弃了该行,该属性将更改为true(如果线条再次可见,则会再次调用着色器(。

没有事件告诉您何时处置了该行。但是,如果您跟踪列表中包含VisualLine的所有动画+它们,则可以使用TextView.VisualLinesChanged事件扫描已释放的VisualLine并停止相应的动画。

相关内容

  • 没有找到相关文章

最新更新