coily 0.1.1 → 0.3.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.cjs CHANGED
@@ -17,7 +17,14 @@ var __copyProps = (to, from, except, desc) => {
17
17
  }
18
18
  return to;
19
19
  };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod));
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
21
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
22
29
 
23
30
  // src/index.ts
@@ -51,13 +58,14 @@ var getArrivalFunction = (behavior) => {
51
58
  return result;
52
59
  };
53
60
  var createSpringImpl = (initial, config, options) => {
61
+ var _a, _b, _c;
54
62
  let state = "resting";
55
63
  let velocity = 0;
56
64
  let target = initial;
57
65
  let value = initial;
58
- const restingDistance = Math.max((options == null ? void 0 : options.restingDistance) ?? 1e-4, 0);
59
- const restingVelocity = Math.max((options == null ? void 0 : options.restingVelocity) ?? 1e-4, 0);
60
- const arrivalFunction = getArrivalFunction((options == null ? void 0 : options.arrivalBehavior) ?? 1);
66
+ const restingDistance = Math.max((_a = options == null ? void 0 : options.restingDistance) != null ? _a : 1e-4, 0);
67
+ const restingVelocity = Math.max((_b = options == null ? void 0 : options.restingVelocity) != null ? _b : 1e-4, 0);
68
+ const arrivalFunction = getArrivalFunction((_c = options == null ? void 0 : options.arrivalBehavior) != null ? _c : 1);
61
69
  const emitter = (0, import_mitt.default)();
62
70
  const { emit, ...emitterApi } = emitter;
63
71
  const spring = {
@@ -67,26 +75,38 @@ var createSpringImpl = (initial, config, options) => {
67
75
  },
68
76
  set target(val) {
69
77
  target = val;
70
- if (Math.abs(value - target) > restingDistance) {
78
+ if (state !== "moving" && Math.abs(value - target) > restingDistance) {
71
79
  state = "moving";
72
80
  emit("update:state", state);
73
81
  }
74
82
  },
83
+ getTarget: () => target,
75
84
  get value() {
76
85
  return value;
77
86
  },
87
+ getValue: () => value,
78
88
  get velocity() {
79
89
  return velocity;
80
90
  },
91
+ getVelocity: () => velocity,
81
92
  get state() {
82
93
  return state;
83
94
  },
95
+ getState: () => state,
84
96
  get config() {
85
97
  return config;
86
98
  },
87
99
  set config(value2) {
88
100
  config = value2;
89
101
  },
102
+ getConfig: () => config,
103
+ jumpTo: (_value, killVelocity = true) => {
104
+ value = _value;
105
+ if (killVelocity) {
106
+ velocity = 0;
107
+ }
108
+ state = Math.abs(velocity) > restingVelocity || Math.abs(value - target) > restingDistance ? "moving" : "resting";
109
+ },
90
110
  freeze: () => {
91
111
  state = "frozen";
92
112
  emit("update:state", state);
@@ -96,13 +116,15 @@ var createSpringImpl = (initial, config, options) => {
96
116
  emit("update:state", state);
97
117
  }
98
118
  };
119
+ const tension = -config.tension * 1e-6;
120
+ const friction = -config.friction * 1e-3;
99
121
  const simulate = (deltaTime) => {
100
122
  if (state === "moving") {
101
123
  const iterations = Math.ceil(deltaTime);
102
124
  for (let n = 0; n < iterations; n++) {
103
125
  const previousDelta = value - target;
104
- const springForce = -config.tension * 1e-6 * previousDelta;
105
- const dampingForce = -config.friction * 1e-3 * velocity;
126
+ const springForce = tension * previousDelta;
127
+ const dampingForce = friction * velocity;
106
128
  const acceleration = (springForce + dampingForce) / config.mass;
107
129
  velocity = velocity + acceleration;
108
130
  value = value + velocity;
@@ -161,7 +183,12 @@ var createSpringChainImpl = (initial, links, config, options) => {
161
183
  if (typeof link === "number") {
162
184
  spring.target = previousSpring.value + link;
163
185
  } else {
164
- spring.target = link(previousSpring.value, previousSpring.target, spring.value, spring.target);
186
+ spring.target = link(
187
+ previousSpring.value,
188
+ previousSpring.target,
189
+ spring.value,
190
+ spring.target
191
+ );
165
192
  }
166
193
  targets[index + 1] = spring.target;
167
194
  states[index + 1] = spring.state;
@@ -169,7 +196,11 @@ var createSpringChainImpl = (initial, links, config, options) => {
169
196
  state = "moving";
170
197
  }
171
198
  } else {
172
- const [spring, simulate2] = createSpringImpl(typeof link === "number" ? previousSpring.value + link : link(previousSpring.value, previousSpring.target), config, options);
199
+ const [spring, simulate2] = createSpringImpl(
200
+ typeof link === "number" ? previousSpring.value + link : link(previousSpring.value, previousSpring.target),
201
+ config,
202
+ options
203
+ );
173
204
  springs.push(spring);
174
205
  simulateFns.push(simulate2);
175
206
  targets[index + 1] = spring.target;
@@ -224,9 +255,11 @@ var createSpringChainImpl = (initial, links, config, options) => {
224
255
  currentTarget = val;
225
256
  updateChainState(currentTarget, currentLinks);
226
257
  },
258
+ getTarget: () => targets[0],
227
259
  get targets() {
228
260
  return targets;
229
261
  },
262
+ getTargets: () => targets,
230
263
  get links() {
231
264
  return links;
232
265
  },
@@ -237,18 +270,23 @@ var createSpringChainImpl = (initial, links, config, options) => {
237
270
  get config() {
238
271
  return config;
239
272
  },
273
+ getConfig: () => config,
240
274
  get values() {
241
275
  return values;
242
276
  },
277
+ getValues: () => values,
243
278
  get velocities() {
244
279
  return velocities;
245
280
  },
281
+ getVelocities: () => velocities,
246
282
  get state() {
247
283
  return state;
248
284
  },
285
+ getState: () => state,
249
286
  get states() {
250
287
  return states;
251
288
  },
289
+ getStates: () => states,
252
290
  freeze: () => {
253
291
  for (const spring of springs) {
254
292
  spring.freeze();
package/dist/index.d.ts CHANGED
@@ -5,46 +5,59 @@ interface SpringConfig {
5
5
  tension: number;
6
6
  friction: number;
7
7
  }
8
- declare type SpringArrivalBehavior = 'bounce' | 'clamp' | 'none' | number | ((velocity: number) => number);
8
+ type SpringArrivalBehavior = 'bounce' | 'clamp' | 'none' | number | ((velocity: number) => number);
9
9
  interface SpringOptions {
10
10
  restingDistance?: number;
11
11
  restingVelocity?: number;
12
12
  arrivalBehavior?: SpringArrivalBehavior;
13
13
  }
14
- declare type SpringState = 'moving' | 'frozen' | 'resting';
15
- declare type SpringEmitter = Emitter<{
14
+ type SpringState = 'moving' | 'frozen' | 'resting';
15
+ type SpringEmitter = Emitter<{
16
16
  'update:value': number;
17
17
  'update:state': SpringState;
18
18
  '*': number | SpringState;
19
19
  }>;
20
20
  interface Spring extends Omit<SpringEmitter, 'emit'> {
21
21
  target: number;
22
+ readonly getTarget: () => number;
22
23
  config: Readonly<SpringConfig>;
24
+ readonly getConfig: () => Readonly<SpringConfig>;
23
25
  readonly value: number;
26
+ readonly getValue: () => number;
24
27
  readonly velocity: number;
28
+ readonly getVelocity: () => number;
25
29
  readonly state: SpringState;
30
+ readonly getState: () => SpringState;
31
+ readonly jumpTo: (value: number, killVelocity?: boolean) => void;
26
32
  readonly freeze: () => void;
27
33
  readonly unfreeze: () => void;
28
34
  }
29
- declare type SimulateFn = (delta: number) => void;
35
+ type SimulateFn = (delta: number) => void;
30
36
  interface StandaloneSpring extends Spring {
31
37
  readonly simulate: SimulateFn;
32
38
  }
33
- declare type SpringChainLinkGetter = number | ((previousValue: number, previousTarget: number, currentValue?: number, currentTarget?: number) => number);
34
- declare type SpringChainEmitter = Emitter<{
39
+ type SpringChainLinkGetter = number | ((previousValue: number, previousTarget: number, currentValue?: number, currentTarget?: number) => number);
40
+ type SpringChainEmitter = Emitter<{
35
41
  'update:value': number[];
36
42
  'update:state': SpringState;
37
43
  '*': number[] | SpringState;
38
44
  }>;
39
45
  interface SpringChain extends Omit<SpringChainEmitter, 'emit'> {
40
46
  target: number;
47
+ readonly getTarget: () => number;
41
48
  links: SpringChainLinkGetter[];
42
49
  config: Readonly<SpringConfig>;
50
+ readonly getConfig: () => Readonly<SpringConfig>;
43
51
  readonly targets: ReadonlyArray<number>;
52
+ readonly getTargets: () => ReadonlyArray<number>;
44
53
  readonly values: ReadonlyArray<number>;
54
+ readonly getValues: () => ReadonlyArray<number>;
45
55
  readonly velocities: ReadonlyArray<number>;
56
+ readonly getVelocities: () => ReadonlyArray<number>;
46
57
  readonly state: SpringState;
58
+ readonly getState: () => SpringState;
47
59
  readonly states: ReadonlyArray<SpringState>;
60
+ readonly getStates: () => ReadonlyArray<SpringState>;
48
61
  readonly freeze: () => void;
49
62
  readonly unfreeze: () => void;
50
63
  }
package/dist/index.js CHANGED
@@ -20,13 +20,14 @@ var getArrivalFunction = (behavior) => {
20
20
  return result;
21
21
  };
22
22
  var createSpringImpl = (initial, config, options) => {
23
+ var _a, _b, _c;
23
24
  let state = "resting";
24
25
  let velocity = 0;
25
26
  let target = initial;
26
27
  let value = initial;
27
- const restingDistance = Math.max((options == null ? void 0 : options.restingDistance) ?? 1e-4, 0);
28
- const restingVelocity = Math.max((options == null ? void 0 : options.restingVelocity) ?? 1e-4, 0);
29
- const arrivalFunction = getArrivalFunction((options == null ? void 0 : options.arrivalBehavior) ?? 1);
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);
30
31
  const emitter = mitt();
31
32
  const { emit, ...emitterApi } = emitter;
32
33
  const spring = {
@@ -36,26 +37,38 @@ var createSpringImpl = (initial, config, options) => {
36
37
  },
37
38
  set target(val) {
38
39
  target = val;
39
- if (Math.abs(value - target) > restingDistance) {
40
+ if (state !== "moving" && Math.abs(value - target) > restingDistance) {
40
41
  state = "moving";
41
42
  emit("update:state", state);
42
43
  }
43
44
  },
45
+ getTarget: () => target,
44
46
  get value() {
45
47
  return value;
46
48
  },
49
+ getValue: () => value,
47
50
  get velocity() {
48
51
  return velocity;
49
52
  },
53
+ getVelocity: () => velocity,
50
54
  get state() {
51
55
  return state;
52
56
  },
57
+ getState: () => state,
53
58
  get config() {
54
59
  return config;
55
60
  },
56
61
  set config(value2) {
57
62
  config = value2;
58
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
+ },
59
72
  freeze: () => {
60
73
  state = "frozen";
61
74
  emit("update:state", state);
@@ -65,13 +78,15 @@ var createSpringImpl = (initial, config, options) => {
65
78
  emit("update:state", state);
66
79
  }
67
80
  };
81
+ const tension = -config.tension * 1e-6;
82
+ const friction = -config.friction * 1e-3;
68
83
  const simulate = (deltaTime) => {
69
84
  if (state === "moving") {
70
85
  const iterations = Math.ceil(deltaTime);
71
86
  for (let n = 0; n < iterations; n++) {
72
87
  const previousDelta = value - target;
73
- const springForce = -config.tension * 1e-6 * previousDelta;
74
- const dampingForce = -config.friction * 1e-3 * velocity;
88
+ const springForce = tension * previousDelta;
89
+ const dampingForce = friction * velocity;
75
90
  const acceleration = (springForce + dampingForce) / config.mass;
76
91
  velocity = velocity + acceleration;
77
92
  value = value + velocity;
@@ -130,7 +145,12 @@ var createSpringChainImpl = (initial, links, config, options) => {
130
145
  if (typeof link === "number") {
131
146
  spring.target = previousSpring.value + link;
132
147
  } else {
133
- spring.target = link(previousSpring.value, previousSpring.target, spring.value, spring.target);
148
+ spring.target = link(
149
+ previousSpring.value,
150
+ previousSpring.target,
151
+ spring.value,
152
+ spring.target
153
+ );
134
154
  }
135
155
  targets[index + 1] = spring.target;
136
156
  states[index + 1] = spring.state;
@@ -138,7 +158,11 @@ var createSpringChainImpl = (initial, links, config, options) => {
138
158
  state = "moving";
139
159
  }
140
160
  } else {
141
- const [spring, simulate2] = createSpringImpl(typeof link === "number" ? previousSpring.value + link : link(previousSpring.value, previousSpring.target), config, options);
161
+ const [spring, simulate2] = createSpringImpl(
162
+ typeof link === "number" ? previousSpring.value + link : link(previousSpring.value, previousSpring.target),
163
+ config,
164
+ options
165
+ );
142
166
  springs.push(spring);
143
167
  simulateFns.push(simulate2);
144
168
  targets[index + 1] = spring.target;
@@ -193,9 +217,11 @@ var createSpringChainImpl = (initial, links, config, options) => {
193
217
  currentTarget = val;
194
218
  updateChainState(currentTarget, currentLinks);
195
219
  },
220
+ getTarget: () => targets[0],
196
221
  get targets() {
197
222
  return targets;
198
223
  },
224
+ getTargets: () => targets,
199
225
  get links() {
200
226
  return links;
201
227
  },
@@ -206,18 +232,23 @@ var createSpringChainImpl = (initial, links, config, options) => {
206
232
  get config() {
207
233
  return config;
208
234
  },
235
+ getConfig: () => config,
209
236
  get values() {
210
237
  return values;
211
238
  },
239
+ getValues: () => values,
212
240
  get velocities() {
213
241
  return velocities;
214
242
  },
243
+ getVelocities: () => velocities,
215
244
  get state() {
216
245
  return state;
217
246
  },
247
+ getState: () => state,
218
248
  get states() {
219
249
  return states;
220
250
  },
251
+ getStates: () => states,
221
252
  freeze: () => {
222
253
  for (const spring of springs) {
223
254
  spring.freeze();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "coily",
3
- "version": "0.1.1",
3
+ "version": "0.3.0",
4
4
  "description": "Simulate values using spring physics",
5
5
  "author": "Tim Morris <timthewebguy@gmail.com>",
6
6
  "homepage": "https://github.com/tkofh/coily#readme",
@@ -32,18 +32,18 @@
32
32
  "test": "vitest run",
33
33
  "test:watch": "vitest watch",
34
34
  "test:ui": "vitest --ui",
35
- "prepublish": "yarn test && yarn build"
35
+ "prepublish": "pnpm test && pnpm build"
36
36
  },
37
37
  "bugs": {
38
38
  "url": "https://github.com/tkofh/coily/issues"
39
39
  },
40
40
  "devDependencies": {
41
- "@vitest/ui": "^0.11.0",
42
- "tsup": "^6.1.3",
43
- "vitest": "^0.16.0"
41
+ "@vitest/ui": "^0.29.2",
42
+ "tsup": "^6.6.3",
43
+ "vitest": "^0.29.2"
44
44
  },
45
45
  "dependencies": {
46
46
  "mitt": "^3.0.0"
47
47
  },
48
- "gitHead": "ed6733ca1768b44341f0ed05f8750466089ddbc1"
48
+ "gitHead": "f6f52d538e85578e1d734a729e4161f54c5b900f"
49
49
  }