如何创建流畅的动画文字选框?

时间:2017-12-04 15:05:45

标签: c# wpf directx sharpdx wpf-animation

我知道有很多关于水平文本动画/文本滚动的不同主题,但不幸的是,它们都没有提供可重复文本的平滑滚动。我尝试使用包含文本的各种WPF控件进行双/厚度动画。还尝试使用可视化刷进行动画制作,与其他方法(例如,使用Canvas.Left属性等)相比,这给我带来了迄今为止最优雅的滚动,但如果文本长度或动画速度为太高了。

我正在使用SharpDX库进行纯粹的DirectX C#实现。还应该提一下,我是DirectX编程的初学者。这是代码:

public void RunMethod()
{
    // Make window active and hide mouse cursor.
    window.PointerCursor = null;
    window.Activate();

    var str = "This is an example of a moving TextLayout object with no snapped pixel boundaries.";

    // Infinite loop to prevent the application from exiting.
    while (true)
    {
        // Dispatch all pending events in the queue.
        window.Dispatcher.ProcessEvents(CoreProcessEventsOption.ProcessAllIfPresent);

        // Quit if the users presses Escape key.
        if (window.GetAsyncKeyState(VirtualKey.Escape) == CoreVirtualKeyStates.Down)
        {
            return;
        }

        // Set the Direct2D drawing target.
        d2dContext.Target = d2dTarget;

        // Clear the target. 
        d2dContext.BeginDraw();
        d2dContext.Clear(Color.CornflowerBlue);

        //float layoutXOffset = 0;
        float layoutXOffset = layoutX;

        // Create the DirectWrite factory objet.
        SharpDX.DirectWrite.Factory fontFactory = new SharpDX.DirectWrite.Factory();

        // Create a TextFormat object that will use the Segoe UI font with a size of 24 DIPs.
        textFormat = new TextFormat(fontFactory, "Verdana", 100.0f);

        textLayout2 = new TextLayout(fontFactory, str, textFormat, 2000.0f, 100.0f);

        // Draw moving text without pixel snapping, thus giving a smoother movement.
        // d2dContext.FillRectangle(new RectangleF(layoutXOffset, 1000, 1000, 100), backgroundBrush);
        d2dContext.DrawTextLayout(new Vector2(layoutXOffset, 0), textLayout2, textBrush, DrawTextOptions.NoSnap);

        d2dContext.EndDraw();

        //var character = str.Substring(0, 1);
        //str = str.Remove(0, 1);
        //str += character;
        layoutX -= 3.0f;

        if (layoutX <= -1000)
        {
            layoutX = 0;
        }

        // Present the current buffer to the screen.
        swapChain.Present(1, PresentFlags.None);
    }
}

基本上它会创建一个无限循环并减去水平偏移。以下是挑战:我需要类似于HTML选框的可重复文本,没有任何空白,可能需要将其扩展到多个监视器。

请建议。

1 个答案:

答案 0 :(得分:0)

我既不知道如何使用DirectX也不知道sharpdx,但如果你想要,你可以考虑这个解决方案

前一段时间我遇到过类似的问题,但是文字框内的文字也是如此。获得赏金之后,我得到了我想要的东西。我发布相关的代码片段作为示例,但您可以查看完整的答案here

基本上,只要你的文本块/文本框包含一个无法完全显示的字符串,导致长度超过textblock / box长度就可以使用这种方法。您可以定义从您需要的基础派生的自定义用户控件(例如SlidingComboBox:Combobox),并为您的故事板定义动画,如下所示

_animation = new DoubleAnimation()
 {
      From = 0,
      RepeatBehavior = SlideForever ? RepeatBehavior.Forever : new RepeatBehavior(1), //repeat only if slide-forever is true
      AutoReverse = SlideForever
 };

在我的示例中,我希望此行为仅在鼠标位于组合框上时才有效,因此在我的自定义OnMouse中输入我有这段代码

if (_parent.ActualWidth < textBlock.ActualWidth)
{
     _animation.Duration = TimeSpan.FromMilliseconds(((int)textBlock.Text?.Length * 100));
     _animation.To = _parent.ActualWidth - textBlock.ActualWidth;
     _storyBoard.Begin(textBlock);
}

其中_parent表示所选项目的容器。检查文本lenght vs combobox lenght后,我启动动画并在要显示的文本末尾结束

请注意,在我提到的问题中,还有其他解决方案。我发布了一个适合我的那个