当我使用Storyboard缩放TextBlock时,它会在缩放时像素化,并且只在完成时渲染。
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="TextBlock" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleY)">
<EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="1.5"/>
是否有一种方式的TextBlock是重新渲染每帧?
我找到了一个解决方案,虽然它不是关于TextBlock了,但对我来说它工作:
private void CreateText(string text)
{
_compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;
CreateDevice();
_spriteTextVisual = _compositor.CreateSpriteVisual();
_spriteTextVisual.Size = new Vector2(512, 512);
_drawingTextSurface = _graphicsDevice.CreateDrawingSurface(new Size(512, 512), DirectXPixelFormat.B8G8R8A8UIntNormalized, DirectXAlphaMode.Premultiplied);
using (var ds = CanvasComposition.CreateDrawingSession(_drawingTextSurface))
{
ds.Clear(Colors.Transparent);
ds.DrawText(text, new Rect(0, 0, 512, 512), Colors.Black, new CanvasTextFormat
{
FontSize = 32,
FontWeight = FontWeights.Light,
VerticalAlignment = CanvasVerticalAlignment.Top,
HorizontalAlignment = CanvasHorizontalAlignment.Center,
LineSpacing = 32
});
}
_surfaceTextBrush = _compositor.CreateSurfaceBrush(_drawingTextSurface);
_spriteTextVisual.Brush = _surfaceTextBrush;
ElementCompositionPreview.SetElementChildVisual(this, _spriteTextVisual);
}
private void CreateDevice()
{
_device = CanvasDevice.GetSharedDevice();
_device.DeviceLost += Device_DeviceLost;
if (_graphicsDevice == null)
{
_graphicsDevice = CanvasComposition.CreateCompositionGraphicsDevice(_compositor, _device);
}
else
{
CanvasComposition.SetCanvasDevice(_graphicsDevice, _device);
}
}
private async void Device_DeviceLost(CanvasDevice sender, object args)
{
_device.DeviceLost -= Device_DeviceLost;
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, CreateDevice);
}
只需要设置这个文本的最大尺寸
这似乎是有意为之——请看Jerry Nixon对一个非常类似的问题的回答。
显然,这是为了确保动画流畅,因为在每一帧完全渲染字体将是昂贵的。
您可能克服这个问题的唯一方法是将TextBlock
包裹在Viewbox
元素中并缩放Viewbox
的Height
属性。然而,这不会自动工作,你还必须将EnableDependentAnimation="True"
添加到DoubleAnimationUsingKeyFrames
元素。不幸的是,你会发现这种方法也会导致每一帧的布局更新,因此非常不和谐。