Autoscrolling on drag, part 3: Dynamic autoscroll based on mouse position

Raymond Chen

Raymond

A common variation on the basic autoscroll algorithm is to scroll faster the further the mouse moves away from the window. You can think of the mouse as tugging on the window via an imaginary rubber band, and the further away from the window you move the mouse, the tauter the rubber band becomes, and the stronger the force applied to the scrolling.

Or you can just say that moving the mouse further from the window makes scrolling faster, and not try to imbue it with pseudo-physics.

We can make these changes to the Try­Auto­Scroll function:

BOOL TryAutoScroll(HWND hwnd, POINT pt)
{
    if (pt.y < 0) {
        ScrollDelta(hwnd, pt.y);
        return TRUE;
    } else if (pt.y > g_cyWindow) {
        ScrollDelta(hwnd, pt.y - g_cyWindow);
        return TRUE;
    }
    return FALSE;
}

Instead of scrolling by a fixed amount at each autoscroll, we instead scroll by an amount proportional to the distance the mouse is from the window. If you move far outside the window, the window scrolls by a lot, but if you’re just barely outside the window, then the window scrolls just a little.

This is a common algorithm, but it too has some downsides.

For one, the maximum autoscroll speed is dependent on how big your monitor is. Which is great if you have a massive 4K monitor, but it’s kind of unfair to people with smaller monitors.

Furthermore, the maximum autoscroll also depends on how close the window is to the edge of the screen. To get high velocity downward scrolling, you have to move the window to the top of the screen so that there’s a lot of room below the window for you to pull the invisible rubber band. This is particularly problematic when the window is maximized, because you may not have any pixels of space outside the window at all!

Next time, a different autoscroll algorithm that avoids these problems.

6 comments

Comments are closed. Login to edit/delete your existing comments

  • Nathan Samson
    Nathan Samson
    ScrollDelta(hwnd, pt.y);

    Surely a real physics-inspired algorithn needs a ^2 here?

    • Avatar
      紅樓鍮

      Force is proportional to deformation; it is energy that’s proportional to deformation squared.

  • Avatar
    Alexey Badalov

    There’s nothing to say a 4k monitor can’t be tiny or a 800×600 monitor massive. Surely the speed needs to be proportional to physical distance, not pixels.

    • Avatar
      cheong00

      As long as the delta distance and screen size are in same unit, it shouldn’t matter whether you use physical distance or pixels.

  • Avatar
    Ray

    I love programs implementing this acceleration in a way that moving the mouse one pixel too far makes you immediately scroll to the end of the list in that direction. Let’s hope they have useful keyboard scroll possibilities to be used afterwards then and trash their “idea” of this.