kopia lustrzana https://github.com/Tldraw/Tldraw
lerp viewports, make page switches instant always
rodzic
2a01720c8d
commit
bfc3991091
|
@ -70,6 +70,7 @@ import {
|
||||||
getOwnProperty,
|
getOwnProperty,
|
||||||
hasOwnProperty,
|
hasOwnProperty,
|
||||||
last,
|
last,
|
||||||
|
lerp,
|
||||||
sortById,
|
sortById,
|
||||||
sortByIndex,
|
sortByIndex,
|
||||||
structuredClone,
|
structuredClone,
|
||||||
|
@ -3126,6 +3127,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
||||||
|
|
||||||
// Following
|
// Following
|
||||||
|
|
||||||
|
// When we are 'locked on' to a user, our camera is derived from their camera.
|
||||||
private _isLockedOnFollowingUser = atom('isLockedOnFollowingUser', false)
|
private _isLockedOnFollowingUser = atom('isLockedOnFollowingUser', false)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3158,6 +3160,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
||||||
|
|
||||||
if (!thisUserId) {
|
if (!thisUserId) {
|
||||||
console.warn('You should set the userId for the current instance before following a user')
|
console.warn('You should set the userId for the current instance before following a user')
|
||||||
|
// allow to continue since it's probably fine most of the time.
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the leader is following us, then we can't follow them
|
// If the leader is following us, then we can't follow them
|
||||||
|
@ -3172,7 +3175,8 @@ export class Editor extends EventEmitter<TLEventMap> {
|
||||||
transact(() => {
|
transact(() => {
|
||||||
this.updateInstanceState({ followingUserId: userId })
|
this.updateInstanceState({ followingUserId: userId })
|
||||||
|
|
||||||
const stopUpdatingPage = react('update current page', () => {
|
// we listen for page changes separately from the 'moveTowardsUser' tick
|
||||||
|
const dispose = react('update current page', () => {
|
||||||
const leaderPresence = latestLeaderPresence.get()
|
const leaderPresence = latestLeaderPresence.get()
|
||||||
if (!leaderPresence) {
|
if (!leaderPresence) {
|
||||||
this.stopFollowingUser()
|
this.stopFollowingUser()
|
||||||
|
@ -3182,17 +3186,19 @@ export class Editor extends EventEmitter<TLEventMap> {
|
||||||
leaderPresence.currentPageId !== this.getCurrentPageId() &&
|
leaderPresence.currentPageId !== this.getCurrentPageId() &&
|
||||||
this.getPage(leaderPresence.currentPageId)
|
this.getPage(leaderPresence.currentPageId)
|
||||||
) {
|
) {
|
||||||
|
// if the page changed, switch page
|
||||||
this.history.ignore(() => {
|
this.history.ignore(() => {
|
||||||
// sneaky store.put here, we can't go through setCurrentPage because it calls stopFollowingUser
|
// sneaky store.put here, we can't go through setCurrentPage because it calls stopFollowingUser
|
||||||
this.store.put([
|
this.store.put([
|
||||||
{ ...this.getInstanceState(), currentPageId: leaderPresence.currentPageId },
|
{ ...this.getInstanceState(), currentPageId: leaderPresence.currentPageId },
|
||||||
])
|
])
|
||||||
|
this._isLockedOnFollowingUser.set(true)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const cancel = () => {
|
const cancel = () => {
|
||||||
stopUpdatingPage()
|
dispose()
|
||||||
this._isLockedOnFollowingUser.set(false)
|
this._isLockedOnFollowingUser.set(false)
|
||||||
this.off('frame', moveTowardsUser)
|
this.off('frame', moveTowardsUser)
|
||||||
this.off('stop-following', cancel)
|
this.off('stop-following', cancel)
|
||||||
|
@ -3235,22 +3241,27 @@ export class Editor extends EventEmitter<TLEventMap> {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const midpointViewport = new Box(
|
// Chase the user's viewport!
|
||||||
(currentViewport.minX + targetViewport.minX) / 2,
|
// Interpolate between the current viewport and the target viewport based on animation speed.
|
||||||
(currentViewport.minY + targetViewport.minY) / 2,
|
// This will produce an 'ease-out' effect.
|
||||||
(currentViewport.width + targetViewport.width) / 2,
|
const t = clamp(animationSpeed * 0.5, 0.1, 0.8)
|
||||||
(currentViewport.height + targetViewport.height) / 2
|
|
||||||
|
const nextViewport = new Box(
|
||||||
|
lerp(currentViewport.minX, targetViewport.minX, t),
|
||||||
|
lerp(currentViewport.minY, targetViewport.minY, t),
|
||||||
|
lerp(currentViewport.width, targetViewport.width, t),
|
||||||
|
lerp(currentViewport.height, targetViewport.height, t)
|
||||||
)
|
)
|
||||||
|
|
||||||
const midpointCamera = new Vec(
|
const nextCamera = new Vec(
|
||||||
-midpointViewport.x,
|
-nextViewport.x,
|
||||||
-midpointViewport.y,
|
-nextViewport.y,
|
||||||
this.getViewportScreenBounds().width / midpointViewport.width
|
this.getViewportScreenBounds().width / nextViewport.width
|
||||||
)
|
)
|
||||||
|
|
||||||
// Update the camera!
|
// Update the camera!
|
||||||
this.stopCameraAnimation()
|
this.stopCameraAnimation()
|
||||||
this._setCamera(midpointCamera)
|
this._setCamera(nextCamera)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.once('stop-following', cancel)
|
this.once('stop-following', cancel)
|
||||||
|
|
Ładowanie…
Reference in New Issue