Fix animation stale reference

This commit is contained in:
2026-07-21 16:03:28 +10:00
parent d2d82ae6ae
commit 9af84760fa
12 changed files with 225 additions and 38 deletions

View File

@@ -49,7 +49,16 @@ function entryFor(route: RouteLocationNormalizedLoaded, status: NativeViewEntry[
}
export function shouldCommitGesture(progress: number, velocity: number, threshold = 0.36) {
return progress >= threshold || (progress >= 0.08 && velocity >= 0.52)
return progress >= threshold || (progress >= 0.08 && velocity >= 1.1)
}
/**
* Converts release velocity (normalized route progress per second) into the
* rate at which the spring is simulated. A deliberate flick can settle up to
* three times faster while a stationary release keeps the baseline spring.
*/
export function springTimeScaleForVelocity(velocity: number) {
return 1 + Math.min(2, Math.abs(velocity) * 0.3)
}
export function definePresentation(definition: NativePresentationDefinition) {
@@ -555,17 +564,24 @@ class NativeRouterRuntimeImpl implements NativeRouterRuntime {
}
return new Promise<void>((resolve) => {
let position = transaction.progress
let velocity = Math.max(-2, Math.min(2, initialVelocity))
let velocity = Math.max(-12, Math.min(12, initialVelocity))
const timeScale = springTimeScaleForVelocity(initialVelocity)
let previous = now()
const step = (time: number) => {
const live = this.mutableTransaction.value
if (!live || live.id !== transaction.id) return resolve()
const dt = Math.min(0.032, Math.max(0.001, (time - previous) / 1000))
const elapsed = Math.min(0.032, Math.max(0.001, (time - previous) / 1000)) * timeScale
previous = time
const displacement = target - position
const acceleration = displacement * 280 - velocity * 30
velocity += acceleration * dt
position += velocity * dt
// Substeps keep the spring stable when a high-velocity flick advances
// several frames of simulated time in one display frame.
const iterations = Math.max(1, Math.ceil(elapsed / (1 / 120)))
const dt = elapsed / iterations
for (let iteration = 0; iteration < iterations; iteration += 1) {
const displacement = target - position
const acceleration = displacement * 280 - velocity * 30
velocity += acceleration * dt
position += velocity * dt
}
const done = Math.abs(target - position) < 0.002 && Math.abs(velocity) < 0.02
this.mutableTransaction.value = {
...live,