Fix new wobble (#1431)

This PR stops collaborator cursors wobbling while viewport-following. 
It's a **new wobble** that we haven't seen before! (It crept in at some
point)

It happens when these three things happen at the same time:
* You're following someone
* They're panning
* They're not moving their pointer

eg: This happens when they're trackpad-panning.

So this is *not* the **old wobble** that we fixed before! That one is
still fixed.

---

The **new wobble** looks like this:

![2023-05-22 at 12 08 51 - Magenta
Urial](https://github.com/tldraw/tldraw/assets/15892272/4b738766-cde3-4a9c-9169-76d622bec3bf)

It's sometimes hard-to-spot because of the _smoothing_ that we do.
When we drastically increase the strength of smoothing... the **new
wobble** is less noticeable:
![2023-05-22 at 12 12 40 - Rose
Goat](https://github.com/tldraw/tldraw/assets/15892272/4ece229a-60e8-4923-89f8-4a0f9b702491)

But we can do better!
So for demonstration purposes... let's turn off _smoothing_ to let us
see the **new wobble** more clearly.
![2023-05-22 at 12 16 02 - Gold
Macaw](https://github.com/tldraw/tldraw/assets/15892272/9030cf2a-bdf3-47f0-87f0-a1195ab2fcbf)

Now we can clearly see what's going on...

The cursor is updating every animation **frame**.
The camera is updating every **tick**.

Depending on your screen's refresh rate, these _might be different_!

Let's test that theory by throttling the **tick** further.
As expected, it increases the **new wobble**:
![2023-05-22 at 14 16 21 - Blush
Caterpillar](https://github.com/tldraw/tldraw/assets/15892272/c70ee08c-8fd3-40ae-a4b3-95637c08acc7)

Let's test the theory again by trying on a screen where the _tick_ and
_frame_ are in sync.
As expected, the **new wobble** doesn't happen _most of the time_.

However, _frame_ and _tick_ can still get out of sync! Which causes the
occasional wobble:

![2023-05-22 at 14 38 21 - Lime
Eagle](https://github.com/tldraw/tldraw/assets/15892272/2a9d8c98-194f-4b73-a7ea-ee85ac1fa28f)

So let's fix both cases...
Instead of making the following-camera update every _tick_...
Let's make it update every _frame_!

![2023-05-22 at 15 28 47 - Salmon
Smelt](https://github.com/tldraw/tldraw/assets/15892272/e9f5c10c-d421-4611-b049-7a961218c087)

The perceptive among you might notice a slight wobble that's still
there...
This is an entirely **different wobble** caused by different things.
We can get to it in the future! But we're back at our original
wobble-quota for now.

![2023-05-22 at 14 32 18 - Brown
Tern](https://github.com/tldraw/tldraw/assets/15892272/e1250715-0bf2-4b87-b6e7-a357bccf4106)

When we turn smoothing back on, things look better than before 👍 

![2023-05-22 at 14 42 48 - Cyan
Roundworm](https://github.com/tldraw/tldraw/assets/15892272/f3616c6f-7969-4a8d-80b1-26ee44e6f451)

### Change Type

- [x] `patch` — Bug Fix

### Test Plan

1. Open a single shared project in two different browser sessions.
2. Make one session's user follow the other.
3. Trackpad-pan the leader's camera around.
4. Check that the wobble has reduced.
This commit is contained in:
Lu Wilson 2023-05-23 01:04:07 -07:00 committed by GitHub
parent 53be923921
commit 3ce18c0c31
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 7 additions and 2 deletions

View file

@ -2030,6 +2030,8 @@ export interface TLEventMap {
// (undocumented)
event: [TLEventInfo];
// (undocumented)
frame: [number];
// (undocumented)
mount: [];
// (undocumented)
tick: [number];

View file

@ -8490,7 +8490,7 @@ export class App extends EventEmitter<TLEventMap> {
})
const cancel = () => {
this.removeListener('tick', moveTowardsUser)
this.removeListener('frame', moveTowardsUser)
this.removeListener('stop-following', cancel)
}
@ -8578,7 +8578,7 @@ export class App extends EventEmitter<TLEventMap> {
}
this.once('stop-following', cancel)
this.addListener('tick', moveTowardsUser)
this.addListener('frame', moveTowardsUser)
return this
}

View file

@ -29,6 +29,8 @@ export class TickManager {
this.last = now
this.t += elapsed
this.app.emit('frame', elapsed)
if (this.t < 16) {
this.raf = requestAnimationFrame(this.tick)
return

View file

@ -14,6 +14,7 @@ export interface TLEventMap {
'stop-following': []
event: [TLEventInfo]
tick: [number]
frame: [number]
'change-history': [{ reason: 'undo' | 'redo' | 'push' } | { reason: 'bail'; markId?: string }]
'mark-history': [{ id: string }]
}