diff --git a/src/io/mouse.js b/src/io/mouse.js index 1c7bb81e5d6..5d9c00fb915 100644 --- a/src/io/mouse.js +++ b/src/io/mouse.js @@ -59,19 +59,13 @@ class Mouse { postData (data) { if (data.x) { this._clientX = data.x; - this._scratchX = Math.round(MathUtil.clamp( - 480 * ((data.x / data.canvasWidth) - 0.5), - -240, - 240 - )); + this._rawScratchX = 480 * ((data.x / data.canvasWidth) - 0.5); + this._scratchX = Math.round(MathUtil.clamp(this._rawScratchX, -240, 240)); } if (data.y) { this._clientY = data.y; - this._scratchY = Math.round(MathUtil.clamp( - -360 * ((data.y / data.canvasHeight) - 0.5), - -180, - 180 - )); + this._rawScratchY = -360 * ((data.y / data.canvasHeight) - 0.5); + this._scratchY = Math.round(MathUtil.clamp(this._rawScratchY, -180, 180)); } if (typeof data.isDown !== 'undefined') { const previousDownState = this._isDown; @@ -133,6 +127,19 @@ class Mouse { return this._scratchY; } + /** + * Check if the mouse is outside the stage. + * @return {boolean} Is the mouse outside the stage? + */ + getIsOutside () { + return !( + this._rawScratchX >= -240 && + this._rawScratchX <= 240 && + this._rawScratchY >= -180 && + this._rawScratchY <= 180 + ); + } + /** * Get the down state of the mouse. * @return {boolean} Is the mouse down? diff --git a/src/sprites/rendered-target.js b/src/sprites/rendered-target.js index 018f7cd16bb..5902ccc6f98 100644 --- a/src/sprites/rendered-target.js +++ b/src/sprites/rendered-target.js @@ -777,6 +777,7 @@ class RenderedTarget extends Target { isTouchingObject (requestedObject) { if (requestedObject === '_mouse_') { if (!this.runtime.ioDevices.mouse) return false; + if (this.runtime.ioDevices.mouse.getIsOutside()) return false; const mouseX = this.runtime.ioDevices.mouse.getClientX(); const mouseY = this.runtime.ioDevices.mouse.getClientY(); return this.isTouchingPoint(mouseX, mouseY); diff --git a/test/unit/sprites_rendered-target.js b/test/unit/sprites_rendered-target.js index 20430008b37..f0e51b18a5d 100644 --- a/test/unit/sprites_rendered-target.js +++ b/test/unit/sprites_rendered-target.js @@ -280,6 +280,39 @@ test('isTouchingPoint', t => { t.end(); }); +test('isTouchingObjectOutsideStage', t => { + const r = new Runtime(); + const s = new Sprite(null, r); + const renderer = new FakeRenderer(); + r.attachRenderer(renderer); + const a = new RenderedTarget(s, r); + a.renderer = renderer; + r.ioDevices.mouse.postData({ + x: 1000, + y: -300 + }); + t.equals(a.isTouchingObject('_mouse_'), false); + t.end(); +}); + +test('isTouchingMouse', t => { + const r = new Runtime(); + const s = new Sprite(null, r); + const renderer = new FakeRenderer(); + r.attachRenderer(renderer); + const a = new RenderedTarget(s, r); + a.renderer = renderer; + // (0, 0) is the top left, and (canvasWidth, canvasHeight) is the bottom right + r.ioDevices.mouse.postData({ + canvasHeight: 360, + canvasWidth: 480, + x: 240, + y: 180 + }); + t.equals(a.isTouchingObject('_mouse_'), true); + t.end(); +}); + test('isTouchingEdge', t => { const r = new Runtime(); const s = new Sprite(null, r);