CAUTION: This is primarily a "note to self" for future Ben. This represents a part of DOM interaction that I don't have a solid mental model for. As such, my confidence level here is not stellar.
The other day, I had to a fix a bug in InVision that related to dragging DOM (Document Object Model) elements up and down in the document. As the user's mouse approached the top or bottom edge of the browser viewport, we needed to scroll the viewport such that the user could drag the selected DOM element to a position that had not been previously-visible within the viewport. Because of some cross-browser quirkiness involved in the getting and setting of document and window dimensions and offsets, I wanted to break this logic out into a demo such that I could reference it at a later time. As such, the logic in this demo will automatically scroll the window when the user approaches the viewport edge.
That said, for this demo, we want to start scrolling the window in a meaningful direction when the user moves their mouse towards the edge of the browser. And, we want the scrolling velocity to increase as the user gets closer to the edge. So, not only do we have to determine if the user's mouse is contained within the "edge" of the viewport, we have to determine how much of the edge has been crossed.
Furthermore, we want the window scrolling to be activated even after the user stops moving their mouse. Meaning, if the user moves their mouse to the "edge" of the viewport and then stops moving, we want the window to continue scrolling until it has reached its maximum scroll position. To accomplish this, I'm using an iterative setTimeout() call. I am sure something much more clever could be accomplished. But, for this demo, I was more concerned with the math and the positional calculations than I was with the smoothness and efficiency of the window scrolling itself.
That said, here is the code. The bulk of the logic is contained within the mousemove handler. The demo steps a 200-pixel "edge" on each side of the viewport that will cause the window to scroll:
Since this is primarily a note-to-self, I'm not going to add much explanation beyond the comments that are in the code. Now, if we open this in the browser and try moving the mouse to the edge of the viewport, we can see the viewport start scrolling automatically with a dynamic intensity:
Obviously, because this is a demo about movement, the effects are much easier to see in the video than they are in an annotated screenshot.
Want to use code from this post? Check out the license.