diff --git a/src/input/MSPointer.js b/src/input/MSPointer.js index c8986e888..c5cc67d00 100644 --- a/src/input/MSPointer.js +++ b/src/input/MSPointer.js @@ -14,24 +14,12 @@ * * Phaser does not yet support {@link http://www.w3.org/TR/pointerevents/#chorded-button-interactions chorded button interactions}. * -* You can disable Phaser's use of Pointer Events by any of three ways: +* You can disable Phaser's use of Pointer Events: * * ```javascript * new Phaser.Game({ mspointer: false }); * ``` * -* ```javascript -* // **Before** `new Phaser.Game(…)`: -* Phaser.Device.onInitialized.add(function () { -* this.mspointer = false; -* }); -* ``` -* -* ```javascript -* // Once, in the earliest State `init` or `create` callback (e.g., Boot): -* this.input.mspointer.stop(); -* ``` -* * @class Phaser.MSPointer * @constructor * @param {Phaser.Game} game - A reference to the currently running game. @@ -56,30 +44,35 @@ Phaser.MSPointer = function (game) this.callbackContext = this.game; /** - * @property {function} pointerDownCallback - A callback that can be fired on a pointerdown (MSPointerDown) event. + * @property {function} pointerDownCallback - A callback that can be fired on a pointerdown event. */ this.pointerDownCallback = null; /** - * @property {function} pointerMoveCallback - A callback that can be fired on a pointermove (MSPointerMove) event. + * @property {function} pointerMoveCallback - A callback that can be fired on a pointermove event. */ this.pointerMoveCallback = null; /** - * @property {function} pointerUpCallback - A callback that can be fired on a pointerup (MSPointerUp) event. + * @property {function} pointerUpCallback - A callback that can be fired on a pointerup event. */ this.pointerUpCallback = null; /** - * @property {function} pointerOutCallback - A callback that can be fired on a pointerout (MSPointerOut) event. + * @property {function} pointerOutCallback - A callback that can be fired on a pointerout event. */ this.pointerOutCallback = null; /** - * @property {function} pointerOverCallback - A callback that can be fired on a pointerover (MSPointerOver) event. + * @property {function} pointerOverCallback - A callback that can be fired on a pointerover event. */ this.pointerOverCallback = null; + /** + * @property {function} pointerCancelCallback - A callback that can be fired on a pointercancel event. + */ + this.pointerCancelCallback = null; + /** * If true the PointerEvent will call preventDefault(), canceling the corresponding MouseEvent or * TouchEvent. @@ -216,16 +209,23 @@ Phaser.MSPointer.prototype = { return _this.onPointerOver(event); }; + this._onMSPointerCancel = function (event) + { + return _this.onPointerCancel(event); + }; + var canvas = this.game.canvas; canvas.addEventListener('MSPointerDown', this._onMSPointerDown, false); canvas.addEventListener('MSPointerMove', this._onMSPointerMove, false); canvas.addEventListener('MSPointerUp', this._onMSPointerUp, false); + canvas.addEventListener('MSPointerCancel', this._onMSPointerCancel, false); // IE11+ uses non-prefix events canvas.addEventListener('pointerdown', this._onMSPointerDown, false); canvas.addEventListener('pointermove', this._onMSPointerMove, false); canvas.addEventListener('pointerup', this._onMSPointerUp, false); + canvas.addEventListener('pointercancel', this._onMSPointerCancel, false); canvas.style['-ms-content-zooming'] = 'none'; canvas.style['-ms-touch-action'] = 'none'; @@ -278,7 +278,7 @@ Phaser.MSPointer.prototype = { event.identifier = event.pointerId; - if (event.pointerType === 'mouse' || event.pointerType === 0x00000004) + if (this.isMousePointerEvent(event)) { this.input.mousePointer.start(event); } @@ -316,7 +316,7 @@ Phaser.MSPointer.prototype = { event.identifier = event.pointerId; - if (event.pointerType === 'mouse' || event.pointerType === 0x00000004) + if (this.isMousePointerEvent(event)) { this.input.mousePointer.move(event); } @@ -356,7 +356,7 @@ Phaser.MSPointer.prototype = { event.identifier = event.pointerId; - if (event.pointerType === 'mouse' || event.pointerType === 0x00000004) + if (this.isMousePointerEvent(event)) { this.input.mousePointer.stop(event); } @@ -378,7 +378,7 @@ Phaser.MSPointer.prototype = { event.identifier = event.pointerId; - if ((event.pointerType === 'mouse' || event.pointerType === 0x00000004) && !this.input.mousePointer.withinGame) + if (this.isMousePointerEvent(event) && !this.input.mousePointer.withinGame) { this.onPointerUp(event); } @@ -412,18 +412,11 @@ Phaser.MSPointer.prototype = { event.identifier = event.pointerId; - if (event.pointerType === 'mouse' || event.pointerType === 0x00000004) - { - this.input.mousePointer.withinGame = false; - } - else - { - var pointer = this.input.getPointerFromIdentifier(event.identifier); + var pointer = this.getPointerFromEvent(event); - if (pointer) - { - pointer.withinGame = false; - } + if (pointer) + { + pointer.withinGame = false; } if (this.pointerOutCallback) @@ -470,23 +463,50 @@ Phaser.MSPointer.prototype = { event.identifier = event.pointerId; - if (event.pointerType === 'mouse' || event.pointerType === 0x00000004) + var pointer = this.getPointerFromEvent(event); + + if (pointer) { - this.input.mousePointer.withinGame = true; + pointer.withinGame = true; } - else + + if (this.pointerOverCallback) { - var pointer = this.input.getPointerFromIdentifier(event.identifier); + this.pointerOverCallback.call(this.callbackContext, event); + } - if (pointer) - { - pointer.withinGame = true; - } + }, + + /** + * The internal method that handles the pointer cancel event from the browser. + * + * @method Phaser.MSPointer#onPointerCancel + * @param {PointerEvent} event + */ + onPointerCancel: function (event) + { + + this.event = event; + + if (this.pointerCancelCallback) + { + this.pointerCancelCallback.call(this.callbackContext, event); } - if (this.pointerOverCallback) + if (!this.game.input.enabled || !this.enabled) { - this.pointerOverCallback.call(this.callbackContext, event); + return; + } + + event.identifier = event.pointerId; + + if (this.isMousePointerEvent(event)) + { + this.input.mousePointer.stop(event); + } + else + { + this.input.stopPointer(event); } }, @@ -520,6 +540,28 @@ Phaser.MSPointer.prototype = { this.active = false; + }, + + /** + * @private + * @param {PointerEvent} event + * @return {boolean} + */ + isMousePointerEvent: function (event) + { + return (event.pointerType === 'mouse' || event.pointerType === 0x00000004); + }, + + /** + * @private + * @param {PointerEvent} event + * @return {?Phaser.Pointer} + */ + getPointerFromEvent: function (event) + { + return this.isMousePointerEvent(event) + ? this.input.mousePointer + : this.input.getPointerFromIdentifier(event.identifier); } }; diff --git a/src/utils/Debug.js b/src/utils/Debug.js index a3e47c11e..74538f85b 100644 --- a/src/utils/Debug.js +++ b/src/utils/Debug.js @@ -568,6 +568,7 @@ Phaser.Utils.Debug.prototype = { this.line('Movement: X: ' + mx + ' Y: ' + my); this.line('Duration: ' + pointer.duration + ' ms'); this.line('is Down: ' + pointer.isDown + ' is Up: ' + pointer.isUp); + this.line('Identifier: ' + pointer.identifier + ' Pointer ID: ' + pointer.pointerId); if (pointer.isMouse) { @@ -689,6 +690,50 @@ Phaser.Utils.Debug.prototype = { }, + /** + * Prints information about an input handler, e.g. `this.input.mouse`. + * + * @method Phaser.Utils.Debug#inputHandler + * @param {Phaser.Keyboard|Phaser.Mouse|Phaser.MouseWheel|Phaser.MSPointer|Phaser.PointerLock} handler + * @param {string} name + * @param {number} x + * @param {number} y + * @param {string} color + */ + inputHandler: function (handler, name, x, y, color) + { + this.start(x, y, color); + + this.line(name || '?'); + this.line('active: ' + handler.active); + + if (!handler.active) + { + this.stop(); + + return; + } + + this.line('enabled: ' + handler.enabled); + + if ('capture' in handler) + { + this.line('capture: ' + handler.capture); + } + + if ('preventDefault' in handler) + { + this.line('preventDefault: ' + handler.preventDefault); + } + + if ('event' in handler) + { + this.line('event: ' + (handler.event ? handler.event.type : handler.event)); + } + + this.stop(); + }, + _inputHandler: function (handler, name) { return this._inputHandlerStatusIcon(handler) + ' ' + name + ' ' + this._inputHandlerCaptureIcon(handler);