How to animate scale of TextBlock in UWP

笑着哭i 提交于 2020-01-01 19:00:14

问题


When I use Storyboard to zoom in TextBlock it pixelates while zooming and rerenders only on complete.

<DoubleAnimationUsingKeyFrames Storyboard.TargetName="TextBlock" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleY)">
      <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="1.5"/>

Is there a way the TextBlock is rerendered each frame?


回答1:


I found a solution though it's not about TextBlock anymore but for me it worked:

    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);
    }

Just have to make this text of max scale size.




回答2:


It seems that this is by design - see this answer by Jerry Nixon on a very similar question.

Apparently this is to ensure the animation is smooth, because rendering the font fully at each frame would be expensive.

The only way you could probably overcome this is to wrap the TextBlock inside a Viewbox element and scale the Viewbox's Height property. This will however not work automatically and you also have to add EnableDependentAnimation="True" to the DoubleAnimationUsingKeyFrames element. Unfortunatelly you will see that this approach also causes layout updates on each frame and is therefore very jarring.



来源:https://stackoverflow.com/questions/39346561/how-to-animate-scale-of-textblock-in-uwp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!