Cancel pointer velocity while pinching (#3462)

There was a bug that could occur if you pinched while using the hand
tool, where on pinch end the hand tool would slide the camera based on
the pinching velocity. The fix is to cancel out any velocity while
pinching.

### Change Type

- [x] `sdk` — Changes the tldraw SDK
- [x] `bugfix` — Bug fix

### Test Plan

On mobile...

1. Select the hand tool.
2. Begin a pinch
3. Stop the pinch
4. The camera should stay where it is

### Release Notes

- Fixed a bug that could occur while pinching with the hand tool
selected.
This commit is contained in:
Steve Ruiz 2024-04-14 14:22:26 +01:00 committed by GitHub
parent 1752977bf6
commit 8c6a9ff47e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 20 additions and 14 deletions

View file

@ -8168,11 +8168,16 @@ export class Editor extends EventEmitter<TLEventMap> {
private _updateInputsFromEvent(
info: TLPointerEventInfo | TLPinchEventInfo | TLWheelEventInfo
): void {
const { previousScreenPoint, previousPagePoint, currentScreenPoint, currentPagePoint } =
this.inputs
const {
pointerVelocity,
previousScreenPoint,
previousPagePoint,
currentScreenPoint,
currentPagePoint,
} = this.inputs
const { screenBounds } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!
const { x: cx, y: cy, z: cz } = this.getCamera()
const { x: cx, y: cy, z: cz } = this.store.unsafeGetWithoutCapture(this.getCameraId())!
const sx = info.point.x - screenBounds.x
const sy = info.point.y - screenBounds.y
@ -8190,9 +8195,9 @@ export class Editor extends EventEmitter<TLEventMap> {
this.inputs.isPen = info.type === 'pointer' && info.isPen
// Reset velocity on pointer down
if (info.name === 'pointer_down') {
this.inputs.pointerVelocity.set(0, 0)
// Reset velocity on pointer down, or when a pinch starts or ends
if (info.name === 'pointer_down' || this.inputs.isPinching) {
pointerVelocity.set(0, 0)
}
// todo: We only have to do this if there are multiple users in the document
@ -8200,14 +8205,15 @@ export class Editor extends EventEmitter<TLEventMap> {
{
id: TLPOINTER_ID,
typeName: 'pointer',
x: currentPagePoint.x,
y: currentPagePoint.y,
x: sx,
y: sy,
lastActivityTimestamp:
// If our pointer moved only because we're following some other user, then don't
// update our last activity timestamp; otherwise, update it to the current timestamp.
info.type === 'pointer' && info.pointerId === INTERNAL_POINTER_IDS.CAMERA_MOVE
? this.store.get(TLPOINTER_ID)?.lastActivityTimestamp ?? Date.now()
: Date.now(),
? this.store.unsafeGetWithoutCapture(TLPOINTER_ID)?.lastActivityTimestamp ??
this._tickManager.now
: this._tickManager.now,
meta: {},
},
])

View file

@ -20,13 +20,13 @@ export class TickManager {
cancelRaf?: null | (() => void)
isPaused = true
last = 0
now = 0
start = () => {
this.isPaused = false
this.cancelRaf?.()
this.cancelRaf = throttleToNextFrame(this.tick)
this.last = Date.now()
this.now = Date.now()
}
tick = () => {
@ -35,8 +35,8 @@ export class TickManager {
}
const now = Date.now()
const elapsed = now - this.last
this.last = now
const elapsed = now - this.now
this.now = now
this.updatePointerVelocity(elapsed)
this.editor.emit('frame', elapsed)