如何在UWP中动画TextBlock的比例



当我使用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元素中并缩放ViewboxHeight属性。然而,这不会自动工作,你还必须将EnableDependentAnimation="True"添加到DoubleAnimationUsingKeyFrames元素。不幸的是,你会发现这种方法也会导致每一帧的布局更新,因此非常不和谐。

最新更新