Click to lock mouse, escape key to escape. That light blue square acts as an 'obstacle'. I was playing around with different behaviors, seeing which felt more satisfying, and this is the best I got to my own tastes without going to the trouble of actual line-box intersections and a setTimeout going on in the background smoothly and quickly pulling the viewport towards where it "wants" to go. Instead I have dumb special-case code, and jarring transitions when you clear the obstacle.
The broad alternative, of having the viewport "forget" that the mouse has tried to move into the obstacle, and just keep track of incremental mouse movement only, is certainly possible, but feels weirdly smushy to me. Maybe some hybrid between this and what I have is satisfying.
I'm not sure why I'm playing with this anyway, I don't have anything particular in mind that I want to build on top of this behavior. I think this kind of mouse-locked viewport-moving is something I came to relatively late in life though --- I never played any typical first-person mouse-and-WASD sort of games until Minecraft, so it still seems novel and interesting to me as a mechanism.