Smooth text animation (Marquee) using WPF

Trying to build a marquee control with smooth text animation. Current efforts include:

  • Using translate transform
  • Using animation on Canvas dependency properties (Left, Right)
  • Using animation on custom dependency property (Point) and using drawing visuals (formattedtext)
  • Using CompositionTarget.Rendering

But the animation is still choppy and resource intensive (2-10% CPU).

Test code used in default wpf window which I assume should produce a smooth animation:

   <TextBlock x:Name="_box" FontSize="64" CacheMode="BitmapCache" Text="lorem ipsum">
        <TextBlock.RenderTransform>
            <TranslateTransform x:Name="AnimatedTranslateTransform" X="0" Y="0" />
        </TextBlock.RenderTransform>
        <TextBlock.Triggers>
            <EventTrigger RoutedEvent="TextBlock.Loaded">
              <BeginStoryboard>
                <Storyboard>
                  <DoubleAnimation
                    Storyboard.TargetName="AnimatedTranslateTransform" 
                    Storyboard.TargetProperty="X"
                    From="-300" To="300" Duration="0:0:5" 
                    AutoReverse="True" RepeatBehavior="Forever" />
                </Storyboard>
              </BeginStoryboard>
            </EventTrigger>
          </TextBlock.Triggers>
    </TextBlock>

Checklist:

  • Confirmed no software rendering is taking place (ms performance tool and checking RenderCapability.Tier)
  • Calling freeze on any imaginable object
  • Disabled any bitmap effect and transparency
  • Checked all marquee controls out there (same issues)

Tested on:

  • CPU: Intell core 2 duo (T6600) @2.2Ghz
  • RAM: 4GB
  • GPU: NVidia GeForce 9600M GS (latest drivers)
  • OS: Windows 7 (64bit)

Any ideas (or better yet code example)?

From the responses it seems this is not a wpf issue (other marquee controls work fine for others but not for me), nut I'm getting the same issues on every machine I tested this on.


Solution 1:

Your animation will be handled entirely at the MilCore layer if:

  1. Your TranslateTransform is a RenderTransform (not a LayoutTransform), and
  2. You use a simple animation such as a DoubleAnimation, and
  3. Your object has no clipping or opacity calculations

Try using a DoubleAnimation-animated TranslateTransform for a RenderTransform on a TextBlock that is a direct child of a Window with default settings.

  • If this is still slow, there is something slow about your Direct3D system because managed code is not involved at all and MilCore's calls are very simple, but

  • If it works smoothly and efficiently, incrementally change it to your poorly-performing code to see what change causes the slowdown.

Given your response to Jobi Joy's answer I would suspect the problem is somewhere in your hardware or Direct3D setup, but the only way to find out is to test it.

Solution 2:

If you are using WPF 4.0, try setting the CacheMode="BitmapCache" (in the XAML) on the element you are animating, in this case, probably a TextBlock.

Solution 3:

Hope this may help you - http://jobijoy.blogspot.com/2008/08/silverlight-marquee-control.html

And the WPF version also can be found here