Marquee doesn't move smooth

804 views Asked by At

I have created myself a small prototype for a marquee. It moves the label from the right edge of the screen to the left. Once there, it starts again at the right so that it looks infinite. Like a news ticker.

My problem is that, the label shifts its position very juddery. It just seems rude and bumpy. I move the label every 33 ms to 1.0 to the left.

My renderer running on the hardware side (Tier 2). Framework: 4.5

XAML:

<Window x:Class="Canny.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="811" Name="main">
<Canvas Name="myCanvas" Background="Black">
    <Label Name="lb1" Content="Lauftext+++" Foreground="WhiteSmoke" FontSize="25" Canvas.Left="618" Canvas.Top="10" FontFamily="Courier New" FontWeight="ExtraBold" FontStretch="UltraExpanded"/>
</Canvas>

XAML.CS:

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Threading;

namespace Canny
{
/// <summary>
/// Interaktionslogik für MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    DispatcherTimer timer;
    double newPos;
    readonly double actualWidthLb;
    int renderingTier;
    public MainWindow()
    {
        InitializeComponent();
        timer = new DispatcherTimer();
        timer.Interval = TimeSpan.FromMilliseconds(33.0);
        timer.Tick += timer_Tick;
        newPos = myCanvas.ActualWidth;
        actualWidthLb = lb1.ActualWidth;
        timer.Start();
        renderingTier = (RenderCapability.Tier >> 16);

    }

    void timer_Tick(object sender, EventArgs e)
    {
        newPos -= 1.0;
        Canvas.SetLeft(lb1,newPos);
        if (Canvas.GetLeft(lb1) + actualWidthLb <= 0)
        {
            Canvas.SetLeft(lb1, myCanvas.ActualWidth);
            newPos = myCanvas.ActualWidth;
        }
    }
}
}

I thank you in advance about advices!

1

There are 1 answers

1
BionicCode On

Have you tried to lower the timer intervall? 33ms are about 30Hz. This rate is much too slow for our eyes to be experienced as a fluently moving picture. Our eyes are faster than this! Thats why you start at least witha rate of 50Hz (20ms) but for a real smooth experience you better start with 70Hz which is similar to 14ms or even faster. (frequency: f = 1/T). To adjust the scrolling speed you could lower the steps (e.g incrementing position value x = x - 0.1 -> slower or x = x - 0.01 -> 100x slower compared to incrementing x by -1.0) and vice versa.

You may consider to use your DispatcherTimer with a DispatcherPriority (via constructor) with a priority something like Render or higher...

But if you are using WPF why don't make use of the nice animation features provided? It's quickly and easily done with Blend. MSDN - How to: Animate an Object Along a Path (Double Animation)