diff --git a/packages/canvas/canvas-display/src/Container.js b/packages/canvas/canvas-display/src/Container.js index 2de0b00..4dc50a9 100644 --- a/packages/canvas/canvas-display/src/Container.js +++ b/packages/canvas/canvas-display/src/Container.js @@ -26,7 +26,7 @@ if (this._mask) { - renderer.mask.pushMask(this._mask); + renderer.maskManager.pushMask(this._mask); } this._renderCanvas(renderer); @@ -37,6 +37,6 @@ if (this._mask) { - renderer.mask.popMask(renderer); + renderer.maskManager.popMask(renderer); } }; diff --git a/packages/canvas/canvas-display/src/Container.js b/packages/canvas/canvas-display/src/Container.js index 2de0b00..4dc50a9 100644 --- a/packages/canvas/canvas-display/src/Container.js +++ b/packages/canvas/canvas-display/src/Container.js @@ -26,7 +26,7 @@ if (this._mask) { - renderer.mask.pushMask(this._mask); + renderer.maskManager.pushMask(this._mask); } this._renderCanvas(renderer); @@ -37,6 +37,6 @@ if (this._mask) { - renderer.mask.popMask(renderer); + renderer.maskManager.popMask(renderer); } }; diff --git a/packages/graphics/test/index.js b/packages/graphics/test/index.js index b8ed40f..6fa2e65 100644 --- a/packages/graphics/test/index.js +++ b/packages/graphics/test/index.js @@ -257,117 +257,8 @@ }); }); - describe('mask', function () + describe('fastRect', function () { - // disabled as canvas renderer is not working on next branch yet - /* it.skip('should trigger interaction callback when no mask present', function () - { - const stage = new Container(); - const pointer = new MockPointer(stage); - const graphics = new Graphics(); - const mask = new Graphics(); - const spy = sinon.spy(); - - graphics.interactive = true; - graphics.beginFill(0xFF0000); - graphics.drawRect(0, 0, 50, 50); - graphics.on('click', spy); - stage.addChild(graphics); - mask.beginFill(); - mask.drawRect(0, 0, 50, 50); - graphics.mask = mask; - - pointer.click(10, 10); - - expect(spy).to.have.been.calledOnce; - }); - - it.skip('should trigger interaction callback when mask uses beginFill', function () - { - const stage = new Container(); - const pointer = new MockPointer(stage); - const graphics = new Graphics(); - const mask = new Graphics(); - const spy = sinon.spy(); - - graphics.interactive = true; - graphics.beginFill(0xFF0000); - graphics.drawRect(0, 0, 50, 50); - graphics.on('click', spy); - stage.addChild(graphics); - mask.beginFill(); - mask.drawRect(0, 0, 50, 50); - graphics.mask = mask; - - pointer.click(10, 10); - - expect(spy).to.have.been.calledOnce; - }); - - it.skip('should not trigger interaction callback when mask doesn\'t use beginFill', function () - { - const stage = new Container(); - const pointer = new MockPointer(stage); - const graphics = new Graphics(); - const mask = new Graphics(); - const spy = sinon.spy(); - - graphics.interactive = true; - graphics.beginFill(0xFF0000); - graphics.drawRect(0, 0, 50, 50); - graphics.on('click', spy); - stage.addChild(graphics); - mask.drawRect(0, 0, 50, 50); - graphics.mask = mask; - - pointer.click(10, 10); - - expect(spy).to.have.not.been.called; - }); - - it.skip('should trigger interaction callback when mask doesn\'t use beginFill but hitArea is defined', function () - { - const stage = new Container(); - const pointer = new MockPointer(stage); - const graphics = new Graphics(); - const mask = new Graphics(); - const spy = sinon.spy(); - - graphics.interactive = true; - graphics.beginFill(0xFF0000); - graphics.hitArea = new Rectangle(0, 0, 50, 50); - graphics.drawRect(0, 0, 50, 50); - graphics.on('click', spy); - stage.addChild(graphics); - mask.drawRect(0, 0, 50, 50); - graphics.mask = mask; - - pointer.click(10, 10); - - expect(spy).to.have.been.calledOnce; - }); - - it.skip('should trigger interaction callback when mask is a sprite', function () - { - const stage = new Container(); - const pointer = new MockPointer(stage); - const graphics = new Graphics(); - const mask = new Graphics(); - const spy = sinon.spy(); - - graphics.interactive = true; - graphics.beginFill(0xFF0000); - graphics.drawRect(0, 0, 50, 50); - graphics.on('click', spy); - stage.addChild(graphics); - mask.drawRect(0, 0, 50, 50); - graphics.mask = new Sprite(mask.generateCanvasTexture()); - - pointer.click(10, 10); - - expect(spy).to.have.been.calledOnce; - });*/ - it('should calculate tint, alpha and blendMode of fastRect correctly', withGL(function () { const renderer = new Renderer(200, 200, {}); diff --git a/packages/canvas/canvas-display/src/Container.js b/packages/canvas/canvas-display/src/Container.js index 2de0b00..4dc50a9 100644 --- a/packages/canvas/canvas-display/src/Container.js +++ b/packages/canvas/canvas-display/src/Container.js @@ -26,7 +26,7 @@ if (this._mask) { - renderer.mask.pushMask(this._mask); + renderer.maskManager.pushMask(this._mask); } this._renderCanvas(renderer); @@ -37,6 +37,6 @@ if (this._mask) { - renderer.mask.popMask(renderer); + renderer.maskManager.popMask(renderer); } }; diff --git a/packages/graphics/test/index.js b/packages/graphics/test/index.js index b8ed40f..6fa2e65 100644 --- a/packages/graphics/test/index.js +++ b/packages/graphics/test/index.js @@ -257,117 +257,8 @@ }); }); - describe('mask', function () + describe('fastRect', function () { - // disabled as canvas renderer is not working on next branch yet - /* it.skip('should trigger interaction callback when no mask present', function () - { - const stage = new Container(); - const pointer = new MockPointer(stage); - const graphics = new Graphics(); - const mask = new Graphics(); - const spy = sinon.spy(); - - graphics.interactive = true; - graphics.beginFill(0xFF0000); - graphics.drawRect(0, 0, 50, 50); - graphics.on('click', spy); - stage.addChild(graphics); - mask.beginFill(); - mask.drawRect(0, 0, 50, 50); - graphics.mask = mask; - - pointer.click(10, 10); - - expect(spy).to.have.been.calledOnce; - }); - - it.skip('should trigger interaction callback when mask uses beginFill', function () - { - const stage = new Container(); - const pointer = new MockPointer(stage); - const graphics = new Graphics(); - const mask = new Graphics(); - const spy = sinon.spy(); - - graphics.interactive = true; - graphics.beginFill(0xFF0000); - graphics.drawRect(0, 0, 50, 50); - graphics.on('click', spy); - stage.addChild(graphics); - mask.beginFill(); - mask.drawRect(0, 0, 50, 50); - graphics.mask = mask; - - pointer.click(10, 10); - - expect(spy).to.have.been.calledOnce; - }); - - it.skip('should not trigger interaction callback when mask doesn\'t use beginFill', function () - { - const stage = new Container(); - const pointer = new MockPointer(stage); - const graphics = new Graphics(); - const mask = new Graphics(); - const spy = sinon.spy(); - - graphics.interactive = true; - graphics.beginFill(0xFF0000); - graphics.drawRect(0, 0, 50, 50); - graphics.on('click', spy); - stage.addChild(graphics); - mask.drawRect(0, 0, 50, 50); - graphics.mask = mask; - - pointer.click(10, 10); - - expect(spy).to.have.not.been.called; - }); - - it.skip('should trigger interaction callback when mask doesn\'t use beginFill but hitArea is defined', function () - { - const stage = new Container(); - const pointer = new MockPointer(stage); - const graphics = new Graphics(); - const mask = new Graphics(); - const spy = sinon.spy(); - - graphics.interactive = true; - graphics.beginFill(0xFF0000); - graphics.hitArea = new Rectangle(0, 0, 50, 50); - graphics.drawRect(0, 0, 50, 50); - graphics.on('click', spy); - stage.addChild(graphics); - mask.drawRect(0, 0, 50, 50); - graphics.mask = mask; - - pointer.click(10, 10); - - expect(spy).to.have.been.calledOnce; - }); - - it.skip('should trigger interaction callback when mask is a sprite', function () - { - const stage = new Container(); - const pointer = new MockPointer(stage); - const graphics = new Graphics(); - const mask = new Graphics(); - const spy = sinon.spy(); - - graphics.interactive = true; - graphics.beginFill(0xFF0000); - graphics.drawRect(0, 0, 50, 50); - graphics.on('click', spy); - stage.addChild(graphics); - mask.drawRect(0, 0, 50, 50); - graphics.mask = new Sprite(mask.generateCanvasTexture()); - - pointer.click(10, 10); - - expect(spy).to.have.been.calledOnce; - });*/ - it('should calculate tint, alpha and blendMode of fastRect correctly', withGL(function () { const renderer = new Renderer(200, 200, {}); diff --git a/packages/interaction/package.json b/packages/interaction/package.json index 8bc5bfa..035f80a 100644 --- a/packages/interaction/package.json +++ b/packages/interaction/package.json @@ -37,6 +37,7 @@ "@pixi/canvas-display": "^5.0.0-alpha", "@pixi/canvas-graphics": "^5.0.0-alpha", "@pixi/canvas-sprite": "^5.0.0-alpha", + "@pixi/sprite": "^5.0.0-alpha", "@pixi/graphics": "^5.0.0-alpha", "floss": "^2.1.3" } diff --git a/packages/canvas/canvas-display/src/Container.js b/packages/canvas/canvas-display/src/Container.js index 2de0b00..4dc50a9 100644 --- a/packages/canvas/canvas-display/src/Container.js +++ b/packages/canvas/canvas-display/src/Container.js @@ -26,7 +26,7 @@ if (this._mask) { - renderer.mask.pushMask(this._mask); + renderer.maskManager.pushMask(this._mask); } this._renderCanvas(renderer); @@ -37,6 +37,6 @@ if (this._mask) { - renderer.mask.popMask(renderer); + renderer.maskManager.popMask(renderer); } }; diff --git a/packages/graphics/test/index.js b/packages/graphics/test/index.js index b8ed40f..6fa2e65 100644 --- a/packages/graphics/test/index.js +++ b/packages/graphics/test/index.js @@ -257,117 +257,8 @@ }); }); - describe('mask', function () + describe('fastRect', function () { - // disabled as canvas renderer is not working on next branch yet - /* it.skip('should trigger interaction callback when no mask present', function () - { - const stage = new Container(); - const pointer = new MockPointer(stage); - const graphics = new Graphics(); - const mask = new Graphics(); - const spy = sinon.spy(); - - graphics.interactive = true; - graphics.beginFill(0xFF0000); - graphics.drawRect(0, 0, 50, 50); - graphics.on('click', spy); - stage.addChild(graphics); - mask.beginFill(); - mask.drawRect(0, 0, 50, 50); - graphics.mask = mask; - - pointer.click(10, 10); - - expect(spy).to.have.been.calledOnce; - }); - - it.skip('should trigger interaction callback when mask uses beginFill', function () - { - const stage = new Container(); - const pointer = new MockPointer(stage); - const graphics = new Graphics(); - const mask = new Graphics(); - const spy = sinon.spy(); - - graphics.interactive = true; - graphics.beginFill(0xFF0000); - graphics.drawRect(0, 0, 50, 50); - graphics.on('click', spy); - stage.addChild(graphics); - mask.beginFill(); - mask.drawRect(0, 0, 50, 50); - graphics.mask = mask; - - pointer.click(10, 10); - - expect(spy).to.have.been.calledOnce; - }); - - it.skip('should not trigger interaction callback when mask doesn\'t use beginFill', function () - { - const stage = new Container(); - const pointer = new MockPointer(stage); - const graphics = new Graphics(); - const mask = new Graphics(); - const spy = sinon.spy(); - - graphics.interactive = true; - graphics.beginFill(0xFF0000); - graphics.drawRect(0, 0, 50, 50); - graphics.on('click', spy); - stage.addChild(graphics); - mask.drawRect(0, 0, 50, 50); - graphics.mask = mask; - - pointer.click(10, 10); - - expect(spy).to.have.not.been.called; - }); - - it.skip('should trigger interaction callback when mask doesn\'t use beginFill but hitArea is defined', function () - { - const stage = new Container(); - const pointer = new MockPointer(stage); - const graphics = new Graphics(); - const mask = new Graphics(); - const spy = sinon.spy(); - - graphics.interactive = true; - graphics.beginFill(0xFF0000); - graphics.hitArea = new Rectangle(0, 0, 50, 50); - graphics.drawRect(0, 0, 50, 50); - graphics.on('click', spy); - stage.addChild(graphics); - mask.drawRect(0, 0, 50, 50); - graphics.mask = mask; - - pointer.click(10, 10); - - expect(spy).to.have.been.calledOnce; - }); - - it.skip('should trigger interaction callback when mask is a sprite', function () - { - const stage = new Container(); - const pointer = new MockPointer(stage); - const graphics = new Graphics(); - const mask = new Graphics(); - const spy = sinon.spy(); - - graphics.interactive = true; - graphics.beginFill(0xFF0000); - graphics.drawRect(0, 0, 50, 50); - graphics.on('click', spy); - stage.addChild(graphics); - mask.drawRect(0, 0, 50, 50); - graphics.mask = new Sprite(mask.generateCanvasTexture()); - - pointer.click(10, 10); - - expect(spy).to.have.been.calledOnce; - });*/ - it('should calculate tint, alpha and blendMode of fastRect correctly', withGL(function () { const renderer = new Renderer(200, 200, {}); diff --git a/packages/interaction/package.json b/packages/interaction/package.json index 8bc5bfa..035f80a 100644 --- a/packages/interaction/package.json +++ b/packages/interaction/package.json @@ -37,6 +37,7 @@ "@pixi/canvas-display": "^5.0.0-alpha", "@pixi/canvas-graphics": "^5.0.0-alpha", "@pixi/canvas-sprite": "^5.0.0-alpha", + "@pixi/sprite": "^5.0.0-alpha", "@pixi/graphics": "^5.0.0-alpha", "floss": "^2.1.3" } diff --git a/packages/interaction/src/InteractionManager.js b/packages/interaction/src/InteractionManager.js index 0500532..a5c6ac2 100644 --- a/packages/interaction/src/InteractionManager.js +++ b/packages/interaction/src/InteractionManager.js @@ -1017,24 +1017,45 @@ let hit = false; let interactiveParent = interactive; - // if the displayobject has a hitArea, then it does not need to hitTest children. + // Flag here can set to false if the event is outside the parents hitArea or mask + let hitTestChildren = true; + + // If there is a hitArea, no need to test against anything else if the pointer is not within the hitArea + // There is also no longer a need to hitTest children. if (displayObject.hitArea) { + if (hitTest) + { + displayObject.worldTransform.applyInverse(point, this._tempPoint); + if (!displayObject.hitArea.contains(this._tempPoint.x, this._tempPoint.y)) + { + hitTest = false; + hitTestChildren = false; + } + else + { + hit = true; + } + } interactiveParent = false; } - // it has a mask! Then lets hit test that before continuing - else if (hitTest && displayObject._mask) + // If there is a mask, no need to test against anything else if the pointer is not within the mask + else if (displayObject._mask) { - if (!displayObject._mask.containsPoint(point)) + if (hitTest) { - hitTest = false; + if (!displayObject._mask.containsPoint(point)) + { + hitTest = false; + hitTestChildren = false; + } } } // ** FREE TIP **! If an object is not interactive or has no buttons in it // (such as a game scene!) set interactiveChildren to false for that displayObject. // This will allow PixiJS to completely ignore and bypass checking the displayObjects children. - if (displayObject.interactiveChildren && displayObject.children) + if (hitTestChildren && displayObject.interactiveChildren && displayObject.children) { const children = displayObject.children; @@ -1084,15 +1105,8 @@ // looking for an interactive child, just in case we hit one if (hitTest && !interactionEvent.target) { - if (displayObject.hitArea) - { - displayObject.worldTransform.applyInverse(point, this._tempPoint); - if (displayObject.hitArea.contains(this._tempPoint.x, this._tempPoint.y)) - { - hit = true; - } - } - else if (displayObject.containsPoint) + // already tested against hitArea if it is defined + if (!displayObject.hitArea && displayObject.containsPoint) { if (displayObject.containsPoint(point)) { diff --git a/packages/canvas/canvas-display/src/Container.js b/packages/canvas/canvas-display/src/Container.js index 2de0b00..4dc50a9 100644 --- a/packages/canvas/canvas-display/src/Container.js +++ b/packages/canvas/canvas-display/src/Container.js @@ -26,7 +26,7 @@ if (this._mask) { - renderer.mask.pushMask(this._mask); + renderer.maskManager.pushMask(this._mask); } this._renderCanvas(renderer); @@ -37,6 +37,6 @@ if (this._mask) { - renderer.mask.popMask(renderer); + renderer.maskManager.popMask(renderer); } }; diff --git a/packages/graphics/test/index.js b/packages/graphics/test/index.js index b8ed40f..6fa2e65 100644 --- a/packages/graphics/test/index.js +++ b/packages/graphics/test/index.js @@ -257,117 +257,8 @@ }); }); - describe('mask', function () + describe('fastRect', function () { - // disabled as canvas renderer is not working on next branch yet - /* it.skip('should trigger interaction callback when no mask present', function () - { - const stage = new Container(); - const pointer = new MockPointer(stage); - const graphics = new Graphics(); - const mask = new Graphics(); - const spy = sinon.spy(); - - graphics.interactive = true; - graphics.beginFill(0xFF0000); - graphics.drawRect(0, 0, 50, 50); - graphics.on('click', spy); - stage.addChild(graphics); - mask.beginFill(); - mask.drawRect(0, 0, 50, 50); - graphics.mask = mask; - - pointer.click(10, 10); - - expect(spy).to.have.been.calledOnce; - }); - - it.skip('should trigger interaction callback when mask uses beginFill', function () - { - const stage = new Container(); - const pointer = new MockPointer(stage); - const graphics = new Graphics(); - const mask = new Graphics(); - const spy = sinon.spy(); - - graphics.interactive = true; - graphics.beginFill(0xFF0000); - graphics.drawRect(0, 0, 50, 50); - graphics.on('click', spy); - stage.addChild(graphics); - mask.beginFill(); - mask.drawRect(0, 0, 50, 50); - graphics.mask = mask; - - pointer.click(10, 10); - - expect(spy).to.have.been.calledOnce; - }); - - it.skip('should not trigger interaction callback when mask doesn\'t use beginFill', function () - { - const stage = new Container(); - const pointer = new MockPointer(stage); - const graphics = new Graphics(); - const mask = new Graphics(); - const spy = sinon.spy(); - - graphics.interactive = true; - graphics.beginFill(0xFF0000); - graphics.drawRect(0, 0, 50, 50); - graphics.on('click', spy); - stage.addChild(graphics); - mask.drawRect(0, 0, 50, 50); - graphics.mask = mask; - - pointer.click(10, 10); - - expect(spy).to.have.not.been.called; - }); - - it.skip('should trigger interaction callback when mask doesn\'t use beginFill but hitArea is defined', function () - { - const stage = new Container(); - const pointer = new MockPointer(stage); - const graphics = new Graphics(); - const mask = new Graphics(); - const spy = sinon.spy(); - - graphics.interactive = true; - graphics.beginFill(0xFF0000); - graphics.hitArea = new Rectangle(0, 0, 50, 50); - graphics.drawRect(0, 0, 50, 50); - graphics.on('click', spy); - stage.addChild(graphics); - mask.drawRect(0, 0, 50, 50); - graphics.mask = mask; - - pointer.click(10, 10); - - expect(spy).to.have.been.calledOnce; - }); - - it.skip('should trigger interaction callback when mask is a sprite', function () - { - const stage = new Container(); - const pointer = new MockPointer(stage); - const graphics = new Graphics(); - const mask = new Graphics(); - const spy = sinon.spy(); - - graphics.interactive = true; - graphics.beginFill(0xFF0000); - graphics.drawRect(0, 0, 50, 50); - graphics.on('click', spy); - stage.addChild(graphics); - mask.drawRect(0, 0, 50, 50); - graphics.mask = new Sprite(mask.generateCanvasTexture()); - - pointer.click(10, 10); - - expect(spy).to.have.been.calledOnce; - });*/ - it('should calculate tint, alpha and blendMode of fastRect correctly', withGL(function () { const renderer = new Renderer(200, 200, {}); diff --git a/packages/interaction/package.json b/packages/interaction/package.json index 8bc5bfa..035f80a 100644 --- a/packages/interaction/package.json +++ b/packages/interaction/package.json @@ -37,6 +37,7 @@ "@pixi/canvas-display": "^5.0.0-alpha", "@pixi/canvas-graphics": "^5.0.0-alpha", "@pixi/canvas-sprite": "^5.0.0-alpha", + "@pixi/sprite": "^5.0.0-alpha", "@pixi/graphics": "^5.0.0-alpha", "floss": "^2.1.3" } diff --git a/packages/interaction/src/InteractionManager.js b/packages/interaction/src/InteractionManager.js index 0500532..a5c6ac2 100644 --- a/packages/interaction/src/InteractionManager.js +++ b/packages/interaction/src/InteractionManager.js @@ -1017,24 +1017,45 @@ let hit = false; let interactiveParent = interactive; - // if the displayobject has a hitArea, then it does not need to hitTest children. + // Flag here can set to false if the event is outside the parents hitArea or mask + let hitTestChildren = true; + + // If there is a hitArea, no need to test against anything else if the pointer is not within the hitArea + // There is also no longer a need to hitTest children. if (displayObject.hitArea) { + if (hitTest) + { + displayObject.worldTransform.applyInverse(point, this._tempPoint); + if (!displayObject.hitArea.contains(this._tempPoint.x, this._tempPoint.y)) + { + hitTest = false; + hitTestChildren = false; + } + else + { + hit = true; + } + } interactiveParent = false; } - // it has a mask! Then lets hit test that before continuing - else if (hitTest && displayObject._mask) + // If there is a mask, no need to test against anything else if the pointer is not within the mask + else if (displayObject._mask) { - if (!displayObject._mask.containsPoint(point)) + if (hitTest) { - hitTest = false; + if (!displayObject._mask.containsPoint(point)) + { + hitTest = false; + hitTestChildren = false; + } } } // ** FREE TIP **! If an object is not interactive or has no buttons in it // (such as a game scene!) set interactiveChildren to false for that displayObject. // This will allow PixiJS to completely ignore and bypass checking the displayObjects children. - if (displayObject.interactiveChildren && displayObject.children) + if (hitTestChildren && displayObject.interactiveChildren && displayObject.children) { const children = displayObject.children; @@ -1084,15 +1105,8 @@ // looking for an interactive child, just in case we hit one if (hitTest && !interactionEvent.target) { - if (displayObject.hitArea) - { - displayObject.worldTransform.applyInverse(point, this._tempPoint); - if (displayObject.hitArea.contains(this._tempPoint.x, this._tempPoint.y)) - { - hit = true; - } - } - else if (displayObject.containsPoint) + // already tested against hitArea if it is defined + if (!displayObject.hitArea && displayObject.containsPoint) { if (displayObject.containsPoint(point)) { diff --git a/packages/interaction/test/InteractionManager.js b/packages/interaction/test/InteractionManager.js index 894366d..fd07b09 100644 --- a/packages/interaction/test/InteractionManager.js +++ b/packages/interaction/test/InteractionManager.js @@ -1,12 +1,13 @@ const MockPointer = require('./MockPointer'); const { Container } = require('@pixi/display'); const { Graphics } = require('@pixi/graphics'); -const { Point } = require('@pixi/math'); +const { Point, Rectangle } = require('@pixi/math'); const { mixins } = require('@pixi/utils'); const { CanvasRenderer } = require('@pixi/canvas-renderer'); const { InteractionManager } = require('../'); const { CanvasGraphicsRenderer } = require('@pixi/canvas-graphics'); const { CanvasSpriteRenderer } = require('@pixi/canvas-sprite'); +const { Sprite } = require('@pixi/sprite'); require('@pixi/canvas-display'); @@ -1101,6 +1102,248 @@ }); }); + describe('masks', function () + { + it('should trigger interaction callback when no mask present', function () + { + const stage = new Container(); + const pointer = new MockPointer(stage); + const graphics = new Graphics(); + const mask = new Graphics(); + const spy = sinon.spy(); + + graphics.interactive = true; + graphics.beginFill(0xFF0000); + graphics.drawRect(0, 0, 50, 50); + graphics.on('click', spy); + stage.addChild(graphics); + mask.beginFill(); + mask.drawRect(0, 0, 50, 50); + graphics.mask = mask; + + pointer.click(10, 10); + + expect(spy).to.have.been.calledOnce; + }); + + it('should trigger interaction callback when mask uses beginFill', function () + { + const stage = new Container(); + const pointer = new MockPointer(stage); + const graphics = new Graphics(); + const mask = new Graphics(); + const spy = sinon.spy(); + + graphics.interactive = true; + graphics.beginFill(0xFF0000); + graphics.drawRect(0, 0, 50, 50); + graphics.on('click', spy); + stage.addChild(graphics); + mask.beginFill(); + mask.drawRect(0, 0, 50, 50); + graphics.mask = mask; + + pointer.click(10, 10); + + expect(spy).to.have.been.calledOnce; + }); + + it('should trigger interaction callback on child when inside of parents mask', function () + { + const stage = new Container(); + const parent = new Container(); + const pointer = new MockPointer(stage); + const graphics = new Graphics(); + const mask = new Graphics(); + const spy = sinon.spy(); + + graphics.interactive = true; + graphics.beginFill(0xFF0000); + graphics.drawRect(0, 0, 50, 50); + graphics.on('click', spy); + stage.addChild(parent); + parent.addChild(graphics); + mask.beginFill(); + mask.drawRect(0, 0, 25, 25); + parent.mask = mask; + + pointer.click(10, 10); + + expect(spy).to.have.been.calledOnce; + }); + + it('should not trigger interaction callback on child when outside of parents mask', function () + { + const stage = new Container(); + const parent = new Container(); + const pointer = new MockPointer(stage); + const graphics = new Graphics(); + const mask = new Graphics(); + const spy = sinon.spy(); + + graphics.interactive = true; + graphics.beginFill(0xFF0000); + graphics.drawRect(0, 0, 50, 50); + graphics.on('click', spy); + stage.addChild(parent); + parent.addChild(graphics); + mask.beginFill(); + mask.drawRect(0, 0, 25, 25); + parent.mask = mask; + + pointer.click(30, 30); + + expect(spy).to.have.not.been.calledOnce; + }); + + it('should not trigger interaction callback when mask doesn\'t use beginFill', function () + { + const stage = new Container(); + const pointer = new MockPointer(stage); + const graphics = new Graphics(); + const mask = new Graphics(); + const spy = sinon.spy(); + + graphics.interactive = true; + graphics.beginFill(0xFF0000); + graphics.drawRect(0, 0, 50, 50); + graphics.on('click', spy); + stage.addChild(graphics); + mask.drawRect(0, 0, 50, 50); + graphics.mask = mask; + + pointer.click(10, 10); + + expect(spy).to.have.not.been.called; + }); + + it('should trigger interaction callback when mask doesn\'t use beginFill but hitArea is defined', function () + { + const stage = new Container(); + const pointer = new MockPointer(stage); + const graphics = new Graphics(); + const mask = new Graphics(); + const spy = sinon.spy(); + + graphics.interactive = true; + graphics.beginFill(0xFF0000); + graphics.hitArea = new Rectangle(0, 0, 50, 50); + graphics.drawRect(0, 0, 50, 50); + graphics.on('click', spy); + stage.addChild(graphics); + mask.drawRect(0, 0, 50, 50); + graphics.mask = mask; + + pointer.click(10, 10); + + expect(spy).to.have.been.calledOnce; + }); + + it('should trigger interaction callback when mask is a sprite', function () + { + const stage = new Container(); + const pointer = new MockPointer(stage); + const graphics = new Graphics(); + const mask = new Graphics(); + const spy = sinon.spy(); + + graphics.interactive = true; + graphics.beginFill(0xFF0000); + graphics.drawRect(0, 0, 50, 50); + graphics.on('click', spy); + stage.addChild(graphics); + mask.drawRect(0, 0, 50, 50); + graphics.mask = new Sprite(mask.generateCanvasTexture()); + + pointer.click(10, 10); + + expect(spy).to.have.been.calledOnce; + }); + }); + + describe('hitArea', function () + { + it('should trigger interaction callback when within hitArea', function () + { + const stage = new Container(); + const pointer = new MockPointer(stage); + const graphics = new Graphics(); + const spy = sinon.spy(); + + graphics.interactive = true; + graphics.beginFill(0xFF0000); + graphics.drawRect(0, 0, 50, 50); + graphics.on('click', spy); + stage.addChild(graphics); + graphics.hitArea = new Rectangle(0, 0, 25, 25); + + pointer.click(10, 10); + + expect(spy).to.have.been.calledOnce; + }); + + it('should not trigger interaction callback when not within hitArea', function () + { + const stage = new Container(); + const pointer = new MockPointer(stage); + const graphics = new Graphics(); + const spy = sinon.spy(); + + graphics.interactive = true; + graphics.beginFill(0xFF0000); + graphics.drawRect(0, 0, 50, 50); + graphics.on('click', spy); + stage.addChild(graphics); + graphics.hitArea = new Rectangle(0, 0, 25, 25); + + pointer.click(30, 30); + + expect(spy).to.have.not.been.calledOnce; + }); + + it('should trigger interaction callback on child when inside of parents hitArea', function () + { + const stage = new Container(); + const parent = new Container(); + const pointer = new MockPointer(stage); + const graphics = new Graphics(); + const spy = sinon.spy(); + + graphics.interactive = true; + graphics.beginFill(0xFF0000); + graphics.drawRect(0, 0, 50, 50); + graphics.on('click', spy); + stage.addChild(parent); + parent.addChild(graphics); + parent.hitArea = new Rectangle(0, 0, 25, 25); + + pointer.click(10, 10); + + expect(spy).to.have.been.calledOnce; + }); + + it('should not trigger interaction callback on child when outside of parents hitArea', function () + { + const stage = new Container(); + const parent = new Container(); + const pointer = new MockPointer(stage); + const graphics = new Graphics(); + const spy = sinon.spy(); + + graphics.interactive = true; + graphics.beginFill(0xFF0000); + graphics.drawRect(0, 0, 50, 50); + graphics.on('click', spy); + stage.addChild(parent); + parent.addChild(graphics); + parent.hitArea = new Rectangle(0, 0, 25, 25); + + pointer.click(30, 30); + + expect(spy).to.have.not.been.calledOnce; + }); + }); + describe('cursor changes', function () { it('cursor should be the cursor of interactive item', function ()