Repository navigation
6.99.40 — the pen's samples are taken once
Pre-releaseThe pen's samples are taken once.
What was wrong
Handwriting came out rough on a real server while the same iPad, the same
build and the same browser drew cleanly on an almost empty page. The
difference was in the captured data, not in the drawing.
getCoalescedEvents() reports the positions the digitizer gathered since the
last animation frame, not since the last move. Where one pointermove is
dispatched per frame the two are the same thing and the batches never overlap.
Where more than one is dispatched in a frame, each is handed the same batch —
and taking every batch whole put the stroke through the same run of samples
twice. The pen ran forward, jumped back and retraced itself, over and over.
The earlier filter could not see it. That one drops a sample identical to the
one immediately before it, which is the right shape for the Pencil reporting a
position twice in a row. Here a whole run of different positions arrives
twice: nothing in A B C D A B C D is an adjacent duplicate, so the entire
second copy went in.
Measured, in a drawing made on a working server
- 48.5% of 1709 samples were repeats of a point the stroke had already
visited. - 164 runs of four samples appeared twice over.
- One stroke jumped backwards 64 times, as far as 28.9 px.
The same iPad on a near-empty page: 0.5–2.0%, and no repeated runs at all.
Which is why this survived every test on the development harness and appeared
the first time the app met a real server and a real note.
The fix
A sample's own time is what tells the batches apart — positions repeat, a pen
held still reports the same place for as long as it is there, but the time a
reading was taken does not. The canvas remembers the newest time it has taken
and ignores anything not newer, so a batch handed over a second time costs
nothing.
It is applied only to a coalesced batch. A move carrying a single position is
left alone: a repeat of that is a repeat of a place, which the earlier filter
already drops, and the move's own timestamp is no use here because Safari
rounds it for privacy and two moves inside one millisecond share it.
Nothing about the file format changes, and nothing already drawn is altered —
the roughness in a drawing saved before this version is in its stored samples
and stays there.