diff --git a/package.json b/package.json index c04499c..a39a3a1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pixi.js", - "version": "4.4.0", + "version": "4.4.1", "description": "Pixi.js is a fast lightweight 2D library that works across all devices.", "author": "Mat Groves", "contributors": [ diff --git a/package.json b/package.json index c04499c..a39a3a1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pixi.js", - "version": "4.4.0", + "version": "4.4.1", "description": "Pixi.js is a fast lightweight 2D library that works across all devices.", "author": "Mat Groves", "contributors": [ diff --git a/src/core/textures/Texture.js b/src/core/textures/Texture.js index 9e1ff87..e70804e 100644 --- a/src/core/textures/Texture.js +++ b/src/core/textures/Texture.js @@ -424,7 +424,7 @@ * @return {PIXI.Texture} Output texture */ static fromLoader(source, imageUrl, name) - { + { const baseTexture = new BaseTexture(source, undefined, getResolutionOfUrl(imageUrl)); const texture = new Texture(baseTexture); diff --git a/package.json b/package.json index c04499c..a39a3a1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pixi.js", - "version": "4.4.0", + "version": "4.4.1", "description": "Pixi.js is a fast lightweight 2D library that works across all devices.", "author": "Mat Groves", "contributors": [ diff --git a/src/core/textures/Texture.js b/src/core/textures/Texture.js index 9e1ff87..e70804e 100644 --- a/src/core/textures/Texture.js +++ b/src/core/textures/Texture.js @@ -424,7 +424,7 @@ * @return {PIXI.Texture} Output texture */ static fromLoader(source, imageUrl, name) - { + { const baseTexture = new BaseTexture(source, undefined, getResolutionOfUrl(imageUrl)); const texture = new Texture(baseTexture); diff --git a/src/interaction/InteractionManager.js b/src/interaction/InteractionManager.js index 8baf13a..67e09f6 100644 --- a/src/interaction/InteractionManager.js +++ b/src/interaction/InteractionManager.js @@ -914,7 +914,7 @@ { const event = events[i]; - const interactionData = this.getInteractionDataForPointerId(event.pointerId); + const interactionData = this.getInteractionDataForPointerId(event); const interactionEvent = this.configureInteractionEventForDOMEvent(this.eventData, event, interactionData); @@ -998,7 +998,7 @@ { const event = events[i]; - const interactionData = this.getInteractionDataForPointerId(event.pointerId); + const interactionData = this.getInteractionDataForPointerId(event); const interactionEvent = this.configureInteractionEventForDOMEvent(this.eventData, event, interactionData); @@ -1098,7 +1098,7 @@ const test = isRightButton ? flags.RIGHT_DOWN : flags.LEFT_DOWN; - const isDown = trackingData !== undefined && (trackingData.flags | test); + const isDown = trackingData !== undefined && (trackingData.flags & test); if (hit) { @@ -1180,7 +1180,7 @@ { const event = events[i]; - const interactionData = this.getInteractionDataForPointerId(event.pointerId); + const interactionData = this.getInteractionDataForPointerId(event); const interactionEvent = this.configureInteractionEventForDOMEvent(this.eventData, event, interactionData); @@ -1255,7 +1255,7 @@ this.setCursorMode(null); } - const interactionData = this.getInteractionDataForPointerId(event.pointerId); + const interactionData = this.getInteractionDataForPointerId(event); const interactionEvent = this.configureInteractionEventForDOMEvent(this.eventData, event, interactionData); @@ -1344,7 +1344,7 @@ // Only mouse and pointer can call onPointerOver, so events will always be length 1 const event = events[0]; - const interactionData = this.getInteractionDataForPointerId(event.pointerId); + const interactionData = this.getInteractionDataForPointerId(event); const interactionEvent = this.configureInteractionEventForDOMEvent(this.eventData, event, interactionData); @@ -1366,12 +1366,14 @@ * Get InteractionData for a given pointerId. Store that data as well * * @private - * @param {number} pointerId - Identifier from a pointer event + * @param {PointerEvent} event - Normalized pointer event, output from normalizeToPointerData * @return {InteractionData} - Interaction data for the given pointer identifier */ - getInteractionDataForPointerId(pointerId) + getInteractionDataForPointerId(event) { - if (pointerId === MOUSE_POINTER_ID) + const pointerId = event.pointerId; + + if (pointerId === MOUSE_POINTER_ID || event.pointerType === 'mouse') { return this.mouse; } diff --git a/package.json b/package.json index c04499c..a39a3a1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pixi.js", - "version": "4.4.0", + "version": "4.4.1", "description": "Pixi.js is a fast lightweight 2D library that works across all devices.", "author": "Mat Groves", "contributors": [ diff --git a/src/core/textures/Texture.js b/src/core/textures/Texture.js index 9e1ff87..e70804e 100644 --- a/src/core/textures/Texture.js +++ b/src/core/textures/Texture.js @@ -424,7 +424,7 @@ * @return {PIXI.Texture} Output texture */ static fromLoader(source, imageUrl, name) - { + { const baseTexture = new BaseTexture(source, undefined, getResolutionOfUrl(imageUrl)); const texture = new Texture(baseTexture); diff --git a/src/interaction/InteractionManager.js b/src/interaction/InteractionManager.js index 8baf13a..67e09f6 100644 --- a/src/interaction/InteractionManager.js +++ b/src/interaction/InteractionManager.js @@ -914,7 +914,7 @@ { const event = events[i]; - const interactionData = this.getInteractionDataForPointerId(event.pointerId); + const interactionData = this.getInteractionDataForPointerId(event); const interactionEvent = this.configureInteractionEventForDOMEvent(this.eventData, event, interactionData); @@ -998,7 +998,7 @@ { const event = events[i]; - const interactionData = this.getInteractionDataForPointerId(event.pointerId); + const interactionData = this.getInteractionDataForPointerId(event); const interactionEvent = this.configureInteractionEventForDOMEvent(this.eventData, event, interactionData); @@ -1098,7 +1098,7 @@ const test = isRightButton ? flags.RIGHT_DOWN : flags.LEFT_DOWN; - const isDown = trackingData !== undefined && (trackingData.flags | test); + const isDown = trackingData !== undefined && (trackingData.flags & test); if (hit) { @@ -1180,7 +1180,7 @@ { const event = events[i]; - const interactionData = this.getInteractionDataForPointerId(event.pointerId); + const interactionData = this.getInteractionDataForPointerId(event); const interactionEvent = this.configureInteractionEventForDOMEvent(this.eventData, event, interactionData); @@ -1255,7 +1255,7 @@ this.setCursorMode(null); } - const interactionData = this.getInteractionDataForPointerId(event.pointerId); + const interactionData = this.getInteractionDataForPointerId(event); const interactionEvent = this.configureInteractionEventForDOMEvent(this.eventData, event, interactionData); @@ -1344,7 +1344,7 @@ // Only mouse and pointer can call onPointerOver, so events will always be length 1 const event = events[0]; - const interactionData = this.getInteractionDataForPointerId(event.pointerId); + const interactionData = this.getInteractionDataForPointerId(event); const interactionEvent = this.configureInteractionEventForDOMEvent(this.eventData, event, interactionData); @@ -1366,12 +1366,14 @@ * Get InteractionData for a given pointerId. Store that data as well * * @private - * @param {number} pointerId - Identifier from a pointer event + * @param {PointerEvent} event - Normalized pointer event, output from normalizeToPointerData * @return {InteractionData} - Interaction data for the given pointer identifier */ - getInteractionDataForPointerId(pointerId) + getInteractionDataForPointerId(event) { - if (pointerId === MOUSE_POINTER_ID) + const pointerId = event.pointerId; + + if (pointerId === MOUSE_POINTER_ID || event.pointerType === 'mouse') { return this.mouse; } diff --git a/test/.eslintrc.json b/test/.eslintrc.json index e03220d..ac12110 100644 --- a/test/.eslintrc.json +++ b/test/.eslintrc.json @@ -12,7 +12,8 @@ "sinon": false, "expect": false, "assert": false, - "PIXI": false + "PIXI": false, + "PointerEvent": true }, "rules": { "func-names": 0, diff --git a/package.json b/package.json index c04499c..a39a3a1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pixi.js", - "version": "4.4.0", + "version": "4.4.1", "description": "Pixi.js is a fast lightweight 2D library that works across all devices.", "author": "Mat Groves", "contributors": [ diff --git a/src/core/textures/Texture.js b/src/core/textures/Texture.js index 9e1ff87..e70804e 100644 --- a/src/core/textures/Texture.js +++ b/src/core/textures/Texture.js @@ -424,7 +424,7 @@ * @return {PIXI.Texture} Output texture */ static fromLoader(source, imageUrl, name) - { + { const baseTexture = new BaseTexture(source, undefined, getResolutionOfUrl(imageUrl)); const texture = new Texture(baseTexture); diff --git a/src/interaction/InteractionManager.js b/src/interaction/InteractionManager.js index 8baf13a..67e09f6 100644 --- a/src/interaction/InteractionManager.js +++ b/src/interaction/InteractionManager.js @@ -914,7 +914,7 @@ { const event = events[i]; - const interactionData = this.getInteractionDataForPointerId(event.pointerId); + const interactionData = this.getInteractionDataForPointerId(event); const interactionEvent = this.configureInteractionEventForDOMEvent(this.eventData, event, interactionData); @@ -998,7 +998,7 @@ { const event = events[i]; - const interactionData = this.getInteractionDataForPointerId(event.pointerId); + const interactionData = this.getInteractionDataForPointerId(event); const interactionEvent = this.configureInteractionEventForDOMEvent(this.eventData, event, interactionData); @@ -1098,7 +1098,7 @@ const test = isRightButton ? flags.RIGHT_DOWN : flags.LEFT_DOWN; - const isDown = trackingData !== undefined && (trackingData.flags | test); + const isDown = trackingData !== undefined && (trackingData.flags & test); if (hit) { @@ -1180,7 +1180,7 @@ { const event = events[i]; - const interactionData = this.getInteractionDataForPointerId(event.pointerId); + const interactionData = this.getInteractionDataForPointerId(event); const interactionEvent = this.configureInteractionEventForDOMEvent(this.eventData, event, interactionData); @@ -1255,7 +1255,7 @@ this.setCursorMode(null); } - const interactionData = this.getInteractionDataForPointerId(event.pointerId); + const interactionData = this.getInteractionDataForPointerId(event); const interactionEvent = this.configureInteractionEventForDOMEvent(this.eventData, event, interactionData); @@ -1344,7 +1344,7 @@ // Only mouse and pointer can call onPointerOver, so events will always be length 1 const event = events[0]; - const interactionData = this.getInteractionDataForPointerId(event.pointerId); + const interactionData = this.getInteractionDataForPointerId(event); const interactionEvent = this.configureInteractionEventForDOMEvent(this.eventData, event, interactionData); @@ -1366,12 +1366,14 @@ * Get InteractionData for a given pointerId. Store that data as well * * @private - * @param {number} pointerId - Identifier from a pointer event + * @param {PointerEvent} event - Normalized pointer event, output from normalizeToPointerData * @return {InteractionData} - Interaction data for the given pointer identifier */ - getInteractionDataForPointerId(pointerId) + getInteractionDataForPointerId(event) { - if (pointerId === MOUSE_POINTER_ID) + const pointerId = event.pointerId; + + if (pointerId === MOUSE_POINTER_ID || event.pointerType === 'mouse') { return this.mouse; } diff --git a/test/.eslintrc.json b/test/.eslintrc.json index e03220d..ac12110 100644 --- a/test/.eslintrc.json +++ b/test/.eslintrc.json @@ -12,7 +12,8 @@ "sinon": false, "expect": false, "assert": false, - "PIXI": false + "PIXI": false, + "PointerEvent": true }, "rules": { "func-names": 0, diff --git a/test/interaction/InteractionManager.js b/test/interaction/InteractionManager.js index 0e7e707..dc70ab5 100644 --- a/test/interaction/InteractionManager.js +++ b/test/interaction/InteractionManager.js @@ -4,6 +4,16 @@ describe('PIXI.interaction.InteractionManager', function () { + afterEach(function () + { + // if we made a MockPointer for the test, clean it up + if (this.pointer) + { + this.pointer.cleanUp(); + this.pointer = null; + } + }); + describe('event basics', function () { it('should call mousedown handler', function () @@ -11,7 +21,7 @@ const stage = new PIXI.Container(); const graphics = new PIXI.Graphics(); const eventSpy = sinon.spy(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); stage.addChild(graphics); graphics.beginFill(0xFFFFFF); @@ -29,7 +39,7 @@ const stage = new PIXI.Container(); const graphics = new PIXI.Graphics(); const eventSpy = sinon.spy(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); stage.addChild(graphics); graphics.beginFill(0xFFFFFF); @@ -47,7 +57,7 @@ const stage = new PIXI.Container(); const graphics = new PIXI.Graphics(); const eventSpy = sinon.spy(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); stage.addChild(graphics); graphics.beginFill(0xFFFFFF); @@ -66,7 +76,7 @@ const stage = new PIXI.Container(); const graphics = new PIXI.Graphics(); const eventSpy = sinon.spy(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); stage.addChild(graphics); graphics.beginFill(0xFFFFFF); @@ -84,7 +94,7 @@ const stage = new PIXI.Container(); const graphics = new PIXI.Graphics(); const eventSpy = sinon.spy(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); stage.addChild(graphics); graphics.beginFill(0xFFFFFF); @@ -286,7 +296,7 @@ const stage = new PIXI.Container(); const graphics = new PIXI.Graphics(); const clickSpy = sinon.spy(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); stage.addChild(graphics); graphics.beginFill(0xFFFFFF); @@ -304,7 +314,7 @@ const stage = new PIXI.Container(); const graphics = new PIXI.Graphics(); const clickSpy = sinon.spy(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); stage.addChild(graphics); graphics.beginFill(0xFFFFFF); @@ -316,6 +326,24 @@ expect(clickSpy).to.not.have.been.called; }); + + it('should not call handler when mousedown not received', function () + { + const stage = new PIXI.Container(); + const graphics = new PIXI.Graphics(); + const clickSpy = sinon.spy(); + const pointer = new MockPointer(stage); + + stage.addChild(graphics); + graphics.beginFill(0xFFFFFF); + graphics.drawRect(0, 0, 50, 50); + graphics.interactive = true; + graphics.on('click', clickSpy); + + pointer.mouseup(10, 10); + + expect(clickSpy).to.not.have.been.called; + }); }); describe('onTap', function () @@ -325,7 +353,7 @@ const stage = new PIXI.Container(); const graphics = new PIXI.Graphics(); const clickSpy = sinon.spy(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); stage.addChild(graphics); graphics.beginFill(0xFFFFFF); @@ -343,7 +371,7 @@ const stage = new PIXI.Container(); const graphics = new PIXI.Graphics(); const clickSpy = sinon.spy(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); stage.addChild(graphics); graphics.beginFill(0xFFFFFF); @@ -396,7 +424,7 @@ it('should callback front child when clicking front child', function () { const stage = new PIXI.Container(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); const scene = getScene('click'); scene.behindChild.interactive = true; @@ -414,7 +442,7 @@ it('should callback front child when clicking overlap', function () { const stage = new PIXI.Container(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); const scene = getScene('click'); scene.behindChild.interactive = true; @@ -432,7 +460,7 @@ it('should callback behind child when clicking behind child', function () { const stage = new PIXI.Container(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); const scene = getScene('click'); scene.behindChild.interactive = true; @@ -453,7 +481,7 @@ it('should not callback when clicking front child', function () { const stage = new PIXI.Container(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); const scene = getScene('click'); scene.behindChild.interactive = true; @@ -470,7 +498,7 @@ it('should callback behind child when clicking overlap', function () { const stage = new PIXI.Container(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); const scene = getScene('click'); scene.behindChild.interactive = true; @@ -487,7 +515,7 @@ it('should callback behind child when clicking behind child', function () { const stage = new PIXI.Container(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); const scene = getScene('click'); scene.behindChild.interactive = true; @@ -507,7 +535,7 @@ it('should callback front child when clicking front child', function () { const stage = new PIXI.Container(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); const scene = getScene('click'); scene.behindChild.x = 25; @@ -524,7 +552,7 @@ it('should callback front child when clicking overlap', function () { const stage = new PIXI.Container(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); const scene = getScene('click'); scene.behindChild.x = 25; @@ -541,7 +569,7 @@ it('should not callback when clicking behind child', function () { const stage = new PIXI.Container(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); const scene = getScene('click'); scene.behindChild.x = 25; @@ -564,7 +592,7 @@ it('should callback parent and front child when clicking front child', function () { const stage = new PIXI.Container(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); const scene = getScene('click'); scene.behindChild.interactive = true; @@ -583,7 +611,7 @@ it('should callback parent and front child when clicking overlap', function () { const stage = new PIXI.Container(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); const scene = getScene('click'); scene.behindChild.interactive = true; @@ -602,7 +630,7 @@ it('should callback parent and behind child when clicking behind child', function () { const stage = new PIXI.Container(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); const scene = getScene('click'); scene.behindChild.interactive = true; @@ -624,7 +652,7 @@ it('should callback parent when clicking front child', function () { const stage = new PIXI.Container(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); const scene = getScene('click'); scene.behindChild.interactive = true; @@ -642,7 +670,7 @@ it('should callback parent and behind child when clicking overlap', function () { const stage = new PIXI.Container(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); const scene = getScene('click'); scene.behindChild.interactive = true; @@ -660,7 +688,7 @@ it('should callback parent and behind child when clicking behind child', function () { const stage = new PIXI.Container(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); const scene = getScene('click'); scene.behindChild.interactive = true; @@ -681,7 +709,7 @@ it('should callback parent and front child when clicking front child', function () { const stage = new PIXI.Container(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); const scene = getScene('click'); scene.behindChild.x = 25; @@ -699,7 +727,7 @@ it('should callback parent and front child when clicking overlap', function () { const stage = new PIXI.Container(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); const scene = getScene('click'); scene.behindChild.x = 25; @@ -717,7 +745,7 @@ it('should callback parent when clicking behind child', function () { const stage = new PIXI.Container(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); const scene = getScene('click'); scene.behindChild.x = 25; @@ -741,7 +769,7 @@ { const stage = new PIXI.Container(); const graphics = new PIXI.Graphics(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); stage.addChild(graphics); graphics.beginFill(0xFFFFFF); @@ -759,7 +787,7 @@ { const stage = new PIXI.Container(); const graphics = new PIXI.Graphics(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); stage.addChild(graphics); graphics.beginFill(0xFFFFFF); @@ -778,7 +806,7 @@ { const stage = new PIXI.Container(); const graphics = new PIXI.Graphics(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); stage.addChild(graphics); graphics.beginFill(0xFFFFFF); @@ -797,7 +825,7 @@ { const stage = new PIXI.Container(); const graphics = new PIXI.Graphics(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); stage.addChild(graphics); graphics.beginFill(0xFFFFFF); @@ -818,7 +846,7 @@ const graphics = new PIXI.Graphics(); const overSpy = sinon.spy(); const defaultSpy = sinon.spy(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); stage.addChild(graphics); graphics.beginFill(0xFFFFFF); @@ -840,7 +868,7 @@ const stage = new PIXI.Container(); const graphics = new PIXI.Graphics(); const defaultSpy = sinon.spy(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); stage.addChild(graphics); graphics.beginFill(0xFFFFFF); @@ -859,7 +887,7 @@ { const stage = new PIXI.Container(); const graphics = new PIXI.Graphics(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); stage.addChild(graphics); graphics.beginFill(0xFFFFFF); @@ -881,7 +909,7 @@ { const stage = new PIXI.Container(); const graphics = new PIXI.Graphics(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); stage.addChild(graphics); graphics.beginFill(0xFFFFFF); @@ -932,7 +960,7 @@ it('should stop hitTesting after first hit', function () { const scene = getScene(); - const pointer = new MockPointer(scene.stage); + const pointer = this.pointer = new MockPointer(scene.stage); const frontHitTest = sinon.spy(scene.frontChild, 'containsPoint'); const middleHitTest = sinon.spy(scene.middleChild, 'containsPoint'); const behindHitTest = sinon.spy(scene.behindChild, 'containsPoint'); @@ -954,7 +982,7 @@ it('should stop hitTesting after first hit', function () { const scene = getScene(); - const pointer = new MockPointer(scene.stage); + const pointer = this.pointer = new MockPointer(scene.stage); const frontHitTest = sinon.spy(scene.frontChild, 'containsPoint'); const middleHitTest = sinon.spy(scene.middleChild, 'containsPoint'); const behindHitTest = sinon.spy(scene.behindChild, 'containsPoint'); @@ -971,4 +999,24 @@ }); }); }); + + describe('pointer handling', function () + { + it('pointer event from mouse should use single mouse data', function () + { + const stage = new PIXI.Container(); + const graphics = new PIXI.Graphics(); + const pointer = this.pointer = new MockPointer(stage, 100, 100, true); + + stage.addChild(graphics); + graphics.beginFill(0xFFFFFF); + graphics.drawRect(0, 0, 50, 50); + graphics.interactive = true; + + pointer.mousemove(20, 10, true); + + expect(pointer.interaction.mouse.global.x).to.equal(20); + expect(pointer.interaction.mouse.global.y).to.equal(10); + }); + }); }); diff --git a/package.json b/package.json index c04499c..a39a3a1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pixi.js", - "version": "4.4.0", + "version": "4.4.1", "description": "Pixi.js is a fast lightweight 2D library that works across all devices.", "author": "Mat Groves", "contributors": [ diff --git a/src/core/textures/Texture.js b/src/core/textures/Texture.js index 9e1ff87..e70804e 100644 --- a/src/core/textures/Texture.js +++ b/src/core/textures/Texture.js @@ -424,7 +424,7 @@ * @return {PIXI.Texture} Output texture */ static fromLoader(source, imageUrl, name) - { + { const baseTexture = new BaseTexture(source, undefined, getResolutionOfUrl(imageUrl)); const texture = new Texture(baseTexture); diff --git a/src/interaction/InteractionManager.js b/src/interaction/InteractionManager.js index 8baf13a..67e09f6 100644 --- a/src/interaction/InteractionManager.js +++ b/src/interaction/InteractionManager.js @@ -914,7 +914,7 @@ { const event = events[i]; - const interactionData = this.getInteractionDataForPointerId(event.pointerId); + const interactionData = this.getInteractionDataForPointerId(event); const interactionEvent = this.configureInteractionEventForDOMEvent(this.eventData, event, interactionData); @@ -998,7 +998,7 @@ { const event = events[i]; - const interactionData = this.getInteractionDataForPointerId(event.pointerId); + const interactionData = this.getInteractionDataForPointerId(event); const interactionEvent = this.configureInteractionEventForDOMEvent(this.eventData, event, interactionData); @@ -1098,7 +1098,7 @@ const test = isRightButton ? flags.RIGHT_DOWN : flags.LEFT_DOWN; - const isDown = trackingData !== undefined && (trackingData.flags | test); + const isDown = trackingData !== undefined && (trackingData.flags & test); if (hit) { @@ -1180,7 +1180,7 @@ { const event = events[i]; - const interactionData = this.getInteractionDataForPointerId(event.pointerId); + const interactionData = this.getInteractionDataForPointerId(event); const interactionEvent = this.configureInteractionEventForDOMEvent(this.eventData, event, interactionData); @@ -1255,7 +1255,7 @@ this.setCursorMode(null); } - const interactionData = this.getInteractionDataForPointerId(event.pointerId); + const interactionData = this.getInteractionDataForPointerId(event); const interactionEvent = this.configureInteractionEventForDOMEvent(this.eventData, event, interactionData); @@ -1344,7 +1344,7 @@ // Only mouse and pointer can call onPointerOver, so events will always be length 1 const event = events[0]; - const interactionData = this.getInteractionDataForPointerId(event.pointerId); + const interactionData = this.getInteractionDataForPointerId(event); const interactionEvent = this.configureInteractionEventForDOMEvent(this.eventData, event, interactionData); @@ -1366,12 +1366,14 @@ * Get InteractionData for a given pointerId. Store that data as well * * @private - * @param {number} pointerId - Identifier from a pointer event + * @param {PointerEvent} event - Normalized pointer event, output from normalizeToPointerData * @return {InteractionData} - Interaction data for the given pointer identifier */ - getInteractionDataForPointerId(pointerId) + getInteractionDataForPointerId(event) { - if (pointerId === MOUSE_POINTER_ID) + const pointerId = event.pointerId; + + if (pointerId === MOUSE_POINTER_ID || event.pointerType === 'mouse') { return this.mouse; } diff --git a/test/.eslintrc.json b/test/.eslintrc.json index e03220d..ac12110 100644 --- a/test/.eslintrc.json +++ b/test/.eslintrc.json @@ -12,7 +12,8 @@ "sinon": false, "expect": false, "assert": false, - "PIXI": false + "PIXI": false, + "PointerEvent": true }, "rules": { "func-names": 0, diff --git a/test/interaction/InteractionManager.js b/test/interaction/InteractionManager.js index 0e7e707..dc70ab5 100644 --- a/test/interaction/InteractionManager.js +++ b/test/interaction/InteractionManager.js @@ -4,6 +4,16 @@ describe('PIXI.interaction.InteractionManager', function () { + afterEach(function () + { + // if we made a MockPointer for the test, clean it up + if (this.pointer) + { + this.pointer.cleanUp(); + this.pointer = null; + } + }); + describe('event basics', function () { it('should call mousedown handler', function () @@ -11,7 +21,7 @@ const stage = new PIXI.Container(); const graphics = new PIXI.Graphics(); const eventSpy = sinon.spy(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); stage.addChild(graphics); graphics.beginFill(0xFFFFFF); @@ -29,7 +39,7 @@ const stage = new PIXI.Container(); const graphics = new PIXI.Graphics(); const eventSpy = sinon.spy(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); stage.addChild(graphics); graphics.beginFill(0xFFFFFF); @@ -47,7 +57,7 @@ const stage = new PIXI.Container(); const graphics = new PIXI.Graphics(); const eventSpy = sinon.spy(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); stage.addChild(graphics); graphics.beginFill(0xFFFFFF); @@ -66,7 +76,7 @@ const stage = new PIXI.Container(); const graphics = new PIXI.Graphics(); const eventSpy = sinon.spy(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); stage.addChild(graphics); graphics.beginFill(0xFFFFFF); @@ -84,7 +94,7 @@ const stage = new PIXI.Container(); const graphics = new PIXI.Graphics(); const eventSpy = sinon.spy(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); stage.addChild(graphics); graphics.beginFill(0xFFFFFF); @@ -286,7 +296,7 @@ const stage = new PIXI.Container(); const graphics = new PIXI.Graphics(); const clickSpy = sinon.spy(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); stage.addChild(graphics); graphics.beginFill(0xFFFFFF); @@ -304,7 +314,7 @@ const stage = new PIXI.Container(); const graphics = new PIXI.Graphics(); const clickSpy = sinon.spy(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); stage.addChild(graphics); graphics.beginFill(0xFFFFFF); @@ -316,6 +326,24 @@ expect(clickSpy).to.not.have.been.called; }); + + it('should not call handler when mousedown not received', function () + { + const stage = new PIXI.Container(); + const graphics = new PIXI.Graphics(); + const clickSpy = sinon.spy(); + const pointer = new MockPointer(stage); + + stage.addChild(graphics); + graphics.beginFill(0xFFFFFF); + graphics.drawRect(0, 0, 50, 50); + graphics.interactive = true; + graphics.on('click', clickSpy); + + pointer.mouseup(10, 10); + + expect(clickSpy).to.not.have.been.called; + }); }); describe('onTap', function () @@ -325,7 +353,7 @@ const stage = new PIXI.Container(); const graphics = new PIXI.Graphics(); const clickSpy = sinon.spy(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); stage.addChild(graphics); graphics.beginFill(0xFFFFFF); @@ -343,7 +371,7 @@ const stage = new PIXI.Container(); const graphics = new PIXI.Graphics(); const clickSpy = sinon.spy(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); stage.addChild(graphics); graphics.beginFill(0xFFFFFF); @@ -396,7 +424,7 @@ it('should callback front child when clicking front child', function () { const stage = new PIXI.Container(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); const scene = getScene('click'); scene.behindChild.interactive = true; @@ -414,7 +442,7 @@ it('should callback front child when clicking overlap', function () { const stage = new PIXI.Container(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); const scene = getScene('click'); scene.behindChild.interactive = true; @@ -432,7 +460,7 @@ it('should callback behind child when clicking behind child', function () { const stage = new PIXI.Container(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); const scene = getScene('click'); scene.behindChild.interactive = true; @@ -453,7 +481,7 @@ it('should not callback when clicking front child', function () { const stage = new PIXI.Container(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); const scene = getScene('click'); scene.behindChild.interactive = true; @@ -470,7 +498,7 @@ it('should callback behind child when clicking overlap', function () { const stage = new PIXI.Container(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); const scene = getScene('click'); scene.behindChild.interactive = true; @@ -487,7 +515,7 @@ it('should callback behind child when clicking behind child', function () { const stage = new PIXI.Container(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); const scene = getScene('click'); scene.behindChild.interactive = true; @@ -507,7 +535,7 @@ it('should callback front child when clicking front child', function () { const stage = new PIXI.Container(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); const scene = getScene('click'); scene.behindChild.x = 25; @@ -524,7 +552,7 @@ it('should callback front child when clicking overlap', function () { const stage = new PIXI.Container(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); const scene = getScene('click'); scene.behindChild.x = 25; @@ -541,7 +569,7 @@ it('should not callback when clicking behind child', function () { const stage = new PIXI.Container(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); const scene = getScene('click'); scene.behindChild.x = 25; @@ -564,7 +592,7 @@ it('should callback parent and front child when clicking front child', function () { const stage = new PIXI.Container(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); const scene = getScene('click'); scene.behindChild.interactive = true; @@ -583,7 +611,7 @@ it('should callback parent and front child when clicking overlap', function () { const stage = new PIXI.Container(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); const scene = getScene('click'); scene.behindChild.interactive = true; @@ -602,7 +630,7 @@ it('should callback parent and behind child when clicking behind child', function () { const stage = new PIXI.Container(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); const scene = getScene('click'); scene.behindChild.interactive = true; @@ -624,7 +652,7 @@ it('should callback parent when clicking front child', function () { const stage = new PIXI.Container(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); const scene = getScene('click'); scene.behindChild.interactive = true; @@ -642,7 +670,7 @@ it('should callback parent and behind child when clicking overlap', function () { const stage = new PIXI.Container(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); const scene = getScene('click'); scene.behindChild.interactive = true; @@ -660,7 +688,7 @@ it('should callback parent and behind child when clicking behind child', function () { const stage = new PIXI.Container(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); const scene = getScene('click'); scene.behindChild.interactive = true; @@ -681,7 +709,7 @@ it('should callback parent and front child when clicking front child', function () { const stage = new PIXI.Container(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); const scene = getScene('click'); scene.behindChild.x = 25; @@ -699,7 +727,7 @@ it('should callback parent and front child when clicking overlap', function () { const stage = new PIXI.Container(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); const scene = getScene('click'); scene.behindChild.x = 25; @@ -717,7 +745,7 @@ it('should callback parent when clicking behind child', function () { const stage = new PIXI.Container(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); const scene = getScene('click'); scene.behindChild.x = 25; @@ -741,7 +769,7 @@ { const stage = new PIXI.Container(); const graphics = new PIXI.Graphics(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); stage.addChild(graphics); graphics.beginFill(0xFFFFFF); @@ -759,7 +787,7 @@ { const stage = new PIXI.Container(); const graphics = new PIXI.Graphics(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); stage.addChild(graphics); graphics.beginFill(0xFFFFFF); @@ -778,7 +806,7 @@ { const stage = new PIXI.Container(); const graphics = new PIXI.Graphics(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); stage.addChild(graphics); graphics.beginFill(0xFFFFFF); @@ -797,7 +825,7 @@ { const stage = new PIXI.Container(); const graphics = new PIXI.Graphics(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); stage.addChild(graphics); graphics.beginFill(0xFFFFFF); @@ -818,7 +846,7 @@ const graphics = new PIXI.Graphics(); const overSpy = sinon.spy(); const defaultSpy = sinon.spy(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); stage.addChild(graphics); graphics.beginFill(0xFFFFFF); @@ -840,7 +868,7 @@ const stage = new PIXI.Container(); const graphics = new PIXI.Graphics(); const defaultSpy = sinon.spy(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); stage.addChild(graphics); graphics.beginFill(0xFFFFFF); @@ -859,7 +887,7 @@ { const stage = new PIXI.Container(); const graphics = new PIXI.Graphics(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); stage.addChild(graphics); graphics.beginFill(0xFFFFFF); @@ -881,7 +909,7 @@ { const stage = new PIXI.Container(); const graphics = new PIXI.Graphics(); - const pointer = new MockPointer(stage); + const pointer = this.pointer = new MockPointer(stage); stage.addChild(graphics); graphics.beginFill(0xFFFFFF); @@ -932,7 +960,7 @@ it('should stop hitTesting after first hit', function () { const scene = getScene(); - const pointer = new MockPointer(scene.stage); + const pointer = this.pointer = new MockPointer(scene.stage); const frontHitTest = sinon.spy(scene.frontChild, 'containsPoint'); const middleHitTest = sinon.spy(scene.middleChild, 'containsPoint'); const behindHitTest = sinon.spy(scene.behindChild, 'containsPoint'); @@ -954,7 +982,7 @@ it('should stop hitTesting after first hit', function () { const scene = getScene(); - const pointer = new MockPointer(scene.stage); + const pointer = this.pointer = new MockPointer(scene.stage); const frontHitTest = sinon.spy(scene.frontChild, 'containsPoint'); const middleHitTest = sinon.spy(scene.middleChild, 'containsPoint'); const behindHitTest = sinon.spy(scene.behindChild, 'containsPoint'); @@ -971,4 +999,24 @@ }); }); }); + + describe('pointer handling', function () + { + it('pointer event from mouse should use single mouse data', function () + { + const stage = new PIXI.Container(); + const graphics = new PIXI.Graphics(); + const pointer = this.pointer = new MockPointer(stage, 100, 100, true); + + stage.addChild(graphics); + graphics.beginFill(0xFFFFFF); + graphics.drawRect(0, 0, 50, 50); + graphics.interactive = true; + + pointer.mousemove(20, 10, true); + + expect(pointer.interaction.mouse.global.x).to.equal(20); + expect(pointer.interaction.mouse.global.y).to.equal(10); + }); + }); }); diff --git a/test/interaction/MockPointer.js b/test/interaction/MockPointer.js index bf22490..c843045 100644 --- a/test/interaction/MockPointer.js +++ b/test/interaction/MockPointer.js @@ -11,9 +11,25 @@ * @param {PIXI.Container} stage - The root of the scene tree * @param {number} [width=100] - Width of the renderer * @param {number} [height=100] - Height of the renderer + * @param {boolean} [ensurePointerEvents=false] - If we should make sure that PointerEvents are 'supported' */ - constructor(stage, width, height) + constructor(stage, width, height, ensurePointerEvents) { + // fake PointerEvent existing + if (ensurePointerEvents && !window.PointerEvent) + { + window.PointerEvent = class PointerEvent extends MouseEvent + { + //eslint-disable-next-line + constructor(type, opts) + { + super(type, opts); + this.pointerType = opts.pointerType; + } + }; + this.createdPointerEvent = true; + } + this.stage = stage; this.renderer = new PIXI.CanvasRenderer(width || 100, height || 100); this.renderer.sayHello = () => { /* empty */ }; @@ -21,6 +37,18 @@ } /** + * Cleans up after tests + */ + cleanup() + { + if (this.createdPointerEvent) + { + delete window.PointerEvent; + } + this.renderer.destroy(); + } + + /** * @private * @param {number} x - pointer x position * @param {number} y - pointer y position @@ -45,14 +73,29 @@ /** * @param {number} x - pointer x position * @param {number} y - pointer y position + * @param {boolean} [asPointer] - if it should be a PointerEvent from a mouse */ - mousemove(x, y) + mousemove(x, y, asPointer) { - const mouseEvent = new MouseEvent('mousemove', { - clientX: x, - clientY: y, - preventDefault: sinon.stub(), - }); + let mouseEvent; + + if (asPointer) + { + mouseEvent = new PointerEvent('pointermove', { + pointerType: 'mouse', + clientX: x, + clientY: y, + preventDefault: sinon.stub(), + }); + } + else + { + mouseEvent = new MouseEvent('mousemove', { + clientX: x, + clientY: y, + preventDefault: sinon.stub(), + }); + } this.setPosition(x, y); this.render();