@n-uf/motion 26.11.3 → 26.11.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/values/easing.ts","../src/values/spring.ts","../src/values/tween.ts","../src/values/motion-value.ts"],"sourcesContent":["/** Maps progress in [0, 1] to eased progress (0 at 0, 1 at 1). */\nexport type Easing = (progress: number) => number;\n\n/** No easing. */\nexport const linear: Easing = (t) => t;\n\nconst EPSILON = 1e-7;\n\n/**\n * The CSS `cubic-bezier(x1, y1, x2, y2)` curve as a function, solved\n * numerically (Newton steps, then bisection). `x1` and `x2` must be in [0, 1].\n */\nexport function cubicBezier(x1: number, y1: number, x2: number, y2: number): Easing {\n if (!(x1 >= 0 && x1 <= 1 && x2 >= 0 && x2 <= 1)) {\n throw new RangeError(`cubicBezier: x1 and x2 must be in [0, 1], got ${x1} and ${x2}`);\n }\n if (x1 === y1 && x2 === y2) return linear;\n const cx = 3 * x1;\n const bx = 3 * (x2 - x1) - cx;\n const ax = 1 - cx - bx;\n const cy = 3 * y1;\n const by = 3 * (y2 - y1) - cy;\n const ay = 1 - cy - by;\n const sampleX = (t: number): number => ((ax * t + bx) * t + cx) * t;\n const sampleY = (t: number): number => ((ay * t + by) * t + cy) * t;\n const slopeX = (t: number): number => (3 * ax * t + 2 * bx) * t + cx;\n const solveX = (x: number): number => {\n let t = x;\n for (let i = 0; i < 8; i++) {\n const error = sampleX(t) - x;\n if (Math.abs(error) < EPSILON) return t;\n const slope = slopeX(t);\n if (Math.abs(slope) < 1e-6) break;\n t -= error / slope;\n }\n let low = 0;\n let high = 1;\n t = x;\n for (let i = 0; i < 40; i++) {\n const value = sampleX(t);\n if (Math.abs(value - x) < EPSILON) return t;\n if (x > value) low = t;\n else high = t;\n t = (low + high) / 2;\n }\n return t;\n };\n return (progress) => (progress <= 0 ? 0 : progress >= 1 ? 1 : sampleY(solveX(progress)));\n}\n\n/** CSS `ease`. */\nexport const ease: Easing = /* @__PURE__ */ cubicBezier(0.25, 0.1, 0.25, 1);\n/** CSS `ease-in`. */\nexport const easeIn: Easing = /* @__PURE__ */ cubicBezier(0.42, 0, 1, 1);\n/** CSS `ease-out`. */\nexport const easeOut: Easing = /* @__PURE__ */ cubicBezier(0, 0, 0.58, 1);\n/** CSS `ease-in-out`. */\nexport const easeInOut: Easing = /* @__PURE__ */ cubicBezier(0.42, 0, 0.58, 1);\n/** Cubic ease-out: fast start, gentle stop. The tween default. */\nexport const easeOutCubic: Easing = (t) => 1 - (1 - t) ** 3;\n/** Cubic ease-in-out. */\nexport const easeInOutCubic: Easing = (t) => (t < 0.5 ? 4 * t * t * t : 1 - (-2 * t + 2) ** 3 / 2);\n","import type { Animatable, Layout, Widen } from \"../shapes\";\nimport { layoutOf, makeValue, sameLayout, writeComponents } from \"../shapes\";\nimport type { Animator } from \"./animator\";\n\n/**\n * Spring settings. Time is in milliseconds everywhere in the API; the physics\n * runs in seconds, so velocity is in units per second.\n */\nexport interface SpringConfig {\n /** Spring constant k. Higher is snappier. Default 300. */\n readonly stiffness?: number;\n /** Damping coefficient c. When set it wins over `dampingRatio`. */\n readonly damping?: number;\n /**\n * Damping as a fraction of critical damping: 1 is critical (the fastest\n * approach with no overshoot), below 1 overshoots and rings, above 1 is\n * sluggish. Default 1.\n */\n readonly dampingRatio?: number;\n /** Mass m. Default 1. */\n readonly mass?: number;\n /** Distance from the target that counts as arrived. Default 0.1 (tuned for pixels). */\n readonly restDelta?: number;\n /** Speed, in units per second, that counts as stopped. Default 1 (tuned for pixels). */\n readonly restSpeed?: number;\n}\n\n/** A {@link SpringConfig} with every field resolved. */\nexport interface SpringParams {\n readonly stiffness: number;\n readonly damping: number;\n readonly dampingRatio: number;\n readonly mass: number;\n readonly restDelta: number;\n readonly restSpeed: number;\n}\n\n/** Defaults of {@link SpringConfig}: critically damped. */\nexport const SPRING_DEFAULTS: SpringParams = {\n stiffness: 300,\n damping: 2 * Math.sqrt(300),\n dampingRatio: 1,\n mass: 1,\n restDelta: 0.1,\n restSpeed: 1,\n};\n\nfunction positive(name: string, value: number): number {\n if (!(value > 0) || !Number.isFinite(value)) throw new RangeError(`spring: ${name} must be a finite number > 0, got ${value}`);\n return value;\n}\n\n/** Resolve a {@link SpringConfig} over the defaults. Throws on a non-positive field. */\nexport function resolveSpring(config: SpringConfig = {}): SpringParams {\n const stiffness = positive(\"stiffness\", config.stiffness ?? SPRING_DEFAULTS.stiffness);\n const mass = positive(\"mass\", config.mass ?? SPRING_DEFAULTS.mass);\n const critical = 2 * Math.sqrt(stiffness * mass);\n const damping = positive(\n config.damping !== undefined ? \"damping\" : \"dampingRatio\",\n config.damping ?? (config.dampingRatio ?? SPRING_DEFAULTS.dampingRatio) * critical,\n );\n return {\n stiffness,\n damping,\n dampingRatio: damping / critical,\n mass,\n restDelta: positive(\"restDelta\", config.restDelta ?? SPRING_DEFAULTS.restDelta),\n restSpeed: positive(\"restSpeed\", config.restSpeed ?? SPRING_DEFAULTS.restSpeed),\n };\n}\n\nconst UNDERDAMPED = 0;\nconst CRITICAL = 1;\nconst OVERDAMPED = 2;\n\n/** The closed-form solution's constants for one set of params. */\ninterface Solver {\n readonly mode: typeof UNDERDAMPED | typeof CRITICAL | typeof OVERDAMPED;\n readonly omega: number;\n readonly decay: number;\n readonly omegaD: number;\n readonly r1: number;\n readonly r2: number;\n}\n\nfunction solverFor(params: SpringParams): Solver {\n const omega = Math.sqrt(params.stiffness / params.mass);\n const zeta = params.dampingRatio;\n if (Math.abs(zeta - 1) < 1e-6) return { mode: CRITICAL, omega, decay: omega, omegaD: 0, r1: 0, r2: 0 };\n if (zeta < 1) {\n return { mode: UNDERDAMPED, omega, decay: zeta * omega, omegaD: omega * Math.sqrt(1 - zeta * zeta), r1: 0, r2: 0 };\n }\n const root = Math.sqrt(zeta * zeta - 1);\n return { mode: OVERDAMPED, omega, decay: 0, omegaD: 0, r1: -omega * (zeta - root), r2: -omega * (zeta + root) };\n}\n\n/**\n * Advance one component exactly: displacement `d0` from the target and\n * velocity `v0` (per second) after `t` seconds. Writes into out[0], out[1].\n * Exact for any `t`, so the curve doesn't depend on the frame rate.\n */\nfunction advance(solver: Solver, d0: number, v0: number, t: number, out: Float64Array): void {\n if (solver.mode === CRITICAL) {\n const w = solver.omega;\n const e = Math.exp(-w * t);\n const b = v0 + w * d0;\n out[0] = e * (d0 + b * t);\n out[1] = e * (v0 - w * b * t);\n } else if (solver.mode === UNDERDAMPED) {\n const a = solver.decay;\n const wd = solver.omegaD;\n const e = Math.exp(-a * t);\n const cos = Math.cos(wd * t);\n const sin = Math.sin(wd * t);\n out[0] = e * (d0 * cos + ((v0 + a * d0) / wd) * sin);\n out[1] = e * (v0 * cos - ((a * v0 + solver.omega * solver.omega * d0) / wd) * sin);\n } else {\n const { r1, r2 } = solver;\n const c2 = (v0 - r1 * d0) / (r2 - r1);\n const c1 = d0 - c2;\n const e1 = Math.exp(r1 * t);\n const e2 = Math.exp(r2 * t);\n out[0] = c1 * e1 + c2 * e2;\n out[1] = c1 * r1 * e1 + c2 * r2 * e2;\n }\n}\n\n/** A scalar spring's position and velocity (units per second). */\nexport interface SpringState {\n readonly value: number;\n readonly velocity: number;\n}\n\n/**\n * One pure spring step for a scalar: where `state` is after `dtMs` heading for\n * `target`. Doesn't settle or snap; {@link createSpring} does that.\n */\nexport function springStep(state: SpringState, target: number, params: SpringParams, dtMs: number): SpringState {\n const out = new Float64Array(2);\n advance(solverFor(params), state.value - target, state.velocity, dtMs / 1000, out);\n return { value: target + out[0]!, velocity: out[1]! };\n}\n\n/** A spring over any {@link Animatable} shape, stepped by hand or by `motionValue`. */\nexport interface Spring<T> extends Animator<T> {\n /** The resolved settings. */\n readonly params: SpringParams;\n /** Set the velocity in units per second (a gesture's release velocity). */\n setVelocity(velocity: T): void;\n /** Change settings mid-flight; position and velocity carry on. */\n configure(config: SpringConfig): void;\n}\n\nclass SpringAnimator implements Spring<Animatable> {\n readonly layout: Layout;\n readonly x: Float64Array;\n readonly v: Float64Array;\n readonly goal: Float64Array;\n readonly scratch = new Float64Array(2);\n config: SpringConfig;\n params: SpringParams;\n solver: Solver;\n settled = true;\n cachedValue: Animatable | null = null;\n\n constructor(initial: Animatable, config: SpringConfig) {\n this.layout = layoutOf(initial);\n const size = this.layout.size;\n this.x = new Float64Array(size);\n this.v = new Float64Array(size);\n this.goal = new Float64Array(size);\n writeComponents(initial, this.x);\n writeComponents(initial, this.goal);\n this.config = config;\n this.params = resolveSpring(config);\n this.solver = solverFor(this.params);\n }\n\n get value(): Animatable {\n if (this.cachedValue === null) this.cachedValue = makeValue(this.layout, this.x);\n return this.cachedValue;\n }\n\n get velocity(): Animatable {\n return makeValue(this.layout, this.v);\n }\n\n get target(): Animatable {\n return makeValue(this.layout, this.goal);\n }\n\n check(value: Animatable, what: string): void {\n if (!sameLayout(layoutOf(value), this.layout)) {\n throw new TypeError(`spring: ${what} has a different shape than the spring's value`);\n }\n }\n\n /** At rest exactly when on the target and not moving. */\n updateSettled(): void {\n for (let i = 0; i < this.x.length; i++) {\n if (this.x[i] !== this.goal[i] || this.v[i] !== 0) {\n this.settled = false;\n return;\n }\n }\n this.settled = true;\n }\n\n setTarget(target: Animatable): void {\n this.check(target, \"the target\");\n writeComponents(target, this.goal);\n // Position and velocity stay as they are: a retarget carries the motion on.\n this.updateSettled();\n }\n\n setVelocity(velocity: Animatable): void {\n this.check(velocity, \"the velocity\");\n writeComponents(velocity, this.v);\n this.updateSettled();\n }\n\n jumpTo(value: Animatable): void {\n this.check(value, \"the value\");\n writeComponents(value, this.x);\n writeComponents(value, this.goal);\n this.v.fill(0);\n this.cachedValue = null;\n this.settled = true;\n }\n\n snap(): void {\n this.x.set(this.goal);\n this.v.fill(0);\n this.cachedValue = null;\n this.settled = true;\n }\n\n configure(config: SpringConfig): void {\n this.config = { ...this.config, ...config };\n this.params = resolveSpring(this.config);\n this.solver = solverFor(this.params);\n }\n\n step(dtMs: number): boolean {\n if (this.settled) return false;\n if (!(dtMs > 0)) return true;\n const t = dtMs / 1000;\n const { x, v, goal, scratch } = this;\n const { restDelta, restSpeed } = this.params;\n let resting = true;\n for (let i = 0; i < x.length; i++) {\n advance(this.solver, x[i]! - goal[i]!, v[i]!, t, scratch);\n x[i] = goal[i]! + scratch[0]!;\n v[i] = scratch[1]!;\n if (resting && (Math.abs(scratch[0]!) > restDelta || Math.abs(scratch[1]!) > restSpeed)) resting = false;\n }\n this.cachedValue = null;\n if (resting) this.snap();\n return !this.settled;\n }\n}\n\n/**\n * A spring starting at rest on `initial`. `initial` fixes the shape: a\n * number, a vector (array), a point `{ x, y }` or a rect `{ x, y, width,\n * height }`; targets and velocities must have the same shape.\n */\nexport function createSpring<T extends Animatable>(initial: T, config: SpringConfig = {}): Spring<Widen<T>> {\n return new SpringAnimator(initial, config) as unknown as Spring<Widen<T>>;\n}\n","import type { Animatable, Layout, Widen } from \"../shapes\";\nimport { layoutOf, makeValue, sameLayout, writeComponents } from \"../shapes\";\nimport type { Animator } from \"./animator\";\nimport { easeOutCubic, type Easing } from \"./easing\";\n\n/** Tween settings. */\nexport interface TweenConfig {\n /** Length of a run in ms. Default 250. 0 jumps to the target on the next step. */\n readonly duration?: number;\n /** Easing of the run. Default {@link easeOutCubic}. */\n readonly easing?: Easing;\n}\n\n/** A tween over any {@link Animatable} shape. */\nexport interface Tween<T> extends Animator<T> {\n /** Run progress in [0, 1]. */\n readonly progress: number;\n /** Change duration or easing; applies from the next target. */\n configure(config: TweenConfig): void;\n}\n\nclass TweenAnimator implements Tween<Animatable> {\n readonly layout: Layout;\n readonly x: Float64Array;\n readonly from: Float64Array;\n readonly goal: Float64Array;\n duration: number;\n easing: Easing;\n elapsed = 0;\n settled = true;\n cachedValue: Animatable | null = null;\n\n constructor(initial: Animatable, config: TweenConfig) {\n this.layout = layoutOf(initial);\n const size = this.layout.size;\n this.x = new Float64Array(size);\n this.from = new Float64Array(size);\n this.goal = new Float64Array(size);\n writeComponents(initial, this.x);\n writeComponents(initial, this.from);\n writeComponents(initial, this.goal);\n this.duration = 250;\n this.easing = easeOutCubic;\n this.configure(config);\n }\n\n get value(): Animatable {\n if (this.cachedValue === null) this.cachedValue = makeValue(this.layout, this.x);\n return this.cachedValue;\n }\n\n get target(): Animatable {\n return makeValue(this.layout, this.goal);\n }\n\n get progress(): number {\n if (this.settled) return 1;\n return this.duration <= 0 ? 0 : Math.min(1, this.elapsed / this.duration);\n }\n\n /** The eased curve's slope at the current progress, as units per second. */\n get velocity(): Animatable {\n const out = new Float64Array(this.layout.size);\n if (!this.settled && this.duration > 0) {\n const p = this.progress;\n const h = 1e-3;\n const lo = Math.max(0, p - h);\n const hi = Math.min(1, p + h);\n const slope = (this.easing(hi) - this.easing(lo)) / (hi - lo);\n const perSecond = (slope / this.duration) * 1000;\n for (let i = 0; i < out.length; i++) out[i] = (this.goal[i]! - this.from[i]!) * perSecond;\n }\n return makeValue(this.layout, out);\n }\n\n configure(config: TweenConfig): void {\n if (config.duration !== undefined) {\n if (!(config.duration >= 0) || !Number.isFinite(config.duration)) {\n throw new RangeError(`tween: duration must be a finite number >= 0, got ${config.duration}`);\n }\n this.duration = config.duration;\n }\n if (config.easing !== undefined) this.easing = config.easing;\n }\n\n check(value: Animatable, what: string): void {\n if (!sameLayout(layoutOf(value), this.layout)) {\n throw new TypeError(`tween: ${what} has a different shape than the tween's value`);\n }\n }\n\n setTarget(target: Animatable): void {\n this.check(target, \"the target\");\n writeComponents(target, this.goal);\n // A new run starts from wherever the value is now (no jump).\n this.from.set(this.x);\n this.elapsed = 0;\n this.settled = true;\n for (let i = 0; i < this.x.length; i++) {\n if (this.x[i] !== this.goal[i]) {\n this.settled = false;\n break;\n }\n }\n }\n\n jumpTo(value: Animatable): void {\n this.check(value, \"the value\");\n writeComponents(value, this.x);\n writeComponents(value, this.from);\n writeComponents(value, this.goal);\n this.cachedValue = null;\n this.settled = true;\n }\n\n snap(): void {\n this.x.set(this.goal);\n this.from.set(this.goal);\n this.cachedValue = null;\n this.settled = true;\n }\n\n step(dtMs: number): boolean {\n if (this.settled) return false;\n this.elapsed += Math.max(0, dtMs);\n const p = this.duration <= 0 ? 1 : Math.min(1, this.elapsed / this.duration);\n if (p >= 1) {\n this.snap();\n return false;\n }\n const eased = this.easing(p);\n for (let i = 0; i < this.x.length; i++) {\n this.x[i] = this.from[i]! + (this.goal[i]! - this.from[i]!) * eased;\n }\n this.cachedValue = null;\n return true;\n }\n}\n\n/**\n * A tween starting at rest on `initial` (same shapes as `createSpring`).\n * Velocity doesn't carry over a retarget: a new target starts a new run from\n * the current value. Use a spring where motion must stay continuous.\n */\nexport function createTween<T extends Animatable>(initial: T, config: TweenConfig = {}): Tween<Widen<T>> {\n return new TweenAnimator(initial, config) as unknown as Tween<Widen<T>>;\n}\n","import type { FrameInfo, FrameLoop, Phase } from \"../clock/frame-loop\";\nimport type { Animatable, Widen } from \"../shapes\";\nimport { shapeEquals } from \"../shapes\";\nimport { batch, effect, signal, untracked, type ReadonlySignal, type Signal } from \"../signals/signals\";\nimport type { Animator } from \"./animator\";\nimport { createSettle, type Settle, type SettleConfig } from \"./settle\";\nimport { createSpring, type Spring, type SpringConfig } from \"./spring\";\nimport { createTween, type Tween, type TweenConfig } from \"./tween\";\n\n/** Options of {@link motionValue}. */\nexport interface MotionOptions {\n /**\n * The frame phase that steps the value. Default `\"layout\"`: it steps after\n * that phase's one-shot tasks, so a target set in input, update or layout\n * moves the value in the same frame, and `write` sees the new value.\n */\n readonly phase?: Phase;\n /**\n * The reduced-motion switch: while it is (or returns) `true`, every new\n * target is reached at once, and a value in flight snaps on its next frame.\n * A function is read on each `set` and each frame, so it can read a signal\n * or a media query.\n */\n readonly reducedMotion?: boolean | (() => boolean);\n}\n\n/** Options of {@link MotionValue.set}. */\nexport interface SetOptions<T> {\n /** Start with this velocity (units per second), e.g. a gesture's release velocity. Springs and settles (a settle caps it toward the target); tweens ignore it. */\n readonly velocity?: T;\n}\n\n/**\n * An animated value on a frame loop. Reading `value` inside a computed or an\n * effect tracks it; it changes once per frame while moving and the loop goes\n * idle when it settles.\n */\nexport interface MotionValue<T, A extends Animator<unknown> = Animator<T>> extends ReadonlySignal<T> {\n /** Where the value is heading. */\n readonly target: T;\n /** The current velocity, units per second. */\n readonly velocity: T;\n /** Whether it is moving (reactive). */\n readonly moving: boolean;\n /** The spring, settle or tween underneath. Change it through this value (`jump`, not the animator's `hold`), so the signal and the loop follow. */\n readonly animator: A;\n /** Head for `target`; a spring keeps its velocity, a settle launches from where it is drawn, a tween restarts. */\n set(target: T, options?: SetOptions<T>): void;\n /** Put the value at `value` at once, at rest. */\n jump(value: T): void;\n /** Finish now: put the value on its target, at rest. */\n snap(): void;\n /**\n * Keep heading for whatever `source` returns. `source` is tracked like an\n * effect, and re-read in this value's phase at most once per frame. Returns\n * a stop function.\n */\n follow(source: () => T): () => void;\n /**\n * Call `listener` each time the value comes to rest: on the frame it\n * settles, or at once when `set` (under reduced motion), `snap` or `jump`\n * leaves it at rest. Returns an unsubscribe function.\n */\n onSettle(listener: (value: T) => void): () => void;\n /** Stop stepping, drop listeners and follows. */\n dispose(): void;\n}\n\nclass Motion<T> implements MotionValue<T> {\n readonly loop: FrameLoop;\n readonly animator: Animator<T>;\n readonly phase: Phase;\n readonly reduced: () => boolean;\n readonly current: Signal<T>;\n readonly movingSignal: Signal<boolean>;\n readonly listeners = new Set<(value: T) => void>();\n readonly follows = new Set<() => void>();\n stop: (() => void) | null = null;\n disposed = false;\n\n constructor(loop: FrameLoop, animator: Animator<T>, options: MotionOptions) {\n this.loop = loop;\n this.animator = animator;\n this.phase = options.phase ?? \"layout\";\n const reducedMotion = options.reducedMotion ?? false;\n this.reduced = typeof reducedMotion === \"function\" ? reducedMotion : () => reducedMotion;\n this.current = signal(animator.value, {\n equals: shapeEquals as (a: T, b: T) => boolean,\n });\n this.movingSignal = signal(false);\n if (!animator.settled) this.start();\n }\n\n get value(): T {\n return this.current.value;\n }\n\n peek(): T {\n return this.current.peek();\n }\n\n get target(): T {\n return this.animator.target;\n }\n\n get velocity(): T {\n return this.animator.velocity;\n }\n\n get moving(): boolean {\n return this.movingSignal.value;\n }\n\n readonly tick = (frame: FrameInfo): boolean => {\n if (this.reduced()) this.animator.snap();\n else this.animator.step(frame.delta);\n if (!this.animator.settled) {\n this.current.value = this.animator.value;\n return true;\n }\n this.stop = null;\n this.rest();\n return false;\n };\n\n start(): void {\n if (this.stop !== null || this.disposed) return;\n this.stop = this.loop.repeat(this.phase, this.tick);\n this.movingSignal.value = true;\n }\n\n halt(): void {\n if (this.stop === null) return;\n this.stop();\n this.stop = null;\n }\n\n /** Publish the resting value and tell the listeners. */\n rest(): void {\n batch(() => {\n this.current.value = this.animator.value;\n this.movingSignal.value = false;\n });\n const value = this.animator.value;\n for (const listener of Array.from(this.listeners)) listener(value);\n }\n\n set(target: T, options?: SetOptions<T>): void {\n if (this.disposed) return;\n untracked(() => {\n this.animator.setTarget(target);\n if (options?.velocity !== undefined) this.animator.setVelocity?.(options.velocity);\n if (this.reduced()) this.animator.snap();\n if (this.animator.settled) {\n this.halt();\n this.rest();\n } else {\n this.start();\n }\n });\n }\n\n jump(value: T): void {\n if (this.disposed) return;\n untracked(() => {\n this.animator.jumpTo(value);\n this.halt();\n this.rest();\n });\n }\n\n snap(): void {\n if (this.disposed) return;\n untracked(() => {\n this.animator.snap();\n this.halt();\n this.rest();\n });\n }\n\n follow(source: () => T): () => void {\n if (this.disposed) return () => {};\n const dispose = effect(\n () => {\n const target = source();\n this.set(target);\n },\n { schedule: this.loop.scheduler(this.phase) },\n );\n const stop = (): void => {\n dispose();\n this.follows.delete(stop);\n };\n this.follows.add(stop);\n return stop;\n }\n\n onSettle(listener: (value: T) => void): () => void {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n dispose(): void {\n if (this.disposed) return;\n this.disposed = true;\n this.halt();\n for (const stop of Array.from(this.follows)) stop();\n this.listeners.clear();\n this.movingSignal.value = false;\n }\n}\n\n/** The value type an animator moves. */\nexport type AnimatorValue<A> = A extends Animator<infer T> ? T : never;\n\n/** Step `animator` on `loop` while it moves, and expose it as a signal. */\nexport function motionValue<A extends Animator<unknown>>(\n loop: FrameLoop,\n animator: A,\n options: MotionOptions = {},\n): MotionValue<AnimatorValue<A>, A> {\n return new Motion(loop, animator, options) as unknown as MotionValue<AnimatorValue<A>, A>;\n}\n\n/** A spring-driven {@link MotionValue}: `createSpring` plus `motionValue`. */\nexport function springValue<T extends Animatable>(\n loop: FrameLoop,\n initial: T,\n options: SpringConfig & MotionOptions = {},\n): MotionValue<Widen<T>, Spring<Widen<T>>> {\n return motionValue(loop, createSpring(initial, options), options) as MotionValue<Widen<T>, Spring<Widen<T>>>;\n}\n\n/**\n * A settle-driven {@link MotionValue}: `createSettle` plus `motionValue`. The\n * one curve for things moving to a new place (see {@link Settle}). To hold it\n * to a pointer, `jump` it on each move; the next `set` launches from there.\n */\nexport function settleValue<T extends Animatable>(\n loop: FrameLoop,\n initial: T,\n options: SettleConfig & MotionOptions = {},\n): MotionValue<Widen<T>, Settle<Widen<T>>> {\n return motionValue(loop, createSettle(initial, options), options) as MotionValue<Widen<T>, Settle<Widen<T>>>;\n}\n\n/** A tween-driven {@link MotionValue}: `createTween` plus `motionValue`. */\nexport function tweenValue<T extends Animatable>(\n loop: FrameLoop,\n initial: T,\n options: TweenConfig & MotionOptions = {},\n): MotionValue<Widen<T>, Tween<Widen<T>>> {\n return motionValue(loop, createTween(initial, options), options) as MotionValue<Widen<T>, Tween<Widen<T>>>;\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,212 @@
1
+ // src/shapes.ts
2
+ var SCALAR = 0;
3
+ var VECTOR = 1;
4
+ var POINT = 2;
5
+ var RECT = 3;
6
+ var SCALAR_LAYOUT = { kind: SCALAR, size: 1 };
7
+ var POINT_LAYOUT = { kind: POINT, size: 2 };
8
+ var RECT_LAYOUT = { kind: RECT, size: 4 };
9
+ function layoutOf(value) {
10
+ if (typeof value === "number") return SCALAR_LAYOUT;
11
+ if (Array.isArray(value)) return { kind: VECTOR, size: value.length };
12
+ if ("width" in value) return RECT_LAYOUT;
13
+ return POINT_LAYOUT;
14
+ }
15
+ function sameLayout(a, b) {
16
+ return a.kind === b.kind && a.size === b.size;
17
+ }
18
+ function writeComponents(value, out) {
19
+ if (typeof value === "number") {
20
+ out[0] = value;
21
+ } else if (Array.isArray(value)) {
22
+ for (let i = 0; i < value.length; i++) out[i] = value[i];
23
+ } else if ("width" in value) {
24
+ out[0] = value.x;
25
+ out[1] = value.y;
26
+ out[2] = value.width;
27
+ out[3] = value.height;
28
+ } else {
29
+ const point = value;
30
+ out[0] = point.x;
31
+ out[1] = point.y;
32
+ }
33
+ }
34
+ function makeValue(layout, components) {
35
+ switch (layout.kind) {
36
+ case SCALAR:
37
+ return components[0];
38
+ case POINT:
39
+ return { x: components[0], y: components[1] };
40
+ case RECT:
41
+ return { x: components[0], y: components[1], width: components[2], height: components[3] };
42
+ default:
43
+ return Array.from(components);
44
+ }
45
+ }
46
+ function shapeEquals(a, b) {
47
+ if (typeof a === "number" || typeof b === "number") return a === b;
48
+ if (Array.isArray(a) || Array.isArray(b)) {
49
+ const u = a;
50
+ const v = b;
51
+ if (u.length !== v.length) return false;
52
+ for (let i = 0; i < u.length; i++) if (u[i] !== v[i]) return false;
53
+ return true;
54
+ }
55
+ const p = a;
56
+ const q = b;
57
+ return p.x === q.x && p.y === q.y && p.width === q.width && p.height === q.height;
58
+ }
59
+
60
+ // src/values/settle.ts
61
+ var SETTLE_TEMPO = { calm: 20, default: 25, quick: 37 };
62
+ var SETTLE_DEFAULTS = { omega: SETTLE_TEMPO.default, restDelta: 0.1 };
63
+ function positive(name, value) {
64
+ if (!(value > 0) || !Number.isFinite(value)) throw new RangeError(`settle: ${name} must be a finite number > 0, got ${value}`);
65
+ return value;
66
+ }
67
+ var SettleAnimator = class {
68
+ layout;
69
+ x;
70
+ v;
71
+ goal;
72
+ omega;
73
+ restDelta;
74
+ settled = true;
75
+ cachedValue = null;
76
+ constructor(initial, config) {
77
+ this.layout = layoutOf(initial);
78
+ this.x = new Float64Array(this.layout.size);
79
+ this.v = new Float64Array(this.layout.size);
80
+ this.goal = new Float64Array(this.layout.size);
81
+ writeComponents(initial, this.x);
82
+ writeComponents(initial, this.goal);
83
+ this.omega = positive("omega", config.omega ?? SETTLE_DEFAULTS.omega);
84
+ this.restDelta = positive("restDelta", config.restDelta ?? SETTLE_DEFAULTS.restDelta);
85
+ }
86
+ get value() {
87
+ if (this.cachedValue === null) this.cachedValue = makeValue(this.layout, this.x);
88
+ return this.cachedValue;
89
+ }
90
+ get velocity() {
91
+ return makeValue(this.layout, this.v);
92
+ }
93
+ get target() {
94
+ return makeValue(this.layout, this.goal);
95
+ }
96
+ check(value, what) {
97
+ if (!sameLayout(layoutOf(value), this.layout)) {
98
+ throw new TypeError(`settle: ${what} has a different shape than the settle's value`);
99
+ }
100
+ }
101
+ /** The launch/clamp/carry rule on component `i`: `launch` for a new target, else clamp or carry. */
102
+ rule(i, launch) {
103
+ const d = this.x[i] - this.goal[i];
104
+ const v = this.v[i];
105
+ const limit = d === 0 ? 0 : -this.omega * d;
106
+ if (launch) {
107
+ this.v[i] = limit;
108
+ return;
109
+ }
110
+ if (d === 0) return;
111
+ if (d * v > 0) return;
112
+ if (Math.abs(v) > Math.abs(limit)) this.v[i] = limit;
113
+ }
114
+ updateSettled() {
115
+ for (let i = 0; i < this.x.length; i++) {
116
+ if (this.x[i] !== this.goal[i] || this.v[i] !== 0) {
117
+ this.settled = false;
118
+ return;
119
+ }
120
+ }
121
+ this.settled = true;
122
+ }
123
+ setTarget(target) {
124
+ this.check(target, "the target");
125
+ writeComponents(target, this.goal);
126
+ for (let i = 0; i < this.x.length; i++) this.rule(i, true);
127
+ this.updateSettled();
128
+ }
129
+ setVelocity(velocity) {
130
+ this.check(velocity, "the velocity");
131
+ writeComponents(velocity, this.v);
132
+ for (let i = 0; i < this.x.length; i++) this.rule(i, false);
133
+ this.updateSettled();
134
+ }
135
+ jumpTo(value) {
136
+ this.check(value, "the value");
137
+ writeComponents(value, this.x);
138
+ writeComponents(value, this.goal);
139
+ this.v.fill(0);
140
+ this.cachedValue = null;
141
+ this.settled = true;
142
+ }
143
+ hold(value) {
144
+ this.jumpTo(value);
145
+ }
146
+ snap() {
147
+ this.x.set(this.goal);
148
+ this.v.fill(0);
149
+ this.cachedValue = null;
150
+ this.settled = true;
151
+ }
152
+ configure(config) {
153
+ if (config.omega !== void 0) this.omega = positive("omega", config.omega);
154
+ if (config.restDelta !== void 0) this.restDelta = positive("restDelta", config.restDelta);
155
+ for (let i = 0; i < this.x.length; i++) this.rule(i, false);
156
+ }
157
+ step(dtMs) {
158
+ if (this.settled) return false;
159
+ if (!(dtMs > 0)) return true;
160
+ const w = this.omega;
161
+ const t = dtMs / 1e3;
162
+ const e = Math.exp(-w * t);
163
+ const { x, v, goal, restDelta } = this;
164
+ const restSpeed = w * restDelta * 1.000001;
165
+ let resting = true;
166
+ for (let i = 0; i < x.length; i++) {
167
+ const d = x[i] - goal[i];
168
+ const b = v[i] + w * d;
169
+ const nd = e * (d + b * t);
170
+ v[i] = e * (v[i] - w * b * t);
171
+ x[i] = goal[i] + nd;
172
+ const near = Math.max(restDelta, 4 * Number.EPSILON * Math.abs(goal[i]));
173
+ if (resting && (Math.abs(nd) > near || Math.abs(v[i]) > Math.max(restSpeed, w * near))) resting = false;
174
+ }
175
+ this.cachedValue = null;
176
+ if (resting) this.snap();
177
+ return !this.settled;
178
+ }
179
+ };
180
+ function createSettle(initial, config = {}) {
181
+ return new SettleAnimator(initial, config);
182
+ }
183
+
184
+ // src/values/reveal.ts
185
+ function reveal(drawn, target) {
186
+ return {
187
+ dx: drawn.x - target.x,
188
+ dy: drawn.y - target.y,
189
+ width: Math.max(0, drawn.width),
190
+ height: Math.max(0, drawn.height),
191
+ clipRight: Math.max(0, target.width - drawn.width),
192
+ clipBottom: Math.max(0, target.height - drawn.height)
193
+ };
194
+ }
195
+ function popIn(progress, from = 0.87) {
196
+ const p = Math.min(1, Math.max(0, progress));
197
+ return { scale: from + (1 - from) * p, opacity: p };
198
+ }
199
+
200
+ export {
201
+ layoutOf,
202
+ sameLayout,
203
+ writeComponents,
204
+ makeValue,
205
+ shapeEquals,
206
+ SETTLE_TEMPO,
207
+ SETTLE_DEFAULTS,
208
+ createSettle,
209
+ reveal,
210
+ popIn
211
+ };
212
+ //# sourceMappingURL=chunk-WQQ2E25M.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/shapes.ts","../src/values/settle.ts","../src/values/reveal.ts"],"sourcesContent":["/** A point or a 2D vector. */\nexport interface Point {\n x: number;\n y: number;\n}\n\n/** An axis-aligned rectangle. */\nexport interface Rect {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n/** Any number of components. */\nexport type Vector = readonly number[];\n\n/** The value shapes springs and tweens move: plain numbers, nothing else. */\nexport type Animatable = number | Point | Rect | Vector;\n\n/** The shape type of an {@link Animatable}: literal numbers widen to `number`. */\nexport type Widen<T> = T extends number\n ? number\n : T extends Vector\n ? Vector\n : T extends Rect\n ? Rect\n : T extends Point\n ? Point\n : never;\n\nconst SCALAR = 0;\nconst VECTOR = 1;\nconst POINT = 2;\nconst RECT = 3;\n\n/** How a shape maps onto a flat list of numbers. Internal to values/. */\nexport interface Layout {\n readonly kind: typeof SCALAR | typeof VECTOR | typeof POINT | typeof RECT;\n readonly size: number;\n}\n\nconst SCALAR_LAYOUT: Layout = { kind: SCALAR, size: 1 };\nconst POINT_LAYOUT: Layout = { kind: POINT, size: 2 };\nconst RECT_LAYOUT: Layout = { kind: RECT, size: 4 };\n\nexport function layoutOf(value: Animatable): Layout {\n if (typeof value === \"number\") return SCALAR_LAYOUT;\n if (Array.isArray(value)) return { kind: VECTOR, size: value.length };\n if (\"width\" in value) return RECT_LAYOUT;\n return POINT_LAYOUT;\n}\n\nexport function sameLayout(a: Layout, b: Layout): boolean {\n return a.kind === b.kind && a.size === b.size;\n}\n\n/** Copy `value`'s components into `out`. */\nexport function writeComponents(value: Animatable, out: Float64Array): void {\n if (typeof value === \"number\") {\n out[0] = value;\n } else if (Array.isArray(value)) {\n for (let i = 0; i < value.length; i++) out[i] = value[i]!;\n } else if (\"width\" in value) {\n out[0] = value.x;\n out[1] = value.y;\n out[2] = value.width;\n out[3] = value.height;\n } else {\n const point = value as Point;\n out[0] = point.x;\n out[1] = point.y;\n }\n}\n\n/** A fresh value of `layout`'s shape from `components`. */\nexport function makeValue(layout: Layout, components: Float64Array): Animatable {\n switch (layout.kind) {\n case SCALAR:\n return components[0]!;\n case POINT:\n return { x: components[0]!, y: components[1]! };\n case RECT:\n return { x: components[0]!, y: components[1]!, width: components[2]!, height: components[3]! };\n default:\n return Array.from(components);\n }\n}\n\n/** Component-wise equality of two values of the same shape. */\nexport function shapeEquals(a: Animatable, b: Animatable): boolean {\n if (typeof a === \"number\" || typeof b === \"number\") return a === b;\n if (Array.isArray(a) || Array.isArray(b)) {\n const u = a as Vector;\n const v = b as Vector;\n if (u.length !== v.length) return false;\n for (let i = 0; i < u.length; i++) if (u[i] !== v[i]) return false;\n return true;\n }\n const p = a as Partial<Rect>;\n const q = b as Partial<Rect>;\n return p.x === q.x && p.y === q.y && p.width === q.width && p.height === q.height;\n}\n","import type { Animatable, Layout, Widen } from \"../shapes\";\nimport { layoutOf, makeValue, sameLayout, writeComponents } from \"../shapes\";\nimport type { Animator } from \"./animator\";\n\n/**\n * Tempos for {@link createSettle}, in 1/s: a settle covers 90 % of the way in\n * ln(10)/omega seconds and is within 1 % in twice that.\n *\n * - `calm` 20: 90 % in 115 ms, done in 230 ms.\n * - `default` 25: 90 % in 92 ms, done in 184 ms.\n * - `quick` 37: 90 % in 62 ms, done in 124 ms (a fast Hyprland setup).\n */\nexport const SETTLE_TEMPO = { calm: 20, default: 25, quick: 37 } as const;\n\n/** Settings of {@link createSettle}. */\nexport interface SettleConfig {\n /** The tempo in 1/s (see {@link SETTLE_TEMPO}). Higher is faster. Default 25. */\n readonly omega?: number;\n /** Distance from the target that counts as arrived. Default 0.1 (tuned for pixels). */\n readonly restDelta?: number;\n}\n\n/**\n * The one curve for things that move to a new place: a window's rect between\n * layout targets, a drawer, a camera. Fast at the start, gentle at the end,\n * and it never passes its target.\n *\n * It is a critically damped spring (stiffness omega², damping 2·omega) with\n * one rule on its velocity, per component:\n *\n * - **Launch.** On a new target, each component gets the velocity\n * omega · distance toward it, from wherever it is drawn: standing still,\n * moving toward it, or moving away (it turns at once rather than drifting\n * further first). From there the spring follows `distance · e^(−omega·t)`\n * exactly: most of the move happens at once, the rest eases in.\n * - **Clamp.** That speed is also the most it may have toward the target, so a\n * velocity set by hand (`setVelocity`, a fling) toward the target is capped\n * there instead of shooting past.\n * - **Carry.** A velocity set by hand away from the target is kept, and the\n * value turns around; a critically damped spring turning around never\n * crosses the target either.\n *\n * So after a new target every component goes straight from where it is drawn\n * to the target and never past it: no overshoot on position, no wobble on\n * size, whatever the retargets. A new target starts from the drawn value,\n * never from the old start.\n *\n * Holding (a pointer owns the value): call `hold(value)` on each move. The\n * value sits exactly there, at rest; the next `setTarget` launches from it.\n */\nexport interface Settle<T> extends Animator<T> {\n /** The tempo in 1/s. */\n readonly omega: number;\n /** Put the value at `value`, at rest, with it as the target: a held value follows its owner 1:1. Same as `jumpTo`. */\n hold(value: T): void;\n /** Set the velocity (units per second); a component moving toward the target is clamped as in the launch rule. */\n setVelocity(velocity: T): void;\n /** Change the tempo or rest distance mid-flight; the value and velocity carry on, re-clamped. */\n configure(config: SettleConfig): void;\n}\n\n/** Defaults of {@link SettleConfig}. */\nexport const SETTLE_DEFAULTS = { omega: SETTLE_TEMPO.default, restDelta: 0.1 } as const;\n\nfunction positive(name: string, value: number): number {\n if (!(value > 0) || !Number.isFinite(value)) throw new RangeError(`settle: ${name} must be a finite number > 0, got ${value}`);\n return value;\n}\n\nclass SettleAnimator implements Settle<Animatable> {\n readonly layout: Layout;\n readonly x: Float64Array;\n readonly v: Float64Array;\n readonly goal: Float64Array;\n omega: number;\n restDelta: number;\n settled = true;\n cachedValue: Animatable | null = null;\n\n constructor(initial: Animatable, config: SettleConfig) {\n this.layout = layoutOf(initial);\n this.x = new Float64Array(this.layout.size);\n this.v = new Float64Array(this.layout.size);\n this.goal = new Float64Array(this.layout.size);\n writeComponents(initial, this.x);\n writeComponents(initial, this.goal);\n this.omega = positive(\"omega\", config.omega ?? SETTLE_DEFAULTS.omega);\n this.restDelta = positive(\"restDelta\", config.restDelta ?? SETTLE_DEFAULTS.restDelta);\n }\n\n get value(): Animatable {\n if (this.cachedValue === null) this.cachedValue = makeValue(this.layout, this.x);\n return this.cachedValue;\n }\n\n get velocity(): Animatable {\n return makeValue(this.layout, this.v);\n }\n\n get target(): Animatable {\n return makeValue(this.layout, this.goal);\n }\n\n check(value: Animatable, what: string): void {\n if (!sameLayout(layoutOf(value), this.layout)) {\n throw new TypeError(`settle: ${what} has a different shape than the settle's value`);\n }\n }\n\n /** The launch/clamp/carry rule on component `i`: `launch` for a new target, else clamp or carry. */\n rule(i: number, launch: boolean): void {\n const d = this.x[i]! - this.goal[i]!;\n const v = this.v[i]!;\n const limit = d === 0 ? 0 : -this.omega * d;\n if (launch) {\n this.v[i] = limit;\n return;\n }\n if (d === 0) return;\n // Moving away from the target (d and v the same sign): carry.\n if (d * v > 0) return;\n // Moving toward it: no faster than a launch from here.\n if (Math.abs(v) > Math.abs(limit)) this.v[i] = limit;\n }\n\n updateSettled(): void {\n for (let i = 0; i < this.x.length; i++) {\n if (this.x[i] !== this.goal[i] || this.v[i] !== 0) {\n this.settled = false;\n return;\n }\n }\n this.settled = true;\n }\n\n setTarget(target: Animatable): void {\n this.check(target, \"the target\");\n writeComponents(target, this.goal);\n for (let i = 0; i < this.x.length; i++) this.rule(i, true);\n this.updateSettled();\n }\n\n setVelocity(velocity: Animatable): void {\n this.check(velocity, \"the velocity\");\n writeComponents(velocity, this.v);\n for (let i = 0; i < this.x.length; i++) this.rule(i, false);\n this.updateSettled();\n }\n\n jumpTo(value: Animatable): void {\n this.check(value, \"the value\");\n writeComponents(value, this.x);\n writeComponents(value, this.goal);\n this.v.fill(0);\n this.cachedValue = null;\n this.settled = true;\n }\n\n hold(value: Animatable): void {\n this.jumpTo(value);\n }\n\n snap(): void {\n this.x.set(this.goal);\n this.v.fill(0);\n this.cachedValue = null;\n this.settled = true;\n }\n\n configure(config: SettleConfig): void {\n if (config.omega !== undefined) this.omega = positive(\"omega\", config.omega);\n if (config.restDelta !== undefined) this.restDelta = positive(\"restDelta\", config.restDelta);\n for (let i = 0; i < this.x.length; i++) this.rule(i, false);\n }\n\n step(dtMs: number): boolean {\n if (this.settled) return false;\n if (!(dtMs > 0)) return true;\n const w = this.omega;\n const t = dtMs / 1000;\n const e = Math.exp(-w * t);\n const { x, v, goal, restDelta } = this;\n // At rest when every component is within restDelta and no faster than a launch from there would be.\n const restSpeed = w * restDelta * 1.000001;\n let resting = true;\n for (let i = 0; i < x.length; i++) {\n // The exact critically damped step: d(t) = e^(−wt)·(d + b·t), b = v + w·d.\n const d = x[i]! - goal[i]!;\n const b = v[i]! + w * d;\n const nd = e * (d + b * t);\n v[i] = e * (v[i]! - w * b * t);\n x[i] = goal[i]! + nd;\n // Within a few float steps of the goal counts as arrived too: a restDelta finer than that would never be met.\n const near = Math.max(restDelta, 4 * Number.EPSILON * Math.abs(goal[i]!));\n if (resting && (Math.abs(nd) > near || Math.abs(v[i]!) > Math.max(restSpeed, w * near))) resting = false;\n }\n this.cachedValue = null;\n if (resting) this.snap();\n return !this.settled;\n }\n}\n\n/**\n * A settle starting at rest on `initial` (a number, a vector, a point or a\n * rect; targets and velocities must have the same shape). See {@link Settle}.\n */\nexport function createSettle<T extends Animatable>(initial: T, config: SettleConfig = {}): Settle<Widen<T>> {\n return new SettleAnimator(initial, config) as unknown as Settle<Widen<T>>;\n}\n","import type { Rect } from \"../shapes\";\n\n/**\n * How to draw a window whose rect is gliding without stretching its content.\n *\n * The content is laid out once at the target size and never scaled. The\n * window's element sits at its target in the layout; to draw it at the\n * gliding rect:\n *\n * - move the element by (`dx`, `dy`), so its top-left corner is the drawn rect's;\n * - draw the frame (background, border, shadow) at `width` × `height`: the drawn size;\n * - clip the content by `clipRight` and `clipBottom` so it fits a frame\n * smaller than the target (CSS: `clip-path: inset(0 clipRight clipBottom 0)`).\n *\n * A window that shrinks shows a band of its own background closing in at the\n * right and bottom; one that grows reveals content already laid out at its\n * new size. Text is never stretched. One transform and one clip per frame, no\n * layout per frame.\n */\nexport interface RevealFrame {\n /** Move the element (laid out at the target) right by this much. */\n readonly dx: number;\n /** Move the element (laid out at the target) down by this much. */\n readonly dy: number;\n /** The frame's width: the drawn rect's. */\n readonly width: number;\n /** The frame's height: the drawn rect's. */\n readonly height: number;\n /** Clip this much off the content's right edge (0 when the frame is at least as wide as the target). */\n readonly clipRight: number;\n /** Clip this much off the content's bottom edge (0 when the frame is at least as tall as the target). */\n readonly clipBottom: number;\n}\n\n/** The {@link RevealFrame} for content laid out at `target` and drawn at `drawn`. */\nexport function reveal(drawn: Rect, target: Rect): RevealFrame {\n return {\n dx: drawn.x - target.x,\n dy: drawn.y - target.y,\n width: Math.max(0, drawn.width),\n height: Math.max(0, drawn.height),\n clipRight: Math.max(0, target.width - drawn.width),\n clipBottom: Math.max(0, target.height - drawn.height),\n };\n}\n\n/** A uniform pop-in (or pop-out, run backwards): scale about the centre and opacity. */\nexport interface PopIn {\n /** Scale about the window's centre: the same on both axes, so nothing is stretched. */\n readonly scale: number;\n readonly opacity: number;\n}\n\n/**\n * Opening and closing: the window grows from `from` of its size to full, about\n * its centre, while fading in. `progress` runs 0 to 1 (take it from a settle\n * on a number with `{ restDelta: 0.001 }`, since the default 0.1 is tuned for\n * pixels and would snap the last 10 %; or from a tween); closing runs it from\n * 1 to 0. Hyprland's default is `popin 87%`.\n */\nexport function popIn(progress: number, from = 0.87): PopIn {\n const p = Math.min(1, Math.max(0, progress));\n return { scale: from + (1 - from) * p, opacity: p };\n}\n"],"mappings":";AA+BA,IAAM,SAAS;AACf,IAAM,SAAS;AACf,IAAM,QAAQ;AACd,IAAM,OAAO;AAQb,IAAM,gBAAwB,EAAE,MAAM,QAAQ,MAAM,EAAE;AACtD,IAAM,eAAuB,EAAE,MAAM,OAAO,MAAM,EAAE;AACpD,IAAM,cAAsB,EAAE,MAAM,MAAM,MAAM,EAAE;AAE3C,SAAS,SAAS,OAA2B;AAClD,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,EAAE,MAAM,QAAQ,MAAM,MAAM,OAAO;AACpE,MAAI,WAAW,MAAO,QAAO;AAC7B,SAAO;AACT;AAEO,SAAS,WAAW,GAAW,GAAoB;AACxD,SAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE;AAC3C;AAGO,SAAS,gBAAgB,OAAmB,KAAyB;AAC1E,MAAI,OAAO,UAAU,UAAU;AAC7B,QAAI,CAAC,IAAI;AAAA,EACX,WAAW,MAAM,QAAQ,KAAK,GAAG;AAC/B,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,IAAK,KAAI,CAAC,IAAI,MAAM,CAAC;AAAA,EACzD,WAAW,WAAW,OAAO;AAC3B,QAAI,CAAC,IAAI,MAAM;AACf,QAAI,CAAC,IAAI,MAAM;AACf,QAAI,CAAC,IAAI,MAAM;AACf,QAAI,CAAC,IAAI,MAAM;AAAA,EACjB,OAAO;AACL,UAAM,QAAQ;AACd,QAAI,CAAC,IAAI,MAAM;AACf,QAAI,CAAC,IAAI,MAAM;AAAA,EACjB;AACF;AAGO,SAAS,UAAU,QAAgB,YAAsC;AAC9E,UAAQ,OAAO,MAAM;AAAA,IACnB,KAAK;AACH,aAAO,WAAW,CAAC;AAAA,IACrB,KAAK;AACH,aAAO,EAAE,GAAG,WAAW,CAAC,GAAI,GAAG,WAAW,CAAC,EAAG;AAAA,IAChD,KAAK;AACH,aAAO,EAAE,GAAG,WAAW,CAAC,GAAI,GAAG,WAAW,CAAC,GAAI,OAAO,WAAW,CAAC,GAAI,QAAQ,WAAW,CAAC,EAAG;AAAA,IAC/F;AACE,aAAO,MAAM,KAAK,UAAU;AAAA,EAChC;AACF;AAGO,SAAS,YAAY,GAAe,GAAwB;AACjE,MAAI,OAAO,MAAM,YAAY,OAAO,MAAM,SAAU,QAAO,MAAM;AACjE,MAAI,MAAM,QAAQ,CAAC,KAAK,MAAM,QAAQ,CAAC,GAAG;AACxC,UAAM,IAAI;AACV,UAAM,IAAI;AACV,QAAI,EAAE,WAAW,EAAE,OAAQ,QAAO;AAClC,aAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,IAAK,KAAI,EAAE,CAAC,MAAM,EAAE,CAAC,EAAG,QAAO;AAC7D,WAAO;AAAA,EACT;AACA,QAAM,IAAI;AACV,QAAM,IAAI;AACV,SAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE;AAC7E;;;AC1FO,IAAM,eAAe,EAAE,MAAM,IAAI,SAAS,IAAI,OAAO,GAAG;AAkDxD,IAAM,kBAAkB,EAAE,OAAO,aAAa,SAAS,WAAW,IAAI;AAE7E,SAAS,SAAS,MAAc,OAAuB;AACrD,MAAI,EAAE,QAAQ,MAAM,CAAC,OAAO,SAAS,KAAK,EAAG,OAAM,IAAI,WAAW,WAAW,IAAI,qCAAqC,KAAK,EAAE;AAC7H,SAAO;AACT;AAEA,IAAM,iBAAN,MAAmD;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACT;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,cAAiC;AAAA,EAEjC,YAAY,SAAqB,QAAsB;AACrD,SAAK,SAAS,SAAS,OAAO;AAC9B,SAAK,IAAI,IAAI,aAAa,KAAK,OAAO,IAAI;AAC1C,SAAK,IAAI,IAAI,aAAa,KAAK,OAAO,IAAI;AAC1C,SAAK,OAAO,IAAI,aAAa,KAAK,OAAO,IAAI;AAC7C,oBAAgB,SAAS,KAAK,CAAC;AAC/B,oBAAgB,SAAS,KAAK,IAAI;AAClC,SAAK,QAAQ,SAAS,SAAS,OAAO,SAAS,gBAAgB,KAAK;AACpE,SAAK,YAAY,SAAS,aAAa,OAAO,aAAa,gBAAgB,SAAS;AAAA,EACtF;AAAA,EAEA,IAAI,QAAoB;AACtB,QAAI,KAAK,gBAAgB,KAAM,MAAK,cAAc,UAAU,KAAK,QAAQ,KAAK,CAAC;AAC/E,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,WAAuB;AACzB,WAAO,UAAU,KAAK,QAAQ,KAAK,CAAC;AAAA,EACtC;AAAA,EAEA,IAAI,SAAqB;AACvB,WAAO,UAAU,KAAK,QAAQ,KAAK,IAAI;AAAA,EACzC;AAAA,EAEA,MAAM,OAAmB,MAAoB;AAC3C,QAAI,CAAC,WAAW,SAAS,KAAK,GAAG,KAAK,MAAM,GAAG;AAC7C,YAAM,IAAI,UAAU,WAAW,IAAI,gDAAgD;AAAA,IACrF;AAAA,EACF;AAAA;AAAA,EAGA,KAAK,GAAW,QAAuB;AACrC,UAAM,IAAI,KAAK,EAAE,CAAC,IAAK,KAAK,KAAK,CAAC;AAClC,UAAM,IAAI,KAAK,EAAE,CAAC;AAClB,UAAM,QAAQ,MAAM,IAAI,IAAI,CAAC,KAAK,QAAQ;AAC1C,QAAI,QAAQ;AACV,WAAK,EAAE,CAAC,IAAI;AACZ;AAAA,IACF;AACA,QAAI,MAAM,EAAG;AAEb,QAAI,IAAI,IAAI,EAAG;AAEf,QAAI,KAAK,IAAI,CAAC,IAAI,KAAK,IAAI,KAAK,EAAG,MAAK,EAAE,CAAC,IAAI;AAAA,EACjD;AAAA,EAEA,gBAAsB;AACpB,aAAS,IAAI,GAAG,IAAI,KAAK,EAAE,QAAQ,KAAK;AACtC,UAAI,KAAK,EAAE,CAAC,MAAM,KAAK,KAAK,CAAC,KAAK,KAAK,EAAE,CAAC,MAAM,GAAG;AACjD,aAAK,UAAU;AACf;AAAA,MACF;AAAA,IACF;AACA,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,UAAU,QAA0B;AAClC,SAAK,MAAM,QAAQ,YAAY;AAC/B,oBAAgB,QAAQ,KAAK,IAAI;AACjC,aAAS,IAAI,GAAG,IAAI,KAAK,EAAE,QAAQ,IAAK,MAAK,KAAK,GAAG,IAAI;AACzD,SAAK,cAAc;AAAA,EACrB;AAAA,EAEA,YAAY,UAA4B;AACtC,SAAK,MAAM,UAAU,cAAc;AACnC,oBAAgB,UAAU,KAAK,CAAC;AAChC,aAAS,IAAI,GAAG,IAAI,KAAK,EAAE,QAAQ,IAAK,MAAK,KAAK,GAAG,KAAK;AAC1D,SAAK,cAAc;AAAA,EACrB;AAAA,EAEA,OAAO,OAAyB;AAC9B,SAAK,MAAM,OAAO,WAAW;AAC7B,oBAAgB,OAAO,KAAK,CAAC;AAC7B,oBAAgB,OAAO,KAAK,IAAI;AAChC,SAAK,EAAE,KAAK,CAAC;AACb,SAAK,cAAc;AACnB,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,KAAK,OAAyB;AAC5B,SAAK,OAAO,KAAK;AAAA,EACnB;AAAA,EAEA,OAAa;AACX,SAAK,EAAE,IAAI,KAAK,IAAI;AACpB,SAAK,EAAE,KAAK,CAAC;AACb,SAAK,cAAc;AACnB,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,UAAU,QAA4B;AACpC,QAAI,OAAO,UAAU,OAAW,MAAK,QAAQ,SAAS,SAAS,OAAO,KAAK;AAC3E,QAAI,OAAO,cAAc,OAAW,MAAK,YAAY,SAAS,aAAa,OAAO,SAAS;AAC3F,aAAS,IAAI,GAAG,IAAI,KAAK,EAAE,QAAQ,IAAK,MAAK,KAAK,GAAG,KAAK;AAAA,EAC5D;AAAA,EAEA,KAAK,MAAuB;AAC1B,QAAI,KAAK,QAAS,QAAO;AACzB,QAAI,EAAE,OAAO,GAAI,QAAO;AACxB,UAAM,IAAI,KAAK;AACf,UAAM,IAAI,OAAO;AACjB,UAAM,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC;AACzB,UAAM,EAAE,GAAG,GAAG,MAAM,UAAU,IAAI;AAElC,UAAM,YAAY,IAAI,YAAY;AAClC,QAAI,UAAU;AACd,aAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK;AAEjC,YAAM,IAAI,EAAE,CAAC,IAAK,KAAK,CAAC;AACxB,YAAM,IAAI,EAAE,CAAC,IAAK,IAAI;AACtB,YAAM,KAAK,KAAK,IAAI,IAAI;AACxB,QAAE,CAAC,IAAI,KAAK,EAAE,CAAC,IAAK,IAAI,IAAI;AAC5B,QAAE,CAAC,IAAI,KAAK,CAAC,IAAK;AAElB,YAAM,OAAO,KAAK,IAAI,WAAW,IAAI,OAAO,UAAU,KAAK,IAAI,KAAK,CAAC,CAAE,CAAC;AACxE,UAAI,YAAY,KAAK,IAAI,EAAE,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC,CAAE,IAAI,KAAK,IAAI,WAAW,IAAI,IAAI,GAAI,WAAU;AAAA,IACrG;AACA,SAAK,cAAc;AACnB,QAAI,QAAS,MAAK,KAAK;AACvB,WAAO,CAAC,KAAK;AAAA,EACf;AACF;AAMO,SAAS,aAAmC,SAAY,SAAuB,CAAC,GAAqB;AAC1G,SAAO,IAAI,eAAe,SAAS,MAAM;AAC3C;;;AC7KO,SAAS,OAAO,OAAa,QAA2B;AAC7D,SAAO;AAAA,IACL,IAAI,MAAM,IAAI,OAAO;AAAA,IACrB,IAAI,MAAM,IAAI,OAAO;AAAA,IACrB,OAAO,KAAK,IAAI,GAAG,MAAM,KAAK;AAAA,IAC9B,QAAQ,KAAK,IAAI,GAAG,MAAM,MAAM;AAAA,IAChC,WAAW,KAAK,IAAI,GAAG,OAAO,QAAQ,MAAM,KAAK;AAAA,IACjD,YAAY,KAAK,IAAI,GAAG,OAAO,SAAS,MAAM,MAAM;AAAA,EACtD;AACF;AAgBO,SAAS,MAAM,UAAkB,OAAO,MAAa;AAC1D,QAAM,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,QAAQ,CAAC;AAC3C,SAAO,EAAE,OAAO,QAAQ,IAAI,QAAQ,GAAG,SAAS,EAAE;AACpD;","names":[]}
package/dist/drag.d.ts ADDED
@@ -0,0 +1,202 @@
1
+ import { R as Rect, P as Point } from './shapes-EbQlwbCu.js';
2
+
3
+ /**
4
+ * The drag intent model's tuning. Distances in px, speeds in px/ms, times in
5
+ * ms; every value can be overridden per intent (see
6
+ * {@link DragIntentOptions.tuning}).
7
+ */
8
+ interface DragTuning {
9
+ /** A mouse press lifts once the pointer has moved this far. */
10
+ readonly lift: number;
11
+ /** A touch press lifts only after it has been held this long… */
12
+ readonly touchHold: number;
13
+ /** …and then moved this far (moving that far before the hold is over is not a drag). */
14
+ readonly touchLift: number;
15
+ /** The pointer's speed is measured over this window and smoothed. */
16
+ readonly speedWindow: number;
17
+ /** Aiming: the smoothed speed is below this… */
18
+ readonly aimSpeed: number;
19
+ /** …or the pointer has stayed within `still` px of one spot for `dwell` ms. */
20
+ readonly still: number;
21
+ readonly dwell: number;
22
+ /** The current target holds while the pointer is within this band of its zone. */
23
+ readonly band: number;
24
+ /** A higher-priority target takes over at once when the pointer is this far inside it. */
25
+ readonly breakthrough: number;
26
+ /** A gap between zones shorter than this keeps the current target (for a pointer that aims). */
27
+ readonly gapGrace: number;
28
+ /** Aiming, the shown target moves to another one only once that one has held this long. */
29
+ readonly switchHold: number;
30
+ /** Room is made once the shown target, and the place in it, have held this long. */
31
+ readonly roomAfter: number;
32
+ /** The pointer has left the item's home once it is outside the home shrunk by this much on every side. */
33
+ readonly homeInset: number;
34
+ }
35
+ /**
36
+ * The defaults: a mouse lifts after 5 px, a touch after a 180 ms hold and
37
+ * 8 px; aiming is slower than 0.45 px/ms over 50 ms, or within 12 px for
38
+ * 90 ms; a 10 px band, a 4 px breakthrough and a 120 ms gap grace; a switch
39
+ * waits 150 ms (the shortest an indicator may show); room after 160 ms.
40
+ */
41
+ declare const DRAG_DEFAULTS: DragTuning;
42
+ /**
43
+ * A drop target: plain data. `hit` is the zone the pointer can be in;
44
+ * `priority` how precise it is (1 beats 2 beats 3; equal priorities go to the
45
+ * smaller zone). `slot` is where the dragged item would land, `label` what to
46
+ * call it; the model reads neither. A `free` target has no slot (the item
47
+ * floats where it is dropped): no room is made for it.
48
+ */
49
+ interface DragTarget {
50
+ readonly id: string;
51
+ readonly priority: 1 | 2 | 3;
52
+ readonly hit: Rect;
53
+ readonly slot?: Rect;
54
+ readonly label?: string;
55
+ readonly free?: boolean;
56
+ }
57
+ /** Whether `point` lies in `rect` grown by `margin` px on every side (shrunk, for a negative margin). */
58
+ declare function inRect(rect: Rect, point: Point, margin?: number): boolean;
59
+ /** The most precise target under `point`: the lowest priority number, then the smallest zone; null when none is. */
60
+ declare function targetAt<T extends DragTarget>(targets: readonly T[], point: Point): T | null;
61
+ /** What a press does so far: not yet a drag (`wait`), a drag (`lift`), or never one (`refuse`: a touch that moved too soon). */
62
+ type LiftDecision = "wait" | "lift" | "refuse";
63
+ /**
64
+ * The lift rule for a press that has moved `distance` px in `elapsed` ms. A
65
+ * mouse (or pen) lifts at `lift` px. A touch lifts only after `touchHold` ms,
66
+ * then at `touchLift` px; moving `touchLift` px before the hold is over
67
+ * refuses the drag (the finger is scrolling or swiping).
68
+ */
69
+ declare function liftDecision(press: {
70
+ readonly touch: boolean;
71
+ readonly distance: number;
72
+ readonly elapsed: number;
73
+ }, tuning?: Partial<DragTuning>): LiftDecision;
74
+ /** One update's answer. */
75
+ interface DragFrame<T extends DragTarget> {
76
+ /** The target the drop indicator shows, or null. */
77
+ readonly shown: T | null;
78
+ /** The others make room for the shown target: it, and the place in it, have held `roomAfter` ms. */
79
+ readonly room: boolean;
80
+ /**
81
+ * The place the room is made for, or null. Within one target it stays on
82
+ * the old place until a new one has held `roomAfter` ms (see
83
+ * {@link DragIntentOptions.placeOf}).
84
+ */
85
+ readonly roomPlace: string | null;
86
+ /** The pointer is aiming: slow, or nearly still for a moment. */
87
+ readonly aiming: boolean;
88
+ }
89
+ /** What a drag intent knows now. */
90
+ interface DragIntentState<T extends DragTarget> {
91
+ /** The pointer's smoothed speed, px/ms. */
92
+ readonly speed: number;
93
+ /** The target under the pointer as the hysteresis holds it, or null. */
94
+ readonly current: T | null;
95
+ /** The target the indicator shows, or null. */
96
+ readonly shown: T | null;
97
+ /** The pointer has left the item's home. */
98
+ readonly leftHome: boolean;
99
+ }
100
+ interface DragIntentOptions<T extends DragTarget> {
101
+ /** Where the item was lifted from: the indicator stays off until the pointer leaves it, and a release there does nothing. */
102
+ readonly home: Rect;
103
+ /** Overrides of {@link DRAG_DEFAULTS}. */
104
+ readonly tuning?: Partial<DragTuning>;
105
+ /**
106
+ * The place within a target the pointer is at (a tab index, a stack
107
+ * position), unique across targets; default: the target's id. Moving between places of the
108
+ * shown target moves the indicator at once but the room only once the new
109
+ * place has held `roomAfter` ms.
110
+ */
111
+ readonly placeOf?: (target: T, point: Point) => string;
112
+ }
113
+ /** A drag's intent: feed it the pointer on every frame; it says what the indicator shows and what a release lands on. */
114
+ interface DragIntent<T extends DragTarget> {
115
+ /**
116
+ * A pointer sample at `time` (ms), with the targets as they stand (they may
117
+ * be rebuilt between calls: the model follows them by id). Call it once a
118
+ * frame while the item is held, also when the pointer doesn't move: a
119
+ * dwell is time passing.
120
+ */
121
+ update(point: Point, time: number, targets: readonly T[]): DragFrame<T>;
122
+ /**
123
+ * What a release at `point` lands on: the shown target whenever one shows
124
+ * (a drop lands where the indicator was), else the target under the
125
+ * pointer, else null (the item goes home). A release over home is null: it
126
+ * does nothing. Feed the release point to `update` first, so a last jump
127
+ * of the pointer counts.
128
+ */
129
+ release(point: Point, targets: readonly T[]): T | null;
130
+ /**
131
+ * Hide the indicator (the view is scrolling under the pointer, say). The
132
+ * aim starts afresh: the next sample never counts as aiming, and a dwell
133
+ * starts again.
134
+ */
135
+ hide(time: number): void;
136
+ /** The item's home moved with the view (it scrolled) by (dx, dy). */
137
+ moveHome(dx: number, dy: number): void;
138
+ readonly state: DragIntentState<T>;
139
+ readonly tuning: DragTuning;
140
+ }
141
+ /**
142
+ * The drag intent model: when the drop indicator shows, which target it
143
+ * shows, when the others make room, and what a release lands on. Pure: fed
144
+ * pointer samples and plain-data targets, no DOM and no clock of its own.
145
+ *
146
+ * - The indicator shows only when the pointer has left the item's home, a
147
+ * target is under it, and it is aiming (slow, or nearly still for a
148
+ * moment). Time spent crossing a big target at speed doesn't count.
149
+ * - The most precise target wins (priority, then the smaller zone).
150
+ * - Hysteresis: the current target holds while the pointer is within `band`
151
+ * px of its zone, unless a more precise one is clearly (`breakthrough` px)
152
+ * under the pointer; for a pointer that aims, a short gap between zones
153
+ * (`gapGrace` ms) keeps it too.
154
+ * - Leaving the shown target: flying, the indicator hides at once; aiming, it
155
+ * moves to the new target once that has held `switchHold` ms (so no
156
+ * indicator shows for less than that), at once for a breakthrough. A target
157
+ * kept only by the gap grace can keep the indicator, never show it.
158
+ * - Room is made once the shown target has held `roomAfter` ms, never for a
159
+ * free target, and closes at once when it changes.
160
+ */
161
+ declare function createDragIntent<T extends DragTarget>(options: DragIntentOptions<T>): DragIntent<T>;
162
+
163
+ /**
164
+ * How a drag previews its drop, from least to most motion while dragging:
165
+ *
166
+ * - `"indicator"`: nothing moves; only the indicator (an outline or an
167
+ * insertion marker) shows the target.
168
+ * - `"gap"`: once the room is made, the others move aside and open the slot;
169
+ * the item stays under the pointer.
170
+ * - `"snap"`: the gap opens and the item itself glides into it (for a target
171
+ * with a slot; one without keeps the indicator).
172
+ *
173
+ * Every mode follows the same intent: what shows, when, and what a release
174
+ * lands on are the drag intent's, so a drop always lands where the preview
175
+ * showed it.
176
+ */
177
+ type DragPreview = "indicator" | "gap" | "snap";
178
+ /** The preview a drag uses unless the host picks another. */
179
+ declare const DRAG_PREVIEW_DEFAULT: DragPreview;
180
+ /** What to draw for one frame of a drag. */
181
+ interface PreviewPlan {
182
+ /** Draw the indicator on the shown target. */
183
+ readonly showIndicator: boolean;
184
+ /** Lay the others out around the room (the gap is open). */
185
+ readonly makeRoom: boolean;
186
+ /** Draw the item in its slot instead of under the pointer. */
187
+ readonly snapItem: boolean;
188
+ }
189
+ /**
190
+ * The plan for a frame of the drag intent under `preview`. `slotted` says
191
+ * whether the shown target's drop has a slot the item can sit in (default: a
192
+ * target that isn't `free`); only such a target snaps, and in `"snap"` it
193
+ * previews with the item rather than the indicator.
194
+ *
195
+ * - `"indicator"`: the indicator, never room, never a snap.
196
+ * - `"gap"`: the indicator, and room when the intent makes it.
197
+ * - `"snap"`: room when the intent makes it, the item snapped into a slotted
198
+ * target's room; the indicator only for a target without a slot.
199
+ */
200
+ declare function previewPlan<T extends DragTarget>(frame: Pick<DragFrame<T>, "shown" | "room">, preview: DragPreview, slotted?: boolean): PreviewPlan;
201
+
202
+ export { DRAG_DEFAULTS, DRAG_PREVIEW_DEFAULT, type DragFrame, type DragIntent, type DragIntentOptions, type DragIntentState, type DragPreview, type DragTarget, type DragTuning, type LiftDecision, type PreviewPlan, createDragIntent, inRect, liftDecision, previewPlan, targetAt };