fluid-lab / gamepad-navigator

GSoC 2020 project
Other
6 stars 10 forks source link

Focus should (optionally) follow scroll. #124

Open duhrer opened 7 months ago

duhrer commented 7 months ago

Currently, if you focus on an element and then scroll away, focus remains on the element. If you scroll down and then attempt to navigate, the view jumps up to the next focusable.

As described in #123, it should be possible to programatically change the "sequential focus starting point" as we scroll (for example, by focusing on whatever element is on the "leading" edge of our scroll direction). As our focus management is from the point of view of document.activeElement, we may need to use one of the approaches that makes it possible to focus on an element until it's blurred, so that the current element shows up in the list of "tabbables".

This should be a configurable feature, i.e. you should be able to turn it off as a general preference.

duhrer commented 6 months ago

With the work on #123, it could be possible to tag and focus on elements along the way, although I'm a bit concerned that:

  1. The effect would be "jumpy"
  2. We'd have to remove the focus magic from each element before working on the next one.

Another idea I had today was to keep track of the vertical and horizontal position of tabbables, and then to set the "current tab index" to something between two tabbables. So if we're scrolling somewhere between tabbable 1 and 2, the tab index might be 1.5, and we'd have logic to ensure that the previous item is 1, and the next is 2.

duhrer commented 5 months ago

So, to make this work at all we have to look at the position of focusable elements and decide where we should be focused based on their vertical and horizontal location. Vertical location is the most obvious deciding factor, if the centre of the viewport is between two elements, we can do something like set the focus index to the point between them.

When there are multiple elements at the same vertical position (such as two links on a line or a menu), we should use the horizontal position as well. If we're just below a menu, and just above a line with two links, our focus should lie between the right-most element of the menu and the left-most link.

If we're dead even with a line with multiple focusable elements, we want to make sure not to "jump" too far back or forward if the user switches to the bumpers. One way to do this would be to focus between two of the elements on the same line, ideally as close to the centre as possible.

duhrer commented 4 months ago

In working on #161, I was thinking about adding another overlay to reinforce the position onscreen (in that case, outlining the focused element).

That got me thinking about this issue. I had toyed with making a "bar" in the middle of the screen, items under the "bar" would be focused as we moved over them.

Today I realised that it should really be "leading edge", i.e. the "bar" is the edge that is moving into new territory. The "trailing" edge would have a gradient overlayed on it so that it's clear which direction we're heading in.

I also realised that this could be part of a larger "pointer manager" component that would be home to the scrolling indicators, the focus indicators, and the mouse pointer indicator.

The "pointer manager" and the "modal manager" would need to interoperate and each know to get out of the other's way, but should otherwise be separate just for ease of development and debugging.