coily 0.4.1 → 0.5.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/dist/index.d.ts DELETED
@@ -1,84 +0,0 @@
1
- import { Emitter } from 'mitt';
2
-
3
- interface SpringConfig {
4
- mass: number;
5
- tension: number;
6
- friction: number;
7
- }
8
- type SpringArrivalBehavior = 'bounce' | 'clamp' | 'none' | number | ((velocity: number) => number);
9
- interface SpringOptions {
10
- restingDistance?: number;
11
- restingVelocity?: number;
12
- arrivalBehavior?: SpringArrivalBehavior;
13
- }
14
- type SpringState = 'moving' | 'frozen' | 'resting';
15
- type SpringEmitter = Emitter<{
16
- 'update:value': number;
17
- 'update:state': SpringState;
18
- '*': number | SpringState;
19
- }>;
20
- interface Spring extends Omit<SpringEmitter, 'emit'> {
21
- target: number;
22
- readonly getTarget: () => number;
23
- config: Readonly<SpringConfig>;
24
- readonly getConfig: () => Readonly<SpringConfig>;
25
- readonly value: number;
26
- readonly getValue: () => number;
27
- readonly velocity: number;
28
- readonly getVelocity: () => number;
29
- readonly state: SpringState;
30
- readonly getState: () => SpringState;
31
- readonly jumpTo: (value: number, killVelocity?: boolean) => void;
32
- readonly freeze: () => void;
33
- readonly unfreeze: () => void;
34
- }
35
- type SimulateFn = (delta: number) => void;
36
- interface StandaloneSpring extends Spring {
37
- readonly simulate: SimulateFn;
38
- }
39
- type SpringChainLinkGetter = number | ((previousValue: number, previousTarget: number, currentValue?: number, currentTarget?: number) => number);
40
- type SpringChainEmitter = Emitter<{
41
- 'update:value': number[];
42
- 'update:state': SpringState;
43
- '*': number[] | SpringState;
44
- }>;
45
- interface SpringChain extends Omit<SpringChainEmitter, 'emit'> {
46
- target: number;
47
- readonly getTarget: () => number;
48
- links: SpringChainLinkGetter[];
49
- config: Readonly<SpringConfig>;
50
- readonly getConfig: () => Readonly<SpringConfig>;
51
- readonly targets: ReadonlyArray<number>;
52
- readonly getTargets: () => ReadonlyArray<number>;
53
- readonly values: ReadonlyArray<number>;
54
- readonly getValues: () => ReadonlyArray<number>;
55
- readonly velocities: ReadonlyArray<number>;
56
- readonly getVelocities: () => ReadonlyArray<number>;
57
- readonly state: SpringState;
58
- readonly getState: () => SpringState;
59
- readonly states: ReadonlyArray<SpringState>;
60
- readonly getStates: () => ReadonlyArray<SpringState>;
61
- readonly freeze: () => void;
62
- readonly unfreeze: () => void;
63
- }
64
- interface StandaloneSpringChain extends SpringChain {
65
- readonly simulate: SimulateFn;
66
- }
67
- type SpringSystemEmitter = Emitter<{
68
- 'simulate:after': number;
69
- '*': number;
70
- }>;
71
- interface SpringSystem extends Omit<SpringSystemEmitter, 'emit'> {
72
- createSpring: (initial: number, config: SpringConfig, options?: SpringOptions) => Spring;
73
- createSpringChain: (initial: number, links: SpringChainLinkGetter[], config: SpringConfig, options?: SpringOptions) => SpringChain;
74
- cleanup: (spring: Spring | SpringChain) => void;
75
- simulate: SimulateFn;
76
- }
77
-
78
- declare const createSpring: (initial: number, config: SpringConfig, options?: SpringOptions) => StandaloneSpring;
79
-
80
- declare const createSpringChain: (initial: number, links: SpringChainLinkGetter[], config: SpringConfig, options?: SpringOptions) => StandaloneSpringChain;
81
-
82
- declare const createSpringSystem: () => SpringSystem;
83
-
84
- export { SimulateFn, Spring, SpringArrivalBehavior, SpringChain, SpringChainLinkGetter, SpringConfig, SpringOptions, SpringState, SpringSystem, StandaloneSpring, StandaloneSpringChain, createSpring, createSpringChain, createSpringSystem };
package/dist/index.js DELETED
@@ -1,318 +0,0 @@
1
- // src/lib/createSpring.ts
2
- import mitt from "mitt";
3
- var getArrivalFunction = (behavior) => {
4
- let result;
5
- if (typeof behavior === "function") {
6
- result = behavior;
7
- } else {
8
- let scalar;
9
- if (typeof behavior === "number") {
10
- scalar = behavior;
11
- } else if (behavior === "bounce") {
12
- scalar = -1;
13
- } else if (behavior === "clamp") {
14
- scalar = 0;
15
- } else if (behavior === "none") {
16
- scalar = 1;
17
- }
18
- result = (velocity) => velocity * scalar;
19
- }
20
- return result;
21
- };
22
- var createSpringImpl = (initial, config, options) => {
23
- var _a, _b, _c;
24
- let state = "resting";
25
- let velocity = 0;
26
- let target = initial;
27
- let value = initial;
28
- const restingDistance = Math.max((_a = options == null ? void 0 : options.restingDistance) != null ? _a : 1e-4, 0);
29
- const restingVelocity = Math.max((_b = options == null ? void 0 : options.restingVelocity) != null ? _b : 1e-4, 0);
30
- const arrivalFunction = getArrivalFunction((_c = options == null ? void 0 : options.arrivalBehavior) != null ? _c : 1);
31
- const emitter = mitt();
32
- const { emit, ...emitterApi } = emitter;
33
- const spring = {
34
- ...emitterApi,
35
- get target() {
36
- return target;
37
- },
38
- set target(val) {
39
- target = val;
40
- if (state !== "moving" && Math.abs(value - target) > restingDistance) {
41
- state = "moving";
42
- emit("update:state", state);
43
- }
44
- },
45
- getTarget: () => target,
46
- get value() {
47
- return value;
48
- },
49
- getValue: () => value,
50
- get velocity() {
51
- return velocity;
52
- },
53
- getVelocity: () => velocity,
54
- get state() {
55
- return state;
56
- },
57
- getState: () => state,
58
- get config() {
59
- return config;
60
- },
61
- set config(value2) {
62
- config = value2;
63
- },
64
- getConfig: () => config,
65
- jumpTo: (_value, killVelocity = true) => {
66
- value = _value;
67
- if (killVelocity) {
68
- velocity = 0;
69
- }
70
- state = Math.abs(velocity) > restingVelocity || Math.abs(value - target) > restingDistance ? "moving" : "resting";
71
- },
72
- freeze: () => {
73
- state = "frozen";
74
- emit("update:state", state);
75
- },
76
- unfreeze: () => {
77
- state = Math.abs(velocity) > restingVelocity || Math.abs(value - target) > restingDistance ? "moving" : "resting";
78
- emit("update:state", state);
79
- }
80
- };
81
- const simulate = (deltaTime) => {
82
- if (state === "moving") {
83
- const iterations = Math.ceil(deltaTime);
84
- for (let n = 0; n < iterations; n++) {
85
- const previousDelta = value - target;
86
- const springForce = -config.tension * 1e-6 * previousDelta;
87
- const dampingForce = -config.friction * 1e-3 * velocity;
88
- const acceleration = (springForce + dampingForce) / config.mass;
89
- velocity = velocity + acceleration;
90
- value = value + velocity;
91
- const delta = value - target;
92
- const absDelta = Math.abs(delta);
93
- if (Math.sign(delta) !== Math.sign(previousDelta)) {
94
- velocity = arrivalFunction(velocity * 1e3) * 1e-3;
95
- value = target + velocity * (absDelta / (absDelta + Math.abs(previousDelta)));
96
- }
97
- if (absDelta < restingDistance && Math.abs(velocity) < restingVelocity) {
98
- value = target;
99
- state = "resting";
100
- emit("update:state", state);
101
- break;
102
- }
103
- }
104
- emit("update:value", value);
105
- }
106
- };
107
- return [spring, simulate];
108
- };
109
-
110
- // src/lib/createSpringChain.ts
111
- import mitt2 from "mitt";
112
- var createSpringChainImpl = (initial, links, config, options) => {
113
- const simulateFns = [];
114
- const springs = [];
115
- const targets = [];
116
- const values = [];
117
- const velocities = [];
118
- const states = [];
119
- let currentTarget = initial;
120
- let currentLinks = links;
121
- let state = "resting";
122
- const updateChainState = (target, links2) => {
123
- if (springs.length === 0) {
124
- const [spring, simulate2] = createSpringImpl(target, config, options);
125
- springs.push(spring);
126
- simulateFns.push(simulate2);
127
- targets.push(spring.target);
128
- values.push(spring.value);
129
- velocities.push(spring.velocity);
130
- states.push(spring.state);
131
- } else {
132
- springs[0].target = target;
133
- targets[0] = target;
134
- states[0] = springs[0].state;
135
- if (state === "resting" && springs[0].state === "moving") {
136
- state = "moving";
137
- }
138
- }
139
- for (const [index, link] of links2.entries()) {
140
- const previousSpring = springs[index];
141
- if (springs[index + 1]) {
142
- const spring = springs[index + 1];
143
- if (typeof link === "number") {
144
- spring.target = previousSpring.value + link;
145
- } else {
146
- spring.target = link(
147
- previousSpring.value,
148
- previousSpring.target,
149
- spring.value,
150
- spring.target
151
- );
152
- }
153
- targets[index + 1] = spring.target;
154
- states[index + 1] = spring.state;
155
- if (state === "resting" && spring.state === "moving") {
156
- state = "moving";
157
- }
158
- } else {
159
- const [spring, simulate2] = createSpringImpl(
160
- typeof link === "number" ? previousSpring.value + link : link(previousSpring.value, previousSpring.target),
161
- config,
162
- options
163
- );
164
- springs.push(spring);
165
- simulateFns.push(simulate2);
166
- targets[index + 1] = spring.target;
167
- values[index + 1] = spring.value;
168
- velocities[index + 1] = spring.velocity;
169
- states[index + 1] = spring.state;
170
- }
171
- }
172
- const cutoff = springs.length + 1;
173
- if (springs.length > cutoff) {
174
- const deleteCount = springs.length - cutoff;
175
- springs.splice(cutoff, deleteCount);
176
- simulateFns.splice(cutoff, deleteCount);
177
- targets.splice(cutoff, deleteCount);
178
- values.splice(cutoff, deleteCount);
179
- velocities.splice(cutoff, deleteCount);
180
- states.splice(cutoff, deleteCount);
181
- }
182
- };
183
- updateChainState(currentTarget, currentLinks);
184
- const emitter = mitt2();
185
- const { emit, ...emitterApi } = emitter;
186
- const simulate = (delta) => {
187
- if (state === "moving") {
188
- let moving = false;
189
- for (let i = 0; i < springs.length; i++) {
190
- simulateFns[i](delta);
191
- if (i < springs.length - 1) {
192
- const link = links[i];
193
- springs[i + 1].target = typeof link === "number" ? springs[i].value + link : link(springs[i].value, springs[i].target, springs[i + 1].value);
194
- }
195
- targets[i] = springs[i].target;
196
- values[i] = springs[i].value;
197
- velocities[i] = springs[i].velocity;
198
- states[i] = springs[i].state;
199
- moving = moving || springs[i].state === "moving";
200
- }
201
- emit("update:value", values);
202
- if (!moving) {
203
- state = "resting";
204
- emit("update:state", state);
205
- }
206
- }
207
- };
208
- return [
209
- {
210
- ...emitterApi,
211
- get target() {
212
- return targets[0];
213
- },
214
- set target(val) {
215
- currentTarget = val;
216
- updateChainState(currentTarget, currentLinks);
217
- },
218
- getTarget: () => targets[0],
219
- get targets() {
220
- return targets;
221
- },
222
- getTargets: () => targets,
223
- get links() {
224
- return links;
225
- },
226
- set links(val) {
227
- currentLinks = val;
228
- updateChainState(currentTarget, currentLinks);
229
- },
230
- get config() {
231
- return config;
232
- },
233
- getConfig: () => config,
234
- get values() {
235
- return values;
236
- },
237
- getValues: () => values,
238
- get velocities() {
239
- return velocities;
240
- },
241
- getVelocities: () => velocities,
242
- get state() {
243
- return state;
244
- },
245
- getState: () => state,
246
- get states() {
247
- return states;
248
- },
249
- getStates: () => states,
250
- freeze: () => {
251
- for (const spring of springs) {
252
- spring.freeze();
253
- }
254
- state = "frozen";
255
- emit("update:state", state);
256
- },
257
- unfreeze: () => {
258
- let moving = false;
259
- for (const spring of springs) {
260
- spring.unfreeze();
261
- moving = moving || spring.state === "moving";
262
- }
263
- state = moving ? "moving" : "resting";
264
- emit("update:state", state);
265
- }
266
- },
267
- simulate
268
- ];
269
- };
270
-
271
- // src/createSpring.ts
272
- var createSpring = (initial, config, options) => {
273
- const [spring, simulate] = createSpringImpl(initial, config, options);
274
- return Object.assign(spring, { simulate });
275
- };
276
-
277
- // src/createSpringChain.ts
278
- var createSpringChain = (initial, links, config, options) => {
279
- const [chain, simulate] = createSpringChainImpl(initial, links, config, options);
280
- return Object.assign(chain, { simulate });
281
- };
282
-
283
- // src/createSpringSystem.ts
284
- import mitt3 from "mitt";
285
- var createSpringSystem = () => {
286
- const springs = /* @__PURE__ */ new Map();
287
- const { emit, ...emitterApi } = mitt3();
288
- return {
289
- ...emitterApi,
290
- createSpring: (initial, config, options) => {
291
- const [spring, simulate] = createSpringImpl(initial, config, options);
292
- springs.set(spring, simulate);
293
- return spring;
294
- },
295
- createSpringChain: (initial, links, config, options) => {
296
- const [chain, simulate] = createSpringChainImpl(initial, links, config, options);
297
- springs.set(chain, simulate);
298
- return chain;
299
- },
300
- cleanup: (spring) => {
301
- springs.delete(spring);
302
- spring.off("*");
303
- spring.off("update:state");
304
- spring.off("update:value");
305
- },
306
- simulate: (delta) => {
307
- for (const simulate of springs.values()) {
308
- simulate(delta);
309
- }
310
- emit("simulate:after", delta);
311
- }
312
- };
313
- };
314
- export {
315
- createSpring,
316
- createSpringChain,
317
- createSpringSystem
318
- };