'use strict'; var solidJs = require('solid-js'); var web = require('solid-js/web'); // src/index.ts function is_date(obj) { return Object.prototype.toString.call(obj) === "[object Date]"; } function createSpring(initialValue, options = {}) { const [signal, setSignal] = solidJs.createSignal(initialValue); const { stiffness = 0.15, damping = 0.8, precision = 0.01 } = options; if (web.isServer) { return [signal, (param, opts = {}) => { if (opts.hard || signal() == null || stiffness >= 1 && damping >= 1) { setSignal(param); return Promise.resolve(); } return new Promise(() => { }); }]; } let value_current = initialValue; let value_last = initialValue; let value_target = initialValue; let inv_mass = 1; let inv_mass_recovery_rate = 0; let raf_id = 0; let settled = true; let time_last = 0; let time_delta = 0; let resolve = () => { }; const cleanup = solidJs.onCleanup(() => { cancelAnimationFrame(raf_id); raf_id = 0; resolve(); }); const frame = (time) => { time_delta = Math.max(1 / 60, (time - time_last) * 60 / 1e3); time_last = time; inv_mass = Math.min(inv_mass + inv_mass_recovery_rate, 1); settled = true; let new_value = tick(value_last, value_current, value_target); value_last = value_current; setSignal(value_current = new_value); if (settled) { cleanup(); } else { raf_id = requestAnimationFrame(frame); } }; const set = (param, opts = {}) => { value_target = typeof param === "function" ? param(value_current) : param; if (opts.hard || stiffness >= 1 && damping >= 1) { cleanup(); setSignal((_) => value_current = value_last = value_target); return Promise.resolve(); } if (opts.soft) { inv_mass_recovery_rate = 1 / (typeof opts.soft === "number" ? opts.soft * 60 : 30); inv_mass = 0; } if (raf_id === 0) { time_last = performance.now(); raf_id = requestAnimationFrame(frame); } return new Promise((r) => resolve = r); }; const tick = (last, current, target) => { if (typeof current === "number" || is_date(current)) { const delta = +target - +current; const velocity = (+current - +last) / time_delta; const spring = stiffness * delta; const damper = damping * velocity; const acceleration = (spring - damper) * inv_mass; const d = (velocity + acceleration) * time_delta; if (Math.abs(d) < precision && Math.abs(delta) < precision) { return target; } settled = false; return typeof current === "number" ? current + d : new Date(+current + d); } if (Array.isArray(current)) { return current.map((_, i) => tick(last[i], current[i], target[i])); } if (typeof current === "object") { const next = { ...current }; for (const k in current) { next[k] = tick(last[k], current[k], target[k]); } return next; } throw new Error(`Cannot spring ${typeof current} values`); }; return [signal, set]; } function createDerivedSpring(target, options) { const [springValue, setSpringValue] = createSpring(target(), options); solidJs.createEffect(() => setSpringValue(target())); return springValue; } exports.createDerivedSpring = createDerivedSpring; exports.createSpring = createSpring;