prosthetic-hand 2.1.0 → 2.1.1
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/lib/Finger.js +3 -3
- package/lib/Hand.js +52 -43
- package/package.json +1 -1
package/lib/Finger.js
CHANGED
|
@@ -199,7 +199,7 @@ export default class Finger {
|
|
|
199
199
|
// 🖐️method moveTo(x: Number, y: Number, delay: Number, options?: {}): this
|
|
200
200
|
// Queues moving this finger to an absolute position at `(x, y)`; the
|
|
201
201
|
// movement will last for `delay` milliseconds.
|
|
202
|
-
moveTo(x, y, delay) {
|
|
202
|
+
moveTo(x, y, delay=0) {
|
|
203
203
|
return this.moveBy(x - this._finalState.x, y - this._finalState.y, delay);
|
|
204
204
|
}
|
|
205
205
|
|
|
@@ -207,7 +207,7 @@ export default class Finger {
|
|
|
207
207
|
// 🖐️method moveBy(x: Number, y: Number, delay: Number, options?: {}): this
|
|
208
208
|
// Queues a move of this finger to an position relative to its last position
|
|
209
209
|
// plus`(x, y)`; the movement will last for `delay` milliseconds.
|
|
210
|
-
moveBy(x, y, delay) {
|
|
210
|
+
moveBy(x, y, delay=0) {
|
|
211
211
|
var fromX = this._finalState.x;
|
|
212
212
|
var fromY = this._finalState.y;
|
|
213
213
|
|
|
@@ -280,7 +280,7 @@ export default class Finger {
|
|
|
280
280
|
* as fas as to `performance.now()`), then checks if the state has changed
|
|
281
281
|
* and means an event should be fired.
|
|
282
282
|
*
|
|
283
|
-
* If `justOne` is set to truthy, then this will run just one
|
|
283
|
+
* If `justOne` is set to truthy, then this will run just one movement.
|
|
284
284
|
* Otherwise, it will run as many movements as needed until `timestamp` is reached.
|
|
285
285
|
*
|
|
286
286
|
* Returns an array of objects of the form `{type: 'foo', event: MouseEvent(...), finger: Finger}`
|
package/lib/Hand.js
CHANGED
|
@@ -21,19 +21,22 @@ var h = new Hand({ timing: '20ms' });
|
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
*/
|
|
24
|
-
export default class Hand {
|
|
24
|
+
export default class Hand extends EventTarget {
|
|
25
|
+
|
|
26
|
+
#fingers = [];
|
|
27
|
+
#fingersAreIdle = true;
|
|
25
28
|
|
|
26
29
|
// 🖐️factory Hand(options?: Hand options): Hand
|
|
27
30
|
// Instantiates a new `Hand` with the given options.
|
|
28
31
|
constructor(options) {
|
|
29
|
-
|
|
32
|
+
super();
|
|
30
33
|
if (!options) {
|
|
31
34
|
options = {};
|
|
32
35
|
}
|
|
33
36
|
|
|
34
|
-
this
|
|
37
|
+
this.#fingers = [];
|
|
35
38
|
|
|
36
|
-
this
|
|
39
|
+
this.#fingersAreIdle = true;
|
|
37
40
|
this._capturedTargets = new Map(),
|
|
38
41
|
|
|
39
42
|
/// TODO: Timing modes: minimal, interval, frames
|
|
@@ -99,18 +102,20 @@ export default class Hand {
|
|
|
99
102
|
// If set to a callback function, it will be called (with the `Hand`
|
|
100
103
|
// as its only argument) whenever the movements start.
|
|
101
104
|
if (options.onStart) {
|
|
102
|
-
this.
|
|
105
|
+
this.addEventListener('start', options.onStart);
|
|
106
|
+
// this._onStart = options.onStart;
|
|
103
107
|
}
|
|
104
108
|
|
|
105
109
|
// 🖐️option onStop: Function
|
|
106
110
|
// If set to a callback function, it will be called (with the `Hand`
|
|
107
111
|
// as its only argument) whenever the movements are completed.
|
|
108
112
|
if (options.onStop) {
|
|
109
|
-
this.
|
|
113
|
+
this.addEventListener('stop', options.onStop);
|
|
114
|
+
// this._onStop = options.onStop;
|
|
110
115
|
}
|
|
111
116
|
|
|
112
117
|
|
|
113
|
-
// Cancellable reference to the next call to
|
|
118
|
+
// Cancellable reference to the next call to `#dispatchEvents`. This
|
|
114
119
|
// might be either a `setTimeout` reference or a `requestAnimationFrame`
|
|
115
120
|
// reference.
|
|
116
121
|
this._nextDispatch = null;
|
|
@@ -129,7 +134,7 @@ export default class Hand {
|
|
|
129
134
|
|
|
130
135
|
var finger = new Finger(fingerMode, options);
|
|
131
136
|
|
|
132
|
-
this.
|
|
137
|
+
this.#fingers.push(finger);
|
|
133
138
|
return finger;
|
|
134
139
|
}
|
|
135
140
|
|
|
@@ -143,19 +148,14 @@ export default class Hand {
|
|
|
143
148
|
|
|
144
149
|
/// TODO: Start up the event loop
|
|
145
150
|
|
|
146
|
-
if (this
|
|
151
|
+
if (this.#fingersAreIdle) {
|
|
147
152
|
// 🖐️section
|
|
148
|
-
// Use `
|
|
149
|
-
//
|
|
150
|
-
// 🖐️event prostheticHandStart: CustomEvent
|
|
153
|
+
// Use `hand.addEventListener('stop', fn)` to do stuff with it.
|
|
154
|
+
// 🖐️event start: CustomEvent
|
|
151
155
|
// Fired when all movements are complete.
|
|
152
|
-
|
|
156
|
+
this.dispatchEvent(new CustomEvent('start', {target: this}));
|
|
153
157
|
|
|
154
|
-
|
|
155
|
-
this._onStart(this);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
this._fingersAreIdle = false;
|
|
158
|
+
this.#fingersAreIdle = false;
|
|
159
159
|
this._scheduleNextDispatch();
|
|
160
160
|
}
|
|
161
161
|
|
|
@@ -166,9 +166,8 @@ export default class Hand {
|
|
|
166
166
|
// Used by this hand's fingers to signal that one finger has finished doing
|
|
167
167
|
// all the queued movements.
|
|
168
168
|
fingerIsIdle() {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
this._fingersAreIdle = true;
|
|
169
|
+
if (this.#fingers.every( f => f.isIdle())) {
|
|
170
|
+
this.#fingersAreIdle = true;
|
|
172
171
|
}
|
|
173
172
|
}
|
|
174
173
|
|
|
@@ -181,7 +180,7 @@ export default class Hand {
|
|
|
181
180
|
|
|
182
181
|
var endTimestamp = performance.now();
|
|
183
182
|
|
|
184
|
-
this.
|
|
183
|
+
this.#fingers.forEach( f => {
|
|
185
184
|
var movesUntil = f._movesUntil;
|
|
186
185
|
if (movesUntil) {
|
|
187
186
|
endTimestamp = Math.max(endTimestamp, movesUntil);
|
|
@@ -190,25 +189,31 @@ export default class Hand {
|
|
|
190
189
|
|
|
191
190
|
var waitUntil = endTimestamp + delay;
|
|
192
191
|
|
|
193
|
-
this.
|
|
192
|
+
this.#fingers.forEach( f => {
|
|
194
193
|
f.waitUntil(waitUntil);
|
|
195
194
|
});
|
|
196
195
|
|
|
197
196
|
}
|
|
198
197
|
|
|
199
198
|
|
|
199
|
+
// 🖐️method run(): Promise to this
|
|
200
|
+
// Returns a `Promise` that resolves when all fingers are idle.
|
|
201
|
+
async run() {
|
|
202
|
+
return new Promise((res)=>{this.addEventListener('stop', res)})
|
|
203
|
+
}
|
|
204
|
+
|
|
200
205
|
|
|
201
206
|
|
|
202
|
-
// 🖐️method
|
|
207
|
+
// 🖐️method private#dispatchEvents(): this
|
|
203
208
|
// Updates all the fingers, fetching their events/touchpoints, and dispatches
|
|
204
209
|
// all `Event`s triggered by the update.
|
|
205
210
|
// This is meant to be called on an internal timer.
|
|
206
|
-
|
|
211
|
+
#dispatchEvents(timestamp) {
|
|
207
212
|
|
|
208
|
-
// 🖐️event
|
|
213
|
+
// 🖐️event tick: CustomEvent
|
|
209
214
|
// Fired a movement is about to start, just before the mouse/touch/pointer
|
|
210
215
|
// events are fired.
|
|
211
|
-
|
|
216
|
+
this.dispatchEvent(new CustomEvent('tick', {target: this}));
|
|
212
217
|
|
|
213
218
|
|
|
214
219
|
var now = timestamp || performance.now();
|
|
@@ -225,7 +230,7 @@ export default class Hand {
|
|
|
225
230
|
this._timingMode === TimingMode.Instant ||
|
|
226
231
|
this._timingMode === TimingMode.FastFrame;
|
|
227
232
|
|
|
228
|
-
this.
|
|
233
|
+
this.#fingers.forEach(f=> {
|
|
229
234
|
|
|
230
235
|
var evs = f.getEvents(now, fast);
|
|
231
236
|
|
|
@@ -266,11 +271,15 @@ export default class Hand {
|
|
|
266
271
|
el = this._capturedTargets.get(ev.pointerId);
|
|
267
272
|
} else {
|
|
268
273
|
el = document.elementFromPoint(ev.clientX, ev.clientY);
|
|
269
|
-
this._hookProstheticCapture(el);
|
|
274
|
+
el && this._hookProstheticCapture(el);
|
|
270
275
|
}
|
|
271
|
-
el.dispatchEvent(ev);
|
|
272
|
-
});
|
|
273
276
|
|
|
277
|
+
if (el) {
|
|
278
|
+
el.dispatchEvent(ev);
|
|
279
|
+
} else {
|
|
280
|
+
console.warning('No target for prosthetic-hand event');
|
|
281
|
+
}
|
|
282
|
+
});
|
|
274
283
|
|
|
275
284
|
/// Build *ONE* `TouchEvent` with `TouchList`s built with
|
|
276
285
|
/// the fingers' touches.
|
|
@@ -452,11 +461,11 @@ export default class Hand {
|
|
|
452
461
|
|
|
453
462
|
|
|
454
463
|
_scheduleNextDispatch(){
|
|
455
|
-
if (this
|
|
456
|
-
// 🖐️event
|
|
464
|
+
if (this.#fingersAreIdle) {
|
|
465
|
+
// 🖐️event stop: CustomEvent
|
|
457
466
|
// Fired when all movements are complete.
|
|
458
467
|
|
|
459
|
-
|
|
468
|
+
this.dispatchEvent(new CustomEvent('stop', {target: this}));
|
|
460
469
|
|
|
461
470
|
|
|
462
471
|
if (this._onStop && this._onStop instanceof Function) {
|
|
@@ -468,10 +477,10 @@ export default class Hand {
|
|
|
468
477
|
// Calculate time for next movement end. Could be refactored out for
|
|
469
478
|
// some timing modes.
|
|
470
479
|
var min = Infinity;
|
|
471
|
-
this.
|
|
480
|
+
this.#fingers.forEach(f=> {
|
|
472
481
|
if (!f.isIdle()) {
|
|
473
482
|
var next = f.getNextMoveEndTime();
|
|
474
|
-
//
|
|
483
|
+
// console.log('next:', next);
|
|
475
484
|
if (next < min) {
|
|
476
485
|
min = next;
|
|
477
486
|
}
|
|
@@ -480,20 +489,20 @@ export default class Hand {
|
|
|
480
489
|
|
|
481
490
|
|
|
482
491
|
if (this._timingMode === TimingMode.Interval) {
|
|
483
|
-
this._nextDispatch = setTimeout(this.
|
|
492
|
+
this._nextDispatch = setTimeout(this.#dispatchEvents.bind(this), this._timeInterval);
|
|
484
493
|
|
|
485
494
|
} else if (this._timingMode === TimingMode.Minimal) {
|
|
486
|
-
this._nextDispatch = setTimeout(this.
|
|
495
|
+
this._nextDispatch = setTimeout(this.#dispatchEvents.bind(this), min - performance.now());
|
|
487
496
|
|
|
488
497
|
} else if (this._timingMode === TimingMode.Instant) {
|
|
489
|
-
return this
|
|
498
|
+
return this.#dispatchEvents(min);
|
|
490
499
|
|
|
491
500
|
} else if (this._timingMode === TimingMode.Frame) {
|
|
492
|
-
this._nextDispatch = requestAnimationFrame( this.
|
|
501
|
+
this._nextDispatch = requestAnimationFrame( this.#dispatchEvents.bind(this) );
|
|
493
502
|
|
|
494
503
|
} else if (this._timingMode === TimingMode.FastFrame) {
|
|
495
504
|
this._nextDispatch = requestAnimationFrame( function() {
|
|
496
|
-
this
|
|
505
|
+
this.#dispatchEvents(min);
|
|
497
506
|
}.bind(this));
|
|
498
507
|
|
|
499
508
|
}
|
|
@@ -508,7 +517,7 @@ export default class Hand {
|
|
|
508
517
|
const releaseFn = el.releasePointerCapture;
|
|
509
518
|
el.setPointerCapture = ((id)=> {
|
|
510
519
|
if (id >= 1000) {
|
|
511
|
-
console.log('capture', id, el)
|
|
520
|
+
// console.log('capture', id, el)
|
|
512
521
|
this._capturedTargets.set(id, el);
|
|
513
522
|
} else
|
|
514
523
|
return captureFn.call(el, id);
|
|
@@ -516,7 +525,7 @@ export default class Hand {
|
|
|
516
525
|
|
|
517
526
|
el.releasePointerCapture = ((id)=> {
|
|
518
527
|
if (this._capturedTargets.get(id) === el) {
|
|
519
|
-
console.log('release', id, el)
|
|
528
|
+
// console.log('release', id, el)
|
|
520
529
|
this._capturedTargets.delete(id);
|
|
521
530
|
} else
|
|
522
531
|
return releaseFn.call(el, id);
|