@vpmedia/phaser 1.0.1 → 1.0.3

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.
Files changed (112) hide show
  1. package/README.md +20 -3
  2. package/dist/phaser.cjs +1 -1
  3. package/dist/phaser.cjs.LICENSE.txt +1 -1
  4. package/dist/phaser.cjs.map +1 -1
  5. package/dist/phaser.js +1 -1
  6. package/dist/phaser.js.LICENSE.txt +1 -1
  7. package/dist/phaser.js.map +1 -1
  8. package/package.json +23 -17
  9. package/src/index.js +142 -0
  10. package/src/phaser/core/animation.js +355 -0
  11. package/src/phaser/core/animation_manager.js +238 -0
  12. package/src/phaser/core/animation_parser.js +133 -0
  13. package/src/phaser/core/array_set.js +107 -0
  14. package/src/phaser/core/cache.js +558 -0
  15. package/src/phaser/core/const.js +106 -0
  16. package/src/phaser/core/device.js +67 -0
  17. package/src/phaser/core/device_util.js +388 -0
  18. package/src/phaser/core/dom.js +207 -0
  19. package/src/phaser/core/event_manager.js +243 -0
  20. package/src/phaser/core/factory.js +74 -0
  21. package/src/phaser/core/frame.js +75 -0
  22. package/src/phaser/core/frame_data.js +84 -0
  23. package/src/phaser/core/frame_util.js +33 -0
  24. package/src/phaser/core/game.js +412 -0
  25. package/src/phaser/core/input.js +401 -0
  26. package/src/phaser/core/input_button.js +102 -0
  27. package/src/phaser/core/input_handler.js +687 -0
  28. package/src/phaser/core/input_mouse.js +289 -0
  29. package/src/phaser/core/input_mspointer.js +197 -0
  30. package/src/phaser/core/input_pointer.js +427 -0
  31. package/src/phaser/core/input_touch.js +157 -0
  32. package/src/phaser/core/loader.js +1057 -0
  33. package/src/phaser/core/loader_parser.js +109 -0
  34. package/src/phaser/core/raf.js +46 -0
  35. package/src/phaser/core/raf_fb.js +75 -0
  36. package/src/phaser/core/raf_to.js +34 -0
  37. package/src/phaser/core/scale_manager.js +806 -0
  38. package/src/phaser/core/scene.js +65 -0
  39. package/src/phaser/core/scene_manager.js +309 -0
  40. package/src/phaser/core/signal.js +175 -0
  41. package/src/phaser/core/signal_binding.js +69 -0
  42. package/src/phaser/core/sound.js +538 -0
  43. package/src/phaser/core/sound_manager.js +364 -0
  44. package/src/phaser/core/stage.js +108 -0
  45. package/src/phaser/core/time.js +203 -0
  46. package/src/phaser/core/timer.js +276 -0
  47. package/src/phaser/core/timer_event.js +21 -0
  48. package/src/phaser/core/tween.js +329 -0
  49. package/src/phaser/core/tween_data.js +258 -0
  50. package/src/phaser/core/tween_easing.js +341 -0
  51. package/src/phaser/core/tween_manager.js +185 -0
  52. package/src/phaser/core/world.js +18 -0
  53. package/src/phaser/display/bitmap_text.js +322 -0
  54. package/src/phaser/display/button.js +194 -0
  55. package/src/phaser/display/canvas/buffer.js +36 -0
  56. package/src/phaser/display/canvas/graphics.js +227 -0
  57. package/src/phaser/display/canvas/masker.js +39 -0
  58. package/src/phaser/display/canvas/pool.js +126 -0
  59. package/src/phaser/display/canvas/renderer.js +123 -0
  60. package/src/phaser/display/canvas/tinter.js +144 -0
  61. package/src/phaser/display/canvas/util.js +159 -0
  62. package/src/phaser/display/display_object.js +597 -0
  63. package/src/phaser/display/graphics.js +723 -0
  64. package/src/phaser/display/graphics_data.js +27 -0
  65. package/src/phaser/display/graphics_data_util.js +15 -0
  66. package/src/phaser/display/group.js +227 -0
  67. package/src/phaser/display/image.js +288 -0
  68. package/src/phaser/display/sprite_batch.js +15 -0
  69. package/src/phaser/display/sprite_util.js +250 -0
  70. package/src/phaser/display/text.js +1089 -0
  71. package/src/phaser/display/webgl/abstract_filter.js +25 -0
  72. package/src/phaser/display/webgl/base_texture.js +68 -0
  73. package/src/phaser/display/webgl/blend_manager.js +35 -0
  74. package/src/phaser/display/webgl/earcut.js +662 -0
  75. package/src/phaser/display/webgl/earcut_node.js +28 -0
  76. package/src/phaser/display/webgl/fast_sprite_batch.js +242 -0
  77. package/src/phaser/display/webgl/filter_manager.js +46 -0
  78. package/src/phaser/display/webgl/filter_texture.js +61 -0
  79. package/src/phaser/display/webgl/graphics.js +624 -0
  80. package/src/phaser/display/webgl/graphics_data.js +42 -0
  81. package/src/phaser/display/webgl/mask_manager.js +36 -0
  82. package/src/phaser/display/webgl/render_texture.js +81 -0
  83. package/src/phaser/display/webgl/renderer.js +234 -0
  84. package/src/phaser/display/webgl/shader/complex.js +74 -0
  85. package/src/phaser/display/webgl/shader/fast.js +97 -0
  86. package/src/phaser/display/webgl/shader/normal.js +225 -0
  87. package/src/phaser/display/webgl/shader/primitive.js +72 -0
  88. package/src/phaser/display/webgl/shader/strip.js +77 -0
  89. package/src/phaser/display/webgl/shader_manager.js +89 -0
  90. package/src/phaser/display/webgl/sprite_batch.js +320 -0
  91. package/src/phaser/display/webgl/stencil_manager.js +170 -0
  92. package/src/phaser/display/webgl/texture.js +117 -0
  93. package/src/phaser/display/webgl/texture_util.js +34 -0
  94. package/src/phaser/display/webgl/util.js +78 -0
  95. package/src/phaser/geom/circle.js +186 -0
  96. package/src/phaser/geom/ellipse.js +65 -0
  97. package/src/phaser/geom/line.js +190 -0
  98. package/src/phaser/geom/matrix.js +147 -0
  99. package/src/phaser/geom/point.js +164 -0
  100. package/src/phaser/geom/polygon.js +140 -0
  101. package/src/phaser/geom/rectangle.js +306 -0
  102. package/src/phaser/geom/rounded_rectangle.js +36 -0
  103. package/src/phaser/geom/util/circle.js +122 -0
  104. package/src/phaser/geom/util/ellipse.js +34 -0
  105. package/src/phaser/geom/util/line.js +135 -0
  106. package/src/phaser/geom/util/matrix.js +53 -0
  107. package/src/phaser/geom/util/point.js +296 -0
  108. package/src/phaser/geom/util/polygon.js +28 -0
  109. package/src/phaser/geom/util/rectangle.js +229 -0
  110. package/src/phaser/geom/util/rounded_rectangle.js +32 -0
  111. package/src/phaser/util/math.js +297 -0
  112. package/src/phaser/util/string.js +32 -0
@@ -0,0 +1,427 @@
1
+ /**
2
+ * @author Andras Csizmadia <andras@vpmedia.hu>
3
+ * @author Richard Davey <rich@photonstorm.com>
4
+ * @copyright Copyright (c) 2018-present Richard Davey, Photon Storm Ltd., Andras Csizmadia <andras@vpmedia.hu> (www.vpmedia.hu)
5
+ */
6
+ import Point from '../geom/point';
7
+ import Circle from '../geom/circle';
8
+ import DeviceButton from './input_button';
9
+ import { POINTER, POINTER_CURSOR, POINTER_CONTACT, MOUSE_OVERRIDES_TOUCH, TOUCH_OVERRIDES_MOUSE, MOUSE_TOUCH_COMBINE } from './const';
10
+
11
+ const NO_BUTTON = 0;
12
+ const LEFT_BUTTON = 1;
13
+ const RIGHT_BUTTON = 2;
14
+ const MIDDLE_BUTTON = 4;
15
+ const BACK_BUTTON = 8;
16
+ const FORWARD_BUTTON = 16;
17
+ const ERASER_BUTTON = 32;
18
+
19
+ export default class {
20
+
21
+ constructor(game, id, pointerMode) {
22
+ this.game = game;
23
+ this.id = id;
24
+ this.type = POINTER;
25
+ this.exists = true;
26
+ this.identifier = 0;
27
+ this.pointerId = null;
28
+ this.pointerMode = pointerMode || (POINTER_CURSOR | POINTER_CONTACT);
29
+ this.target = null;
30
+ this.button = null;
31
+ this.leftButton = new DeviceButton(this, LEFT_BUTTON);
32
+ this.rightButton = new DeviceButton(this, RIGHT_BUTTON);
33
+ this.middleButton = new DeviceButton(this, MIDDLE_BUTTON);
34
+ this.backButton = new DeviceButton(this, BACK_BUTTON);
35
+ this.forwardButton = new DeviceButton(this, FORWARD_BUTTON);
36
+ this.eraserButton = new DeviceButton(this, ERASER_BUTTON);
37
+ this._holdSent = false;
38
+ this._history = [];
39
+ this._nextDrop = 0;
40
+ this._stateReset = false;
41
+ this.withinGame = false;
42
+ this.clientX = -1;
43
+ this.clientY = -1;
44
+ this.pageX = -1;
45
+ this.pageY = -1;
46
+ this.screenX = -1;
47
+ this.screenY = -1;
48
+ this.rawMovementX = 0;
49
+ this.rawMovementY = 0;
50
+ this.movementX = 0;
51
+ this.movementY = 0;
52
+ this.x = -1;
53
+ this.y = -1;
54
+ this.isMouse = (id === 0);
55
+ this.isDown = false;
56
+ this.isUp = true;
57
+ this.timeDown = 0;
58
+ this.timeUp = 0;
59
+ this.previousTapTime = 0;
60
+ this.totalTouches = 0;
61
+ this.msSinceLastClick = Number.MAX_VALUE;
62
+ this.targetObject = null;
63
+ this.interactiveCandidates = [];
64
+ this.active = false;
65
+ this.dirty = false;
66
+ this.position = new Point();
67
+ this.positionDown = new Point();
68
+ this.positionUp = new Point();
69
+ this.circle = new Circle(0, 0, 44);
70
+ this._clickTrampolines = null;
71
+ this._trampolineTargetObject = null;
72
+ }
73
+
74
+ resetButtons() {
75
+ this.isDown = false;
76
+ this.isUp = true;
77
+ if (this.isMouse) {
78
+ this.leftButton.reset();
79
+ }
80
+ }
81
+
82
+ updateButtons(event) {
83
+ if (event.type.toLowerCase().substr(-4) === 'down') {
84
+ this.isUp = false;
85
+ this.isDown = true;
86
+ } else {
87
+ this.isUp = true;
88
+ this.isDown = false;
89
+ }
90
+ }
91
+
92
+ start(event) {
93
+ const input = this.game.input;
94
+ if (event.pointerId) {
95
+ this.pointerId = event.pointerId;
96
+ }
97
+ this.identifier = event.identifier;
98
+ this.target = event.target;
99
+ if (this.isMouse) {
100
+ this.updateButtons(event);
101
+ } else {
102
+ this.isDown = true;
103
+ this.isUp = false;
104
+ }
105
+ this.active = true;
106
+ this.withinGame = true;
107
+ this.dirty = false;
108
+ this._history = [];
109
+ this._clickTrampolines = null;
110
+ this._trampolineTargetObject = null;
111
+ // Work out how long it has been since the last click
112
+ this.msSinceLastClick = this.game.time.time - this.timeDown;
113
+ this.timeDown = this.game.time.time;
114
+ this._holdSent = false;
115
+ // This sets the x/y and other local values
116
+ this.move(event, true);
117
+ // x and y are the old values here?
118
+ this.positionDown.setTo(this.x, this.y);
119
+ if (input.multiInputOverride === MOUSE_OVERRIDES_TOUCH || input.multiInputOverride === MOUSE_TOUCH_COMBINE || (input.multiInputOverride === TOUCH_OVERRIDES_MOUSE && input.totalActivePointers === 0)) {
120
+ input.x = this.x;
121
+ input.y = this.y;
122
+ input.position.setTo(this.x, this.y);
123
+ input.onDown.dispatch(this, event);
124
+ input.resetSpeed(this.x, this.y);
125
+ }
126
+ this._stateReset = false;
127
+ this.totalTouches += 1;
128
+ if (this.targetObject !== null) {
129
+ this.targetObject._touchedHandler(this);
130
+ }
131
+ return this;
132
+ }
133
+
134
+ update() {
135
+ const input = this.game.input;
136
+ if (this.active) {
137
+ // Force a check?
138
+ if (this.dirty) {
139
+ if (input.interactiveItems.total > 0) {
140
+ this.processInteractiveObjects(false);
141
+ }
142
+ this.dirty = false;
143
+ }
144
+ if (this._holdSent === false && this.duration >= input.holdRate) {
145
+ if (input.multiInputOverride === MOUSE_OVERRIDES_TOUCH || input.multiInputOverride === MOUSE_TOUCH_COMBINE || (input.multiInputOverride === TOUCH_OVERRIDES_MOUSE && input.totalActivePointers === 0)) {
146
+ input.onHold.dispatch(this);
147
+ }
148
+ this._holdSent = true;
149
+ }
150
+ // Update the droppings history
151
+ if (input.recordPointerHistory && this.game.time.time >= this._nextDrop) {
152
+ this._nextDrop = this.game.time.time + input.recordRate;
153
+ this._history.push({
154
+ x: this.position.x,
155
+ y: this.position.y,
156
+ });
157
+ if (this._history.length > input.recordLimit) {
158
+ this._history.shift();
159
+ }
160
+ }
161
+ }
162
+ }
163
+
164
+ move(event, fromClick = false) {
165
+ const input = this.game.input;
166
+ if (input.pollLocked) {
167
+ return null;
168
+ }
169
+ if (fromClick && this.isMouse) {
170
+ this.updateButtons(event);
171
+ }
172
+ this.clientX = event.clientX;
173
+ this.clientY = event.clientY;
174
+ this.pageX = event.pageX;
175
+ this.pageY = event.pageY;
176
+ this.screenX = event.screenX;
177
+ this.screenY = event.screenY;
178
+ if (this.isMouse && input.mouse.locked && !fromClick) {
179
+ this.rawMovementX = event.movementX || event.mozMovementX || event.webkitMovementX || 0;
180
+ this.rawMovementY = event.movementY || event.mozMovementY || event.webkitMovementY || 0;
181
+ this.movementX += this.rawMovementX;
182
+ this.movementY += this.rawMovementY;
183
+ }
184
+ this.x = (this.pageX - this.game.scale.offset.x) * input.scale.x;
185
+ this.y = (this.pageY - this.game.scale.offset.y) * input.scale.y;
186
+ this.position.setTo(this.x, this.y);
187
+ this.circle.x = this.x;
188
+ this.circle.y = this.y;
189
+ if (input.multiInputOverride === MOUSE_OVERRIDES_TOUCH || input.multiInputOverride === MOUSE_TOUCH_COMBINE || (input.multiInputOverride === TOUCH_OVERRIDES_MOUSE && input.totalActivePointers === 0)) {
190
+ input.activePointer = this;
191
+ input.x = this.x;
192
+ input.y = this.y;
193
+ input.position.setTo(input.x, input.y);
194
+ input.circle.x = input.x;
195
+ input.circle.y = input.y;
196
+ }
197
+ this.withinGame = this.game.scale.bounds.contains(this.pageX, this.pageY);
198
+ // If the game is paused we don't process any target objects or callbacks
199
+ if (this.game.paused) {
200
+ return this;
201
+ }
202
+ let i = input.moveCallbacks.length;
203
+ while (i) {
204
+ i -= 1;
205
+ input.moveCallbacks[i].callback.call(input.moveCallbacks[i].context, this, this.x, this.y, fromClick);
206
+ }
207
+ // Easy out if we're dragging something and it still exists
208
+ if (this.targetObject !== null && this.targetObject.isDragged === true) {
209
+ if (this.targetObject.update(this) === false) {
210
+ this.targetObject = null;
211
+ }
212
+ } else if (input.interactiveItems.total > 0) {
213
+ this.processInteractiveObjects(fromClick);
214
+ }
215
+ return this;
216
+ }
217
+
218
+ processInteractiveObjects(fromClick = false) {
219
+ // Work out which object is on the top
220
+ let highestRenderOrderID = 0;
221
+ let highestInputPriorityID = -1;
222
+ let candidateTarget = null;
223
+ // First pass gets all objects that the pointer is over that DON'T use pixelPerfect checks and get the highest ID
224
+ // We know they'll be valid for input detection but not which is the top just yet
225
+ let currentNode = this.game.input.interactiveItems.first;
226
+ this.interactiveCandidates = [];
227
+ while (currentNode) {
228
+ // Reset checked status
229
+ currentNode.checked = false;
230
+ if (currentNode.validForInput(highestInputPriorityID, highestRenderOrderID, false)) {
231
+ // Flag it as checked so we don't re-scan it on the next phase
232
+ currentNode.checked = true;
233
+ if ((fromClick && currentNode.checkPointerDown(this, true)) || (!fromClick && currentNode.checkPointerOver(this, true))) {
234
+ highestRenderOrderID = currentNode.sprite.renderOrderID;
235
+ highestInputPriorityID = currentNode.priorityID;
236
+ candidateTarget = currentNode;
237
+ this.interactiveCandidates.push(currentNode);
238
+ }
239
+ }
240
+ currentNode = this.game.input.interactiveItems.next;
241
+ }
242
+ // Then in the second sweep we process ONLY the pixel perfect ones that are checked and who have a higher ID
243
+ // because if their ID is lower anyway then we can just automatically discount them
244
+ // (A node that was previously checked did not request a pixel-perfect check.)
245
+ currentNode = this.game.input.interactiveItems.first;
246
+ while (currentNode) {
247
+ if (!currentNode.checked && currentNode.validForInput(highestInputPriorityID, highestRenderOrderID, true)) {
248
+ if ((fromClick && currentNode.checkPointerDown(this, false)) || (!fromClick && currentNode.checkPointerOver(this, false))) {
249
+ highestRenderOrderID = currentNode.sprite.renderOrderID;
250
+ highestInputPriorityID = currentNode.priorityID;
251
+ candidateTarget = currentNode;
252
+ this.interactiveCandidates.push(currentNode);
253
+ }
254
+ }
255
+ currentNode = this.game.input.interactiveItems.next;
256
+ }
257
+ if (this.game.input.customCandidateHandler) {
258
+ candidateTarget = this.game.input.customCandidateHandler.call(this.game.input.customCandidateHandlerContext, this, this.interactiveCandidates, candidateTarget);
259
+ }
260
+ this.swapTarget(candidateTarget, false);
261
+ return (this.targetObject !== null);
262
+ }
263
+
264
+ swapTarget(newTarget, silent = false) {
265
+ // Now we know the top-most item (if any) we can process it
266
+ if (newTarget === null) {
267
+ // The pointer isn't currently over anything, check if we've got a lingering previous target
268
+ if (this.targetObject) {
269
+ this.targetObject._pointerOutHandler(this, silent);
270
+ this.targetObject = null;
271
+ }
272
+ } else if (this.targetObject === null) {
273
+ // And now set the new one
274
+ this.targetObject = newTarget;
275
+ newTarget._pointerOverHandler(this, silent);
276
+ } else if (this.targetObject === newTarget) {
277
+ // We've got a target from the last update
278
+ // Same target as before, so update it
279
+ if (newTarget.update(this) === false) {
280
+ this.targetObject = null;
281
+ }
282
+ } else {
283
+ // The target has changed, so tell the old one we've left it
284
+ this.targetObject._pointerOutHandler(this, silent);
285
+ // And now set the new one
286
+ this.targetObject = newTarget;
287
+ this.targetObject._pointerOverHandler(this, silent);
288
+ }
289
+ }
290
+
291
+ leave(event) {
292
+ this.withinGame = false;
293
+ this.move(event, false);
294
+ }
295
+
296
+ stop(event) {
297
+ const input = this.game.input;
298
+ if (this._stateReset && this.withinGame) {
299
+ event.preventDefault();
300
+ return null;
301
+ }
302
+ this.timeUp = this.game.time.time;
303
+ if (input.multiInputOverride === MOUSE_OVERRIDES_TOUCH || input.multiInputOverride === MOUSE_TOUCH_COMBINE || (input.multiInputOverride === TOUCH_OVERRIDES_MOUSE && input.totalActivePointers === 0)) {
304
+ input.onUp.dispatch(this, event);
305
+ // Was it a tap?
306
+ if (this.duration >= 0 && this.duration <= input.tapRate) {
307
+ // Was it a double-tap?
308
+ if (this.timeUp - this.previousTapTime < input.doubleTapRate) {
309
+ // Yes, let's dispatch the signal then with the 2nd parameter set to true
310
+ input.onTap.dispatch(this, true);
311
+ } else {
312
+ // Wasn't a double-tap, so dispatch a single tap signal
313
+ input.onTap.dispatch(this, false);
314
+ }
315
+ this.previousTapTime = this.timeUp;
316
+ }
317
+ }
318
+ if (this.isMouse) {
319
+ this.updateButtons(event);
320
+ } else {
321
+ this.isDown = false;
322
+ this.isUp = true;
323
+ }
324
+ // Mouse is always active
325
+ if (this.id > 0) {
326
+ this.active = false;
327
+ }
328
+ this.withinGame = this.game.scale.bounds.contains(event.pageX, event.pageY);
329
+ this.pointerId = null;
330
+ this.identifier = null;
331
+ this.positionUp.setTo(this.x, this.y);
332
+ if (this.isMouse === false) {
333
+ input.currentPointers -= 1;
334
+ }
335
+ input.interactiveItems.callAll('_releasedHandler', this);
336
+ if (this._clickTrampolines) {
337
+ this._trampolineTargetObject = this.targetObject;
338
+ }
339
+ this.targetObject = null;
340
+ return this;
341
+ }
342
+
343
+ justPressed(duration) {
344
+ duration = duration || this.game.input.justPressedRate;
345
+ return (this.isDown === true && (this.timeDown + duration) > this.game.time.time);
346
+ }
347
+
348
+ justReleased(duration) {
349
+ duration = duration || this.game.input.justReleasedRate;
350
+ return (this.isUp && (this.timeUp + duration) > this.game.time.time);
351
+ }
352
+
353
+ addClickTrampoline(name, callback, callbackContext, callbackArgs) {
354
+ if (!this.isDown) {
355
+ return;
356
+ }
357
+ this._clickTrampolines = this._clickTrampolines || [];
358
+ const trampolines = this._clickTrampolines;
359
+ for (let i = 0; i < trampolines.length; i += 1) {
360
+ if (trampolines[i].name === name) {
361
+ trampolines.splice(i, 1);
362
+ break;
363
+ }
364
+ }
365
+ trampolines.push({
366
+ name,
367
+ targetObject: this.targetObject,
368
+ callback,
369
+ callbackContext,
370
+ callbackArgs,
371
+ });
372
+ }
373
+
374
+ processClickTrampolines() {
375
+ const trampolines = this._clickTrampolines;
376
+ if (!trampolines) {
377
+ return;
378
+ }
379
+ for (let i = 0; i < trampolines.length; i += 1) {
380
+ const trampoline = trampolines[i];
381
+ if (trampoline.targetObject === this._trampolineTargetObject) {
382
+ trampoline.callback.apply(trampoline.callbackContext, trampoline.callbackArgs);
383
+ }
384
+ }
385
+ this._clickTrampolines = null;
386
+ this._trampolineTargetObject = null;
387
+ }
388
+
389
+ reset() {
390
+ if (this.isMouse === false) {
391
+ this.active = false;
392
+ }
393
+ this.pointerId = null;
394
+ this.identifier = null;
395
+ this.dirty = false;
396
+ this.totalTouches = 0;
397
+ this._holdSent = false;
398
+ this._history.length = 0;
399
+ this._stateReset = true;
400
+ this.resetButtons();
401
+ if (this.targetObject) {
402
+ this.targetObject._releasedHandler(this);
403
+ }
404
+ this.targetObject = null;
405
+ }
406
+
407
+ resetMovement() {
408
+ this.movementX = 0;
409
+ this.movementY = 0;
410
+ }
411
+
412
+ get duration() {
413
+ if (this.isUp) {
414
+ return -1;
415
+ }
416
+ return this.game.time.time - this.timeDown;
417
+ }
418
+
419
+ get worldX() {
420
+ return this.x;
421
+ }
422
+
423
+ get worldY() {
424
+ return this.y;
425
+ }
426
+
427
+ }
@@ -0,0 +1,157 @@
1
+ /**
2
+ * @author Andras Csizmadia <andras@vpmedia.hu>
3
+ * @author Richard Davey <rich@photonstorm.com>
4
+ * @copyright Copyright (c) 2018-present Richard Davey, Photon Storm Ltd., Andras Csizmadia <andras@vpmedia.hu> (www.vpmedia.hu)
5
+ */
6
+
7
+ export default class {
8
+
9
+ constructor(game) {
10
+ this.game = game;
11
+ this.enabled = true;
12
+ this.callbackContext = this.game;
13
+ this.touchStartCallback = null;
14
+ this.touchMoveCallback = null;
15
+ this.touchEndCallback = null;
16
+ this.touchEnterCallback = null;
17
+ this.touchLeaveCallback = null;
18
+ this.touchCancelCallback = null;
19
+ this.preventDefault = true;
20
+ this.event = null;
21
+ this._onTouchStart = null;
22
+ this._onTouchMove = null;
23
+ this._onTouchEnd = null;
24
+ this._onTouchEnter = null;
25
+ this._onTouchLeave = null;
26
+ this._onTouchCancel = null;
27
+ this._onTouchMove = null;
28
+ }
29
+
30
+ start() {
31
+ if (!this.game.device.touch || this._onTouchStart !== null) {
32
+ return;
33
+ }
34
+ const scope = this;
35
+ this._onTouchStart = event => scope.onTouchStart(event);
36
+ this._onTouchMove = event => scope.onTouchMove(event);
37
+ this._onTouchEnd = event => scope.onTouchEnd(event);
38
+ this._onTouchEnter = event => scope.onTouchEnter(event);
39
+ this._onTouchLeave = event => scope.onTouchLeave(event);
40
+ this._onTouchCancel = event => scope.onTouchCancel(event);
41
+ this.game.canvas.addEventListener('touchstart', this._onTouchStart, false);
42
+ this.game.canvas.addEventListener('touchmove', this._onTouchMove, false);
43
+ this.game.canvas.addEventListener('touchend', this._onTouchEnd, false);
44
+ this.game.canvas.addEventListener('touchcancel', this._onTouchCancel, false);
45
+ if (!this.game.device.cocoonJS) {
46
+ this.game.canvas.addEventListener('touchenter', this._onTouchEnter, false);
47
+ this.game.canvas.addEventListener('touchleave', this._onTouchLeave, false);
48
+ }
49
+ }
50
+
51
+ stop() {
52
+ if (!this.game.device.touch) {
53
+ return;
54
+ }
55
+ this.game.canvas.removeEventListener('touchstart', this._onTouchStart);
56
+ this.game.canvas.removeEventListener('touchmove', this._onTouchMove);
57
+ this.game.canvas.removeEventListener('touchend', this._onTouchEnd);
58
+ this.game.canvas.removeEventListener('touchenter', this._onTouchEnter);
59
+ this.game.canvas.removeEventListener('touchleave', this._onTouchLeave);
60
+ this.game.canvas.removeEventListener('touchcancel', this._onTouchCancel);
61
+ }
62
+
63
+ consumeDocumentTouches() {
64
+ this._documentTouchMove = (event) => {
65
+ event.preventDefault();
66
+ };
67
+ document.addEventListener('touchmove', this._documentTouchMove, false);
68
+ }
69
+
70
+ onTouchStart(event) {
71
+ this.game.input.executeTouchLockCallbacks(false, event);
72
+ this.event = event;
73
+ if (!this.game.input.enabled || !this.enabled) {
74
+ return;
75
+ }
76
+ if (this.touchStartCallback) {
77
+ this.touchStartCallback.call(this.callbackContext, event);
78
+ }
79
+ this.eventPreventDefault(event);
80
+ // event.targetTouches = list of all touches on the TARGET ELEMENT (i.e. game dom element)
81
+ // event.touches = list of all touches on the ENTIRE DOCUMENT, not just the target element
82
+ // event.changedTouches = the touches that CHANGED in this event, not the total number of them
83
+ for (let i = 0; i < event.changedTouches.length; i += 1) {
84
+ this.game.input.startPointer(event.changedTouches[i]);
85
+ }
86
+ }
87
+
88
+ onTouchCancel(event) {
89
+ this.event = event;
90
+ if (this.touchCancelCallback) {
91
+ this.touchCancelCallback.call(this.callbackContext, event);
92
+ }
93
+ if (!this.game.input.enabled || !this.enabled) {
94
+ return;
95
+ }
96
+ this.eventPreventDefault(event);
97
+ // Touch cancel - touches that were disrupted (perhaps by moving into a plugin or browser chrome)
98
+ // http://www.w3.org/TR/touch-events/#dfn-touchcancel
99
+ for (let i = 0; i < event.changedTouches.length; i += 1) {
100
+ this.game.input.stopPointer(event.changedTouches[i]);
101
+ }
102
+ }
103
+
104
+ onTouchEnter(event) {
105
+ this.event = event;
106
+ if (this.touchEnterCallback) {
107
+ this.touchEnterCallback.call(this.callbackContext, event);
108
+ }
109
+ if (!this.game.input.enabled || !this.enabled) {
110
+ return;
111
+ }
112
+ this.eventPreventDefault(event);
113
+ }
114
+
115
+ onTouchLeave(event) {
116
+ this.event = event;
117
+ if (this.touchLeaveCallback) {
118
+ this.touchLeaveCallback.call(this.callbackContext, event);
119
+ }
120
+ this.eventPreventDefault(event);
121
+ }
122
+
123
+ onTouchMove(event) {
124
+ this.event = event;
125
+ if (this.touchMoveCallback) {
126
+ this.touchMoveCallback.call(this.callbackContext, event);
127
+ }
128
+ this.eventPreventDefault(event);
129
+ for (let i = 0; i < event.changedTouches.length; i += 1) {
130
+ this.game.input.updatePointer(event.changedTouches[i]);
131
+ }
132
+ }
133
+
134
+ onTouchEnd(event) {
135
+ this.game.input.executeTouchLockCallbacks(true, event);
136
+ this.event = event;
137
+ if (this.touchEndCallback) {
138
+ this.touchEndCallback.call(this.callbackContext, event);
139
+ }
140
+ this.eventPreventDefault(event);
141
+ // For touch end its a list of the touch points that have been removed from the surface
142
+ // https://developer.mozilla.org/en-US/docs/DOM/TouchList
143
+ // event.changedTouches = the touches that CHANGED in this event, not the total number of them
144
+ for (let i = 0; i < event.changedTouches.length; i += 1) {
145
+ this.game.input.stopPointer(event.changedTouches[i]);
146
+ }
147
+ }
148
+
149
+ eventPreventDefault(event) {
150
+ if (this.preventDefault) {
151
+ if (typeof event.cancelable !== 'boolean' || event.cancelable) {
152
+ event.preventDefault();
153
+ }
154
+ }
155
+ }
156
+
157
+ }