coily 0.14.0 → 0.16.0
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.
- package/README.md +133 -51
- package/dist/config-B8M2xp26.d.ts +295 -0
- package/dist/css.d.ts +203 -0
- package/dist/css.js +318 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.js +99 -53
- package/dist/nuxt.d.ts +24 -15
- package/dist/nuxt.js +16 -5
- package/dist/solver-CAXuxdKj.js +243 -0
- package/dist/system-C7PbI4L0.d.ts +1213 -0
- package/dist/system-WejqGkfv.js +2920 -0
- package/dist/vue.d.ts +224 -128
- package/dist/vue.js +161 -41
- package/package.json +2 -1
- package/dist/system-BXxAHM2a.js +0 -1758
- package/dist/system-Ci-R4RaI.d.ts +0 -1032
package/dist/vue.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { a as
|
|
1
|
+
import { a as SpringSourceSymbol, n as CompositeSpring, o as isSpringSource, r as SpringDefinition, t as createSpringSystem } from "./system-WejqGkfv.js";
|
|
2
|
+
import { o as invariant } from "./solver-CAXuxdKj.js";
|
|
2
3
|
import { computed, customRef, defineComponent, getCurrentInstance, getCurrentScope, inject, onBeforeUnmount, onMounted, onScopeDispose, provide, toRefs, toValue, watchSyncEffect } from "vue";
|
|
3
4
|
//#region src/vue/local.ts
|
|
4
5
|
const localProvides = /* @__PURE__ */ new WeakMap();
|
|
@@ -26,25 +27,24 @@ function injectLocal(key) {
|
|
|
26
27
|
//#region src/vue/system.ts
|
|
27
28
|
const SpringSystemKey = Symbol.for("coily/spring-system");
|
|
28
29
|
/**
|
|
29
|
-
*
|
|
30
|
-
* starts or stops it. With `app`, the
|
|
31
|
-
*
|
|
32
|
-
* component
|
|
33
|
-
*
|
|
30
|
+
* Provides a spring system you create and manage yourself. Coily never
|
|
31
|
+
* starts or stops it. With `app`, the whole app gets it, as with the
|
|
32
|
+
* Nuxt module. Without `app`, call it in `setup()`, and it reaches the
|
|
33
|
+
* current component, including its own `useSpring` calls, and its
|
|
34
|
+
* descendants. Mostly useful in tests.
|
|
34
35
|
*/
|
|
35
36
|
function provideSpringSystem(system, app) {
|
|
36
37
|
if (app) app.provide(SpringSystemKey, system);
|
|
37
38
|
else provideLocal(SpringSystemKey, system);
|
|
38
39
|
}
|
|
39
40
|
/**
|
|
40
|
-
* Returns the spring system
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
41
|
+
* Returns the spring system this component or an ancestor provides, or
|
|
42
|
+
* creates one. A created system is provided to this component and its
|
|
43
|
+
* descendants, starts when the component mounts, and is disposed before
|
|
44
|
+
* it unmounts.
|
|
44
45
|
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
* Throws outside `setup()`.
|
|
46
|
+
* A call below a provider returns the provided system, and `options`
|
|
47
|
+
* applies only when the call creates one. Throws outside `setup()`.
|
|
48
48
|
*/
|
|
49
49
|
function useSpringSystem(options) {
|
|
50
50
|
if (!getCurrentInstance()) throw new Error("useSpringSystem must be called inside setup()");
|
|
@@ -53,7 +53,7 @@ function useSpringSystem(options) {
|
|
|
53
53
|
const system = createSpringSystem(options);
|
|
54
54
|
provideLocal(SpringSystemKey, system);
|
|
55
55
|
onMounted(() => system.start());
|
|
56
|
-
onBeforeUnmount(() => system.
|
|
56
|
+
onBeforeUnmount(() => system.dispose());
|
|
57
57
|
return system;
|
|
58
58
|
}
|
|
59
59
|
//#endregion
|
|
@@ -83,6 +83,9 @@ function createReactiveSpringRef(spring, config, instanceKey) {
|
|
|
83
83
|
triggerVelocity?.();
|
|
84
84
|
triggerTimeRemaining?.();
|
|
85
85
|
});
|
|
86
|
+
const triggerRemaining = () => triggerTimeRemaining?.();
|
|
87
|
+
spring.onStart(triggerRemaining);
|
|
88
|
+
spring.onStop(triggerRemaining);
|
|
86
89
|
const value = divergentRef((track, trigger) => ({
|
|
87
90
|
get() {
|
|
88
91
|
triggerValue ??= trigger;
|
|
@@ -142,27 +145,38 @@ const CompositeSpringInstanceKey = Symbol("composite-spring");
|
|
|
142
145
|
function hasCompositeSpringInstance(value) {
|
|
143
146
|
return typeof value === "object" && value !== null && CompositeSpringInstanceKey in value;
|
|
144
147
|
}
|
|
148
|
+
/** The composite that `value` leads with, or `undefined` when it is not a `CompositeLeader`. */
|
|
149
|
+
function compositeLeaderOf(value) {
|
|
150
|
+
if (value instanceof CompositeSpring) return value;
|
|
151
|
+
if (hasCompositeSpringInstance(value)) return value[CompositeSpringInstanceKey];
|
|
152
|
+
}
|
|
153
|
+
const SHAPED_SOURCE = "useSpring follows a scalar SpringSource or a composite spring, not a source of another shape. Derive a scalar source with mapSpring";
|
|
145
154
|
function resolveConfigShape(config) {
|
|
146
155
|
return computed(() => toValue(config));
|
|
147
156
|
}
|
|
148
|
-
|
|
157
|
+
/**
|
|
158
|
+
* Creates the composite behind an object `useSpring`. `target` resolves
|
|
159
|
+
* to a shape to animate toward or a `CompositeLeader` to follow, and it
|
|
160
|
+
* can switch between them.
|
|
161
|
+
*/
|
|
162
|
+
function createCompositeSpringRef(target, config, options) {
|
|
149
163
|
const system = injectSpringSystem();
|
|
150
164
|
const resolvedConfig = resolveConfigShape(config);
|
|
151
|
-
const
|
|
165
|
+
const resolve = () => {
|
|
166
|
+
const next = toValue(target);
|
|
167
|
+
const leader = compositeLeaderOf(next);
|
|
168
|
+
if (leader !== void 0) return leader;
|
|
169
|
+
invariant(!isSpringSource(next), SHAPED_SOURCE);
|
|
170
|
+
return next;
|
|
171
|
+
};
|
|
172
|
+
const initial = resolve();
|
|
173
|
+
const spring = system.createSpring(initial instanceof CompositeSpring ? initial.value : initial, resolvedConfig.value, options);
|
|
152
174
|
const ref = createReactiveSpringRef(spring, resolvedConfig, CompositeSpringInstanceKey);
|
|
153
175
|
watchSyncEffect(() => {
|
|
154
|
-
spring.target =
|
|
176
|
+
spring.target = resolve();
|
|
155
177
|
});
|
|
156
178
|
return ref;
|
|
157
179
|
}
|
|
158
|
-
function createLinkedCompositeSpringRef(leaderRef, config, options) {
|
|
159
|
-
const system = injectSpringSystem();
|
|
160
|
-
const leader = leaderRef[CompositeSpringInstanceKey];
|
|
161
|
-
const resolvedConfig = resolveConfigShape(config);
|
|
162
|
-
const spring = system.createSpring(leader.value, resolvedConfig.value, options);
|
|
163
|
-
spring.target = leader;
|
|
164
|
-
return createReactiveSpringRef(spring, resolvedConfig, CompositeSpringInstanceKey);
|
|
165
|
-
}
|
|
166
180
|
//#endregion
|
|
167
181
|
//#region src/vue/spring.ts
|
|
168
182
|
const SpringInstanceKey = Symbol("spring");
|
|
@@ -171,10 +185,10 @@ function hasSpringInstance(value) {
|
|
|
171
185
|
}
|
|
172
186
|
function useSpring(target, config, options) {
|
|
173
187
|
if (hasSpringInstance(target)) return createLinkedSpringRef(target, config, options);
|
|
174
|
-
|
|
175
|
-
const resolved = toValue(
|
|
176
|
-
if (typeof resolved === "number" || isSpringSource(resolved)) return createSpringRef(
|
|
177
|
-
return createCompositeSpringRef(
|
|
188
|
+
const follow = isSpringSource(target) ? () => target : target;
|
|
189
|
+
const resolved = toValue(follow);
|
|
190
|
+
if (typeof resolved === "number" || isSpringSource(resolved) && typeof resolved[SpringSourceSymbol].value === "number") return createSpringRef(follow, config, options);
|
|
191
|
+
return createCompositeSpringRef(follow, config, options);
|
|
178
192
|
}
|
|
179
193
|
function createSpringRef(target, config, options) {
|
|
180
194
|
const system = injectSpringSystem();
|
|
@@ -194,16 +208,121 @@ function createLinkedSpringRef(leaderRef, config, options) {
|
|
|
194
208
|
return createReactiveSpringRef(system.createSpring(leader, resolvedConfig.value, options), resolvedConfig, SpringInstanceKey);
|
|
195
209
|
}
|
|
196
210
|
//#endregion
|
|
211
|
+
//#region src/vue/ramp.ts
|
|
212
|
+
/**
|
|
213
|
+
* Creates a ramp and returns it as a `RampRef`. A ramp moves toward
|
|
214
|
+
* `target` in a straight line at `rate` value units per second, and
|
|
215
|
+
* stops there. A target of `Infinity` or `-Infinity` makes it endless.
|
|
216
|
+
* A spring following the ref with the default `arrival` tracks its
|
|
217
|
+
* steady motion exactly, with no frame-to-frame steps. On an endless
|
|
218
|
+
* ramp, that spring lags behind like a heavy spinning object.
|
|
219
|
+
*
|
|
220
|
+
* A new `target` sends the ramp there from its current value. A new
|
|
221
|
+
* `rate` applies from the current value on.
|
|
222
|
+
*
|
|
223
|
+
* Call it during `setup()` below a provided spring system (the coily/nuxt
|
|
224
|
+
* module, or `useSpringSystem()` in an ancestor). It throws without one.
|
|
225
|
+
* The ramp is disposed with the component's scope.
|
|
226
|
+
*
|
|
227
|
+
* @example
|
|
228
|
+
* ```ts
|
|
229
|
+
* const angle = useRamp(Infinity, 270, { from: 0 })
|
|
230
|
+
* const ring = useSpring(angle, { duration: 300, dampingRatio: 1 })
|
|
231
|
+
* // template: <div :style="{ rotate: `${ring}deg` }" />
|
|
232
|
+
*
|
|
233
|
+
* const heading = ref(0)
|
|
234
|
+
* const slew = useRamp(heading, 400) // turns toward heading at 400 deg/s
|
|
235
|
+
* ```
|
|
236
|
+
*/
|
|
237
|
+
function useRamp(target, rate, options) {
|
|
238
|
+
const system = injectSpringSystem();
|
|
239
|
+
const initial = toValue(target);
|
|
240
|
+
const from = options?.from ?? initial;
|
|
241
|
+
invariant(Number.isFinite(from), "useRamp needs a finite `from` when its initial target is infinite");
|
|
242
|
+
const ramp = system.createRamp(from, {
|
|
243
|
+
rate: toValue(rate),
|
|
244
|
+
target: initial,
|
|
245
|
+
purpose: options?.purpose
|
|
246
|
+
});
|
|
247
|
+
watchSyncEffect(() => {
|
|
248
|
+
ramp.target = toValue(target);
|
|
249
|
+
});
|
|
250
|
+
watchSyncEffect(() => {
|
|
251
|
+
ramp.rate = toValue(rate);
|
|
252
|
+
});
|
|
253
|
+
const ref = createRampRef(ramp);
|
|
254
|
+
if (getCurrentScope()) onScopeDispose(() => ramp.dispose());
|
|
255
|
+
return ref;
|
|
256
|
+
}
|
|
257
|
+
function createRampRef(ramp) {
|
|
258
|
+
const triggers = /* @__PURE__ */ new Set();
|
|
259
|
+
let unread = false;
|
|
260
|
+
let unsubscribe = null;
|
|
261
|
+
const triggerAll = () => {
|
|
262
|
+
for (const trigger of triggers) trigger();
|
|
263
|
+
};
|
|
264
|
+
const onUpdate = () => {
|
|
265
|
+
if (unread) {
|
|
266
|
+
unsubscribe();
|
|
267
|
+
unsubscribe = null;
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
unread = true;
|
|
271
|
+
triggerAll();
|
|
272
|
+
};
|
|
273
|
+
const read = (trigger) => {
|
|
274
|
+
triggers.add(trigger);
|
|
275
|
+
unread = false;
|
|
276
|
+
if (unsubscribe === null) {
|
|
277
|
+
const offUpdate = ramp.onUpdate(onUpdate);
|
|
278
|
+
const offStart = ramp.onStart(triggerAll);
|
|
279
|
+
const offStop = ramp.onStop(triggerAll);
|
|
280
|
+
unsubscribe = () => {
|
|
281
|
+
offUpdate();
|
|
282
|
+
offStart();
|
|
283
|
+
offStop();
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
};
|
|
287
|
+
const value = customRef((track, trigger) => ({
|
|
288
|
+
get() {
|
|
289
|
+
track();
|
|
290
|
+
read(trigger);
|
|
291
|
+
return ramp.value;
|
|
292
|
+
},
|
|
293
|
+
set(next) {
|
|
294
|
+
ramp.value = next;
|
|
295
|
+
trigger();
|
|
296
|
+
}
|
|
297
|
+
}));
|
|
298
|
+
const readOnly = (get) => customRef((track, trigger) => ({
|
|
299
|
+
get() {
|
|
300
|
+
track();
|
|
301
|
+
read(trigger);
|
|
302
|
+
return get();
|
|
303
|
+
},
|
|
304
|
+
set() {}
|
|
305
|
+
}));
|
|
306
|
+
const ref = Object.assign(value, {
|
|
307
|
+
velocity: readOnly(() => ramp.velocity),
|
|
308
|
+
timeRemaining: readOnly(() => ramp.timeRemaining),
|
|
309
|
+
isResting: readOnly(() => ramp.isResting),
|
|
310
|
+
jumpTo: (next) => ramp.jumpTo(next)
|
|
311
|
+
});
|
|
312
|
+
Object.defineProperty(ref, "settled", { get: () => ramp.settled });
|
|
313
|
+
Object.defineProperty(ref, SpringSourceSymbol, { value: ramp[SpringSourceSymbol] });
|
|
314
|
+
return ref;
|
|
315
|
+
}
|
|
316
|
+
//#endregion
|
|
197
317
|
//#region src/vue/pool.ts
|
|
198
318
|
/**
|
|
199
|
-
* Returns spring factories bound to the provided spring system
|
|
200
|
-
*
|
|
201
|
-
* alive
|
|
202
|
-
* structurally impossible.
|
|
319
|
+
* Returns spring factories bound to the provided spring system. When
|
|
320
|
+
* the current effect scope stops, the pool disposes every pooled spring
|
|
321
|
+
* still alive.
|
|
203
322
|
*
|
|
204
|
-
* Call it during `setup()`
|
|
205
|
-
*
|
|
206
|
-
*
|
|
323
|
+
* Call it during `setup()` or inside an effect scope, below a provided
|
|
324
|
+
* spring system. It throws without one. Outside a scope, you must
|
|
325
|
+
* dispose each pooled spring yourself.
|
|
207
326
|
*/
|
|
208
327
|
function useSpringPool() {
|
|
209
328
|
const system = injectSpringSystem();
|
|
@@ -225,13 +344,14 @@ function useSpringPool() {
|
|
|
225
344
|
//#endregion
|
|
226
345
|
//#region src/vue/component.ts
|
|
227
346
|
/**
|
|
228
|
-
*
|
|
229
|
-
* slot
|
|
230
|
-
* provided spring system.
|
|
347
|
+
* A renderless component that passes one spring's state to its default
|
|
348
|
+
* slot: the template-only form of `useSpring`. It must render below a
|
|
349
|
+
* provided spring system, and throws otherwise. A template ref to it
|
|
350
|
+
* reads the same fields as the slot scope.
|
|
231
351
|
*
|
|
232
352
|
* @example
|
|
233
353
|
* ```vue
|
|
234
|
-
* <SpringValue :target="expanded ? 1 : 0" purpose="
|
|
354
|
+
* <SpringValue :target="expanded ? 1 : 0" purpose="nonmotion" v-slot="{ value }">
|
|
235
355
|
* <div :style="{ opacity: value }" />
|
|
236
356
|
* </SpringValue>
|
|
237
357
|
* ```
|
|
@@ -262,4 +382,4 @@ const SpringValue = defineComponent((props, { slots, expose }) => {
|
|
|
262
382
|
]
|
|
263
383
|
});
|
|
264
384
|
//#endregion
|
|
265
|
-
export { SpringValue, provideSpringSystem, useSpring, useSpringPool, useSpringSystem };
|
|
385
|
+
export { SpringValue, provideSpringSystem, useRamp, useSpring, useSpringPool, useSpringSystem };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "coily",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"description": "Simulate values using spring physics",
|
|
5
5
|
"homepage": "https://github.com/tkofh/coily#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
"sideEffects": false,
|
|
20
20
|
"exports": {
|
|
21
21
|
".": "./dist/index.js",
|
|
22
|
+
"./css": "./dist/css.js",
|
|
22
23
|
"./nuxt": "./dist/nuxt.js",
|
|
23
24
|
"./vue": "./dist/vue.js",
|
|
24
25
|
"./package.json": "./package.json"
|