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:
- Your TranslateTransform is a RenderTransform (not a LayoutTransform), and
- You use a simple animation such as a DoubleAnimation, and
- 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