Question

I have all the necessary code to move and click the mouse via C# code, but I don't want to just set the mouse position to X and Y; that will look jerky. Instead, I want to have a smooth transition from point X1, Y1 to point X2, Y2 over Z seconds. Similar to keyframing.

I'm looking for a method similar to this:

public void TransitionMouse(int x, int y, double durationInSecs)

It will just smoothly move the mouse from its current position to x and y in durationInSecs seconds. I have a function called:

public void MoveMouse(int x, int y)

That moves the mouse to x, y immediately.


EDIT

Thanks for the help guys! Here's the finished, and tested, code:

    [DllImport("user32.dll")]
    static extern bool SetCursorPos(int X, int Y);

    public void TransitionMouseTo(double x, double y, double durationSecs)
    {
        double frames = durationSecs*100;

        PointF vector = new PointF();
        PointF mousePos = Cursor.Position;

        vector.X = (float)((x - mousePos.X) / frames);
        vector.Y = (float)((y - mousePos.Y) / frames);

        for (int i = 0; i < frames; i++)
        {
            SetCursorPos((int)(mousePos.X += vector.X), (int)(mousePos.Y += vector.Y));
            Thread.Sleep((int)((durationSecs / frames) * 1000.0));
        }
    }
Was it helpful?

Solution

You could do this in several ways. One option would be to calculate the vector required to move the mouse every frame and apply it over the time period to the mouse position.

So, if we are at position 5,5 and want to move to 20,30 over 10 frames, our vector would be the following:

val = (target - start) / frames;

x = (20 - 5) / 10; y = (30 - 5) / 10;

Vector = 1.5,2.5

Then, in your TransitionMouse method, you apply the vector to the mouse position slowly over whatever duration you wish, using the Thread.Sleep method to control the speed. The code might look like this:

public void TransitionMouseTo(int x, int y, int durationSecs)
{
    int frames = 10;

    PointF vector = new PointF();

    vector.X = (x - Cursor.Position.X) / frames;
    vector.Y = (y - Cursor.Position.Y) / frames;  

    for (int i = 0; i < frames; i++)
    {
        Point pos = Cursor.Position;

        pos.X += vector.X;
        pos.Y += vector.Y;

        Cursor.Position = pos;

        Thread.Sleep((durationSecs / frames) * 1000);
    }
}

Another way of doing it would be to use Bresenhams algorithm to calculate all the points the mouse cursor will move through and then loop through each point and apply it to the cursor again using Thread.Sleep to keep the timing correct.

Steve

OTHER TIPS

really depend on your definition of smooth, however most algorithm of "smooth" motion use spline to interpolate between 2 or more data points.

this could help http://geekswithblogs.net/JuanDoNeblo/archive/2007/10/25/Data-Interpolation-with-SPLINE-in-Csharp.aspx

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top