Add resistance to bottom handle drag
Feature summary
The role of a user interface is to understand what the user is trying to do, and to communicate back what it's understood, so the user can react accordingly.
When the user is trying to drag something into a possible state, the item should move in a 1:1 ratio, pinned to the user's pointer. In the case of the workspace switcher, 1:1 movement means "I know you are trying to get to the next workspace, and there's a workspace for you to get to."
In case there is no workspace in the direction the user is dragging, the workspace switcher should still move, but with resistance. This communicates to the user "hey, I hear that you're trying to drag to a new workspace, but there's nothing there to see."
How would you like it to work
Here's a formula for calculating resistance:
- Calculate how far the pointer is from a valid position. If the workspace is at x=0 and the user tries to drag to the right by 160 pixels, the overflow is
-160
. - Convert this number to a percentage, using the workspace's width as the denominator:
progress = overflow / basis;
If the screen is 1280dp wide,-160 / 1280 = -.125;
- Increase the resistance as the user drags farther into an invalid state with a sine function:
sin(progress * PI / 2);
As the user approaches maximum drag, the sine approaches1
. - Choose a factor to determine how far the UI should move at its maximum extent and multiply the computed resistance:
basis / factor * sin(progress * PI / 2)
Back to our example, if the factor is 5
(that is, the screen should move by 1/5 its width at maximum drag), resistance would be:
1280 / 5 * Math.sin(-160 / 1280 * Math.PI / 2) // = -49
When the user's finger has dragged 160dp out-of-bounds, the UI should move by -49dp to connote "I know you're trying to drag right, but it's not possible to drag right"
Relevant links, screenshots, screencasts etc.
I've given a whole talk on this, but I don't have a public video link handy.