@vpmedia/phaser 1.0.1 → 1.0.2

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 (107) hide show
  1. package/dist/phaser.cjs.LICENSE.txt +1 -1
  2. package/dist/phaser.js.LICENSE.txt +1 -1
  3. package/package.json +2 -3
  4. package/src/index.js +99 -0
  5. package/src/phaser/core/animation.js +355 -0
  6. package/src/phaser/core/animation_manager.js +238 -0
  7. package/src/phaser/core/animation_parser.js +130 -0
  8. package/src/phaser/core/array_set.js +108 -0
  9. package/src/phaser/core/cache.js +558 -0
  10. package/src/phaser/core/const.js +106 -0
  11. package/src/phaser/core/device.js +67 -0
  12. package/src/phaser/core/device_util.js +386 -0
  13. package/src/phaser/core/dom.js +207 -0
  14. package/src/phaser/core/event_manager.js +243 -0
  15. package/src/phaser/core/factory.js +74 -0
  16. package/src/phaser/core/frame.js +75 -0
  17. package/src/phaser/core/frame_data.js +84 -0
  18. package/src/phaser/core/frame_util.js +31 -0
  19. package/src/phaser/core/game.js +412 -0
  20. package/src/phaser/core/input.js +401 -0
  21. package/src/phaser/core/input_button.js +102 -0
  22. package/src/phaser/core/input_handler.js +687 -0
  23. package/src/phaser/core/input_mouse.js +289 -0
  24. package/src/phaser/core/input_mspointer.js +197 -0
  25. package/src/phaser/core/input_pointer.js +427 -0
  26. package/src/phaser/core/input_touch.js +157 -0
  27. package/src/phaser/core/loader.js +946 -0
  28. package/src/phaser/core/loader_parser.js +105 -0
  29. package/src/phaser/core/raf.js +46 -0
  30. package/src/phaser/core/raf_fb.js +75 -0
  31. package/src/phaser/core/raf_to.js +34 -0
  32. package/src/phaser/core/scale_manager.js +806 -0
  33. package/src/phaser/core/scene.js +66 -0
  34. package/src/phaser/core/scene_manager.js +310 -0
  35. package/src/phaser/core/signal.js +175 -0
  36. package/src/phaser/core/signal_binding.js +69 -0
  37. package/src/phaser/core/sound.js +538 -0
  38. package/src/phaser/core/sound_manager.js +365 -0
  39. package/src/phaser/core/stage.js +108 -0
  40. package/src/phaser/core/time.js +203 -0
  41. package/src/phaser/core/timer.js +276 -0
  42. package/src/phaser/core/timer_event.js +21 -0
  43. package/src/phaser/core/tween.js +329 -0
  44. package/src/phaser/core/tween_data.js +258 -0
  45. package/src/phaser/core/tween_easing.js +316 -0
  46. package/src/phaser/core/tween_manager.js +185 -0
  47. package/src/phaser/core/world.js +18 -0
  48. package/src/phaser/display/bitmap_text.js +322 -0
  49. package/src/phaser/display/button.js +194 -0
  50. package/src/phaser/display/canvas/buffer.js +36 -0
  51. package/src/phaser/display/canvas/graphics.js +227 -0
  52. package/src/phaser/display/canvas/masker.js +39 -0
  53. package/src/phaser/display/canvas/pool.js +121 -0
  54. package/src/phaser/display/canvas/renderer.js +123 -0
  55. package/src/phaser/display/canvas/tinter.js +141 -0
  56. package/src/phaser/display/canvas/util.js +151 -0
  57. package/src/phaser/display/display_object.js +597 -0
  58. package/src/phaser/display/graphics.js +723 -0
  59. package/src/phaser/display/graphics_data.js +27 -0
  60. package/src/phaser/display/graphics_data_util.js +14 -0
  61. package/src/phaser/display/group.js +227 -0
  62. package/src/phaser/display/image.js +288 -0
  63. package/src/phaser/display/sprite_batch.js +15 -0
  64. package/src/phaser/display/sprite_util.js +248 -0
  65. package/src/phaser/display/text.js +1089 -0
  66. package/src/phaser/display/webgl/abstract_filter.js +25 -0
  67. package/src/phaser/display/webgl/base_texture.js +68 -0
  68. package/src/phaser/display/webgl/blend_manager.js +35 -0
  69. package/src/phaser/display/webgl/earcut.js +647 -0
  70. package/src/phaser/display/webgl/earcut_node.js +28 -0
  71. package/src/phaser/display/webgl/fast_sprite_batch.js +242 -0
  72. package/src/phaser/display/webgl/filter_manager.js +46 -0
  73. package/src/phaser/display/webgl/filter_texture.js +61 -0
  74. package/src/phaser/display/webgl/graphics.js +618 -0
  75. package/src/phaser/display/webgl/graphics_data.js +42 -0
  76. package/src/phaser/display/webgl/mask_manager.js +36 -0
  77. package/src/phaser/display/webgl/render_texture.js +81 -0
  78. package/src/phaser/display/webgl/renderer.js +234 -0
  79. package/src/phaser/display/webgl/shader/complex.js +74 -0
  80. package/src/phaser/display/webgl/shader/fast.js +97 -0
  81. package/src/phaser/display/webgl/shader/normal.js +225 -0
  82. package/src/phaser/display/webgl/shader/primitive.js +72 -0
  83. package/src/phaser/display/webgl/shader/strip.js +77 -0
  84. package/src/phaser/display/webgl/shader_manager.js +89 -0
  85. package/src/phaser/display/webgl/sprite_batch.js +320 -0
  86. package/src/phaser/display/webgl/stencil_manager.js +170 -0
  87. package/src/phaser/display/webgl/texture.js +117 -0
  88. package/src/phaser/display/webgl/texture_util.js +32 -0
  89. package/src/phaser/display/webgl/util.js +74 -0
  90. package/src/phaser/geom/circle.js +186 -0
  91. package/src/phaser/geom/ellipse.js +65 -0
  92. package/src/phaser/geom/line.js +190 -0
  93. package/src/phaser/geom/matrix.js +147 -0
  94. package/src/phaser/geom/point.js +164 -0
  95. package/src/phaser/geom/polygon.js +141 -0
  96. package/src/phaser/geom/rectangle.js +306 -0
  97. package/src/phaser/geom/rounded_rectangle.js +36 -0
  98. package/src/phaser/geom/util/circle.js +115 -0
  99. package/src/phaser/geom/util/ellipse.js +30 -0
  100. package/src/phaser/geom/util/line.js +130 -0
  101. package/src/phaser/geom/util/matrix.js +48 -0
  102. package/src/phaser/geom/util/point.js +276 -0
  103. package/src/phaser/geom/util/polygon.js +24 -0
  104. package/src/phaser/geom/util/rectangle.js +212 -0
  105. package/src/phaser/geom/util/rounded_rectangle.js +28 -0
  106. package/src/phaser/util/math.js +279 -0
  107. package/src/phaser/util/string.js +26 -0
@@ -0,0 +1,687 @@
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 { GROUP } from './const';
8
+ import { distance } from '../util/math';
9
+
10
+ export default class {
11
+
12
+ constructor(sprite) {
13
+ this.sprite = sprite;
14
+ this.game = sprite.game;
15
+ this.enabled = false;
16
+ this.checked = false;
17
+ this.priorityID = 0;
18
+ this.useHandCursor = false;
19
+ this._setHandCursor = false;
20
+ this.isDragged = false;
21
+ this.allowHorizontalDrag = true;
22
+ this.allowVerticalDrag = true;
23
+ this.bringToTop = false;
24
+ this.snapOffset = null;
25
+ this.snapOnDrag = false;
26
+ this.snapOnRelease = false;
27
+ this.snapX = 0;
28
+ this.snapY = 0;
29
+ this.snapOffsetX = 0;
30
+ this.snapOffsetY = 0;
31
+ this.pixelPerfectOver = false;
32
+ this.pixelPerfectClick = false;
33
+ this.pixelPerfectAlpha = 255;
34
+ this.draggable = false;
35
+ this.boundsRect = null;
36
+ this.boundsSprite = null;
37
+ this.scaleLayer = false;
38
+ this.dragOffset = new Point();
39
+ this.dragFromCenter = false;
40
+ this.dragStopBlocksInputUp = false;
41
+ this.dragStartPoint = new Point();
42
+ this.dragDistanceThreshold = 0;
43
+ this.dragTimeThreshold = 0;
44
+ this.downPoint = new Point();
45
+ this.snapPoint = new Point();
46
+ this._dragPoint = new Point();
47
+ this._dragPhase = false;
48
+ this._pendingDrag = false;
49
+ this._dragTimePass = false;
50
+ this._dragDistancePass = false;
51
+ this._wasEnabled = false;
52
+ this._tempPoint = new Point();
53
+ this._pointerData = [];
54
+ this._pointerData.push({
55
+ id: 0,
56
+ x: 0,
57
+ y: 0,
58
+ camX: 0,
59
+ camY: 0,
60
+ isDown: false,
61
+ isUp: false,
62
+ isOver: false,
63
+ isOut: false,
64
+ timeOver: 0,
65
+ timeOut: 0,
66
+ timeDown: 0,
67
+ timeUp: 0,
68
+ downDuration: 0,
69
+ isDragged: false,
70
+ });
71
+ }
72
+
73
+ start(priority = 0, useHandCursor = false) {
74
+ // Turning on
75
+ if (this.enabled === false) {
76
+ // Register, etc
77
+ this.game.input.interactiveItems.add(this);
78
+ this.useHandCursor = useHandCursor;
79
+ this.priorityID = priority;
80
+ for (let i = 0; i < 10; i += 1) {
81
+ this._pointerData[i] = {
82
+ id: i,
83
+ x: 0,
84
+ y: 0,
85
+ isDown: false,
86
+ isUp: false,
87
+ isOver: false,
88
+ isOut: false,
89
+ timeOver: 0,
90
+ timeOut: 0,
91
+ timeDown: 0,
92
+ timeUp: 0,
93
+ downDuration: 0,
94
+ isDragged: false,
95
+ };
96
+ }
97
+ this.snapOffset = new Point();
98
+ this.enabled = true;
99
+ this._wasEnabled = true;
100
+ }
101
+ this.sprite.events.onAddedToGroup.add(this.addedToGroup, this);
102
+ this.sprite.events.onRemovedFromGroup.add(this.removedFromGroup, this);
103
+ return this.sprite;
104
+ }
105
+
106
+ addedToGroup() {
107
+ if (this._dragPhase) {
108
+ return;
109
+ }
110
+ if (this._wasEnabled && !this.enabled) {
111
+ this.start();
112
+ }
113
+ }
114
+
115
+ removedFromGroup() {
116
+ if (this._dragPhase) {
117
+ return;
118
+ }
119
+ if (this.enabled) {
120
+ this._wasEnabled = true;
121
+ this.stop();
122
+ } else {
123
+ this._wasEnabled = false;
124
+ }
125
+ }
126
+
127
+ reset() {
128
+ this.enabled = false;
129
+ for (let i = 0; i < 10; i += 1) {
130
+ this._pointerData[i] = {
131
+ id: i,
132
+ x: 0,
133
+ y: 0,
134
+ isDown: false,
135
+ isUp: false,
136
+ isOver: false,
137
+ isOut: false,
138
+ timeOver: 0,
139
+ timeOut: 0,
140
+ timeDown: 0,
141
+ timeUp: 0,
142
+ downDuration: 0,
143
+ isDragged: false,
144
+ };
145
+ }
146
+ }
147
+
148
+ stop() {
149
+ if (this.enabled) {
150
+ this.enabled = false;
151
+ this.game.input.interactiveItems.remove(this);
152
+ }
153
+ }
154
+
155
+ destroy() {
156
+ if (this.sprite) {
157
+ if (this._setHandCursor) {
158
+ this.game.canvas.style.cursor = 'default';
159
+ this._setHandCursor = false;
160
+ }
161
+ this.enabled = false;
162
+ this.game.input.interactiveItems.remove(this);
163
+ this._pointerData.length = 0;
164
+ this.boundsRect = null;
165
+ this.boundsSprite = null;
166
+ this.sprite = null;
167
+ }
168
+
169
+ }
170
+
171
+ validForInput(highestID, highestRenderID, includePixelPerfect = true) {
172
+ if (!this.enabled || this.sprite.scale.x === 0 || this.sprite.scale.y === 0 || this.priorityID < this.game.input.minPriorityID || (this.sprite.parent && this.sprite.parent.ignoreChildInput)) {
173
+ return false;
174
+ }
175
+ // If we're trying to specifically IGNORE pixel perfect objects, then set includePixelPerfect to false and skip it
176
+ if (!includePixelPerfect && (this.pixelPerfectClick || this.pixelPerfectOver)) {
177
+ return false;
178
+ }
179
+ if (this.priorityID > highestID || (this.priorityID === highestID && this.sprite.renderOrderID > highestRenderID)) {
180
+ return true;
181
+ }
182
+ return false;
183
+ }
184
+
185
+ isPixelPerfect() {
186
+ return (this.pixelPerfectClick || this.pixelPerfectOver);
187
+ }
188
+
189
+ pointerX(pointerId = 0) {
190
+ return this._pointerData[pointerId].x;
191
+ }
192
+
193
+ pointerY(pointerId = 0) {
194
+ return this._pointerData[pointerId].y;
195
+ }
196
+
197
+ pointerDown(pointerId = 0) {
198
+ return this._pointerData[pointerId].isDown;
199
+ }
200
+
201
+ pointerUp(pointerId = 0) {
202
+ return this._pointerData[pointerId].isUp;
203
+ }
204
+
205
+ pointerTimeDown(pointerId = 0) {
206
+ return this._pointerData[pointerId].timeDown;
207
+ }
208
+
209
+ pointerTimeUp(pointerId = 0) {
210
+ return this._pointerData[pointerId].timeUp;
211
+ }
212
+
213
+ pointerOver(pointerId) {
214
+ if (!this.enabled) {
215
+ return false;
216
+ }
217
+ if (pointerId === undefined) {
218
+ for (let i = 0; i < 10; i += 1) {
219
+ if (this._pointerData[i].isOver) {
220
+ return true;
221
+ }
222
+ }
223
+ return false;
224
+ }
225
+ return this._pointerData[pointerId].isOver;
226
+ }
227
+
228
+ pointerOut(pointerId) {
229
+ if (!this.enabled) {
230
+ return false;
231
+ }
232
+ if (pointerId === undefined) {
233
+ for (let i = 0; i < 10; i += 1) {
234
+ if (this._pointerData[i].isOut) {
235
+ return true;
236
+ }
237
+ }
238
+ }
239
+ return this._pointerData[pointerId].isOut;
240
+ }
241
+
242
+ pointerTimeOver(pointerId = 0) {
243
+ return this._pointerData[pointerId].timeOver;
244
+ }
245
+
246
+ pointerTimeOut(pointerId = 0) {
247
+ return this._pointerData[pointerId].timeOut;
248
+ }
249
+
250
+ pointerDragged(pointerId = 0) {
251
+ return this._pointerData[pointerId].isDragged;
252
+ }
253
+
254
+ checkPointerDown(pointer = 0, fastTest = false) {
255
+ if (!pointer.isDown || !this.enabled || !this.sprite || !this.sprite.parent || !this.sprite.visible || !this.sprite.parent.visible || this.sprite.worldScale.x === 0 || this.sprite.worldScale.y === 0) {
256
+ return false;
257
+ }
258
+ // Need to pass it a temp point, in case we need it again for the pixel check
259
+ if (this.game.input.hitTest(this.sprite, pointer, this._tempPoint)) {
260
+ if (!fastTest && this.pixelPerfectClick) {
261
+ return this.checkPixel(this._tempPoint.x, this._tempPoint.y);
262
+ }
263
+ return true;
264
+ }
265
+ return false;
266
+ }
267
+
268
+ checkPointerOver(pointer = 0, fastTest = false) {
269
+ if (!this.enabled || !this.sprite || !this.sprite.parent || !this.sprite.visible || !this.sprite.parent.visible || this.sprite.worldScale.x === 0 || this.sprite.worldScale.y === 0) {
270
+ return false;
271
+ }
272
+ // Need to pass it a temp point, in case we need it again for the pixel check
273
+ if (this.game.input.hitTest(this.sprite, pointer, this._tempPoint)) {
274
+ if (!fastTest && this.pixelPerfectOver) {
275
+ return this.checkPixel(this._tempPoint.x, this._tempPoint.y);
276
+ }
277
+ return true;
278
+ }
279
+ return false;
280
+ }
281
+
282
+ checkPixel(x, y, pointer) {
283
+ // Grab a pixel from our image into the hitCanvas and then test it
284
+ if (this.sprite.texture.baseTexture.source) {
285
+ if (x === null && y === null) {
286
+ // Use the pointer parameter
287
+ this.game.input.getLocalPosition(this.sprite, pointer, this._tempPoint);
288
+ x = this._tempPoint.x;
289
+ y = this._tempPoint.y;
290
+ }
291
+ if (this.sprite.anchor.x !== 0) {
292
+ x -= -this.sprite.texture.frame.width * this.sprite.anchor.x;
293
+ }
294
+ if (this.sprite.anchor.y !== 0) {
295
+ y -= -this.sprite.texture.frame.height * this.sprite.anchor.y;
296
+ }
297
+ x += this.sprite.texture.frame.x;
298
+ y += this.sprite.texture.frame.y;
299
+ if (this.sprite.texture.trim) {
300
+ x -= this.sprite.texture.trim.x;
301
+ y -= this.sprite.texture.trim.y;
302
+ // If the coordinates are outside the trim area we return false immediately, to save doing a draw call
303
+ if (x < this.sprite.texture.crop.x || x > this.sprite.texture.crop.right || y < this.sprite.texture.crop.y || y > this.sprite.texture.crop.bottom) {
304
+ this._dx = x;
305
+ this._dy = y;
306
+ return false;
307
+ }
308
+ }
309
+ this._dx = x;
310
+ this._dy = y;
311
+ this.game.input.hitContext.clearRect(0, 0, 1, 1);
312
+ this.game.input.hitContext.drawImage(this.sprite.texture.baseTexture.source, x, y, 1, 1, 0, 0, 1, 1);
313
+ const rgb = this.game.input.hitContext.getImageData(0, 0, 1, 1);
314
+ if (rgb.data[3] >= this.pixelPerfectAlpha) {
315
+ return true;
316
+ }
317
+ }
318
+ return false;
319
+ }
320
+
321
+ update(pointer) {
322
+ if (this.sprite === null || this.sprite.parent === undefined) {
323
+ // Abort. We've been destroyed.
324
+ return false;
325
+ }
326
+ if (!this.enabled || !this.sprite.visible || !this.sprite.parent.visible) {
327
+ this._pointerOutHandler(pointer);
328
+ return false;
329
+ }
330
+ if (this._pendingDrag) {
331
+ if (!this._dragDistancePass) {
332
+ this._dragDistancePass = (distance(pointer.x, pointer.y, this.downPoint.x, this.downPoint.y) >= this.dragDistanceThreshold);
333
+ }
334
+ if (this._dragDistancePass && this._dragTimePass) {
335
+ this.startDrag(pointer);
336
+ }
337
+ return true;
338
+ } else if (this.draggable && this._draggedPointerID === pointer.id) {
339
+ return this.updateDrag(pointer, false);
340
+ } else if (this._pointerData[pointer.id].isOver) {
341
+ if (this.checkPointerOver(pointer)) {
342
+ this._pointerData[pointer.id].x = pointer.x - this.sprite.x;
343
+ this._pointerData[pointer.id].y = pointer.y - this.sprite.y;
344
+ return true;
345
+ }
346
+ this._pointerOutHandler(pointer);
347
+ return false;
348
+ }
349
+ return false;
350
+ }
351
+
352
+ _pointerOverHandler(pointer, silent) {
353
+ if (this.sprite === null) {
354
+ // Abort. We've been destroyed.
355
+ return;
356
+ }
357
+ const data = this._pointerData[pointer.id];
358
+ if (data.isOver === false || pointer.dirty) {
359
+ const sendEvent = (data.isOver === false);
360
+ data.isOver = true;
361
+ data.isOut = false;
362
+ data.timeOver = this.game.time.time;
363
+ data.x = pointer.x - this.sprite.x;
364
+ data.y = pointer.y - this.sprite.y;
365
+ if (this.useHandCursor && data.isDragged === false) {
366
+ this.game.canvas.style.cursor = 'pointer';
367
+ this._setHandCursor = true;
368
+ }
369
+ if (!silent && sendEvent && this.sprite && this.sprite.events) {
370
+ this.sprite.events.onInputOver$dispatch(this.sprite, pointer);
371
+ }
372
+ if (this.sprite.parent && this.sprite.parent.type === GROUP) {
373
+ this.sprite.parent.onChildInputOver.dispatch(this.sprite, pointer);
374
+ }
375
+ }
376
+ }
377
+
378
+ _pointerOutHandler(pointer, silent) {
379
+ if (this.sprite === null) {
380
+ // Abort. We've been destroyed.
381
+ return;
382
+ }
383
+ const data = this._pointerData[pointer.id];
384
+ data.isOver = false;
385
+ data.isOut = true;
386
+ data.timeOut = this.game.time.time;
387
+ if (this.useHandCursor && data.isDragged === false) {
388
+ this.game.canvas.style.cursor = 'default';
389
+ this._setHandCursor = false;
390
+ }
391
+ if (!silent && this.sprite && this.sprite.events) {
392
+ this.sprite.events.onInputOut$dispatch(this.sprite, pointer);
393
+ if (this.sprite && this.sprite.parent && this.sprite.parent.type === GROUP) {
394
+ this.sprite.parent.onChildInputOut.dispatch(this.sprite, pointer);
395
+ }
396
+ }
397
+ }
398
+
399
+ _touchedHandler(pointer) {
400
+ if (this.sprite === null) {
401
+ // Abort. We've been destroyed.
402
+ return;
403
+ }
404
+ const data = this._pointerData[pointer.id];
405
+ if (!data.isDown && data.isOver) {
406
+ if (this.pixelPerfectClick && !this.checkPixel(null, null, pointer)) {
407
+ return;
408
+ }
409
+ data.isDown = true;
410
+ data.isUp = false;
411
+ data.timeDown = this.game.time.time;
412
+ this.downPoint.set(pointer.x, pointer.y);
413
+ // It's possible the onInputDown event creates a new Sprite that is on-top of this one, so we ought to force a Pointer update
414
+ pointer.dirty = true;
415
+ if (this.sprite && this.sprite.events) {
416
+ this.sprite.events.onInputDown$dispatch(this.sprite, pointer);
417
+ // The event above might have destroyed this sprite.
418
+ if (this.sprite && this.sprite.parent && this.sprite.parent.type === GROUP) {
419
+ this.sprite.parent.onChildInputDown.dispatch(this.sprite, pointer);
420
+ }
421
+ // The events might have destroyed this sprite.
422
+ if (this.sprite === null) {
423
+ return;
424
+ }
425
+ }
426
+ // Start drag
427
+ if (this.draggable && this.isDragged === false) {
428
+ if (this.dragTimeThreshold === 0 && this.dragDistanceThreshold === 0) {
429
+ this.startDrag(pointer);
430
+ } else {
431
+ this._pendingDrag = true;
432
+ this._dragDistancePass = (this.dragDistanceThreshold === 0);
433
+ if (this.dragTimeThreshold > 0) {
434
+ this._dragTimePass = false;
435
+ this.game.time.events.add(this.dragTimeThreshold, this.dragTimeElapsed, this, pointer);
436
+ } else {
437
+ this._dragTimePass = true;
438
+ }
439
+ }
440
+ }
441
+ if (this.bringToTop) {
442
+ this.sprite.bringToTop();
443
+ }
444
+ }
445
+ }
446
+
447
+ dragTimeElapsed(pointer) {
448
+ this._dragTimePass = true;
449
+ if (this._pendingDrag && this.sprite) {
450
+ if (this._dragDistancePass) {
451
+ this.startDrag(pointer);
452
+ }
453
+ }
454
+ }
455
+
456
+ _releasedHandler(pointer) {
457
+ if (this.sprite === null) {
458
+ // Abort. We've been destroyed.
459
+ return;
460
+ }
461
+ const data = this._pointerData[pointer.id];
462
+ // If was previously touched by this Pointer, check if still is AND still over this item
463
+ if (data.isDown && pointer.isUp) {
464
+ data.isDown = false;
465
+ data.isUp = true;
466
+ data.timeUp = this.game.time.time;
467
+ data.downDuration = data.timeUp - data.timeDown;
468
+ // Only release the InputUp signal if the pointer is still over this sprite
469
+ let isOver = this.checkPointerOver(pointer);
470
+ if (this.sprite && this.sprite.events) {
471
+ if (!this.dragStopBlocksInputUp || this.dragStopBlocksInputUp && !(this.draggable && this.isDragged && this._draggedPointerID === pointer.id)) {
472
+ this.sprite.events.onInputUp$dispatch(this.sprite, pointer, isOver);
473
+ }
474
+ if (this.sprite && this.sprite.parent && this.sprite.parent.type === GROUP) {
475
+ this.sprite.parent.onChildInputUp.dispatch(this.sprite, pointer, isOver);
476
+ }
477
+ // The onInputUp event may have changed the sprite so that checkPointerOver is no longer true, so update it.
478
+ if (isOver) {
479
+ isOver = this.checkPointerOver(pointer);
480
+ }
481
+ }
482
+ data.isOver = isOver;
483
+ if (!isOver && this.useHandCursor) {
484
+ this.game.canvas.style.cursor = 'default';
485
+ this._setHandCursor = false;
486
+ }
487
+ // It's possible the onInputUp event created a new Sprite that is on-top of this one, so force a Pointer update
488
+ pointer.dirty = true;
489
+ this._pendingDrag = false;
490
+ // Stop drag
491
+ if (this.draggable && this.isDragged && this._draggedPointerID === pointer.id) {
492
+ this.stopDrag(pointer);
493
+ }
494
+ }
495
+ }
496
+
497
+ updateDrag(pointer, fromStart = false) {
498
+ if (pointer.isUp) {
499
+ this.stopDrag(pointer);
500
+ return false;
501
+ }
502
+ const px = this.globalToLocalX(pointer.x) + this._dragPoint.x + this.dragOffset.x;
503
+ const py = this.globalToLocalY(pointer.y) + this._dragPoint.y + this.dragOffset.y;
504
+ const cx = 0;
505
+ const cy = 0;
506
+ if (this.allowHorizontalDrag) {
507
+ this.sprite.x = px + cx;
508
+ }
509
+ if (this.allowVerticalDrag) {
510
+ this.sprite.y = py + cy;
511
+ }
512
+ if (this.boundsRect) {
513
+ this.checkBoundsRect();
514
+ }
515
+ if (this.boundsSprite) {
516
+ this.checkBoundsSprite();
517
+ }
518
+ if (this.snapOnDrag) {
519
+ this.sprite.x = Math.round((this.sprite.x - (this.snapOffsetX % this.snapX)) / this.snapX) * this.snapX + (this.snapOffsetX % this.snapX);
520
+ this.sprite.y = Math.round((this.sprite.y - (this.snapOffsetY % this.snapY)) / this.snapY) * this.snapY + (this.snapOffsetY % this.snapY);
521
+ this.snapPoint.set(this.sprite.x, this.sprite.y);
522
+ }
523
+ this.sprite.events.onDragUpdate.dispatch(this.sprite, pointer, px, py, this.snapPoint, fromStart);
524
+ return true;
525
+ }
526
+
527
+ justOver(pointerId = 0, delay = 500) {
528
+ return (this._pointerData[pointerId].isOver && this.overDuration(pointerId) < delay);
529
+ }
530
+
531
+ justOut(pointerId = 0, delay = 500) {
532
+ return (this._pointerData[pointerId].isOut && (this.game.time.time - this._pointerData[pointerId].timeOut < delay));
533
+ }
534
+
535
+ justPressed(pointerId = 0, delay = 500) {
536
+ return (this._pointerData[pointerId].isDown && this.downDuration(pointerId) < delay);
537
+ }
538
+
539
+ justReleased(pointerId = 0, delay = 500) {
540
+ return (this._pointerData[pointerId].isUp && (this.game.time.time - this._pointerData[pointerId].timeUp < delay));
541
+ }
542
+
543
+ overDuration(pointerId = 0) {
544
+ if (this._pointerData[pointerId].isOver) {
545
+ return this.game.time.time - this._pointerData[pointerId].timeOver;
546
+ }
547
+ return -1;
548
+ }
549
+
550
+ downDuration(pointerId = 0) {
551
+ if (this._pointerData[pointerId].isDown) {
552
+ return this.game.time.time - this._pointerData[pointerId].timeDown;
553
+ }
554
+ return -1;
555
+ }
556
+
557
+ enableDrag(lockCenter = false, bringToTop = false, pixelPerfect = false, alphaThreshold = 255, boundsRect = null, boundsSprite = null) {
558
+ this._dragPoint = new Point();
559
+ this.draggable = true;
560
+ this.bringToTop = bringToTop;
561
+ this.dragOffset = new Point();
562
+ this.dragFromCenter = lockCenter;
563
+ this.pixelPerfectClick = pixelPerfect;
564
+ this.pixelPerfectAlpha = alphaThreshold;
565
+ if (boundsRect) {
566
+ this.boundsRect = boundsRect;
567
+ }
568
+ if (boundsSprite) {
569
+ this.boundsSprite = boundsSprite;
570
+ }
571
+ }
572
+
573
+ disableDrag() {
574
+ if (this._pointerData) {
575
+ for (let i = 0; i < 10; i += 1) {
576
+ this._pointerData[i].isDragged = false;
577
+ }
578
+ }
579
+ this.draggable = false;
580
+ this.isDragged = false;
581
+ this._draggedPointerID = -1;
582
+ this._pendingDrag = false;
583
+ }
584
+
585
+ startDrag(pointer) {
586
+ const x = this.sprite.x;
587
+ const y = this.sprite.y;
588
+ this.isDragged = true;
589
+ this._draggedPointerID = pointer.id;
590
+ this._pointerData[pointer.id].camX = 0;
591
+ this._pointerData[pointer.id].camY = 0;
592
+ this._pointerData[pointer.id].isDragged = true;
593
+ if (this.dragFromCenter) {
594
+ const bounds = this.sprite.getBounds();
595
+ this.sprite.x = this.globalToLocalX(pointer.x) + (this.sprite.x - bounds.centerX);
596
+ this.sprite.y = this.globalToLocalY(pointer.y) + (this.sprite.y - bounds.centerY);
597
+ }
598
+ this._dragPoint.setTo(this.sprite.x - this.globalToLocalX(pointer.x), this.sprite.y - this.globalToLocalY(pointer.y));
599
+ this.updateDrag(pointer, true);
600
+ if (this.bringToTop) {
601
+ this._dragPhase = true;
602
+ this.sprite.parent.bringToTop(this.sprite);
603
+ }
604
+ this.dragStartPoint.set(x, y);
605
+ this.sprite.events.onDragStart$dispatch(this.sprite, pointer, x, y);
606
+ this._pendingDrag = false;
607
+ }
608
+
609
+ globalToLocalX(x) {
610
+ if (this.scaleLayer) {
611
+ x -= this.game.scale.grid.boundsFluid.x;
612
+ x *= this.game.scale.grid.scaleFluidInversed.x;
613
+ }
614
+ return x;
615
+ }
616
+
617
+ globalToLocalY(y) {
618
+ if (this.scaleLayer) {
619
+ y -= this.game.scale.grid.boundsFluid.y;
620
+ y *= this.game.scale.grid.scaleFluidInversed.y;
621
+ }
622
+ return y;
623
+ }
624
+
625
+ stopDrag(pointer) {
626
+ this.isDragged = false;
627
+ this._draggedPointerID = -1;
628
+ this._pointerData[pointer.id].isDragged = false;
629
+ this._dragPhase = false;
630
+ this._pendingDrag = false;
631
+ if (this.snapOnRelease) {
632
+ this.sprite.x = Math.round((this.sprite.x - (this.snapOffsetX % this.snapX)) / this.snapX) * this.snapX + (this.snapOffsetX % this.snapX);
633
+ this.sprite.y = Math.round((this.sprite.y - (this.snapOffsetY % this.snapY)) / this.snapY) * this.snapY + (this.snapOffsetY % this.snapY);
634
+ }
635
+ this.sprite.events.onDragStop$dispatch(this.sprite, pointer);
636
+ if (this.checkPointerOver(pointer) === false) {
637
+ this._pointerOutHandler(pointer);
638
+ }
639
+ }
640
+
641
+ setDragLock(allowHorizontal = true, allowVertical = true) {
642
+ this.allowHorizontalDrag = allowHorizontal;
643
+ this.allowVerticalDrag = allowVertical;
644
+ }
645
+
646
+ enableSnap(snapX, snapY, onDrag = true, onRelease = false, snapOffsetX = 0, snapOffsetY = 0) {
647
+ this.snapX = snapX;
648
+ this.snapY = snapY;
649
+ this.snapOffsetX = snapOffsetX;
650
+ this.snapOffsetY = snapOffsetY;
651
+ this.snapOnDrag = onDrag;
652
+ this.snapOnRelease = onRelease;
653
+ }
654
+
655
+ disableSnap() {
656
+ this.snapOnDrag = false;
657
+ this.snapOnRelease = false;
658
+ }
659
+
660
+ checkBoundsRect() {
661
+ if (this.sprite.left < this.boundsRect.left) {
662
+ this.sprite.x = this.boundsRect.x + this.sprite.offsetX;
663
+ } else if (this.sprite.right > this.boundsRect.right) {
664
+ this.sprite.x = this.boundsRect.right - (this.sprite.width - this.sprite.offsetX);
665
+ }
666
+ if (this.sprite.top < this.boundsRect.top) {
667
+ this.sprite.y = this.boundsRect.top + this.sprite.offsetY;
668
+ } else if (this.sprite.bottom > this.boundsRect.bottom) {
669
+ this.sprite.y = this.boundsRect.bottom - (this.sprite.height - this.sprite.offsetY);
670
+ }
671
+ }
672
+
673
+ checkBoundsSprite() {
674
+ if (this.sprite.left < this.boundsSprite.left) {
675
+ this.sprite.x = this.boundsSprite.left + this.sprite.offsetX;
676
+ } else if (this.sprite.right > this.boundsSprite.right) {
677
+ this.sprite.x = this.boundsSprite.right - (this.sprite.width - this.sprite.offsetX);
678
+ }
679
+ if (this.sprite.top < this.boundsSprite.top) {
680
+ this.sprite.y = this.boundsSprite.top + this.sprite.offsetY;
681
+ } else if (this.sprite.bottom > this.boundsSprite.bottom) {
682
+ this.sprite.y = this.boundsSprite.bottom - (this.sprite.height - this.sprite.offsetY);
683
+ }
684
+
685
+ }
686
+
687
+ }