westures-core 1.2.1 → 1.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/CHANGELOG.md +11 -0
- package/README.md +3 -14
- package/dist/index.js +111 -111
- package/dist/index.js.map +1 -1
- package/package.json +30 -14
- package/src/Input.js +6 -2
- package/src/Region.js +40 -10
- package/src/State.js +39 -37
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.3.0
|
|
4
|
+
|
|
5
|
+
- Introduce "headless" mode, which allows westures to be run in a server environment.
|
|
6
|
+
|
|
7
|
+
## 1.2.0
|
|
8
|
+
|
|
9
|
+
- Switch to "parcel" from "parcel-bundler"
|
|
10
|
+
- Add a list of the PHASES to constants.js
|
|
11
|
+
- Provide Input.elapsedTime
|
|
12
|
+
- Provide Point2D.anglesTo()
|
|
13
|
+
|
|
3
14
|
## 1.1.0
|
|
4
15
|
|
|
5
16
|
- Switch to using pointer events by default, combined with setting touch-action:
|
package/README.md
CHANGED
|
@@ -1,14 +1,8 @@
|
|
|
1
1
|
# westures-core
|
|
2
2
|
|
|
3
|
-
[
|
|
8
|
-
](https://coveralls.io/github/mvanderkamp/westures-core?branch=master)
|
|
9
|
-
[
|
|
11
|
-
](https://codeclimate.com/github/mvanderkamp/westures-core/maintainability)
|
|
3
|
+
[](https://github.com/mvanderkamp/westures-core/actions/workflows/node.js.yml)
|
|
4
|
+
[](https://coveralls.io/github/mvanderkamp/westures-core?branch=main)
|
|
5
|
+
[](https://codeclimate.com/github/mvanderkamp/westures-core/maintainability)
|
|
12
6
|
|
|
13
7
|
Westures is a robust n-pointer multitouch gesture detection library for
|
|
14
8
|
JavaScript. This means that each gesture is be capable of working seamlessly as
|
|
@@ -111,11 +105,6 @@ Name | Description
|
|
|
111
105
|
constants | Constant values used throughout the engine
|
|
112
106
|
utils | Helpful utility functions
|
|
113
107
|
|
|
114
|
-
Here is a graph to help you understand the relationships between these classes:
|
|
115
|
-
|
|
116
|
-

|
|
118
|
-
|
|
119
108
|
## Basic Usage
|
|
120
109
|
|
|
121
110
|
- [Declaring a Region](#declaring-a-region)
|
package/dist/index.js
CHANGED
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
* and routines used by the package. Use responsibly.
|
|
4
4
|
*
|
|
5
5
|
* @namespace westures-core
|
|
6
|
-
*/
|
|
6
|
+
*/ "use strict";
|
|
7
7
|
var $de0d6a332419bf3c$exports = {};
|
|
8
|
-
|
|
8
|
+
"use strict";
|
|
9
9
|
let $de0d6a332419bf3c$var$g_id = 0;
|
|
10
10
|
/**
|
|
11
11
|
* The Gesture class that all gestures inherit from. A custom gesture class will
|
|
@@ -32,9 +32,8 @@ let $de0d6a332419bf3c$var$g_id = 0;
|
|
|
32
32
|
* @param {number} [options.maxInputs=Number.MAX_VALUE] - The maximum number of
|
|
33
33
|
* pointers that may be active for the gesture to be recognized. Uses <=.
|
|
34
34
|
*/ class $de0d6a332419bf3c$var$Gesture {
|
|
35
|
-
constructor(type, element, handler, options = {
|
|
36
|
-
|
|
37
|
-
if (typeof type !== 'string') throw new TypeError('Gestures require a string type / name');
|
|
35
|
+
constructor(type, element, handler, options = {}){
|
|
36
|
+
if (typeof type !== "string") throw new TypeError("Gestures require a string type / name");
|
|
38
37
|
/**
|
|
39
38
|
* The name of the gesture. (e.g. 'pan' or 'tap' or 'pinch').
|
|
40
39
|
*
|
|
@@ -78,9 +77,7 @@ let $de0d6a332419bf3c$var$g_id = 0;
|
|
|
78
77
|
const count = state.active.length;
|
|
79
78
|
const event = state.event;
|
|
80
79
|
const { enableKeys: enableKeys , disableKeys: disableKeys , minInputs: minInputs , maxInputs: maxInputs } = this.options;
|
|
81
|
-
return minInputs <= count && maxInputs >= count && (enableKeys.length === 0 || enableKeys.some((k)=>event[k]
|
|
82
|
-
)) && !disableKeys.some((k)=>event[k]
|
|
83
|
-
);
|
|
80
|
+
return minInputs <= count && maxInputs >= count && (enableKeys.length === 0 || enableKeys.some((k)=>event[k])) && !disableKeys.some((k)=>event[k]);
|
|
84
81
|
}
|
|
85
82
|
/**
|
|
86
83
|
* Event hook for the start phase of a gesture.
|
|
@@ -169,11 +166,11 @@ $de0d6a332419bf3c$exports = $de0d6a332419bf3c$var$Gesture;
|
|
|
169
166
|
|
|
170
167
|
|
|
171
168
|
var $e2125e2e71e37a0c$exports = {};
|
|
172
|
-
|
|
169
|
+
"use strict";
|
|
173
170
|
var $0ca7bfe1c074e8ca$exports = {};
|
|
174
|
-
|
|
171
|
+
"use strict";
|
|
175
172
|
var $6c3676f10a43b740$exports = {};
|
|
176
|
-
|
|
173
|
+
"use strict";
|
|
177
174
|
/**
|
|
178
175
|
* The Point2D class stores and operates on 2-dimensional points, represented as
|
|
179
176
|
* x and y coordinates.
|
|
@@ -214,8 +211,7 @@ var $6c3676f10a43b740$exports = {};
|
|
|
214
211
|
*
|
|
215
212
|
* @returns {number[]}
|
|
216
213
|
*/ anglesTo(points) {
|
|
217
|
-
return points.map((point)=>this.angleTo(point)
|
|
218
|
-
);
|
|
214
|
+
return points.map((point)=>this.angleTo(point));
|
|
219
215
|
}
|
|
220
216
|
/**
|
|
221
217
|
* Determine the average distance from this point to the provided array of
|
|
@@ -275,8 +271,7 @@ var $6c3676f10a43b740$exports = {};
|
|
|
275
271
|
*
|
|
276
272
|
* @return {number} The total distance from this point to the provided points.
|
|
277
273
|
*/ totalDistanceTo(points) {
|
|
278
|
-
return points.reduce((d, p)=>d + this.distanceTo(p)
|
|
279
|
-
, 0);
|
|
274
|
+
return points.reduce((d, p)=>d + this.distanceTo(p), 0);
|
|
280
275
|
}
|
|
281
276
|
/**
|
|
282
277
|
* Calculates the centroid of a list of points.
|
|
@@ -311,17 +306,17 @@ $6c3676f10a43b740$exports = $6c3676f10a43b740$var$Point2D;
|
|
|
311
306
|
|
|
312
307
|
|
|
313
308
|
var $be6f0e84320366a7$exports = {};
|
|
314
|
-
|
|
309
|
+
"use strict";
|
|
315
310
|
/**
|
|
316
311
|
* List of events that trigger the cancel phase.
|
|
317
312
|
*
|
|
318
313
|
* @memberof westures-core
|
|
319
314
|
* @type {string[]}
|
|
320
315
|
*/ const $be6f0e84320366a7$var$CANCEL_EVENTS = [
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
316
|
+
"blur",
|
|
317
|
+
"pointercancel",
|
|
318
|
+
"touchcancel",
|
|
319
|
+
"mouseleave"
|
|
325
320
|
];
|
|
326
321
|
/**
|
|
327
322
|
* List of keyboard events that trigger a restart.
|
|
@@ -329,8 +324,8 @@ var $be6f0e84320366a7$exports = {};
|
|
|
329
324
|
* @memberof westures-core
|
|
330
325
|
* @type {string[]}
|
|
331
326
|
*/ const $be6f0e84320366a7$var$KEYBOARD_EVENTS = [
|
|
332
|
-
|
|
333
|
-
|
|
327
|
+
"keydown",
|
|
328
|
+
"keyup"
|
|
334
329
|
];
|
|
335
330
|
/**
|
|
336
331
|
* List of mouse events to listen to.
|
|
@@ -338,9 +333,9 @@ var $be6f0e84320366a7$exports = {};
|
|
|
338
333
|
* @memberof westures-core
|
|
339
334
|
* @type {string[]}
|
|
340
335
|
*/ const $be6f0e84320366a7$var$MOUSE_EVENTS = [
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
336
|
+
"mousedown",
|
|
337
|
+
"mousemove",
|
|
338
|
+
"mouseup"
|
|
344
339
|
];
|
|
345
340
|
/**
|
|
346
341
|
* List of pointer events to listen to.
|
|
@@ -348,9 +343,9 @@ var $be6f0e84320366a7$exports = {};
|
|
|
348
343
|
* @memberof westures-core
|
|
349
344
|
* @type {string[]}
|
|
350
345
|
*/ const $be6f0e84320366a7$var$POINTER_EVENTS = [
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
346
|
+
"pointerdown",
|
|
347
|
+
"pointermove",
|
|
348
|
+
"pointerup"
|
|
354
349
|
];
|
|
355
350
|
/**
|
|
356
351
|
* List of touch events to listen to.
|
|
@@ -358,9 +353,9 @@ var $be6f0e84320366a7$exports = {};
|
|
|
358
353
|
* @memberof westures-core
|
|
359
354
|
* @type {string[]}
|
|
360
355
|
*/ const $be6f0e84320366a7$var$TOUCH_EVENTS = [
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
356
|
+
"touchend",
|
|
357
|
+
"touchmove",
|
|
358
|
+
"touchstart"
|
|
364
359
|
];
|
|
365
360
|
/**
|
|
366
361
|
* List of potentially state-modifying keys.
|
|
@@ -369,10 +364,10 @@ var $be6f0e84320366a7$exports = {};
|
|
|
369
364
|
* @memberof westures-core
|
|
370
365
|
* @type {string[]}
|
|
371
366
|
*/ const $be6f0e84320366a7$var$STATE_KEYS = [
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
367
|
+
"altKey",
|
|
368
|
+
"ctrlKey",
|
|
369
|
+
"metaKey",
|
|
370
|
+
"shiftKey"
|
|
376
371
|
];
|
|
377
372
|
/**
|
|
378
373
|
* List of the 'key' values on KeyboardEvent objects of the potentially
|
|
@@ -381,35 +376,35 @@ var $be6f0e84320366a7$exports = {};
|
|
|
381
376
|
* @memberof westures-core
|
|
382
377
|
* @type {string[]}
|
|
383
378
|
*/ const $be6f0e84320366a7$var$STATE_KEY_STRINGS = [
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
379
|
+
"Alt",
|
|
380
|
+
"Control",
|
|
381
|
+
"Meta",
|
|
382
|
+
"Shift"
|
|
388
383
|
];
|
|
389
384
|
/**
|
|
390
385
|
* The cancel phase.
|
|
391
386
|
*
|
|
392
387
|
* @memberof westures-core
|
|
393
388
|
* @type {string}
|
|
394
|
-
*/ const $be6f0e84320366a7$var$CANCEL =
|
|
389
|
+
*/ const $be6f0e84320366a7$var$CANCEL = "cancel";
|
|
395
390
|
/**
|
|
396
391
|
* The end phase.
|
|
397
392
|
*
|
|
398
393
|
* @memberof westures-core
|
|
399
394
|
* @type {string}
|
|
400
|
-
*/ const $be6f0e84320366a7$var$END =
|
|
395
|
+
*/ const $be6f0e84320366a7$var$END = "end";
|
|
401
396
|
/**
|
|
402
397
|
* The move phase.
|
|
403
398
|
*
|
|
404
399
|
* @memberof westures-core
|
|
405
400
|
* @type {string}
|
|
406
|
-
*/ const $be6f0e84320366a7$var$MOVE =
|
|
401
|
+
*/ const $be6f0e84320366a7$var$MOVE = "move";
|
|
407
402
|
/**
|
|
408
403
|
* The start phase.
|
|
409
404
|
*
|
|
410
405
|
* @memberof westures-core
|
|
411
406
|
* @type {string}
|
|
412
|
-
*/ const $be6f0e84320366a7$var$START =
|
|
407
|
+
*/ const $be6f0e84320366a7$var$START = "start";
|
|
413
408
|
/**
|
|
414
409
|
* The recognized phases.
|
|
415
410
|
*
|
|
@@ -511,7 +506,7 @@ $0ca7bfe1c074e8ca$exports = $0ca7bfe1c074e8ca$var$PointerData;
|
|
|
511
506
|
|
|
512
507
|
|
|
513
508
|
var $4559ecf940edc78d$exports = {};
|
|
514
|
-
|
|
509
|
+
"use strict";
|
|
515
510
|
const $4559ecf940edc78d$var$PI_2 = 2 * Math.PI;
|
|
516
511
|
const $4559ecf940edc78d$var$PI_NVE = -Math.PI;
|
|
517
512
|
/**
|
|
@@ -539,7 +534,7 @@ const $4559ecf940edc78d$var$PI_NVE = -Math.PI;
|
|
|
539
534
|
*
|
|
540
535
|
* @return {Element[]} The elements along the composed path of the event.
|
|
541
536
|
*/ function $4559ecf940edc78d$var$getPropagationPath(event) {
|
|
542
|
-
if (typeof event.composedPath ===
|
|
537
|
+
if (typeof event.composedPath === "function") return event.composedPath();
|
|
543
538
|
const path = [];
|
|
544
539
|
for(let node = event.target; node !== document; node = node.parentNode)path.push(node);
|
|
545
540
|
path.push(document);
|
|
@@ -575,8 +570,7 @@ const $4559ecf940edc78d$var$PI_NVE = -Math.PI;
|
|
|
575
570
|
* @return {Set} Set consisting of elements in 'left' that are not in
|
|
576
571
|
* 'right'.
|
|
577
572
|
*/ function $4559ecf940edc78d$var$setDifference(left, right) {
|
|
578
|
-
return $4559ecf940edc78d$var$setFilter(left, (element)=>!right.has(element)
|
|
579
|
-
);
|
|
573
|
+
return $4559ecf940edc78d$var$setFilter(left, (element)=>!right.has(element));
|
|
580
574
|
}
|
|
581
575
|
$4559ecf940edc78d$exports = {
|
|
582
576
|
angularDifference: $4559ecf940edc78d$var$angularDifference,
|
|
@@ -598,14 +592,17 @@ var $e2125e2e71e37a0c$require$getPropagationPath = $4559ecf940edc78d$exports.get
|
|
|
598
592
|
* @param {number} identifier - The identifier for this input, so that it can
|
|
599
593
|
* be located in subsequent Event objects.
|
|
600
594
|
*/ class $e2125e2e71e37a0c$var$Input {
|
|
601
|
-
constructor(event, identifier){
|
|
595
|
+
constructor(event, identifier, headless = false){
|
|
602
596
|
const currentData = new $0ca7bfe1c074e8ca$exports(event, identifier);
|
|
603
597
|
/**
|
|
604
598
|
* The set of elements along the original event's propagation path at the
|
|
605
599
|
* time it was dispatched.
|
|
606
600
|
*
|
|
607
601
|
* @type {WeakSet.<Element>}
|
|
608
|
-
*/ this.initialElements = new WeakSet(
|
|
602
|
+
*/ if (headless) this.initialElements = new WeakSet([
|
|
603
|
+
event.target
|
|
604
|
+
]);
|
|
605
|
+
else this.initialElements = new WeakSet($e2125e2e71e37a0c$require$getPropagationPath(event));
|
|
609
606
|
/**
|
|
610
607
|
* Holds the initial data from the mousedown / touchstart / pointerdown that
|
|
611
608
|
* began this input.
|
|
@@ -674,39 +671,22 @@ $e2125e2e71e37a0c$exports = $e2125e2e71e37a0c$var$Input;
|
|
|
674
671
|
|
|
675
672
|
|
|
676
673
|
var $b66a0f22c18e3e3d$exports = {};
|
|
677
|
-
|
|
674
|
+
"use strict";
|
|
678
675
|
var $639be6fb478a6d5a$exports = {};
|
|
679
|
-
|
|
676
|
+
"use strict";
|
|
680
677
|
|
|
681
678
|
var $639be6fb478a6d5a$require$CANCEL = $be6f0e84320366a7$exports.CANCEL;
|
|
682
679
|
var $639be6fb478a6d5a$require$END = $be6f0e84320366a7$exports.END;
|
|
683
680
|
var $639be6fb478a6d5a$require$MOVE = $be6f0e84320366a7$exports.MOVE;
|
|
684
681
|
var $639be6fb478a6d5a$require$PHASE = $be6f0e84320366a7$exports.PHASE;
|
|
685
682
|
var $639be6fb478a6d5a$require$START = $be6f0e84320366a7$exports.START;
|
|
683
|
+
var $639be6fb478a6d5a$require$MOUSE_EVENTS = $be6f0e84320366a7$exports.MOUSE_EVENTS;
|
|
684
|
+
var $639be6fb478a6d5a$require$POINTER_EVENTS = $be6f0e84320366a7$exports.POINTER_EVENTS;
|
|
685
|
+
var $639be6fb478a6d5a$require$TOUCH_EVENTS = $be6f0e84320366a7$exports.TOUCH_EVENTS;
|
|
686
686
|
|
|
687
687
|
|
|
688
688
|
const $639be6fb478a6d5a$var$symbols = {
|
|
689
|
-
inputs: Symbol.for(
|
|
690
|
-
};
|
|
691
|
-
/**
|
|
692
|
-
* Set of helper functions for updating inputs based on type of input.
|
|
693
|
-
* Must be called with a bound 'this', via bind(), or call(), or apply().
|
|
694
|
-
*
|
|
695
|
-
* @private
|
|
696
|
-
* @inner
|
|
697
|
-
* @memberof westure-core.State
|
|
698
|
-
*/ const $639be6fb478a6d5a$var$update_fns = {
|
|
699
|
-
TouchEvent: function TouchEvent(event) {
|
|
700
|
-
Array.from(event.changedTouches).forEach((touch)=>{
|
|
701
|
-
this.updateInput(event, touch.identifier);
|
|
702
|
-
});
|
|
703
|
-
},
|
|
704
|
-
PointerEvent: function PointerEvent(event) {
|
|
705
|
-
this.updateInput(event, event.pointerId);
|
|
706
|
-
},
|
|
707
|
-
MouseEvent: function MouseEvent(event) {
|
|
708
|
-
if (event.button === 0) this.updateInput(event, event.button);
|
|
709
|
-
}
|
|
689
|
+
inputs: Symbol.for("inputs")
|
|
710
690
|
};
|
|
711
691
|
/**
|
|
712
692
|
* Keeps track of currently active and ending input points on the interactive
|
|
@@ -715,14 +695,21 @@ const $639be6fb478a6d5a$var$symbols = {
|
|
|
715
695
|
* @memberof westures-core
|
|
716
696
|
*
|
|
717
697
|
* @param {Element} element - The element underpinning the associated Region.
|
|
698
|
+
* @param {boolean} [headless=false] - Whether westures is operating in
|
|
699
|
+
* "headless" mode.
|
|
718
700
|
*/ class $639be6fb478a6d5a$var$State {
|
|
719
|
-
constructor(element){
|
|
701
|
+
constructor(element, headless = false){
|
|
720
702
|
/**
|
|
721
703
|
* Keep a reference to the element for the associated region.
|
|
722
704
|
*
|
|
723
705
|
* @type {Element}
|
|
724
706
|
*/ this.element = element;
|
|
725
707
|
/**
|
|
708
|
+
* Whether westures is operating in "headless" mode.
|
|
709
|
+
*
|
|
710
|
+
* @type {boolean}
|
|
711
|
+
*/ this.headless = headless;
|
|
712
|
+
/**
|
|
726
713
|
* Keeps track of the current Input objects.
|
|
727
714
|
*
|
|
728
715
|
* @alias [@@inputs]
|
|
@@ -750,8 +737,7 @@ const $639be6fb478a6d5a$var$symbols = {
|
|
|
750
737
|
* The centroid of the currently active points.
|
|
751
738
|
*
|
|
752
739
|
* @type {westures-core.Point2D}
|
|
753
|
-
*/ this.centroid = {
|
|
754
|
-
};
|
|
740
|
+
*/ this.centroid = {};
|
|
755
741
|
/**
|
|
756
742
|
* The latest event that the state processed.
|
|
757
743
|
*
|
|
@@ -762,7 +748,7 @@ const $639be6fb478a6d5a$var$symbols = {
|
|
|
762
748
|
* Deletes all inputs that are in the 'end' phase.
|
|
763
749
|
*/ clearEndedInputs() {
|
|
764
750
|
this[$639be6fb478a6d5a$var$symbols.inputs].forEach((v, k)=>{
|
|
765
|
-
if (v.phase ===
|
|
751
|
+
if (v.phase === "end") this[$639be6fb478a6d5a$var$symbols.inputs].delete(k);
|
|
766
752
|
});
|
|
767
753
|
}
|
|
768
754
|
/**
|
|
@@ -770,16 +756,14 @@ const $639be6fb478a6d5a$var$symbols = {
|
|
|
770
756
|
*
|
|
771
757
|
* @return {westures-core.Input[]} Inputs in the given phase.
|
|
772
758
|
*/ getInputsInPhase(phase) {
|
|
773
|
-
return this.inputs.filter((i)=>i.phase === phase
|
|
774
|
-
);
|
|
759
|
+
return this.inputs.filter((i)=>i.phase === phase);
|
|
775
760
|
}
|
|
776
761
|
/**
|
|
777
762
|
* @param {string} phase - One of 'start', 'move', 'end', or 'cancel'.
|
|
778
763
|
*
|
|
779
764
|
* @return {westures-core.Input[]} Inputs <b>not</b> in the given phase.
|
|
780
765
|
*/ getInputsNotInPhase(phase) {
|
|
781
|
-
return this.inputs.filter((i)=>i.phase !== phase
|
|
782
|
-
);
|
|
766
|
+
return this.inputs.filter((i)=>i.phase !== phase);
|
|
783
767
|
}
|
|
784
768
|
/**
|
|
785
769
|
* @return {boolean} True if there are no active inputs. False otherwise.
|
|
@@ -796,8 +780,8 @@ const $639be6fb478a6d5a$var$symbols = {
|
|
|
796
780
|
*/ updateInput(event, identifier) {
|
|
797
781
|
switch($639be6fb478a6d5a$require$PHASE[event.type]){
|
|
798
782
|
case $639be6fb478a6d5a$require$START:
|
|
799
|
-
this[$639be6fb478a6d5a$var$symbols.inputs].set(identifier, new $e2125e2e71e37a0c$exports(event, identifier));
|
|
800
|
-
try {
|
|
783
|
+
this[$639be6fb478a6d5a$var$symbols.inputs].set(identifier, new $e2125e2e71e37a0c$exports(event, identifier, this.headless));
|
|
784
|
+
if (!this.headless) try {
|
|
801
785
|
this.element.setPointerCapture(identifier);
|
|
802
786
|
} catch (e) {
|
|
803
787
|
// NOP: Optional operation failed.
|
|
@@ -806,9 +790,9 @@ const $639be6fb478a6d5a$var$symbols = {
|
|
|
806
790
|
// All of 'end', 'move', and 'cancel' perform updates, hence the
|
|
807
791
|
// following fall-throughs
|
|
808
792
|
case $639be6fb478a6d5a$require$END:
|
|
809
|
-
try {
|
|
793
|
+
if (!this.headless) try {
|
|
810
794
|
this.element.releasePointerCapture(identifier);
|
|
811
|
-
} catch (
|
|
795
|
+
} catch (e) {
|
|
812
796
|
// NOP: Optional operation failed.
|
|
813
797
|
}
|
|
814
798
|
case $639be6fb478a6d5a$require$CANCEL:
|
|
@@ -825,7 +809,13 @@ const $639be6fb478a6d5a$var$symbols = {
|
|
|
825
809
|
* @private
|
|
826
810
|
* @param {Event} event - The event being captured.
|
|
827
811
|
*/ updateAllInputs(event) {
|
|
828
|
-
$639be6fb478a6d5a$
|
|
812
|
+
if ($639be6fb478a6d5a$require$POINTER_EVENTS.includes(event.type)) this.updateInput(event, event.pointerId);
|
|
813
|
+
else if ($639be6fb478a6d5a$require$MOUSE_EVENTS.includes(event.type)) {
|
|
814
|
+
if (event.button === 0) this.updateInput(event, event.button);
|
|
815
|
+
} else if ($639be6fb478a6d5a$require$TOUCH_EVENTS.includes(event.type)) Array.from(event.changedTouches).forEach((touch)=>{
|
|
816
|
+
this.updateInput(event, touch.identifier);
|
|
817
|
+
});
|
|
818
|
+
else throw new Error(`Unexpected event type: ${event.type}`);
|
|
829
819
|
this.updateFields(event);
|
|
830
820
|
}
|
|
831
821
|
/**
|
|
@@ -835,9 +825,8 @@ const $639be6fb478a6d5a$var$symbols = {
|
|
|
835
825
|
* @param {Event} event - Event with which to update the convenience fields.
|
|
836
826
|
*/ updateFields(event) {
|
|
837
827
|
this.inputs = Array.from(this[$639be6fb478a6d5a$var$symbols.inputs].values());
|
|
838
|
-
this.active = this.getInputsNotInPhase(
|
|
839
|
-
this.activePoints = this.active.map((i)=>i.current.point
|
|
840
|
-
);
|
|
828
|
+
this.active = this.getInputsNotInPhase("end");
|
|
829
|
+
this.activePoints = this.active.map((i)=>i.current.point);
|
|
841
830
|
this.centroid = $6c3676f10a43b740$exports.centroid(this.activePoints);
|
|
842
831
|
this.event = event;
|
|
843
832
|
}
|
|
@@ -865,8 +854,9 @@ var $b66a0f22c18e3e3d$require$setFilter = $4559ecf940edc78d$exports.setFilter;
|
|
|
865
854
|
*
|
|
866
855
|
* @memberof westures-core
|
|
867
856
|
*
|
|
868
|
-
* @param {Element} element=
|
|
869
|
-
* events.
|
|
857
|
+
* @param {Element} [element=null] - The element which should listen to input
|
|
858
|
+
* events. If not provided, will be set to the window unless operating in
|
|
859
|
+
* "headless" mode.
|
|
870
860
|
* @param {object} [options]
|
|
871
861
|
* @param {boolean} [options.capture=false] - Whether the region uses the
|
|
872
862
|
* capture phase of input events. If false, uses the bubbling phase.
|
|
@@ -877,13 +867,26 @@ var $b66a0f22c18e3e3d$require$setFilter = $4559ecf940edc78d$exports.setFilter;
|
|
|
877
867
|
* ignored. Here there by dragons if set to false.
|
|
878
868
|
* @param {string} [options.touchAction='none'] - Value to set the CSS
|
|
879
869
|
* 'touch-action' property to on elements added to the region.
|
|
870
|
+
* @param {boolean} [options.headless=false] - Set to true to turn on "headless"
|
|
871
|
+
* mode. This mode is intended for use outside of a browser environment. It does
|
|
872
|
+
* not listen to window events, so instead you will have to send events directly
|
|
873
|
+
* into the region. Pointer down/move/up events should be sent to
|
|
874
|
+
* Region.arbitrate(event), cancel events should be sent to
|
|
875
|
+
* Region.cancel(event), and keyboard events should be sent to
|
|
876
|
+
* Region.handleKeyboardEvent(event). You do not need to supply an element to
|
|
877
|
+
* the Region constructor in this mode, but you will still need to attach
|
|
878
|
+
* elements to Gestures, and the events you pass in should specify event.target
|
|
879
|
+
* appropriately, in order to select which gestures to run.
|
|
880
880
|
*/ class $b66a0f22c18e3e3d$var$Region {
|
|
881
|
-
constructor(element =
|
|
882
|
-
}){
|
|
881
|
+
constructor(element = null, options = {}){
|
|
883
882
|
options = {
|
|
884
883
|
...$b66a0f22c18e3e3d$var$Region.DEFAULTS,
|
|
885
884
|
...options
|
|
886
885
|
};
|
|
886
|
+
if (element === null) {
|
|
887
|
+
if (options.headless) element = null;
|
|
888
|
+
else element = window;
|
|
889
|
+
}
|
|
887
890
|
/**
|
|
888
891
|
* The list of relations between elements, their gestures, and the handlers.
|
|
889
892
|
*
|
|
@@ -914,8 +917,8 @@ var $b66a0f22c18e3e3d$require$setFilter = $4559ecf940edc78d$exports.setFilter;
|
|
|
914
917
|
* The internal state object for a Region. Keeps track of inputs.
|
|
915
918
|
*
|
|
916
919
|
* @type {westures-core.State}
|
|
917
|
-
*/ this.state = new $639be6fb478a6d5a$exports(this.element);
|
|
918
|
-
// Begin operating immediately.
|
|
920
|
+
*/ this.state = new $639be6fb478a6d5a$exports(this.element, options.headless);
|
|
921
|
+
if (!options.headless) // Begin operating immediately.
|
|
919
922
|
this.activate();
|
|
920
923
|
}
|
|
921
924
|
/**
|
|
@@ -965,14 +968,14 @@ var $b66a0f22c18e3e3d$require$setFilter = $4559ecf940edc78d$exports.setFilter;
|
|
|
965
968
|
* @private
|
|
966
969
|
* @param {Event} event - The event emitted from the window object.
|
|
967
970
|
*/ cancel(event) {
|
|
968
|
-
if (this.options.preventDefault) event.preventDefault();
|
|
971
|
+
if (this.options.preventDefault && typeof event.preventDefault === "function") event.preventDefault();
|
|
969
972
|
this.state.inputs.forEach((input)=>{
|
|
970
973
|
input.update(event);
|
|
971
974
|
});
|
|
972
975
|
this.activeGestures.forEach((gesture)=>{
|
|
973
976
|
gesture.evaluateHook($b66a0f22c18e3e3d$require$CANCEL, this.state);
|
|
974
977
|
});
|
|
975
|
-
this.state = new $639be6fb478a6d5a$exports(this.element);
|
|
978
|
+
this.state = new $639be6fb478a6d5a$exports(this.element, this.options.headless);
|
|
976
979
|
this.resetActiveGestures();
|
|
977
980
|
}
|
|
978
981
|
/**
|
|
@@ -1057,7 +1060,7 @@ var $b66a0f22c18e3e3d$require$setFilter = $4559ecf940edc78d$exports.setFilter;
|
|
|
1057
1060
|
this.state.updateAllInputs(event);
|
|
1058
1061
|
this.updateActiveGestures(event, isInitial);
|
|
1059
1062
|
if (this.activeGestures.size > 0) {
|
|
1060
|
-
if (this.options.preventDefault) event.preventDefault();
|
|
1063
|
+
if (this.options.preventDefault && typeof event.preventDefault === "function") event.preventDefault();
|
|
1061
1064
|
this.activeGestures.forEach((gesture)=>{
|
|
1062
1065
|
gesture.evaluateHook($b66a0f22c18e3e3d$require$PHASE[event.type], this.state);
|
|
1063
1066
|
});
|
|
@@ -1070,7 +1073,7 @@ var $b66a0f22c18e3e3d$require$setFilter = $4559ecf940edc78d$exports.setFilter;
|
|
|
1070
1073
|
*
|
|
1071
1074
|
* @param {westures-core.Gesture} gesture - Instantiated gesture to add.
|
|
1072
1075
|
*/ addGesture(gesture) {
|
|
1073
|
-
gesture.element.style.touchAction = this.options.touchAction;
|
|
1076
|
+
if (!this.options.headless) gesture.element.style.touchAction = this.options.touchAction;
|
|
1074
1077
|
this.gestures.add(gesture);
|
|
1075
1078
|
}
|
|
1076
1079
|
/**
|
|
@@ -1089,31 +1092,30 @@ var $b66a0f22c18e3e3d$require$setFilter = $4559ecf940edc78d$exports.setFilter;
|
|
|
1089
1092
|
*
|
|
1090
1093
|
* @return {westures-core.Gesture[]} Gestures to which the element is bound.
|
|
1091
1094
|
*/ getGesturesByElement(element) {
|
|
1092
|
-
return $b66a0f22c18e3e3d$require$setFilter(this.gestures, (gesture)=>gesture.element === element
|
|
1093
|
-
);
|
|
1095
|
+
return $b66a0f22c18e3e3d$require$setFilter(this.gestures, (gesture)=>gesture.element === element);
|
|
1094
1096
|
}
|
|
1095
1097
|
/**
|
|
1096
1098
|
* Remove all gestures bound to the given element.
|
|
1097
1099
|
*
|
|
1098
1100
|
* @param {Element} element - The element to unbind.
|
|
1099
1101
|
*/ removeGesturesByElement(element) {
|
|
1100
|
-
this.getGesturesByElement(element).forEach((g)=>this.removeGesture(g)
|
|
1101
|
-
);
|
|
1102
|
+
this.getGesturesByElement(element).forEach((g)=>this.removeGesture(g));
|
|
1102
1103
|
}
|
|
1103
1104
|
}
|
|
1104
1105
|
$b66a0f22c18e3e3d$var$Region.DEFAULTS = {
|
|
1105
1106
|
capture: false,
|
|
1106
1107
|
preferPointer: true,
|
|
1107
1108
|
preventDefault: true,
|
|
1108
|
-
touchAction:
|
|
1109
|
+
touchAction: "none",
|
|
1110
|
+
headless: false
|
|
1109
1111
|
};
|
|
1110
1112
|
$b66a0f22c18e3e3d$exports = $b66a0f22c18e3e3d$var$Region;
|
|
1111
1113
|
|
|
1112
1114
|
|
|
1113
1115
|
var $01c3d7b128023e4f$exports = {};
|
|
1114
|
-
|
|
1115
|
-
const $01c3d7b128023e4f$var$cascade = Symbol(
|
|
1116
|
-
const $01c3d7b128023e4f$var$smooth = Symbol(
|
|
1116
|
+
"use strict";
|
|
1117
|
+
const $01c3d7b128023e4f$var$cascade = Symbol("cascade");
|
|
1118
|
+
const $01c3d7b128023e4f$var$smooth = Symbol("smooth");
|
|
1117
1119
|
/**
|
|
1118
1120
|
* Determines whether to apply smoothing. Smoothing is on by default but turned
|
|
1119
1121
|
* off if either:<br>
|
|
@@ -1131,7 +1133,7 @@ const $01c3d7b128023e4f$var$smooth = Symbol('smooth');
|
|
|
1131
1133
|
* @returns {boolean} Whether to apply smoothing.
|
|
1132
1134
|
*/ function $01c3d7b128023e4f$var$smoothingIsApplicable(isRequested) {
|
|
1133
1135
|
if (isRequested) try {
|
|
1134
|
-
return window.matchMedia(
|
|
1136
|
+
return window.matchMedia("(pointer: coarse)").matches;
|
|
1135
1137
|
} catch (e) {
|
|
1136
1138
|
return true;
|
|
1137
1139
|
}
|
|
@@ -1162,8 +1164,7 @@ const $01c3d7b128023e4f$var$smooth = Symbol('smooth');
|
|
|
1162
1164
|
* the data.
|
|
1163
1165
|
* @param {*} [options.identity=0] The identity value of this smoothable data.
|
|
1164
1166
|
*/ class $01c3d7b128023e4f$var$Smoothable {
|
|
1165
|
-
constructor(options = {
|
|
1166
|
-
}){
|
|
1167
|
+
constructor(options = {}){
|
|
1167
1168
|
const final_options = {
|
|
1168
1169
|
...$01c3d7b128023e4f$var$Smoothable.DEFAULTS,
|
|
1169
1170
|
...options
|
|
@@ -1177,8 +1178,7 @@ const $01c3d7b128023e4f$var$smooth = Symbol('smooth');
|
|
|
1177
1178
|
* @return {*} The smoothed out data.
|
|
1178
1179
|
*/ this.next = null;
|
|
1179
1180
|
if ($01c3d7b128023e4f$var$smoothingIsApplicable(final_options.applySmoothing)) this.next = this[$01c3d7b128023e4f$var$smooth].bind(this);
|
|
1180
|
-
else this.next = (data)=>data
|
|
1181
|
-
;
|
|
1181
|
+
else this.next = (data)=>data;
|
|
1182
1182
|
/**
|
|
1183
1183
|
* The "identity" value of the data that will be smoothed.
|
|
1184
1184
|
*
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":"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","sources":["index.js","src/Gesture.js","src/Input.js","src/PointerData.js","src/Point2D.js","src/constants.js","src/utils.js","src/Region.js","src/State.js","src/Smoothable.js"],"sourcesContent":["/**\n * The global API interface for westures-core. Exposes all classes, constants,\n * and routines used by the package. Use responsibly.\n *\n * @namespace westures-core\n */\n\n'use strict';\n\nconst Gesture = require('./src/Gesture.js');\nconst Input = require('./src/Input.js');\nconst Point2D = require('./src/Point2D.js');\nconst PointerData = require('./src/PointerData.js');\nconst Region = require('./src/Region.js');\nconst Smoothable = require('./src/Smoothable.js');\nconst State = require('./src/State.js');\nconst constants = require('./src/constants.js');\nconst utils = require('./src/utils.js');\n\nmodule.exports = {\n Gesture,\n Input,\n Point2D,\n PointerData,\n Region,\n Smoothable,\n State,\n ...constants,\n ...utils,\n};\n\n","'use strict';\n\nlet g_id = 0;\n\n/**\n * The Gesture class that all gestures inherit from. A custom gesture class will\n * need to override some or all of the four phase \"hooks\": start, move, end, and\n * cancel.\n *\n * @memberof westures-core\n *\n * @param {string} type - The name of the gesture.\n * @param {Element} element - The element to which to associate the gesture.\n * @param {Function} handler - The function handler to execute when a gesture\n * is recognized on the associated element.\n * @param {object} [options] - Generic gesture options\n * @param {westures-core.STATE_KEYS[]} [options.enableKeys=[]] - List of keys\n * which will enable the gesture. The gesture will not be recognized unless one\n * of these keys is pressed while the interaction occurs. If not specified or an\n * empty list, the gesture is treated as though the enable key is always down.\n * @param {westures-core.STATE_KEYS[]} [options.disableKeys=[]] - List of keys\n * which will disable the gesture. The gesture will not be recognized if one of\n * these keys is pressed while the interaction occurs. If not specified or an\n * empty list, the gesture is treated as though the disable key is never down.\n * @param {number} [options.minInputs=1] - The minimum number of pointers that\n * must be active for the gesture to be recognized. Uses >=.\n * @param {number} [options.maxInputs=Number.MAX_VALUE] - The maximum number of\n * pointers that may be active for the gesture to be recognized. Uses <=.\n */\nclass Gesture {\n constructor(type, element, handler, options = {}) {\n if (typeof type !== 'string') {\n throw new TypeError('Gestures require a string type / name');\n }\n\n /**\n * The name of the gesture. (e.g. 'pan' or 'tap' or 'pinch').\n *\n * @type {string}\n */\n this.type = type;\n\n /**\n * The unique identifier for each gesture. This allows for distinctions\n * across instances of Gestures that are created on the fly (e.g.\n * gesture-tap-1, gesture-tap-2).\n *\n * @type {string}\n */\n this.id = `gesture-${this.type}-${g_id++}`;\n\n /**\n * The element to which to associate the gesture.\n *\n * @type {Element}\n */\n this.element = element;\n\n /**\n * The function handler to execute when the gesture is recognized on the\n * associated element.\n *\n * @type {Function}\n */\n this.handler = handler;\n\n /**\n * The options. Can usually be adjusted live, though be careful doing this.\n *\n * @type {object}\n */\n this.options = { ...Gesture.DEFAULTS, ...options };\n }\n\n /**\n * Determines whether this gesture is enabled.\n *\n * @param {westures-core.State} state - The input state object of the current\n * region.\n *\n * @return {boolean} true if enabled, false otherwise.\n */\n isEnabled(state) {\n const count = state.active.length;\n const event = state.event;\n const { enableKeys, disableKeys, minInputs, maxInputs } = this.options;\n\n return (minInputs <= count) && (maxInputs >= count) &&\n (enableKeys.length === 0 || enableKeys.some(k => event[k])) &&\n !disableKeys.some(k => event[k]);\n }\n\n /**\n * Event hook for the start phase of a gesture.\n *\n * @param {westures-core.State} state - The input state object of the current\n * region.\n *\n * @return {?Object} Gesture is considered recognized if an Object is\n * returned.\n */\n start() {\n return null;\n }\n\n /**\n * Event hook for the move phase of a gesture.\n *\n * @param {westures-core.State} state - The input state object of the current\n * region.\n *\n * @return {?Object} Gesture is considered recognized if an Object is\n * returned.\n */\n move() {\n return null;\n }\n\n /**\n * Event hook for the end phase of a gesture.\n *\n * @param {westures-core.State} state - The input state object of the current\n * region.\n *\n * @return {?Object} Gesture is considered recognized if an Object is\n * returned.\n */\n end() {\n return null;\n }\n\n /**\n * Event hook for when an input is cancelled.\n *\n * @param {westures-core.State} state - The input state object of the current\n * region.\n *\n * @return {?Object} Gesture is considered recognized if an Object is\n * returned.\n */\n cancel() {\n return null;\n }\n\n /**\n * Evalutes the given gesture hook, and dispatches any data that is produced\n * by calling [recognize]{@link westures-core.Gesture#recognize}.\n *\n * @param {string} hook - Must be one of 'start', 'move', 'end', or 'cancel'.\n * @param {westures-core.State} state - The current State instance.\n */\n evaluateHook(hook, state) {\n const data = this[hook](state);\n if (data) {\n this.recognize(hook, state, data);\n }\n }\n\n /**\n * Recognize a Gesture by calling the handler. Standardizes the way the\n * handler is called so that classes extending Gesture can circumvent the\n * evaluateHook approach but still provide results that have a common format.\n *\n * Note that the properties in the \"data\" object will receive priority when\n * constructing the results. This can be used to override standard results\n * such as the phase or the centroid.\n *\n * @param {string} hook - Must be one of 'start', 'move', 'end', or 'cancel'.\n * @param {westures-core.State} state - current input state.\n * @param {Object} data - Results data specific to the recognized gesture.\n */\n recognize(hook, state, data) {\n this.handler({\n centroid: state.centroid,\n event: state.event,\n phase: hook,\n type: this.type,\n target: this.element,\n ...data,\n });\n }\n}\n\nGesture.DEFAULTS = {\n enableKeys: [],\n disableKeys: [],\n minInputs: 1,\n maxInputs: Number.MAX_VALUE,\n};\n\nmodule.exports = Gesture;\n\n","'use strict';\n\nconst PointerData = require('./PointerData.js');\nconst { getPropagationPath } = require('./utils.js');\n\n/**\n * Tracks a single input and contains information about the current, previous,\n * and initial events.\n *\n * @memberof westures-core\n *\n * @param {(PointerEvent | MouseEvent | TouchEvent)} event - The input event\n * which will initialize this Input object.\n * @param {number} identifier - The identifier for this input, so that it can\n * be located in subsequent Event objects.\n */\nclass Input {\n constructor(event, identifier) {\n const currentData = new PointerData(event, identifier);\n\n /**\n * The set of elements along the original event's propagation path at the\n * time it was dispatched.\n *\n * @type {WeakSet.<Element>}\n */\n this.initialElements = new WeakSet(getPropagationPath(event));\n\n /**\n * Holds the initial data from the mousedown / touchstart / pointerdown that\n * began this input.\n *\n * @type {westures-core.PointerData}\n */\n this.initial = currentData;\n\n /**\n * Holds the most current pointer data for this Input.\n *\n * @type {westures-core.PointerData}\n */\n this.current = currentData;\n\n /**\n * Holds the previous pointer data for this Input.\n *\n * @type {westures-core.PointerData}\n */\n this.previous = currentData;\n\n /**\n * The identifier for the pointer / touch / mouse button associated with\n * this input.\n *\n * @type {number}\n */\n this.identifier = identifier;\n }\n\n /**\n * The phase of the input: 'start' or 'move' or 'end' or 'cancel'\n *\n * @type {string}\n */\n get phase() { return this.current.type; }\n\n /**\n * The timestamp of the initiating event for this input.\n *\n * @type {number}\n */\n get startTime() { return this.initial.time; }\n\n /**\n * The amount of time elapsed between the start of this input and its latest\n * event.\n *\n * @type {number}\n */\n get elapsedTime() { return this.current.time - this.initial.time; }\n\n /**\n * @return {number} The distance between the initiating event for this input\n * and its current event.\n */\n totalDistance() {\n return this.initial.point.distanceTo(this.current.point);\n }\n\n /**\n * Saves the given raw event in PointerData form as the current data for this\n * input, pushing the old current data into the previous slot, and tossing\n * out the old previous data.\n *\n * @param {Event} event - The event object to wrap with a PointerData.\n */\n update(event) {\n this.previous = this.current;\n this.current = new PointerData(event, this.identifier);\n }\n}\n\nmodule.exports = Input;\n\n","'use strict';\n\nconst Point2D = require('./Point2D.js');\nconst { PHASE } = require('./constants.js');\n\n/**\n * @private\n * @inner\n * @memberof westures-core.PointerData\n *\n * @return {Event} The Event object which corresponds to the given identifier.\n * Contains clientX, clientY values.\n */\nfunction getEventObject(event, identifier) {\n if (event.changedTouches) {\n return Array.from(event.changedTouches).find(touch => {\n return touch.identifier === identifier;\n });\n }\n return event;\n}\n\n/**\n * Low-level storage of pointer data based on incoming data from an interaction\n * event.\n *\n * @memberof westures-core\n *\n * @param {Event} event - The event object being wrapped.\n * @param {number} identifier - The index of touch if applicable\n */\nclass PointerData {\n constructor(event, identifier) {\n const { clientX, clientY } = getEventObject(event, identifier);\n\n /**\n * The original event object.\n *\n * @type {Event}\n */\n this.event = event;\n\n /**\n * The type or 'phase' of this batch of pointer data. 'start' or 'move' or\n * 'end' or 'cancel'\n *\n * @type {string}\n */\n this.type = PHASE[event.type];\n\n /**\n * The timestamp of the event in milliseconds elapsed since January 1, 1970,\n * 00:00:00 UTC.\n *\n * @type {number}\n */\n this.time = Date.now();\n\n /**\n * The (x,y) coordinate of the event, wrapped in a Point2D.\n *\n * @type {westures-core.Point2D}\n */\n this.point = new Point2D(clientX, clientY);\n }\n}\n\nmodule.exports = PointerData;\n\n","'use strict';\n\n/**\n * The Point2D class stores and operates on 2-dimensional points, represented as\n * x and y coordinates.\n *\n * @memberof westures-core\n *\n * @param {number} [ x=0 ] - The x coordinate of the point.\n * @param {number} [ y=0 ] - The y coordinate of the point.\n */\nclass Point2D {\n constructor(x = 0, y = 0) {\n /**\n * The x coordinate of the point.\n *\n * @type {number}\n */\n this.x = x;\n\n /**\n * The y coordinate of the point.\n *\n * @type {number}\n */\n this.y = y;\n }\n\n /**\n * Calculates the angle between this point and the given point.\n *\n * @param {!westures-core.Point2D} point - Projected point for calculating the\n * angle.\n *\n * @return {number} Radians along the unit circle where the projected\n * point lies.\n */\n angleTo(point) {\n return Math.atan2(point.y - this.y, point.x - this.x);\n }\n\n /**\n * Determine the angle from the centroid to each of the points.\n *\n * @param {!westures-core.Point2D[]} points - the Point2D objects to calculate\n * the angles to.\n *\n * @returns {number[]}\n */\n anglesTo(points) {\n return points.map(point => this.angleTo(point));\n }\n\n /**\n * Determine the average distance from this point to the provided array of\n * points.\n *\n * @param {!westures-core.Point2D[]} points - the Point2D objects to calculate\n * the average distance to.\n *\n * @return {number} The average distance from this point to the provided\n * points.\n */\n averageDistanceTo(points) {\n return this.totalDistanceTo(points) / points.length;\n }\n\n /**\n * Clone this point.\n *\n * @return {westures-core.Point2D} A new Point2D, identical to this point.\n */\n clone() {\n return new Point2D(this.x, this.y);\n }\n\n /**\n * Calculates the distance between two points.\n *\n * @param {!westures-core.Point2D} point - Point to which the distance is\n * calculated.\n *\n * @return {number} The distance between the two points, a.k.a. the\n * hypoteneuse.\n */\n distanceTo(point) {\n return Math.hypot(point.x - this.x, point.y - this.y);\n }\n\n /**\n * Subtract the given point from this point.\n *\n * @param {!westures-core.Point2D} point - Point to subtract from this point.\n *\n * @return {westures-core.Point2D} A new Point2D, which is the result of (this\n * - point).\n */\n minus(point) {\n return new Point2D(\n this.x - point.x,\n this.y - point.y,\n );\n }\n\n /**\n * Return the summation of this point to the given point.\n *\n * @param {!westures-core.Point2D} point - Point to add to this point.\n *\n * @return {westures-core.Point2D} A new Point2D, which is the addition of the\n * two points.\n */\n plus(point) {\n return new Point2D(\n this.x + point.x,\n this.y + point.y,\n );\n }\n\n /**\n * Calculates the total distance from this point to an array of points.\n *\n * @param {!westures-core.Point2D[]} points - The array of Point2D objects to\n * calculate the total distance to.\n *\n * @return {number} The total distance from this point to the provided points.\n */\n totalDistanceTo(points) {\n return points.reduce((d, p) => d + this.distanceTo(p), 0);\n }\n\n /**\n * Calculates the centroid of a list of points.\n *\n * @param {westures-core.Point2D[]} points - The array of Point2D objects for\n * which to calculate the centroid.\n *\n * @return {westures-core.Point2D} The centroid of the provided points.\n */\n static centroid(points = []) {\n if (points.length === 0) return null;\n\n const total = Point2D.sum(points);\n total.x /= points.length;\n total.y /= points.length;\n return total;\n }\n\n /**\n * Calculates the sum of the given points.\n *\n * @param {westures-core.Point2D[]} points - The Point2D objects to sum up.\n *\n * @return {westures-core.Point2D} A new Point2D representing the sum of the\n * given points.\n */\n static sum(points = []) {\n return points.reduce(\n (total, pt) => {\n total.x += pt.x;\n total.y += pt.y;\n return total;\n },\n new Point2D(0, 0),\n );\n }\n}\n\nmodule.exports = Point2D;\n\n","'use strict';\n\n/**\n * List of events that trigger the cancel phase.\n *\n * @memberof westures-core\n * @type {string[]}\n */\nconst CANCEL_EVENTS = [\n 'blur',\n 'pointercancel',\n 'touchcancel',\n 'mouseleave',\n];\n\n/**\n * List of keyboard events that trigger a restart.\n *\n * @memberof westures-core\n * @type {string[]}\n */\nconst KEYBOARD_EVENTS = [\n 'keydown',\n 'keyup',\n];\n\n/**\n * List of mouse events to listen to.\n *\n * @memberof westures-core\n * @type {string[]}\n */\nconst MOUSE_EVENTS = [\n 'mousedown',\n 'mousemove',\n 'mouseup',\n];\n\n/**\n * List of pointer events to listen to.\n *\n * @memberof westures-core\n * @type {string[]}\n */\nconst POINTER_EVENTS = [\n 'pointerdown',\n 'pointermove',\n 'pointerup',\n];\n\n/**\n * List of touch events to listen to.\n *\n * @memberof westures-core\n * @type {string[]}\n */\nconst TOUCH_EVENTS = [\n 'touchend',\n 'touchmove',\n 'touchstart',\n];\n\n/**\n * List of potentially state-modifying keys.\n * Entries are: ['altKey', 'ctrlKey', 'metaKey', 'shiftKey'].\n *\n * @memberof westures-core\n * @type {string[]}\n */\nconst STATE_KEYS = [\n 'altKey',\n 'ctrlKey',\n 'metaKey',\n 'shiftKey',\n];\n\n/**\n * List of the 'key' values on KeyboardEvent objects of the potentially\n * state-modifying keys.\n *\n * @memberof westures-core\n * @type {string[]}\n */\nconst STATE_KEY_STRINGS = [\n 'Alt',\n 'Control',\n 'Meta',\n 'Shift',\n];\n\n/**\n * The cancel phase.\n *\n * @memberof westures-core\n * @type {string}\n */\nconst CANCEL = 'cancel';\n\n/**\n * The end phase.\n *\n * @memberof westures-core\n * @type {string}\n */\nconst END = 'end';\n\n/**\n * The move phase.\n *\n * @memberof westures-core\n * @type {string}\n */\nconst MOVE = 'move';\n\n/**\n * The start phase.\n *\n * @memberof westures-core\n * @type {string}\n */\nconst START = 'start';\n\n/**\n * The recognized phases.\n *\n * @memberof westures-core\n * @type {list.<string>}\n */\nconst PHASES = [START, MOVE, END, CANCEL];\n\n/**\n * Object that normalizes the names of window events to be either of type start,\n * move, end, or cancel.\n *\n * @memberof westures-core\n * @type {object}\n */\nconst PHASE = {\n blur: CANCEL,\n pointercancel: CANCEL,\n touchcancel: CANCEL,\n\n mouseup: END,\n pointerup: END,\n touchend: END,\n\n mousemove: MOVE,\n pointermove: MOVE,\n touchmove: MOVE,\n\n mousedown: START,\n pointerdown: START,\n touchstart: START,\n};\n\nmodule.exports = {\n CANCEL_EVENTS,\n KEYBOARD_EVENTS,\n MOUSE_EVENTS,\n POINTER_EVENTS,\n TOUCH_EVENTS,\n\n STATE_KEYS,\n STATE_KEY_STRINGS,\n\n CANCEL,\n END,\n MOVE,\n START,\n\n PHASE,\n PHASES,\n};\n\n","'use strict';\n\nconst PI_2 = 2 * Math.PI;\nconst PI_NVE = -Math.PI;\n\n/**\n * Helper function to regulate angular differences, so they don't jump from 0 to\n * 2 * PI or vice versa.\n *\n * @memberof westures-core\n *\n * @param {number} a - Angle in radians.\n * @param {number} b - Angle in radians.\n\n * @return {number} c, given by: c = a - b such that |c| < PI\n */\nfunction angularDifference(a, b) {\n let diff = a - b;\n if (diff < PI_NVE) {\n diff += PI_2;\n } else if (diff > Math.PI) {\n diff -= PI_2;\n }\n return diff;\n}\n\n/**\n * In case event.composedPath() is not available.\n *\n * @memberof westures-core\n *\n * @param {Event} event\n *\n * @return {Element[]} The elements along the composed path of the event.\n */\nfunction getPropagationPath(event) {\n if (typeof event.composedPath === 'function') {\n return event.composedPath();\n }\n\n const path = [];\n for (let node = event.target; node !== document; node = node.parentNode) {\n path.push(node);\n }\n path.push(document);\n path.push(window);\n\n return path;\n}\n\n/**\n * Performs a set filter operation.\n *\n * @memberof westures-core\n *\n * @param {Set} set - The set to filter.\n * @param {Function} predicate - Function to test elements of 'set'. Receives\n * one argument: the current set element.\n *\n * @return {Set} Set consisting of elements in 'set' for which 'predicate' is\n * true.\n */\nfunction setFilter(set, predicate) {\n const result = new Set();\n set.forEach(element => {\n if (predicate(element)) {\n result.add(element);\n }\n });\n return result;\n}\n\n/**\n * Performs a set difference operation.\n *\n * @memberof westures-core\n *\n * @param {Set} left - Base set.\n * @param {Set} right - Set of elements to remove from 'left'.\n *\n * @return {Set} Set consisting of elements in 'left' that are not in\n * 'right'.\n */\nfunction setDifference(left, right) {\n return setFilter(left, element => !right.has(element));\n}\n\nmodule.exports = {\n angularDifference,\n getPropagationPath,\n setDifference,\n setFilter,\n};\n\n","'use strict';\n\nconst State = require('./State.js');\nconst {\n CANCEL_EVENTS,\n KEYBOARD_EVENTS,\n MOUSE_EVENTS,\n POINTER_EVENTS,\n TOUCH_EVENTS,\n\n STATE_KEY_STRINGS,\n\n PHASE,\n\n CANCEL,\n END,\n START,\n} = require('./constants.js');\nconst {\n setDifference,\n setFilter,\n} = require('./utils.js');\n\n/**\n * Allows the user to specify the control region which will listen for user\n * input events.\n *\n * @memberof westures-core\n *\n * @param {Element} element=window - The element which should listen to input\n * events.\n * @param {object} [options]\n * @param {boolean} [options.capture=false] - Whether the region uses the\n * capture phase of input events. If false, uses the bubbling phase.\n * @param {boolean} [options.preferPointer=true] - If false, the region listens\n * to mouse/touch events instead of pointer events.\n * @param {boolean} [options.preventDefault=true] - Whether the default\n * browser functionality should be disabled. This option should most likely be\n * ignored. Here there by dragons if set to false.\n * @param {string} [options.touchAction='none'] - Value to set the CSS\n * 'touch-action' property to on elements added to the region.\n */\nclass Region {\n constructor(element = window, options = {}) {\n options = { ...Region.DEFAULTS, ...options };\n\n /**\n * The list of relations between elements, their gestures, and the handlers.\n *\n * @type {Set.<westures-core.Gesture>}\n */\n this.gestures = new Set();\n\n /**\n * The list of active gestures for the current input session.\n *\n * @type {Set.<westures-core.Gesture>}\n */\n this.activeGestures = new Set();\n\n /**\n * The base list of potentially active gestures for the current input\n * session.\n *\n * @type {Set.<westures-core.Gesture>}\n */\n this.potentialGestures = new Set();\n\n /**\n * The element being bound to.\n *\n * @type {Element}\n */\n this.element = element;\n\n /**\n * The user-supplied options for the Region.\n *\n * @type {object}\n */\n this.options = options;\n\n /**\n * The internal state object for a Region. Keeps track of inputs.\n *\n * @type {westures-core.State}\n */\n this.state = new State(this.element);\n\n // Begin operating immediately.\n this.activate();\n }\n\n /**\n * Activates the region by adding event listeners for all appropriate input\n * events to the region's element.\n *\n * @private\n */\n activate() {\n /*\n * Listening to both mouse and touch comes with the difficulty that\n * preventDefault() must be called to prevent both events from iterating\n * through the system. However I have left it as an option to the end user,\n * which defaults to calling preventDefault(), in case there's a use-case I\n * haven't considered or am not aware of.\n *\n * It also may be a good idea to keep regions small in large pages.\n *\n * See:\n * https://www.html5rocks.com/en/mobile/touchandmouse/\n * https://developer.mozilla.org/en-US/docs/Web/API/Touch_events\n * https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events\n */\n let eventNames = [];\n if (this.options.preferPointer && window.PointerEvent) {\n eventNames = POINTER_EVENTS;\n } else {\n eventNames = MOUSE_EVENTS.concat(TOUCH_EVENTS);\n }\n\n // Bind detected browser events to the region element.\n const arbitrate = this.arbitrate.bind(this);\n eventNames.forEach(eventName => {\n this.element.addEventListener(eventName, arbitrate, {\n capture: this.options.capture,\n once: false,\n passive: false,\n });\n });\n\n const cancel = this.cancel.bind(this);\n CANCEL_EVENTS.forEach(eventName => {\n window.addEventListener(eventName, cancel);\n });\n\n const handleKeyboardEvent = this.handleKeyboardEvent.bind(this);\n KEYBOARD_EVENTS.forEach(eventName => {\n window.addEventListener(eventName, handleKeyboardEvent);\n });\n }\n\n /**\n * Handles a cancel event. Resets the state and the active / potential gesture\n * lists.\n *\n * @private\n * @param {Event} event - The event emitted from the window object.\n */\n cancel(event) {\n if (this.options.preventDefault) event.preventDefault();\n this.state.inputs.forEach(input => {\n input.update(event);\n });\n this.activeGestures.forEach(gesture => {\n gesture.evaluateHook(CANCEL, this.state);\n });\n this.state = new State(this.element);\n this.resetActiveGestures();\n }\n\n /**\n * Handles a keyboard event, triggering a restart of any gestures that need\n * it.\n *\n * @private\n * @param {KeyboardEvent} event - The keyboard event.\n */\n handleKeyboardEvent(event) {\n if (STATE_KEY_STRINGS.indexOf(event.key) >= 0) {\n this.state.event = event;\n const oldActiveGestures = this.activeGestures;\n this.setActiveGestures();\n\n setDifference(oldActiveGestures, this.activeGestures).forEach(gesture => {\n gesture.evaluateHook(END, this.state);\n });\n setDifference(this.activeGestures, oldActiveGestures).forEach(gesture => {\n gesture.evaluateHook(START, this.state);\n });\n }\n }\n\n /**\n * Resets the active gestures.\n *\n * @private\n */\n resetActiveGestures() {\n this.potentialGestures = new Set();\n this.activeGestures = new Set();\n }\n\n /**\n * Selects active gestures from the list of potentially active gestures.\n *\n * @private\n */\n setActiveGestures() {\n this.activeGestures = setFilter(this.potentialGestures, gesture => {\n return gesture.isEnabled(this.state);\n });\n }\n\n /**\n * Selects the potentially active gestures.\n *\n * @private\n */\n setPotentialGestures() {\n const input = this.state.inputs[0];\n this.potentialGestures = setFilter(this.gestures, gesture => {\n return input.initialElements.has(gesture.element);\n });\n }\n\n /**\n * Selects the gestures that are active for the current input sequence.\n *\n * @private\n * @param {Event} event - The event emitted from the window object.\n * @param {boolean} isInitial - Whether this is an initial contact.\n */\n updateActiveGestures(event, isInitial) {\n if (PHASE[event.type] === START) {\n if (isInitial) {\n this.setPotentialGestures();\n }\n this.setActiveGestures();\n }\n }\n\n /**\n * Evaluates whether the current input session has completed.\n *\n * @private\n * @param {Event} event - The event emitted from the window object.\n */\n pruneActiveGestures(event) {\n if (PHASE[event.type] === END) {\n if (this.state.hasNoInputs()) {\n this.resetActiveGestures();\n } else {\n this.setActiveGestures();\n }\n }\n }\n\n /**\n * All input events flow through this function. It makes sure that the input\n * state is maintained, determines which gestures to analyze based on the\n * initial position of the inputs, calls the relevant gesture hooks, and\n * dispatches gesture data.\n *\n * @private\n * @param {Event} event - The event emitted from the window object.\n */\n arbitrate(event) {\n const isInitial = this.state.hasNoInputs();\n this.state.updateAllInputs(event);\n this.updateActiveGestures(event, isInitial);\n\n if (this.activeGestures.size > 0) {\n if (this.options.preventDefault) event.preventDefault();\n\n this.activeGestures.forEach(gesture => {\n gesture.evaluateHook(PHASE[event.type], this.state);\n });\n }\n\n this.state.clearEndedInputs();\n this.pruneActiveGestures(event);\n }\n\n /**\n * Adds the given gesture to the region.\n *\n * @param {westures-core.Gesture} gesture - Instantiated gesture to add.\n */\n addGesture(gesture) {\n gesture.element.style.touchAction = this.options.touchAction;\n this.gestures.add(gesture);\n }\n\n /**\n * Removes the given gesture from the region.\n *\n * @param {westures-core.Gesture} gesture - Instantiated gesture to add.\n */\n removeGesture(gesture) {\n this.gestures.delete(gesture);\n this.potentialGestures.delete(gesture);\n this.activeGestures.delete(gesture);\n }\n\n /**\n * Retrieves Gestures by their associated element.\n *\n * @param {Element} element - The element for which to find gestures.\n *\n * @return {westures-core.Gesture[]} Gestures to which the element is bound.\n */\n getGesturesByElement(element) {\n return setFilter(this.gestures, gesture => gesture.element === element);\n }\n\n /**\n * Remove all gestures bound to the given element.\n *\n * @param {Element} element - The element to unbind.\n */\n removeGesturesByElement(element) {\n this.getGesturesByElement(element).forEach(g => this.removeGesture(g));\n }\n}\n\nRegion.DEFAULTS = {\n capture: false,\n preferPointer: true,\n preventDefault: true,\n touchAction: 'none',\n};\n\nmodule.exports = Region;\n","'use strict';\n\nconst {\n CANCEL,\n END,\n MOVE,\n PHASE,\n START,\n} = require('./constants.js');\nconst Input = require('./Input.js');\nconst Point2D = require('./Point2D.js');\n\nconst symbols = {\n inputs: Symbol.for('inputs'),\n};\n\n/**\n * Set of helper functions for updating inputs based on type of input.\n * Must be called with a bound 'this', via bind(), or call(), or apply().\n *\n * @private\n * @inner\n * @memberof westure-core.State\n */\nconst update_fns = {\n TouchEvent: function TouchEvent(event) {\n Array.from(event.changedTouches).forEach(touch => {\n this.updateInput(event, touch.identifier);\n });\n },\n\n PointerEvent: function PointerEvent(event) {\n this.updateInput(event, event.pointerId);\n },\n\n MouseEvent: function MouseEvent(event) {\n if (event.button === 0) {\n this.updateInput(event, event.button);\n }\n },\n};\n\n/**\n * Keeps track of currently active and ending input points on the interactive\n * surface.\n *\n * @memberof westures-core\n *\n * @param {Element} element - The element underpinning the associated Region.\n */\nclass State {\n constructor(element) {\n /**\n * Keep a reference to the element for the associated region.\n *\n * @type {Element}\n */\n this.element = element;\n\n /**\n * Keeps track of the current Input objects.\n *\n * @alias [@@inputs]\n * @type {Map.<westures-core.Input>}\n * @memberof westure-core.State\n */\n this[symbols.inputs] = new Map();\n\n /**\n * All currently valid inputs, including those that have ended.\n *\n * @type {westures-core.Input[]}\n */\n this.inputs = [];\n\n /**\n * The array of currently active inputs, sourced from the current Input\n * objects. \"Active\" is defined as not being in the 'end' phase.\n *\n * @type {westures-core.Input[]}\n */\n this.active = [];\n\n /**\n * The array of latest point data for the currently active inputs, sourced\n * from this.active.\n *\n * @type {westures-core.Point2D[]}\n */\n this.activePoints = [];\n\n /**\n * The centroid of the currently active points.\n *\n * @type {westures-core.Point2D}\n */\n this.centroid = {};\n\n /**\n * The latest event that the state processed.\n *\n * @type {Event}\n */\n this.event = null;\n }\n\n /**\n * Deletes all inputs that are in the 'end' phase.\n */\n clearEndedInputs() {\n this[symbols.inputs].forEach((v, k) => {\n if (v.phase === 'end') this[symbols.inputs].delete(k);\n });\n }\n\n /**\n * @param {string} phase - One of 'start', 'move', 'end', or 'cancel'.\n *\n * @return {westures-core.Input[]} Inputs in the given phase.\n */\n getInputsInPhase(phase) {\n return this.inputs.filter(i => i.phase === phase);\n }\n\n /**\n * @param {string} phase - One of 'start', 'move', 'end', or 'cancel'.\n *\n * @return {westures-core.Input[]} Inputs <b>not</b> in the given phase.\n */\n getInputsNotInPhase(phase) {\n return this.inputs.filter(i => i.phase !== phase);\n }\n\n /**\n * @return {boolean} True if there are no active inputs. False otherwise.\n */\n hasNoInputs() {\n return this[symbols.inputs].size === 0;\n }\n\n /**\n * Update the input with the given identifier using the given event.\n *\n * @private\n *\n * @param {Event} event - The event being captured.\n * @param {number} identifier - The identifier of the input to update.\n */\n updateInput(event, identifier) {\n switch (PHASE[event.type]) {\n case START:\n this[symbols.inputs].set(\n identifier,\n new Input(event, identifier),\n );\n try {\n this.element.setPointerCapture(identifier);\n } catch (e) {\n // NOP: Optional operation failed.\n }\n break;\n\n // All of 'end', 'move', and 'cancel' perform updates, hence the\n // following fall-throughs\n case END:\n try {\n this.element.releasePointerCapture(identifier);\n } catch (e) {\n // NOP: Optional operation failed.\n }\n case CANCEL:\n case MOVE:\n if (this[symbols.inputs].has(identifier)) {\n this[symbols.inputs].get(identifier).update(event);\n }\n break;\n\n default:\n console.warn(`Unrecognized event type: ${event.type}`);\n }\n }\n\n /**\n * Updates the inputs with new information based upon a new event being fired.\n *\n * @private\n * @param {Event} event - The event being captured.\n */\n updateAllInputs(event) {\n update_fns[event.constructor.name].call(this, event);\n this.updateFields(event);\n }\n\n /**\n * Updates the convenience fields.\n *\n * @private\n * @param {Event} event - Event with which to update the convenience fields.\n */\n updateFields(event) {\n this.inputs = Array.from(this[symbols.inputs].values());\n this.active = this.getInputsNotInPhase('end');\n this.activePoints = this.active.map(i => i.current.point);\n this.centroid = Point2D.centroid(this.activePoints);\n this.event = event;\n }\n}\n\nmodule.exports = State;\n\n","'use strict';\n\nconst cascade = Symbol('cascade');\nconst smooth = Symbol('smooth');\n\n/**\n * Determines whether to apply smoothing. Smoothing is on by default but turned\n * off if either:<br>\n * 1. The user explicitly requests that it be turned off.<br>\n * 2. The active pointer is not \"coarse\".<br>\n *\n * @see {@link\n * https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia}\n *\n * @inner\n * @memberof westures-core.Smoothable\n *\n * @param {boolean} isRequested - Whether smoothing was requested by the user.\n *\n * @returns {boolean} Whether to apply smoothing.\n */\nfunction smoothingIsApplicable(isRequested) {\n if (isRequested) {\n try {\n return window.matchMedia('(pointer: coarse)').matches;\n } catch (e) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * A Smoothable datatype is one that is capable of smoothing out a series of\n * values as they come in, one at a time, providing a more consistent series. It\n * does this by creating some inertia in the values using a cascading average.\n * (For those who are interested in such things, this effectively means that it\n * provides a practical application of Zeno's Dichotomy).\n *\n * @example\n * const x = new Smoothable({ identity: 1 });\n * const a = x.next(1); // 1.0\n * const b = x.next(1.2); // 1.1\n * const c = x.next(0.9); // 1.0\n * const d = x.next(0.6); // 0.8\n * const e = x.next(1.2); // 1.0\n * const f = x.next(1.6); // 1.3\n * x.restart();\n * const g = x.next(0); // 0.5\n *\n * @memberof westures-core\n *\n * @param {Object} [options]\n * @param {boolean} [options.applySmoothing=true] Whether to apply smoothing to\n * the data.\n * @param {*} [options.identity=0] The identity value of this smoothable data.\n */\nclass Smoothable {\n constructor(options = {}) {\n const final_options = { ...Smoothable.DEFAULTS, ...options };\n\n /**\n * The function through which smoothed emits are passed.\n *\n * @method\n * @param {*} data - The data to emit.\n *\n * @return {*} The smoothed out data.\n */\n this.next = null;\n if (smoothingIsApplicable(final_options.applySmoothing)) {\n this.next = this[smooth].bind(this);\n } else {\n this.next = data => data;\n }\n\n /**\n * The \"identity\" value of the data that will be smoothed.\n *\n * @type {*}\n * @default 0\n */\n this.identity = final_options.identity;\n\n /**\n * The cascading average of outgoing values.\n *\n * @memberof westures-core.Smoothable\n * @alias [@@cascade]\n * @type {object}\n */\n this[cascade] = this.identity;\n }\n\n /**\n * Restart the Smoothable gesture.\n */\n restart() {\n this[cascade] = this.identity;\n }\n\n /**\n * Smooth out the outgoing data.\n *\n * @memberof westures-core.Smoothable\n * @alias [@@smooth]\n * @param {object} data - The next batch of data to emit.\n *\n * @return {?object}\n */\n [smooth](data) {\n const average = this.average(this[cascade], data);\n this[cascade] = average;\n return average;\n }\n\n /**\n * Average out two values, as part of the smoothing algorithm. Override this\n * method if the data being smoothed is not a Number.\n *\n * @param {number} a\n * @param {number} b\n *\n * @return {number} The average of 'a' and 'b'\n */\n average(a, b) {\n return (a + b) / 2;\n }\n}\n\nSmoothable.DEFAULTS = {\n applySmoothing: true,\n identity: 0,\n};\n\nmodule.exports = Smoothable;\n\n"],"names":[],"version":3,"file":"index.js.map"}
|
|
1
|
+
{"mappings":"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","sources":["index.js","src/Gesture.js","src/Input.js","src/PointerData.js","src/Point2D.js","src/constants.js","src/utils.js","src/Region.js","src/State.js","src/Smoothable.js"],"sourcesContent":["/**\n * The global API interface for westures-core. Exposes all classes, constants,\n * and routines used by the package. Use responsibly.\n *\n * @namespace westures-core\n */\n\n'use strict';\n\nconst Gesture = require('./src/Gesture.js');\nconst Input = require('./src/Input.js');\nconst Point2D = require('./src/Point2D.js');\nconst PointerData = require('./src/PointerData.js');\nconst Region = require('./src/Region.js');\nconst Smoothable = require('./src/Smoothable.js');\nconst State = require('./src/State.js');\nconst constants = require('./src/constants.js');\nconst utils = require('./src/utils.js');\n\nmodule.exports = {\n Gesture,\n Input,\n Point2D,\n PointerData,\n Region,\n Smoothable,\n State,\n ...constants,\n ...utils,\n};\n\n","'use strict';\n\nlet g_id = 0;\n\n/**\n * The Gesture class that all gestures inherit from. A custom gesture class will\n * need to override some or all of the four phase \"hooks\": start, move, end, and\n * cancel.\n *\n * @memberof westures-core\n *\n * @param {string} type - The name of the gesture.\n * @param {Element} element - The element to which to associate the gesture.\n * @param {Function} handler - The function handler to execute when a gesture\n * is recognized on the associated element.\n * @param {object} [options] - Generic gesture options\n * @param {westures-core.STATE_KEYS[]} [options.enableKeys=[]] - List of keys\n * which will enable the gesture. The gesture will not be recognized unless one\n * of these keys is pressed while the interaction occurs. If not specified or an\n * empty list, the gesture is treated as though the enable key is always down.\n * @param {westures-core.STATE_KEYS[]} [options.disableKeys=[]] - List of keys\n * which will disable the gesture. The gesture will not be recognized if one of\n * these keys is pressed while the interaction occurs. If not specified or an\n * empty list, the gesture is treated as though the disable key is never down.\n * @param {number} [options.minInputs=1] - The minimum number of pointers that\n * must be active for the gesture to be recognized. Uses >=.\n * @param {number} [options.maxInputs=Number.MAX_VALUE] - The maximum number of\n * pointers that may be active for the gesture to be recognized. Uses <=.\n */\nclass Gesture {\n constructor(type, element, handler, options = {}) {\n if (typeof type !== 'string') {\n throw new TypeError('Gestures require a string type / name');\n }\n\n /**\n * The name of the gesture. (e.g. 'pan' or 'tap' or 'pinch').\n *\n * @type {string}\n */\n this.type = type;\n\n /**\n * The unique identifier for each gesture. This allows for distinctions\n * across instances of Gestures that are created on the fly (e.g.\n * gesture-tap-1, gesture-tap-2).\n *\n * @type {string}\n */\n this.id = `gesture-${this.type}-${g_id++}`;\n\n /**\n * The element to which to associate the gesture.\n *\n * @type {Element}\n */\n this.element = element;\n\n /**\n * The function handler to execute when the gesture is recognized on the\n * associated element.\n *\n * @type {Function}\n */\n this.handler = handler;\n\n /**\n * The options. Can usually be adjusted live, though be careful doing this.\n *\n * @type {object}\n */\n this.options = { ...Gesture.DEFAULTS, ...options };\n }\n\n /**\n * Determines whether this gesture is enabled.\n *\n * @param {westures-core.State} state - The input state object of the current\n * region.\n *\n * @return {boolean} true if enabled, false otherwise.\n */\n isEnabled(state) {\n const count = state.active.length;\n const event = state.event;\n const { enableKeys, disableKeys, minInputs, maxInputs } = this.options;\n\n return (minInputs <= count) && (maxInputs >= count) &&\n (enableKeys.length === 0 || enableKeys.some(k => event[k])) &&\n !disableKeys.some(k => event[k]);\n }\n\n /**\n * Event hook for the start phase of a gesture.\n *\n * @param {westures-core.State} state - The input state object of the current\n * region.\n *\n * @return {?Object} Gesture is considered recognized if an Object is\n * returned.\n */\n start() {\n return null;\n }\n\n /**\n * Event hook for the move phase of a gesture.\n *\n * @param {westures-core.State} state - The input state object of the current\n * region.\n *\n * @return {?Object} Gesture is considered recognized if an Object is\n * returned.\n */\n move() {\n return null;\n }\n\n /**\n * Event hook for the end phase of a gesture.\n *\n * @param {westures-core.State} state - The input state object of the current\n * region.\n *\n * @return {?Object} Gesture is considered recognized if an Object is\n * returned.\n */\n end() {\n return null;\n }\n\n /**\n * Event hook for when an input is cancelled.\n *\n * @param {westures-core.State} state - The input state object of the current\n * region.\n *\n * @return {?Object} Gesture is considered recognized if an Object is\n * returned.\n */\n cancel() {\n return null;\n }\n\n /**\n * Evalutes the given gesture hook, and dispatches any data that is produced\n * by calling [recognize]{@link westures-core.Gesture#recognize}.\n *\n * @param {string} hook - Must be one of 'start', 'move', 'end', or 'cancel'.\n * @param {westures-core.State} state - The current State instance.\n */\n evaluateHook(hook, state) {\n const data = this[hook](state);\n if (data) {\n this.recognize(hook, state, data);\n }\n }\n\n /**\n * Recognize a Gesture by calling the handler. Standardizes the way the\n * handler is called so that classes extending Gesture can circumvent the\n * evaluateHook approach but still provide results that have a common format.\n *\n * Note that the properties in the \"data\" object will receive priority when\n * constructing the results. This can be used to override standard results\n * such as the phase or the centroid.\n *\n * @param {string} hook - Must be one of 'start', 'move', 'end', or 'cancel'.\n * @param {westures-core.State} state - current input state.\n * @param {Object} data - Results data specific to the recognized gesture.\n */\n recognize(hook, state, data) {\n this.handler({\n centroid: state.centroid,\n event: state.event,\n phase: hook,\n type: this.type,\n target: this.element,\n ...data,\n });\n }\n}\n\nGesture.DEFAULTS = {\n enableKeys: [],\n disableKeys: [],\n minInputs: 1,\n maxInputs: Number.MAX_VALUE,\n};\n\nmodule.exports = Gesture;\n\n","'use strict';\n\nconst PointerData = require('./PointerData.js');\nconst { getPropagationPath } = require('./utils.js');\n\n/**\n * Tracks a single input and contains information about the current, previous,\n * and initial events.\n *\n * @memberof westures-core\n *\n * @param {(PointerEvent | MouseEvent | TouchEvent)} event - The input event\n * which will initialize this Input object.\n * @param {number} identifier - The identifier for this input, so that it can\n * be located in subsequent Event objects.\n */\nclass Input {\n constructor(event, identifier, headless = false) {\n const currentData = new PointerData(event, identifier);\n\n /**\n * The set of elements along the original event's propagation path at the\n * time it was dispatched.\n *\n * @type {WeakSet.<Element>}\n */\n if (headless) {\n this.initialElements = new WeakSet([event.target]);\n } else {\n this.initialElements = new WeakSet(getPropagationPath(event));\n }\n\n /**\n * Holds the initial data from the mousedown / touchstart / pointerdown that\n * began this input.\n *\n * @type {westures-core.PointerData}\n */\n this.initial = currentData;\n\n /**\n * Holds the most current pointer data for this Input.\n *\n * @type {westures-core.PointerData}\n */\n this.current = currentData;\n\n /**\n * Holds the previous pointer data for this Input.\n *\n * @type {westures-core.PointerData}\n */\n this.previous = currentData;\n\n /**\n * The identifier for the pointer / touch / mouse button associated with\n * this input.\n *\n * @type {number}\n */\n this.identifier = identifier;\n }\n\n /**\n * The phase of the input: 'start' or 'move' or 'end' or 'cancel'\n *\n * @type {string}\n */\n get phase() { return this.current.type; }\n\n /**\n * The timestamp of the initiating event for this input.\n *\n * @type {number}\n */\n get startTime() { return this.initial.time; }\n\n /**\n * The amount of time elapsed between the start of this input and its latest\n * event.\n *\n * @type {number}\n */\n get elapsedTime() { return this.current.time - this.initial.time; }\n\n /**\n * @return {number} The distance between the initiating event for this input\n * and its current event.\n */\n totalDistance() {\n return this.initial.point.distanceTo(this.current.point);\n }\n\n /**\n * Saves the given raw event in PointerData form as the current data for this\n * input, pushing the old current data into the previous slot, and tossing\n * out the old previous data.\n *\n * @param {Event} event - The event object to wrap with a PointerData.\n */\n update(event) {\n this.previous = this.current;\n this.current = new PointerData(event, this.identifier);\n }\n}\n\nmodule.exports = Input;\n\n","'use strict';\n\nconst Point2D = require('./Point2D.js');\nconst { PHASE } = require('./constants.js');\n\n/**\n * @private\n * @inner\n * @memberof westures-core.PointerData\n *\n * @return {Event} The Event object which corresponds to the given identifier.\n * Contains clientX, clientY values.\n */\nfunction getEventObject(event, identifier) {\n if (event.changedTouches) {\n return Array.from(event.changedTouches).find(touch => {\n return touch.identifier === identifier;\n });\n }\n return event;\n}\n\n/**\n * Low-level storage of pointer data based on incoming data from an interaction\n * event.\n *\n * @memberof westures-core\n *\n * @param {Event} event - The event object being wrapped.\n * @param {number} identifier - The index of touch if applicable\n */\nclass PointerData {\n constructor(event, identifier) {\n const { clientX, clientY } = getEventObject(event, identifier);\n\n /**\n * The original event object.\n *\n * @type {Event}\n */\n this.event = event;\n\n /**\n * The type or 'phase' of this batch of pointer data. 'start' or 'move' or\n * 'end' or 'cancel'\n *\n * @type {string}\n */\n this.type = PHASE[event.type];\n\n /**\n * The timestamp of the event in milliseconds elapsed since January 1, 1970,\n * 00:00:00 UTC.\n *\n * @type {number}\n */\n this.time = Date.now();\n\n /**\n * The (x,y) coordinate of the event, wrapped in a Point2D.\n *\n * @type {westures-core.Point2D}\n */\n this.point = new Point2D(clientX, clientY);\n }\n}\n\nmodule.exports = PointerData;\n\n","'use strict';\n\n/**\n * The Point2D class stores and operates on 2-dimensional points, represented as\n * x and y coordinates.\n *\n * @memberof westures-core\n *\n * @param {number} [ x=0 ] - The x coordinate of the point.\n * @param {number} [ y=0 ] - The y coordinate of the point.\n */\nclass Point2D {\n constructor(x = 0, y = 0) {\n /**\n * The x coordinate of the point.\n *\n * @type {number}\n */\n this.x = x;\n\n /**\n * The y coordinate of the point.\n *\n * @type {number}\n */\n this.y = y;\n }\n\n /**\n * Calculates the angle between this point and the given point.\n *\n * @param {!westures-core.Point2D} point - Projected point for calculating the\n * angle.\n *\n * @return {number} Radians along the unit circle where the projected\n * point lies.\n */\n angleTo(point) {\n return Math.atan2(point.y - this.y, point.x - this.x);\n }\n\n /**\n * Determine the angle from the centroid to each of the points.\n *\n * @param {!westures-core.Point2D[]} points - the Point2D objects to calculate\n * the angles to.\n *\n * @returns {number[]}\n */\n anglesTo(points) {\n return points.map(point => this.angleTo(point));\n }\n\n /**\n * Determine the average distance from this point to the provided array of\n * points.\n *\n * @param {!westures-core.Point2D[]} points - the Point2D objects to calculate\n * the average distance to.\n *\n * @return {number} The average distance from this point to the provided\n * points.\n */\n averageDistanceTo(points) {\n return this.totalDistanceTo(points) / points.length;\n }\n\n /**\n * Clone this point.\n *\n * @return {westures-core.Point2D} A new Point2D, identical to this point.\n */\n clone() {\n return new Point2D(this.x, this.y);\n }\n\n /**\n * Calculates the distance between two points.\n *\n * @param {!westures-core.Point2D} point - Point to which the distance is\n * calculated.\n *\n * @return {number} The distance between the two points, a.k.a. the\n * hypoteneuse.\n */\n distanceTo(point) {\n return Math.hypot(point.x - this.x, point.y - this.y);\n }\n\n /**\n * Subtract the given point from this point.\n *\n * @param {!westures-core.Point2D} point - Point to subtract from this point.\n *\n * @return {westures-core.Point2D} A new Point2D, which is the result of (this\n * - point).\n */\n minus(point) {\n return new Point2D(\n this.x - point.x,\n this.y - point.y,\n );\n }\n\n /**\n * Return the summation of this point to the given point.\n *\n * @param {!westures-core.Point2D} point - Point to add to this point.\n *\n * @return {westures-core.Point2D} A new Point2D, which is the addition of the\n * two points.\n */\n plus(point) {\n return new Point2D(\n this.x + point.x,\n this.y + point.y,\n );\n }\n\n /**\n * Calculates the total distance from this point to an array of points.\n *\n * @param {!westures-core.Point2D[]} points - The array of Point2D objects to\n * calculate the total distance to.\n *\n * @return {number} The total distance from this point to the provided points.\n */\n totalDistanceTo(points) {\n return points.reduce((d, p) => d + this.distanceTo(p), 0);\n }\n\n /**\n * Calculates the centroid of a list of points.\n *\n * @param {westures-core.Point2D[]} points - The array of Point2D objects for\n * which to calculate the centroid.\n *\n * @return {westures-core.Point2D} The centroid of the provided points.\n */\n static centroid(points = []) {\n if (points.length === 0) return null;\n\n const total = Point2D.sum(points);\n total.x /= points.length;\n total.y /= points.length;\n return total;\n }\n\n /**\n * Calculates the sum of the given points.\n *\n * @param {westures-core.Point2D[]} points - The Point2D objects to sum up.\n *\n * @return {westures-core.Point2D} A new Point2D representing the sum of the\n * given points.\n */\n static sum(points = []) {\n return points.reduce(\n (total, pt) => {\n total.x += pt.x;\n total.y += pt.y;\n return total;\n },\n new Point2D(0, 0),\n );\n }\n}\n\nmodule.exports = Point2D;\n\n","'use strict';\n\n/**\n * List of events that trigger the cancel phase.\n *\n * @memberof westures-core\n * @type {string[]}\n */\nconst CANCEL_EVENTS = [\n 'blur',\n 'pointercancel',\n 'touchcancel',\n 'mouseleave',\n];\n\n/**\n * List of keyboard events that trigger a restart.\n *\n * @memberof westures-core\n * @type {string[]}\n */\nconst KEYBOARD_EVENTS = [\n 'keydown',\n 'keyup',\n];\n\n/**\n * List of mouse events to listen to.\n *\n * @memberof westures-core\n * @type {string[]}\n */\nconst MOUSE_EVENTS = [\n 'mousedown',\n 'mousemove',\n 'mouseup',\n];\n\n/**\n * List of pointer events to listen to.\n *\n * @memberof westures-core\n * @type {string[]}\n */\nconst POINTER_EVENTS = [\n 'pointerdown',\n 'pointermove',\n 'pointerup',\n];\n\n/**\n * List of touch events to listen to.\n *\n * @memberof westures-core\n * @type {string[]}\n */\nconst TOUCH_EVENTS = [\n 'touchend',\n 'touchmove',\n 'touchstart',\n];\n\n/**\n * List of potentially state-modifying keys.\n * Entries are: ['altKey', 'ctrlKey', 'metaKey', 'shiftKey'].\n *\n * @memberof westures-core\n * @type {string[]}\n */\nconst STATE_KEYS = [\n 'altKey',\n 'ctrlKey',\n 'metaKey',\n 'shiftKey',\n];\n\n/**\n * List of the 'key' values on KeyboardEvent objects of the potentially\n * state-modifying keys.\n *\n * @memberof westures-core\n * @type {string[]}\n */\nconst STATE_KEY_STRINGS = [\n 'Alt',\n 'Control',\n 'Meta',\n 'Shift',\n];\n\n/**\n * The cancel phase.\n *\n * @memberof westures-core\n * @type {string}\n */\nconst CANCEL = 'cancel';\n\n/**\n * The end phase.\n *\n * @memberof westures-core\n * @type {string}\n */\nconst END = 'end';\n\n/**\n * The move phase.\n *\n * @memberof westures-core\n * @type {string}\n */\nconst MOVE = 'move';\n\n/**\n * The start phase.\n *\n * @memberof westures-core\n * @type {string}\n */\nconst START = 'start';\n\n/**\n * The recognized phases.\n *\n * @memberof westures-core\n * @type {list.<string>}\n */\nconst PHASES = [START, MOVE, END, CANCEL];\n\n/**\n * Object that normalizes the names of window events to be either of type start,\n * move, end, or cancel.\n *\n * @memberof westures-core\n * @type {object}\n */\nconst PHASE = {\n blur: CANCEL,\n pointercancel: CANCEL,\n touchcancel: CANCEL,\n\n mouseup: END,\n pointerup: END,\n touchend: END,\n\n mousemove: MOVE,\n pointermove: MOVE,\n touchmove: MOVE,\n\n mousedown: START,\n pointerdown: START,\n touchstart: START,\n};\n\nmodule.exports = {\n CANCEL_EVENTS,\n KEYBOARD_EVENTS,\n MOUSE_EVENTS,\n POINTER_EVENTS,\n TOUCH_EVENTS,\n\n STATE_KEYS,\n STATE_KEY_STRINGS,\n\n CANCEL,\n END,\n MOVE,\n START,\n\n PHASE,\n PHASES,\n};\n\n","'use strict';\n\nconst PI_2 = 2 * Math.PI;\nconst PI_NVE = -Math.PI;\n\n/**\n * Helper function to regulate angular differences, so they don't jump from 0 to\n * 2 * PI or vice versa.\n *\n * @memberof westures-core\n *\n * @param {number} a - Angle in radians.\n * @param {number} b - Angle in radians.\n\n * @return {number} c, given by: c = a - b such that |c| < PI\n */\nfunction angularDifference(a, b) {\n let diff = a - b;\n if (diff < PI_NVE) {\n diff += PI_2;\n } else if (diff > Math.PI) {\n diff -= PI_2;\n }\n return diff;\n}\n\n/**\n * In case event.composedPath() is not available.\n *\n * @memberof westures-core\n *\n * @param {Event} event\n *\n * @return {Element[]} The elements along the composed path of the event.\n */\nfunction getPropagationPath(event) {\n if (typeof event.composedPath === 'function') {\n return event.composedPath();\n }\n\n const path = [];\n for (let node = event.target; node !== document; node = node.parentNode) {\n path.push(node);\n }\n path.push(document);\n path.push(window);\n\n return path;\n}\n\n/**\n * Performs a set filter operation.\n *\n * @memberof westures-core\n *\n * @param {Set} set - The set to filter.\n * @param {Function} predicate - Function to test elements of 'set'. Receives\n * one argument: the current set element.\n *\n * @return {Set} Set consisting of elements in 'set' for which 'predicate' is\n * true.\n */\nfunction setFilter(set, predicate) {\n const result = new Set();\n set.forEach(element => {\n if (predicate(element)) {\n result.add(element);\n }\n });\n return result;\n}\n\n/**\n * Performs a set difference operation.\n *\n * @memberof westures-core\n *\n * @param {Set} left - Base set.\n * @param {Set} right - Set of elements to remove from 'left'.\n *\n * @return {Set} Set consisting of elements in 'left' that are not in\n * 'right'.\n */\nfunction setDifference(left, right) {\n return setFilter(left, element => !right.has(element));\n}\n\nmodule.exports = {\n angularDifference,\n getPropagationPath,\n setDifference,\n setFilter,\n};\n\n","'use strict';\n\nconst State = require('./State.js');\nconst {\n CANCEL_EVENTS,\n KEYBOARD_EVENTS,\n MOUSE_EVENTS,\n POINTER_EVENTS,\n TOUCH_EVENTS,\n\n STATE_KEY_STRINGS,\n\n PHASE,\n\n CANCEL,\n END,\n START,\n} = require('./constants.js');\nconst {\n setDifference,\n setFilter,\n} = require('./utils.js');\n\n/**\n * Allows the user to specify the control region which will listen for user\n * input events.\n *\n * @memberof westures-core\n *\n * @param {Element} [element=null] - The element which should listen to input\n * events. If not provided, will be set to the window unless operating in\n * \"headless\" mode.\n * @param {object} [options]\n * @param {boolean} [options.capture=false] - Whether the region uses the\n * capture phase of input events. If false, uses the bubbling phase.\n * @param {boolean} [options.preferPointer=true] - If false, the region listens\n * to mouse/touch events instead of pointer events.\n * @param {boolean} [options.preventDefault=true] - Whether the default\n * browser functionality should be disabled. This option should most likely be\n * ignored. Here there by dragons if set to false.\n * @param {string} [options.touchAction='none'] - Value to set the CSS\n * 'touch-action' property to on elements added to the region.\n * @param {boolean} [options.headless=false] - Set to true to turn on \"headless\"\n * mode. This mode is intended for use outside of a browser environment. It does\n * not listen to window events, so instead you will have to send events directly\n * into the region. Pointer down/move/up events should be sent to\n * Region.arbitrate(event), cancel events should be sent to\n * Region.cancel(event), and keyboard events should be sent to\n * Region.handleKeyboardEvent(event). You do not need to supply an element to\n * the Region constructor in this mode, but you will still need to attach\n * elements to Gestures, and the events you pass in should specify event.target\n * appropriately, in order to select which gestures to run.\n */\nclass Region {\n constructor(element = null, options = {}) {\n options = { ...Region.DEFAULTS, ...options };\n if (element === null) {\n if (options.headless) {\n element = null;\n } else {\n element = window;\n }\n }\n\n /**\n * The list of relations between elements, their gestures, and the handlers.\n *\n * @type {Set.<westures-core.Gesture>}\n */\n this.gestures = new Set();\n\n /**\n * The list of active gestures for the current input session.\n *\n * @type {Set.<westures-core.Gesture>}\n */\n this.activeGestures = new Set();\n\n /**\n * The base list of potentially active gestures for the current input\n * session.\n *\n * @type {Set.<westures-core.Gesture>}\n */\n this.potentialGestures = new Set();\n\n /**\n * The element being bound to.\n *\n * @type {Element}\n */\n this.element = element;\n\n /**\n * The user-supplied options for the Region.\n *\n * @type {object}\n */\n this.options = options;\n\n /**\n * The internal state object for a Region. Keeps track of inputs.\n *\n * @type {westures-core.State}\n */\n this.state = new State(this.element, options.headless);\n\n if (!options.headless) {\n // Begin operating immediately.\n this.activate();\n }\n }\n\n /**\n * Activates the region by adding event listeners for all appropriate input\n * events to the region's element.\n *\n * @private\n */\n activate() {\n /*\n * Listening to both mouse and touch comes with the difficulty that\n * preventDefault() must be called to prevent both events from iterating\n * through the system. However I have left it as an option to the end user,\n * which defaults to calling preventDefault(), in case there's a use-case I\n * haven't considered or am not aware of.\n *\n * It also may be a good idea to keep regions small in large pages.\n *\n * See:\n * https://www.html5rocks.com/en/mobile/touchandmouse/\n * https://developer.mozilla.org/en-US/docs/Web/API/Touch_events\n * https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events\n */\n let eventNames = [];\n if (this.options.preferPointer && window.PointerEvent) {\n eventNames = POINTER_EVENTS;\n } else {\n eventNames = MOUSE_EVENTS.concat(TOUCH_EVENTS);\n }\n\n // Bind detected browser events to the region element.\n const arbitrate = this.arbitrate.bind(this);\n eventNames.forEach(eventName => {\n this.element.addEventListener(eventName, arbitrate, {\n capture: this.options.capture,\n once: false,\n passive: false,\n });\n });\n\n const cancel = this.cancel.bind(this);\n CANCEL_EVENTS.forEach(eventName => {\n window.addEventListener(eventName, cancel);\n });\n\n const handleKeyboardEvent = this.handleKeyboardEvent.bind(this);\n KEYBOARD_EVENTS.forEach(eventName => {\n window.addEventListener(eventName, handleKeyboardEvent);\n });\n }\n\n /**\n * Handles a cancel event. Resets the state and the active / potential gesture\n * lists.\n *\n * @private\n * @param {Event} event - The event emitted from the window object.\n */\n cancel(event) {\n if (\n this.options.preventDefault && typeof event.preventDefault === 'function'\n ) {\n event.preventDefault();\n }\n this.state.inputs.forEach(input => {\n input.update(event);\n });\n this.activeGestures.forEach(gesture => {\n gesture.evaluateHook(CANCEL, this.state);\n });\n this.state = new State(this.element, this.options.headless);\n this.resetActiveGestures();\n }\n\n /**\n * Handles a keyboard event, triggering a restart of any gestures that need\n * it.\n *\n * @private\n * @param {KeyboardEvent} event - The keyboard event.\n */\n handleKeyboardEvent(event) {\n if (STATE_KEY_STRINGS.indexOf(event.key) >= 0) {\n this.state.event = event;\n const oldActiveGestures = this.activeGestures;\n this.setActiveGestures();\n\n setDifference(oldActiveGestures, this.activeGestures).forEach(gesture => {\n gesture.evaluateHook(END, this.state);\n });\n setDifference(this.activeGestures, oldActiveGestures).forEach(gesture => {\n gesture.evaluateHook(START, this.state);\n });\n }\n }\n\n /**\n * Resets the active gestures.\n *\n * @private\n */\n resetActiveGestures() {\n this.potentialGestures = new Set();\n this.activeGestures = new Set();\n }\n\n /**\n * Selects active gestures from the list of potentially active gestures.\n *\n * @private\n */\n setActiveGestures() {\n this.activeGestures = setFilter(this.potentialGestures, gesture => {\n return gesture.isEnabled(this.state);\n });\n }\n\n /**\n * Selects the potentially active gestures.\n *\n * @private\n */\n setPotentialGestures() {\n const input = this.state.inputs[0];\n this.potentialGestures = setFilter(this.gestures, gesture => {\n return input.initialElements.has(gesture.element);\n });\n }\n\n /**\n * Selects the gestures that are active for the current input sequence.\n *\n * @private\n * @param {Event} event - The event emitted from the window object.\n * @param {boolean} isInitial - Whether this is an initial contact.\n */\n updateActiveGestures(event, isInitial) {\n if (PHASE[event.type] === START) {\n if (isInitial) {\n this.setPotentialGestures();\n }\n this.setActiveGestures();\n }\n }\n\n /**\n * Evaluates whether the current input session has completed.\n *\n * @private\n * @param {Event} event - The event emitted from the window object.\n */\n pruneActiveGestures(event) {\n if (PHASE[event.type] === END) {\n if (this.state.hasNoInputs()) {\n this.resetActiveGestures();\n } else {\n this.setActiveGestures();\n }\n }\n }\n\n /**\n * All input events flow through this function. It makes sure that the input\n * state is maintained, determines which gestures to analyze based on the\n * initial position of the inputs, calls the relevant gesture hooks, and\n * dispatches gesture data.\n *\n * @private\n * @param {Event} event - The event emitted from the window object.\n */\n arbitrate(event) {\n const isInitial = this.state.hasNoInputs();\n this.state.updateAllInputs(event);\n this.updateActiveGestures(event, isInitial);\n\n if (this.activeGestures.size > 0) {\n if (\n this.options.preventDefault &&\n typeof event.preventDefault === 'function'\n ) event.preventDefault();\n\n this.activeGestures.forEach(gesture => {\n gesture.evaluateHook(PHASE[event.type], this.state);\n });\n }\n\n this.state.clearEndedInputs();\n this.pruneActiveGestures(event);\n }\n\n /**\n * Adds the given gesture to the region.\n *\n * @param {westures-core.Gesture} gesture - Instantiated gesture to add.\n */\n addGesture(gesture) {\n if (!this.options.headless) {\n gesture.element.style.touchAction = this.options.touchAction;\n }\n this.gestures.add(gesture);\n }\n\n /**\n * Removes the given gesture from the region.\n *\n * @param {westures-core.Gesture} gesture - Instantiated gesture to add.\n */\n removeGesture(gesture) {\n this.gestures.delete(gesture);\n this.potentialGestures.delete(gesture);\n this.activeGestures.delete(gesture);\n }\n\n /**\n * Retrieves Gestures by their associated element.\n *\n * @param {Element} element - The element for which to find gestures.\n *\n * @return {westures-core.Gesture[]} Gestures to which the element is bound.\n */\n getGesturesByElement(element) {\n return setFilter(this.gestures, gesture => gesture.element === element);\n }\n\n /**\n * Remove all gestures bound to the given element.\n *\n * @param {Element} element - The element to unbind.\n */\n removeGesturesByElement(element) {\n this.getGesturesByElement(element).forEach(g => this.removeGesture(g));\n }\n}\n\nRegion.DEFAULTS = {\n capture: false,\n preferPointer: true,\n preventDefault: true,\n touchAction: 'none',\n headless: false,\n};\n\nmodule.exports = Region;\n","'use strict';\n\nconst {\n CANCEL,\n END,\n MOVE,\n PHASE,\n START,\n MOUSE_EVENTS,\n POINTER_EVENTS,\n TOUCH_EVENTS,\n} = require('./constants.js');\nconst Input = require('./Input.js');\nconst Point2D = require('./Point2D.js');\n\nconst symbols = {\n inputs: Symbol.for('inputs'),\n};\n\n/**\n * Keeps track of currently active and ending input points on the interactive\n * surface.\n *\n * @memberof westures-core\n *\n * @param {Element} element - The element underpinning the associated Region.\n * @param {boolean} [headless=false] - Whether westures is operating in\n * \"headless\" mode.\n */\nclass State {\n constructor(element, headless = false) {\n /**\n * Keep a reference to the element for the associated region.\n *\n * @type {Element}\n */\n this.element = element;\n\n /**\n * Whether westures is operating in \"headless\" mode.\n *\n * @type {boolean}\n */\n this.headless = headless;\n\n /**\n * Keeps track of the current Input objects.\n *\n * @alias [@@inputs]\n * @type {Map.<westures-core.Input>}\n * @memberof westure-core.State\n */\n this[symbols.inputs] = new Map();\n\n /**\n * All currently valid inputs, including those that have ended.\n *\n * @type {westures-core.Input[]}\n */\n this.inputs = [];\n\n /**\n * The array of currently active inputs, sourced from the current Input\n * objects. \"Active\" is defined as not being in the 'end' phase.\n *\n * @type {westures-core.Input[]}\n */\n this.active = [];\n\n /**\n * The array of latest point data for the currently active inputs, sourced\n * from this.active.\n *\n * @type {westures-core.Point2D[]}\n */\n this.activePoints = [];\n\n /**\n * The centroid of the currently active points.\n *\n * @type {westures-core.Point2D}\n */\n this.centroid = {};\n\n /**\n * The latest event that the state processed.\n *\n * @type {Event}\n */\n this.event = null;\n }\n\n /**\n * Deletes all inputs that are in the 'end' phase.\n */\n clearEndedInputs() {\n this[symbols.inputs].forEach((v, k) => {\n if (v.phase === 'end') this[symbols.inputs].delete(k);\n });\n }\n\n /**\n * @param {string} phase - One of 'start', 'move', 'end', or 'cancel'.\n *\n * @return {westures-core.Input[]} Inputs in the given phase.\n */\n getInputsInPhase(phase) {\n return this.inputs.filter(i => i.phase === phase);\n }\n\n /**\n * @param {string} phase - One of 'start', 'move', 'end', or 'cancel'.\n *\n * @return {westures-core.Input[]} Inputs <b>not</b> in the given phase.\n */\n getInputsNotInPhase(phase) {\n return this.inputs.filter(i => i.phase !== phase);\n }\n\n /**\n * @return {boolean} True if there are no active inputs. False otherwise.\n */\n hasNoInputs() {\n return this[symbols.inputs].size === 0;\n }\n\n /**\n * Update the input with the given identifier using the given event.\n *\n * @private\n *\n * @param {Event} event - The event being captured.\n * @param {number} identifier - The identifier of the input to update.\n */\n updateInput(event, identifier) {\n switch (PHASE[event.type]) {\n case START:\n this[symbols.inputs].set(\n identifier,\n new Input(event, identifier, this.headless),\n );\n if (!this.headless) {\n try {\n this.element.setPointerCapture(identifier);\n } catch (e) {\n // NOP: Optional operation failed.\n }\n }\n break;\n\n // All of 'end', 'move', and 'cancel' perform updates, hence the\n // following fall-throughs\n case END:\n if (!this.headless) {\n try {\n this.element.releasePointerCapture(identifier);\n } catch (e) {\n // NOP: Optional operation failed.\n }\n }\n case CANCEL:\n case MOVE:\n if (this[symbols.inputs].has(identifier)) {\n this[symbols.inputs].get(identifier).update(event);\n }\n break;\n\n default:\n console.warn(`Unrecognized event type: ${event.type}`);\n }\n }\n\n /**\n * Updates the inputs with new information based upon a new event being fired.\n *\n * @private\n * @param {Event} event - The event being captured.\n */\n updateAllInputs(event) {\n if (POINTER_EVENTS.includes(event.type)) {\n this.updateInput(event, event.pointerId);\n } else if (MOUSE_EVENTS.includes(event.type)) {\n if (event.button === 0) {\n this.updateInput(event, event.button);\n }\n } else if (TOUCH_EVENTS.includes(event.type)) {\n Array.from(event.changedTouches).forEach(touch => {\n this.updateInput(event, touch.identifier);\n });\n } else {\n throw new Error(`Unexpected event type: ${event.type}`);\n }\n this.updateFields(event);\n }\n\n /**\n * Updates the convenience fields.\n *\n * @private\n * @param {Event} event - Event with which to update the convenience fields.\n */\n updateFields(event) {\n this.inputs = Array.from(this[symbols.inputs].values());\n this.active = this.getInputsNotInPhase('end');\n this.activePoints = this.active.map(i => i.current.point);\n this.centroid = Point2D.centroid(this.activePoints);\n this.event = event;\n }\n}\n\nmodule.exports = State;\n\n","'use strict';\n\nconst cascade = Symbol('cascade');\nconst smooth = Symbol('smooth');\n\n/**\n * Determines whether to apply smoothing. Smoothing is on by default but turned\n * off if either:<br>\n * 1. The user explicitly requests that it be turned off.<br>\n * 2. The active pointer is not \"coarse\".<br>\n *\n * @see {@link\n * https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia}\n *\n * @inner\n * @memberof westures-core.Smoothable\n *\n * @param {boolean} isRequested - Whether smoothing was requested by the user.\n *\n * @returns {boolean} Whether to apply smoothing.\n */\nfunction smoothingIsApplicable(isRequested) {\n if (isRequested) {\n try {\n return window.matchMedia('(pointer: coarse)').matches;\n } catch (e) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * A Smoothable datatype is one that is capable of smoothing out a series of\n * values as they come in, one at a time, providing a more consistent series. It\n * does this by creating some inertia in the values using a cascading average.\n * (For those who are interested in such things, this effectively means that it\n * provides a practical application of Zeno's Dichotomy).\n *\n * @example\n * const x = new Smoothable({ identity: 1 });\n * const a = x.next(1); // 1.0\n * const b = x.next(1.2); // 1.1\n * const c = x.next(0.9); // 1.0\n * const d = x.next(0.6); // 0.8\n * const e = x.next(1.2); // 1.0\n * const f = x.next(1.6); // 1.3\n * x.restart();\n * const g = x.next(0); // 0.5\n *\n * @memberof westures-core\n *\n * @param {Object} [options]\n * @param {boolean} [options.applySmoothing=true] Whether to apply smoothing to\n * the data.\n * @param {*} [options.identity=0] The identity value of this smoothable data.\n */\nclass Smoothable {\n constructor(options = {}) {\n const final_options = { ...Smoothable.DEFAULTS, ...options };\n\n /**\n * The function through which smoothed emits are passed.\n *\n * @method\n * @param {*} data - The data to emit.\n *\n * @return {*} The smoothed out data.\n */\n this.next = null;\n if (smoothingIsApplicable(final_options.applySmoothing)) {\n this.next = this[smooth].bind(this);\n } else {\n this.next = data => data;\n }\n\n /**\n * The \"identity\" value of the data that will be smoothed.\n *\n * @type {*}\n * @default 0\n */\n this.identity = final_options.identity;\n\n /**\n * The cascading average of outgoing values.\n *\n * @memberof westures-core.Smoothable\n * @alias [@@cascade]\n * @type {object}\n */\n this[cascade] = this.identity;\n }\n\n /**\n * Restart the Smoothable gesture.\n */\n restart() {\n this[cascade] = this.identity;\n }\n\n /**\n * Smooth out the outgoing data.\n *\n * @memberof westures-core.Smoothable\n * @alias [@@smooth]\n * @param {object} data - The next batch of data to emit.\n *\n * @return {?object}\n */\n [smooth](data) {\n const average = this.average(this[cascade], data);\n this[cascade] = average;\n return average;\n }\n\n /**\n * Average out two values, as part of the smoothing algorithm. Override this\n * method if the data being smoothed is not a Number.\n *\n * @param {number} a\n * @param {number} b\n *\n * @return {number} The average of 'a' and 'b'\n */\n average(a, b) {\n return (a + b) / 2;\n }\n}\n\nSmoothable.DEFAULTS = {\n applySmoothing: true,\n identity: 0,\n};\n\nmodule.exports = Smoothable;\n\n"],"names":[],"version":3,"file":"index.js.map"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "westures-core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "The core engine of Westures, a robust n-pointer multitouch gesture detection library for JavaScript.",
|
|
5
5
|
"author": "Michael van der Kamp <michael.vanderkamp@usask.ca>",
|
|
6
6
|
"keywords": [
|
|
@@ -33,8 +33,12 @@
|
|
|
33
33
|
"homepage": "https://mvanderkamp.github.io/westures-core/index.html",
|
|
34
34
|
"license": "MIT",
|
|
35
35
|
"scripts": {
|
|
36
|
-
"build": "
|
|
36
|
+
"build": "parcel build",
|
|
37
|
+
"build:debug": "parcel build --no-optimize",
|
|
37
38
|
"coveralls": "jest --coverage && cat ./coverage/lcov.info | coveralls",
|
|
39
|
+
"docs": "jsdoc -c .jsdocrc.json",
|
|
40
|
+
"lint": "eslint src test index.js",
|
|
41
|
+
"lint:fix": "eslint --fix src test index.js",
|
|
38
42
|
"test": "jest",
|
|
39
43
|
"test:debug": "node inspect $(npm bin)/jest --runInBand"
|
|
40
44
|
},
|
|
@@ -45,19 +49,31 @@
|
|
|
45
49
|
],
|
|
46
50
|
"setupFilesAfterEnv": [
|
|
47
51
|
"./test/setup.js"
|
|
48
|
-
]
|
|
52
|
+
],
|
|
53
|
+
"testEnvironment": "jsdom",
|
|
54
|
+
"testPathIgnorePatterns": [
|
|
55
|
+
"/node_modules/",
|
|
56
|
+
"/dist/"
|
|
57
|
+
],
|
|
58
|
+
"coveragePathIgnorePatterns": [
|
|
59
|
+
"/node_modules/",
|
|
60
|
+
"/dist/",
|
|
61
|
+
"/test/"
|
|
62
|
+
],
|
|
63
|
+
"fakeTimers": {
|
|
64
|
+
"enableGlobally": true,
|
|
65
|
+
"legacyFakeTimers": true
|
|
66
|
+
}
|
|
49
67
|
},
|
|
50
68
|
"devDependencies": {
|
|
51
|
-
"@babel/core": "^7.
|
|
52
|
-
"@babel/preset-env": "^7.
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"jest": "^
|
|
57
|
-
"jsdoc": "^
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
"tui-jsdoc-template": "^1.2.2",
|
|
61
|
-
"underscore": "^1.13.2"
|
|
69
|
+
"@babel/core": "^7.21.8",
|
|
70
|
+
"@babel/preset-env": "^7.21.5",
|
|
71
|
+
"docdash": "^2.0.1",
|
|
72
|
+
"eslint": "^8.41.0",
|
|
73
|
+
"jest": "^29.5.0",
|
|
74
|
+
"jest-environment-jsdom": "^29.5.0",
|
|
75
|
+
"jsdoc": "^4.0.2",
|
|
76
|
+
"parcel": "^2.8.3",
|
|
77
|
+
"underscore": "^1.13.6"
|
|
62
78
|
}
|
|
63
79
|
}
|
package/src/Input.js
CHANGED
|
@@ -15,7 +15,7 @@ const { getPropagationPath } = require('./utils.js');
|
|
|
15
15
|
* be located in subsequent Event objects.
|
|
16
16
|
*/
|
|
17
17
|
class Input {
|
|
18
|
-
constructor(event, identifier) {
|
|
18
|
+
constructor(event, identifier, headless = false) {
|
|
19
19
|
const currentData = new PointerData(event, identifier);
|
|
20
20
|
|
|
21
21
|
/**
|
|
@@ -24,7 +24,11 @@ class Input {
|
|
|
24
24
|
*
|
|
25
25
|
* @type {WeakSet.<Element>}
|
|
26
26
|
*/
|
|
27
|
-
|
|
27
|
+
if (headless) {
|
|
28
|
+
this.initialElements = new WeakSet([event.target]);
|
|
29
|
+
} else {
|
|
30
|
+
this.initialElements = new WeakSet(getPropagationPath(event));
|
|
31
|
+
}
|
|
28
32
|
|
|
29
33
|
/**
|
|
30
34
|
* Holds the initial data from the mousedown / touchstart / pointerdown that
|
package/src/Region.js
CHANGED
|
@@ -27,8 +27,9 @@ const {
|
|
|
27
27
|
*
|
|
28
28
|
* @memberof westures-core
|
|
29
29
|
*
|
|
30
|
-
* @param {Element} element=
|
|
31
|
-
* events.
|
|
30
|
+
* @param {Element} [element=null] - The element which should listen to input
|
|
31
|
+
* events. If not provided, will be set to the window unless operating in
|
|
32
|
+
* "headless" mode.
|
|
32
33
|
* @param {object} [options]
|
|
33
34
|
* @param {boolean} [options.capture=false] - Whether the region uses the
|
|
34
35
|
* capture phase of input events. If false, uses the bubbling phase.
|
|
@@ -39,10 +40,27 @@ const {
|
|
|
39
40
|
* ignored. Here there by dragons if set to false.
|
|
40
41
|
* @param {string} [options.touchAction='none'] - Value to set the CSS
|
|
41
42
|
* 'touch-action' property to on elements added to the region.
|
|
43
|
+
* @param {boolean} [options.headless=false] - Set to true to turn on "headless"
|
|
44
|
+
* mode. This mode is intended for use outside of a browser environment. It does
|
|
45
|
+
* not listen to window events, so instead you will have to send events directly
|
|
46
|
+
* into the region. Pointer down/move/up events should be sent to
|
|
47
|
+
* Region.arbitrate(event), cancel events should be sent to
|
|
48
|
+
* Region.cancel(event), and keyboard events should be sent to
|
|
49
|
+
* Region.handleKeyboardEvent(event). You do not need to supply an element to
|
|
50
|
+
* the Region constructor in this mode, but you will still need to attach
|
|
51
|
+
* elements to Gestures, and the events you pass in should specify event.target
|
|
52
|
+
* appropriately, in order to select which gestures to run.
|
|
42
53
|
*/
|
|
43
54
|
class Region {
|
|
44
|
-
constructor(element =
|
|
55
|
+
constructor(element = null, options = {}) {
|
|
45
56
|
options = { ...Region.DEFAULTS, ...options };
|
|
57
|
+
if (element === null) {
|
|
58
|
+
if (options.headless) {
|
|
59
|
+
element = null;
|
|
60
|
+
} else {
|
|
61
|
+
element = window;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
46
64
|
|
|
47
65
|
/**
|
|
48
66
|
* The list of relations between elements, their gestures, and the handlers.
|
|
@@ -85,10 +103,12 @@ class Region {
|
|
|
85
103
|
*
|
|
86
104
|
* @type {westures-core.State}
|
|
87
105
|
*/
|
|
88
|
-
this.state = new State(this.element);
|
|
106
|
+
this.state = new State(this.element, options.headless);
|
|
89
107
|
|
|
90
|
-
|
|
91
|
-
|
|
108
|
+
if (!options.headless) {
|
|
109
|
+
// Begin operating immediately.
|
|
110
|
+
this.activate();
|
|
111
|
+
}
|
|
92
112
|
}
|
|
93
113
|
|
|
94
114
|
/**
|
|
@@ -148,14 +168,18 @@ class Region {
|
|
|
148
168
|
* @param {Event} event - The event emitted from the window object.
|
|
149
169
|
*/
|
|
150
170
|
cancel(event) {
|
|
151
|
-
if (
|
|
171
|
+
if (
|
|
172
|
+
this.options.preventDefault && typeof event.preventDefault === 'function'
|
|
173
|
+
) {
|
|
174
|
+
event.preventDefault();
|
|
175
|
+
}
|
|
152
176
|
this.state.inputs.forEach(input => {
|
|
153
177
|
input.update(event);
|
|
154
178
|
});
|
|
155
179
|
this.activeGestures.forEach(gesture => {
|
|
156
180
|
gesture.evaluateHook(CANCEL, this.state);
|
|
157
181
|
});
|
|
158
|
-
this.state = new State(this.element);
|
|
182
|
+
this.state = new State(this.element, this.options.headless);
|
|
159
183
|
this.resetActiveGestures();
|
|
160
184
|
}
|
|
161
185
|
|
|
@@ -261,7 +285,10 @@ class Region {
|
|
|
261
285
|
this.updateActiveGestures(event, isInitial);
|
|
262
286
|
|
|
263
287
|
if (this.activeGestures.size > 0) {
|
|
264
|
-
if (
|
|
288
|
+
if (
|
|
289
|
+
this.options.preventDefault &&
|
|
290
|
+
typeof event.preventDefault === 'function'
|
|
291
|
+
) event.preventDefault();
|
|
265
292
|
|
|
266
293
|
this.activeGestures.forEach(gesture => {
|
|
267
294
|
gesture.evaluateHook(PHASE[event.type], this.state);
|
|
@@ -278,7 +305,9 @@ class Region {
|
|
|
278
305
|
* @param {westures-core.Gesture} gesture - Instantiated gesture to add.
|
|
279
306
|
*/
|
|
280
307
|
addGesture(gesture) {
|
|
281
|
-
|
|
308
|
+
if (!this.options.headless) {
|
|
309
|
+
gesture.element.style.touchAction = this.options.touchAction;
|
|
310
|
+
}
|
|
282
311
|
this.gestures.add(gesture);
|
|
283
312
|
}
|
|
284
313
|
|
|
@@ -319,6 +348,7 @@ Region.DEFAULTS = {
|
|
|
319
348
|
preferPointer: true,
|
|
320
349
|
preventDefault: true,
|
|
321
350
|
touchAction: 'none',
|
|
351
|
+
headless: false,
|
|
322
352
|
};
|
|
323
353
|
|
|
324
354
|
module.exports = Region;
|
package/src/State.js
CHANGED
|
@@ -6,6 +6,9 @@ const {
|
|
|
6
6
|
MOVE,
|
|
7
7
|
PHASE,
|
|
8
8
|
START,
|
|
9
|
+
MOUSE_EVENTS,
|
|
10
|
+
POINTER_EVENTS,
|
|
11
|
+
TOUCH_EVENTS,
|
|
9
12
|
} = require('./constants.js');
|
|
10
13
|
const Input = require('./Input.js');
|
|
11
14
|
const Point2D = require('./Point2D.js');
|
|
@@ -14,32 +17,6 @@ const symbols = {
|
|
|
14
17
|
inputs: Symbol.for('inputs'),
|
|
15
18
|
};
|
|
16
19
|
|
|
17
|
-
/**
|
|
18
|
-
* Set of helper functions for updating inputs based on type of input.
|
|
19
|
-
* Must be called with a bound 'this', via bind(), or call(), or apply().
|
|
20
|
-
*
|
|
21
|
-
* @private
|
|
22
|
-
* @inner
|
|
23
|
-
* @memberof westure-core.State
|
|
24
|
-
*/
|
|
25
|
-
const update_fns = {
|
|
26
|
-
TouchEvent: function TouchEvent(event) {
|
|
27
|
-
Array.from(event.changedTouches).forEach(touch => {
|
|
28
|
-
this.updateInput(event, touch.identifier);
|
|
29
|
-
});
|
|
30
|
-
},
|
|
31
|
-
|
|
32
|
-
PointerEvent: function PointerEvent(event) {
|
|
33
|
-
this.updateInput(event, event.pointerId);
|
|
34
|
-
},
|
|
35
|
-
|
|
36
|
-
MouseEvent: function MouseEvent(event) {
|
|
37
|
-
if (event.button === 0) {
|
|
38
|
-
this.updateInput(event, event.button);
|
|
39
|
-
}
|
|
40
|
-
},
|
|
41
|
-
};
|
|
42
|
-
|
|
43
20
|
/**
|
|
44
21
|
* Keeps track of currently active and ending input points on the interactive
|
|
45
22
|
* surface.
|
|
@@ -47,9 +24,11 @@ const update_fns = {
|
|
|
47
24
|
* @memberof westures-core
|
|
48
25
|
*
|
|
49
26
|
* @param {Element} element - The element underpinning the associated Region.
|
|
27
|
+
* @param {boolean} [headless=false] - Whether westures is operating in
|
|
28
|
+
* "headless" mode.
|
|
50
29
|
*/
|
|
51
30
|
class State {
|
|
52
|
-
constructor(element) {
|
|
31
|
+
constructor(element, headless = false) {
|
|
53
32
|
/**
|
|
54
33
|
* Keep a reference to the element for the associated region.
|
|
55
34
|
*
|
|
@@ -57,6 +36,13 @@ class State {
|
|
|
57
36
|
*/
|
|
58
37
|
this.element = element;
|
|
59
38
|
|
|
39
|
+
/**
|
|
40
|
+
* Whether westures is operating in "headless" mode.
|
|
41
|
+
*
|
|
42
|
+
* @type {boolean}
|
|
43
|
+
*/
|
|
44
|
+
this.headless = headless;
|
|
45
|
+
|
|
60
46
|
/**
|
|
61
47
|
* Keeps track of the current Input objects.
|
|
62
48
|
*
|
|
@@ -151,22 +137,26 @@ class State {
|
|
|
151
137
|
case START:
|
|
152
138
|
this[symbols.inputs].set(
|
|
153
139
|
identifier,
|
|
154
|
-
new Input(event, identifier),
|
|
140
|
+
new Input(event, identifier, this.headless),
|
|
155
141
|
);
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
142
|
+
if (!this.headless) {
|
|
143
|
+
try {
|
|
144
|
+
this.element.setPointerCapture(identifier);
|
|
145
|
+
} catch (e) {
|
|
146
|
+
// NOP: Optional operation failed.
|
|
147
|
+
}
|
|
160
148
|
}
|
|
161
149
|
break;
|
|
162
150
|
|
|
163
151
|
// All of 'end', 'move', and 'cancel' perform updates, hence the
|
|
164
152
|
// following fall-throughs
|
|
165
153
|
case END:
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
154
|
+
if (!this.headless) {
|
|
155
|
+
try {
|
|
156
|
+
this.element.releasePointerCapture(identifier);
|
|
157
|
+
} catch (e) {
|
|
158
|
+
// NOP: Optional operation failed.
|
|
159
|
+
}
|
|
170
160
|
}
|
|
171
161
|
case CANCEL:
|
|
172
162
|
case MOVE:
|
|
@@ -187,7 +177,19 @@ class State {
|
|
|
187
177
|
* @param {Event} event - The event being captured.
|
|
188
178
|
*/
|
|
189
179
|
updateAllInputs(event) {
|
|
190
|
-
|
|
180
|
+
if (POINTER_EVENTS.includes(event.type)) {
|
|
181
|
+
this.updateInput(event, event.pointerId);
|
|
182
|
+
} else if (MOUSE_EVENTS.includes(event.type)) {
|
|
183
|
+
if (event.button === 0) {
|
|
184
|
+
this.updateInput(event, event.button);
|
|
185
|
+
}
|
|
186
|
+
} else if (TOUCH_EVENTS.includes(event.type)) {
|
|
187
|
+
Array.from(event.changedTouches).forEach(touch => {
|
|
188
|
+
this.updateInput(event, touch.identifier);
|
|
189
|
+
});
|
|
190
|
+
} else {
|
|
191
|
+
throw new Error(`Unexpected event type: ${event.type}`);
|
|
192
|
+
}
|
|
191
193
|
this.updateFields(event);
|
|
192
194
|
}
|
|
193
195
|
|