@ssgoi/core
Version:
Core animation engine for SSGOI - Native app-like page transitions with spring physics
168 lines (167 loc) • 5.33 kB
JavaScript
var I = Object.defineProperty;
var _ = (a, e, t) => e in a ? I(a, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : a[e] = t;
var n = (a, e, t) => _(a, typeof e != "symbol" ? e + "" : e, t);
const x = 0.05;
class b {
constructor(e) {
n(this, "omega");
// Angular frequency
n(this, "zeta");
// Damping ratio
n(this, "restDelta");
n(this, "restSpeed");
const { stiffness: t, damping: s } = e, i = 1;
this.omega = Math.sqrt(t / i), this.zeta = s / (2 * Math.sqrt(t * i)), this.restDelta = e.restDelta ?? 0.01, this.restSpeed = e.restSpeed ?? 0.01;
}
step(e, t, s) {
const i = Math.min(s, 0.033), { omega: r, zeta: p } = this, { position: c, velocity: d } = e, h = -2 * i * p * r * d, o = i * r * r * (t - c), l = d + h + o;
return {
position: c + i * l,
velocity: l
};
}
isSettled(e, t) {
const s = Math.abs(t - e.position), i = Math.abs(e.velocity);
return s < this.restDelta && i < this.restSpeed;
}
}
class H {
constructor(e) {
n(this, "leader");
n(this, "follower");
n(this, "restDelta");
n(this, "restSpeed");
this.restDelta = e.restDelta ?? 0.01, this.restSpeed = e.restSpeed ?? 0.01, this.leader = new b({
stiffness: e.stiffness,
damping: e.damping,
restDelta: this.restDelta,
restSpeed: this.restSpeed
});
let t, s, i, r;
typeof e.follower == "number" ? (t = e.stiffness * e.follower, s = e.damping) : e.follower ? (t = e.follower.stiffness, s = e.follower.damping, i = e.follower.restDelta, r = e.follower.restSpeed) : (t = e.stiffness, s = e.damping), this.follower = new b({
stiffness: t,
damping: s,
restDelta: i ?? this.restDelta,
restSpeed: r ?? this.restSpeed
});
}
step(e, t, s) {
const r = e._leader ?? {
position: e.position,
velocity: e.velocity
}, p = this.leader.step(r, t, s), c = this.follower.step(
e,
p.position,
s
);
return {
position: c.position,
velocity: c.velocity,
_leader: p
};
}
isSettled(e, t) {
const s = e, i = Math.abs(t - e.position) < this.restDelta && Math.abs(e.velocity) < this.restSpeed;
return s._leader ? Math.abs(t - s._leader.position) < this.restDelta && Math.abs(s._leader.velocity) < this.restSpeed && i : i;
}
}
const L = 0.01, M = 500, v = 10;
class F {
constructor(e) {
n(this, "acceleration");
n(this, "resistance");
n(this, "resistanceType");
n(this, "min");
n(this, "max");
n(this, "bounceStiffness");
n(this, "bounceDamping");
n(this, "restDelta");
this.acceleration = e.acceleration, this.resistance = e.resistance, this.resistanceType = e.resistanceType ?? "quadratic", this.min = e.min, this.max = e.max, this.bounceStiffness = e.bounceStiffness ?? M, this.bounceDamping = e.bounceDamping ?? v, this.restDelta = e.restDelta ?? L;
}
step(e, t, s) {
const i = Math.min(s, 0.033), { acceleration: r, resistance: p, resistanceType: c, min: d, max: h } = this, { position: o, velocity: l } = e, f = d !== void 0 && o < d, w = h !== void 0 && o > h;
let u;
if (f || w) {
const D = o - (f ? d : h), O = -this.bounceStiffness * D, E = -this.bounceDamping * l;
u = O + E;
} else {
const m = t > o ? 1 : -1;
let D;
c === "linear" ? D = p * l : D = p * l * Math.abs(l), u = m * r - D;
}
const T = l + u * i;
let S = o + T * i;
if (!f && !w) {
const m = t > o ? 1 : -1;
(m > 0 && S > t || m < 0 && S < t) && (S = t);
}
return {
position: S,
velocity: S === t ? 0 : T
};
}
isSettled(e, t) {
return Math.abs(t - e.position) < this.restDelta;
}
}
class y {
/**
* Create an Integrator from physics config
*
* @param config Physics configuration (spring or inertia)
* @returns Appropriate Integrator instance
* @throws Error if both spring and inertia are provided
*/
static from(e) {
if (e.spring && e.inertia)
throw new Error(
"Cannot use both 'spring' and 'inertia' together. Choose one physics type."
);
if (e.inertia)
return new F({
acceleration: e.inertia.acceleration,
resistance: e.inertia.resistance,
resistanceType: e.inertia.resistanceType,
min: e.inertia.min,
max: e.inertia.max,
bounceStiffness: e.inertia.bounceStiffness,
bounceDamping: e.inertia.bounceDamping,
restDelta: e.inertia.restDelta
});
const t = e.spring ?? { stiffness: 300, damping: 30 };
if (t.doubleSpring) {
const s = t.doubleSpring;
let i;
return typeof s == "number" ? i = s : typeof s == "object" && (i = {
stiffness: s.stiffness,
damping: s.damping
}), new H({
stiffness: t.stiffness,
damping: t.damping,
follower: i,
restDelta: t.restDelta,
restSpeed: t.restSpeed
});
}
return new b({
stiffness: t.stiffness,
damping: t.damping,
restDelta: t.restDelta,
restSpeed: t.restSpeed
});
}
/**
* Create an Integrator from SpringConfig (legacy support)
* @deprecated Use from({ spring: config }) instead
*/
static fromSpring(e) {
return y.from({ spring: e });
}
}
export {
H as D,
y as I,
x as S,
b as a,
F as b
};