diff --git a/src/core/display/Bounds.js b/src/core/display/Bounds.js index 79d7fc5..620c6dd 100644 --- a/src/core/display/Bounds.js +++ b/src/core/display/Bounds.js @@ -211,6 +211,10 @@ this.maxY = maxY; } + /** + * adds other Bounds + * @param bounds {PIXI.Bounds} + */ addBounds(bounds) { const minX = this.minX, minY = this.minY, maxX = this.maxX, maxY = this.maxY; @@ -220,6 +224,48 @@ this.maxX = bounds.maxX > maxX ? bounds.maxX : maxX; this.maxY = bounds.maxY > maxY ? bounds.maxY : maxY; } + + /** + * adds other Bounds, masked with Bounds + * @param bounds {PIXI.Bounds} + * @param mask {PIXI.Bounds} + */ + addBoundsMask(bounds, mask) + { + const _minX = bounds.minX > mask.minX ? bounds.minX : mask.minX; + const _minY = bounds.minY > mask.minY ? bounds.minY : mask.minY; + const _maxX = bounds.maxX < mask.maxX ? bounds.maxX : mask.maxX; + const _maxY = bounds.maxY < mask.maxY ? bounds.maxY : mask.maxY; + if (_minX <= _maxX && _minY <= _maxY) + { + const minX = this.minX, minY = this.minY, maxX = this.maxX, maxY = this.maxY; + this.minX = _minX < minX ? _minX : minX; + this.minY = _minY < minY ? _minY : minY; + this.maxX = _maxX > maxX ? _maxX : maxX; + this.maxY = _maxY > maxY ? _maxY : maxY; + } + } + + /** + * adds other Bounds, masked with Rectangle + * @param bounds {PIXI.Bounds} + * @param area {PIXI.Rectangle} + */ + addBoundsArea(bounds, area) + { + const _minX = bounds.minX > area.x ? bounds.minX : area.x; + const _minY = bounds.minY > area.y ? bounds.minY : area.y; + const _maxX = bounds.maxX < area.x + area.width ? bounds.maxX : (area.x + area.width); + const _maxY = bounds.maxY < area.y + area.height ? bounds.maxY : (area.y + area.height); + if (_minX <= _maxX && _minY <= _maxY) + { + const minX = this.minX, minY = this.minY, maxX = this.maxX, maxY = this.maxY; + this.minX = _minX < minX ? _minX : minX; + this.minY = _minY < minY ? _minY : minY; + this.maxX = _maxX > maxX ? _maxX : maxX; + this.maxY = _maxY > maxY ? _maxY : maxY; + } + } } export default Bounds; diff --git a/src/core/display/Bounds.js b/src/core/display/Bounds.js index 79d7fc5..620c6dd 100644 --- a/src/core/display/Bounds.js +++ b/src/core/display/Bounds.js @@ -211,6 +211,10 @@ this.maxY = maxY; } + /** + * adds other Bounds + * @param bounds {PIXI.Bounds} + */ addBounds(bounds) { const minX = this.minX, minY = this.minY, maxX = this.maxX, maxY = this.maxY; @@ -220,6 +224,48 @@ this.maxX = bounds.maxX > maxX ? bounds.maxX : maxX; this.maxY = bounds.maxY > maxY ? bounds.maxY : maxY; } + + /** + * adds other Bounds, masked with Bounds + * @param bounds {PIXI.Bounds} + * @param mask {PIXI.Bounds} + */ + addBoundsMask(bounds, mask) + { + const _minX = bounds.minX > mask.minX ? bounds.minX : mask.minX; + const _minY = bounds.minY > mask.minY ? bounds.minY : mask.minY; + const _maxX = bounds.maxX < mask.maxX ? bounds.maxX : mask.maxX; + const _maxY = bounds.maxY < mask.maxY ? bounds.maxY : mask.maxY; + if (_minX <= _maxX && _minY <= _maxY) + { + const minX = this.minX, minY = this.minY, maxX = this.maxX, maxY = this.maxY; + this.minX = _minX < minX ? _minX : minX; + this.minY = _minY < minY ? _minY : minY; + this.maxX = _maxX > maxX ? _maxX : maxX; + this.maxY = _maxY > maxY ? _maxY : maxY; + } + } + + /** + * adds other Bounds, masked with Rectangle + * @param bounds {PIXI.Bounds} + * @param area {PIXI.Rectangle} + */ + addBoundsArea(bounds, area) + { + const _minX = bounds.minX > area.x ? bounds.minX : area.x; + const _minY = bounds.minY > area.y ? bounds.minY : area.y; + const _maxX = bounds.maxX < area.x + area.width ? bounds.maxX : (area.x + area.width); + const _maxY = bounds.maxY < area.y + area.height ? bounds.maxY : (area.y + area.height); + if (_minX <= _maxX && _minY <= _maxY) + { + const minX = this.minX, minY = this.minY, maxX = this.maxX, maxY = this.maxY; + this.minX = _minX < minX ? _minX : minX; + this.minY = _minY < minY ? _minY : minY; + this.maxX = _maxX > maxX ? _maxX : maxX; + this.maxY = _maxY > maxY ? _maxY : maxY; + } + } } export default Bounds; diff --git a/src/core/display/Container.js b/src/core/display/Container.js index abad78d..d568571 100644 --- a/src/core/display/Container.js +++ b/src/core/display/Container.js @@ -301,11 +301,6 @@ { this._boundsID++; - if (!this.visible) - { - return; - } - this.transform.updateTransform(this.parent.transform); //TODO: check render flags, how to process stuff here @@ -313,7 +308,11 @@ for (let i = 0, j = this.children.length; i < j; ++i) { - this.children[i].updateTransform(); + var child = this.children[i]; + if (child.visible) + { + child.updateTransform(); + } } } @@ -321,23 +320,33 @@ { this._bounds.clear(); - if(!this.visible) - { - return; - } - this._calculateBounds(); for (let i = 0; i < this.children.length; i++) { const child = this.children[i]; + if (!child.visible || !child.renderable) { + continue; + } + child.calculateBounds(); - this._bounds.addBounds(child._bounds); + //TODO: filter+mask, need to mask both somehow + if (child._mask) + { + child._mask.calculateBounds(); + this._bounds.addBoundsMask(child._bounds, child._mask._bounds); + } else if (child.filterArea) + { + this._bounds.addBoundsArea(child._bounds, child.filterArea); + } else + { + this._bounds.addBounds(child._bounds); + } } - this._boundsID = this._lastBoundsID; + this._lastBoundsID = this._boundsID; } _calculateBounds() diff --git a/src/core/display/Bounds.js b/src/core/display/Bounds.js index 79d7fc5..620c6dd 100644 --- a/src/core/display/Bounds.js +++ b/src/core/display/Bounds.js @@ -211,6 +211,10 @@ this.maxY = maxY; } + /** + * adds other Bounds + * @param bounds {PIXI.Bounds} + */ addBounds(bounds) { const minX = this.minX, minY = this.minY, maxX = this.maxX, maxY = this.maxY; @@ -220,6 +224,48 @@ this.maxX = bounds.maxX > maxX ? bounds.maxX : maxX; this.maxY = bounds.maxY > maxY ? bounds.maxY : maxY; } + + /** + * adds other Bounds, masked with Bounds + * @param bounds {PIXI.Bounds} + * @param mask {PIXI.Bounds} + */ + addBoundsMask(bounds, mask) + { + const _minX = bounds.minX > mask.minX ? bounds.minX : mask.minX; + const _minY = bounds.minY > mask.minY ? bounds.minY : mask.minY; + const _maxX = bounds.maxX < mask.maxX ? bounds.maxX : mask.maxX; + const _maxY = bounds.maxY < mask.maxY ? bounds.maxY : mask.maxY; + if (_minX <= _maxX && _minY <= _maxY) + { + const minX = this.minX, minY = this.minY, maxX = this.maxX, maxY = this.maxY; + this.minX = _minX < minX ? _minX : minX; + this.minY = _minY < minY ? _minY : minY; + this.maxX = _maxX > maxX ? _maxX : maxX; + this.maxY = _maxY > maxY ? _maxY : maxY; + } + } + + /** + * adds other Bounds, masked with Rectangle + * @param bounds {PIXI.Bounds} + * @param area {PIXI.Rectangle} + */ + addBoundsArea(bounds, area) + { + const _minX = bounds.minX > area.x ? bounds.minX : area.x; + const _minY = bounds.minY > area.y ? bounds.minY : area.y; + const _maxX = bounds.maxX < area.x + area.width ? bounds.maxX : (area.x + area.width); + const _maxY = bounds.maxY < area.y + area.height ? bounds.maxY : (area.y + area.height); + if (_minX <= _maxX && _minY <= _maxY) + { + const minX = this.minX, minY = this.minY, maxX = this.maxX, maxY = this.maxY; + this.minX = _minX < minX ? _minX : minX; + this.minY = _minY < minY ? _minY : minY; + this.maxX = _maxX > maxX ? _maxX : maxX; + this.maxY = _maxY > maxY ? _maxY : maxY; + } + } } export default Bounds; diff --git a/src/core/display/Container.js b/src/core/display/Container.js index abad78d..d568571 100644 --- a/src/core/display/Container.js +++ b/src/core/display/Container.js @@ -301,11 +301,6 @@ { this._boundsID++; - if (!this.visible) - { - return; - } - this.transform.updateTransform(this.parent.transform); //TODO: check render flags, how to process stuff here @@ -313,7 +308,11 @@ for (let i = 0, j = this.children.length; i < j; ++i) { - this.children[i].updateTransform(); + var child = this.children[i]; + if (child.visible) + { + child.updateTransform(); + } } } @@ -321,23 +320,33 @@ { this._bounds.clear(); - if(!this.visible) - { - return; - } - this._calculateBounds(); for (let i = 0; i < this.children.length; i++) { const child = this.children[i]; + if (!child.visible || !child.renderable) { + continue; + } + child.calculateBounds(); - this._bounds.addBounds(child._bounds); + //TODO: filter+mask, need to mask both somehow + if (child._mask) + { + child._mask.calculateBounds(); + this._bounds.addBoundsMask(child._bounds, child._mask._bounds); + } else if (child.filterArea) + { + this._bounds.addBoundsArea(child._bounds, child.filterArea); + } else + { + this._bounds.addBounds(child._bounds); + } } - this._boundsID = this._lastBoundsID; + this._lastBoundsID = this._boundsID; } _calculateBounds() diff --git a/src/core/display/DisplayObject.js b/src/core/display/DisplayObject.js index 4c61c4b..3ed56b9 100644 --- a/src/core/display/DisplayObject.js +++ b/src/core/display/DisplayObject.js @@ -28,7 +28,7 @@ //TODO: need to create Transform from factory /** * World transform and local transform of this object. - * This will be reworked in v4.1, please do not use it yet unless you know what are you doing! + * This will become read-only later, please do not assign anything there unless you know what are you doing * * @member {PIXI.TransformBase} */ @@ -45,6 +45,8 @@ * The visibility of the object. If false the object will not be drawn, and * the updateTransform function will not be called. * + * Only affects recursive calls from parent. You can ask for bounds or call updateTransform manually + * * @member {boolean} */ this.visible = true; @@ -53,6 +55,8 @@ * Can this object be rendered, if false the object will not be drawn but the updateTransform * methods will still be called. * + * Only affects recursive calls from parent. You can ask for bounds manually + * * @member {boolean} */ this.renderable = true; diff --git a/src/core/display/Bounds.js b/src/core/display/Bounds.js index 79d7fc5..620c6dd 100644 --- a/src/core/display/Bounds.js +++ b/src/core/display/Bounds.js @@ -211,6 +211,10 @@ this.maxY = maxY; } + /** + * adds other Bounds + * @param bounds {PIXI.Bounds} + */ addBounds(bounds) { const minX = this.minX, minY = this.minY, maxX = this.maxX, maxY = this.maxY; @@ -220,6 +224,48 @@ this.maxX = bounds.maxX > maxX ? bounds.maxX : maxX; this.maxY = bounds.maxY > maxY ? bounds.maxY : maxY; } + + /** + * adds other Bounds, masked with Bounds + * @param bounds {PIXI.Bounds} + * @param mask {PIXI.Bounds} + */ + addBoundsMask(bounds, mask) + { + const _minX = bounds.minX > mask.minX ? bounds.minX : mask.minX; + const _minY = bounds.minY > mask.minY ? bounds.minY : mask.minY; + const _maxX = bounds.maxX < mask.maxX ? bounds.maxX : mask.maxX; + const _maxY = bounds.maxY < mask.maxY ? bounds.maxY : mask.maxY; + if (_minX <= _maxX && _minY <= _maxY) + { + const minX = this.minX, minY = this.minY, maxX = this.maxX, maxY = this.maxY; + this.minX = _minX < minX ? _minX : minX; + this.minY = _minY < minY ? _minY : minY; + this.maxX = _maxX > maxX ? _maxX : maxX; + this.maxY = _maxY > maxY ? _maxY : maxY; + } + } + + /** + * adds other Bounds, masked with Rectangle + * @param bounds {PIXI.Bounds} + * @param area {PIXI.Rectangle} + */ + addBoundsArea(bounds, area) + { + const _minX = bounds.minX > area.x ? bounds.minX : area.x; + const _minY = bounds.minY > area.y ? bounds.minY : area.y; + const _maxX = bounds.maxX < area.x + area.width ? bounds.maxX : (area.x + area.width); + const _maxY = bounds.maxY < area.y + area.height ? bounds.maxY : (area.y + area.height); + if (_minX <= _maxX && _minY <= _maxY) + { + const minX = this.minX, minY = this.minY, maxX = this.maxX, maxY = this.maxY; + this.minX = _minX < minX ? _minX : minX; + this.minY = _minY < minY ? _minY : minY; + this.maxX = _maxX > maxX ? _maxX : maxX; + this.maxY = _maxY > maxY ? _maxY : maxY; + } + } } export default Bounds; diff --git a/src/core/display/Container.js b/src/core/display/Container.js index abad78d..d568571 100644 --- a/src/core/display/Container.js +++ b/src/core/display/Container.js @@ -301,11 +301,6 @@ { this._boundsID++; - if (!this.visible) - { - return; - } - this.transform.updateTransform(this.parent.transform); //TODO: check render flags, how to process stuff here @@ -313,7 +308,11 @@ for (let i = 0, j = this.children.length; i < j; ++i) { - this.children[i].updateTransform(); + var child = this.children[i]; + if (child.visible) + { + child.updateTransform(); + } } } @@ -321,23 +320,33 @@ { this._bounds.clear(); - if(!this.visible) - { - return; - } - this._calculateBounds(); for (let i = 0; i < this.children.length; i++) { const child = this.children[i]; + if (!child.visible || !child.renderable) { + continue; + } + child.calculateBounds(); - this._bounds.addBounds(child._bounds); + //TODO: filter+mask, need to mask both somehow + if (child._mask) + { + child._mask.calculateBounds(); + this._bounds.addBoundsMask(child._bounds, child._mask._bounds); + } else if (child.filterArea) + { + this._bounds.addBoundsArea(child._bounds, child.filterArea); + } else + { + this._bounds.addBounds(child._bounds); + } } - this._boundsID = this._lastBoundsID; + this._lastBoundsID = this._boundsID; } _calculateBounds() diff --git a/src/core/display/DisplayObject.js b/src/core/display/DisplayObject.js index 4c61c4b..3ed56b9 100644 --- a/src/core/display/DisplayObject.js +++ b/src/core/display/DisplayObject.js @@ -28,7 +28,7 @@ //TODO: need to create Transform from factory /** * World transform and local transform of this object. - * This will be reworked in v4.1, please do not use it yet unless you know what are you doing! + * This will become read-only later, please do not assign anything there unless you know what are you doing * * @member {PIXI.TransformBase} */ @@ -45,6 +45,8 @@ * The visibility of the object. If false the object will not be drawn, and * the updateTransform function will not be called. * + * Only affects recursive calls from parent. You can ask for bounds or call updateTransform manually + * * @member {boolean} */ this.visible = true; @@ -53,6 +55,8 @@ * Can this object be rendered, if false the object will not be drawn but the updateTransform * methods will still be called. * + * Only affects recursive calls from parent. You can ask for bounds manually + * * @member {boolean} */ this.renderable = true; diff --git a/src/core/graphics/Graphics.js b/src/core/graphics/Graphics.js index deba490..aad7144 100644 --- a/src/core/graphics/Graphics.js +++ b/src/core/graphics/Graphics.js @@ -789,11 +789,6 @@ */ _calculateBounds() { - if (!this.renderable) - { - return; - } - if (this.boundsDirty !== this.dirty) { this.boundsDirty = this.dirty; diff --git a/src/core/display/Bounds.js b/src/core/display/Bounds.js index 79d7fc5..620c6dd 100644 --- a/src/core/display/Bounds.js +++ b/src/core/display/Bounds.js @@ -211,6 +211,10 @@ this.maxY = maxY; } + /** + * adds other Bounds + * @param bounds {PIXI.Bounds} + */ addBounds(bounds) { const minX = this.minX, minY = this.minY, maxX = this.maxX, maxY = this.maxY; @@ -220,6 +224,48 @@ this.maxX = bounds.maxX > maxX ? bounds.maxX : maxX; this.maxY = bounds.maxY > maxY ? bounds.maxY : maxY; } + + /** + * adds other Bounds, masked with Bounds + * @param bounds {PIXI.Bounds} + * @param mask {PIXI.Bounds} + */ + addBoundsMask(bounds, mask) + { + const _minX = bounds.minX > mask.minX ? bounds.minX : mask.minX; + const _minY = bounds.minY > mask.minY ? bounds.minY : mask.minY; + const _maxX = bounds.maxX < mask.maxX ? bounds.maxX : mask.maxX; + const _maxY = bounds.maxY < mask.maxY ? bounds.maxY : mask.maxY; + if (_minX <= _maxX && _minY <= _maxY) + { + const minX = this.minX, minY = this.minY, maxX = this.maxX, maxY = this.maxY; + this.minX = _minX < minX ? _minX : minX; + this.minY = _minY < minY ? _minY : minY; + this.maxX = _maxX > maxX ? _maxX : maxX; + this.maxY = _maxY > maxY ? _maxY : maxY; + } + } + + /** + * adds other Bounds, masked with Rectangle + * @param bounds {PIXI.Bounds} + * @param area {PIXI.Rectangle} + */ + addBoundsArea(bounds, area) + { + const _minX = bounds.minX > area.x ? bounds.minX : area.x; + const _minY = bounds.minY > area.y ? bounds.minY : area.y; + const _maxX = bounds.maxX < area.x + area.width ? bounds.maxX : (area.x + area.width); + const _maxY = bounds.maxY < area.y + area.height ? bounds.maxY : (area.y + area.height); + if (_minX <= _maxX && _minY <= _maxY) + { + const minX = this.minX, minY = this.minY, maxX = this.maxX, maxY = this.maxY; + this.minX = _minX < minX ? _minX : minX; + this.minY = _minY < minY ? _minY : minY; + this.maxX = _maxX > maxX ? _maxX : maxX; + this.maxY = _maxY > maxY ? _maxY : maxY; + } + } } export default Bounds; diff --git a/src/core/display/Container.js b/src/core/display/Container.js index abad78d..d568571 100644 --- a/src/core/display/Container.js +++ b/src/core/display/Container.js @@ -301,11 +301,6 @@ { this._boundsID++; - if (!this.visible) - { - return; - } - this.transform.updateTransform(this.parent.transform); //TODO: check render flags, how to process stuff here @@ -313,7 +308,11 @@ for (let i = 0, j = this.children.length; i < j; ++i) { - this.children[i].updateTransform(); + var child = this.children[i]; + if (child.visible) + { + child.updateTransform(); + } } } @@ -321,23 +320,33 @@ { this._bounds.clear(); - if(!this.visible) - { - return; - } - this._calculateBounds(); for (let i = 0; i < this.children.length; i++) { const child = this.children[i]; + if (!child.visible || !child.renderable) { + continue; + } + child.calculateBounds(); - this._bounds.addBounds(child._bounds); + //TODO: filter+mask, need to mask both somehow + if (child._mask) + { + child._mask.calculateBounds(); + this._bounds.addBoundsMask(child._bounds, child._mask._bounds); + } else if (child.filterArea) + { + this._bounds.addBoundsArea(child._bounds, child.filterArea); + } else + { + this._bounds.addBounds(child._bounds); + } } - this._boundsID = this._lastBoundsID; + this._lastBoundsID = this._boundsID; } _calculateBounds() diff --git a/src/core/display/DisplayObject.js b/src/core/display/DisplayObject.js index 4c61c4b..3ed56b9 100644 --- a/src/core/display/DisplayObject.js +++ b/src/core/display/DisplayObject.js @@ -28,7 +28,7 @@ //TODO: need to create Transform from factory /** * World transform and local transform of this object. - * This will be reworked in v4.1, please do not use it yet unless you know what are you doing! + * This will become read-only later, please do not assign anything there unless you know what are you doing * * @member {PIXI.TransformBase} */ @@ -45,6 +45,8 @@ * The visibility of the object. If false the object will not be drawn, and * the updateTransform function will not be called. * + * Only affects recursive calls from parent. You can ask for bounds or call updateTransform manually + * * @member {boolean} */ this.visible = true; @@ -53,6 +55,8 @@ * Can this object be rendered, if false the object will not be drawn but the updateTransform * methods will still be called. * + * Only affects recursive calls from parent. You can ask for bounds manually + * * @member {boolean} */ this.renderable = true; diff --git a/src/core/graphics/Graphics.js b/src/core/graphics/Graphics.js index deba490..aad7144 100644 --- a/src/core/graphics/Graphics.js +++ b/src/core/graphics/Graphics.js @@ -789,11 +789,6 @@ */ _calculateBounds() { - if (!this.renderable) - { - return; - } - if (this.boundsDirty !== this.dirty) { this.boundsDirty = this.dirty; diff --git a/test/core/Bounds.js b/test/core/Bounds.js index d46ee5f..e15cbd1 100644 --- a/test/core/Bounds.js +++ b/test/core/Bounds.js @@ -230,7 +230,7 @@ }); - it('should register correct width and height with an a DisplayObject is visible false', function() { + it('should register correct width and height with Container children not visible', function() { var parent = new PIXI.Container(); @@ -262,7 +262,7 @@ expect(bounds.width).to.equal(10); expect(bounds.height).to.equal(10); - container.visible = false; + sprite.renderable = false; bounds = container.getBounds(); @@ -271,6 +271,78 @@ expect(bounds.width).to.equal(0); expect(bounds.height).to.equal(0); + bounds = sprite.getBounds(); + + expect(bounds.x).to.equal(30); + expect(bounds.y).to.equal(20); + expect(bounds.width).to.equal(10); + expect(bounds.height).to.equal(10); + + }); + + it('should register correct bounds of invisible Container', function() { + var parent = new PIXI.Container(); + + var container = new PIXI.Container();//Graphics().beginFill(0xFF0000).drawCircle(0, 0, 10, 10);//texture); + + var texture = PIXI.RenderTexture.create(10, 10); + var sprite = new PIXI.Sprite(texture); + + container.addChild(sprite); + parent.addChild(container); + + sprite.position.set(30, 20); + container.visible = false; + container.position.set(100, 100); + + var bounds; + + bounds = container.getBounds(); + + expect(bounds.x).to.equal(130); + expect(bounds.y).to.equal(120); + expect(bounds.width).to.equal(10); + expect(bounds.height).to.equal(10); + + }); + + it('should register correct width and height with Container masked child', function() { + + var parent = new PIXI.Container(); + + var container = new PIXI.Container();//Graphics().beginFill(0xFF0000).drawCircle(0, 0, 10, 10);//texture); + + var graphics = new PIXI.Graphics().beginFill(0xFF0000).drawRect(0, 0, 10, 10);//texture); + + var texture = PIXI.RenderTexture.create(10, 10); + var sprite = new PIXI.Sprite(texture); + + container.addChild(sprite); + container.addChild(graphics); + sprite.mask = graphics; + + parent.addChild(container); + + sprite.position.x = 30; + sprite.position.y = 20; + graphics.position.x = 32; + graphics.position.y = 23; + + var bounds; + + bounds = graphics.getBounds(); + + expect(bounds.x).to.equal(32); + expect(bounds.y).to.equal(23); + expect(bounds.width).to.equal(10); + expect(bounds.height).to.equal(10); + + bounds = container.getBounds(); + + expect(bounds.x).to.equal(32); + expect(bounds.y).to.equal(23); + expect(bounds.width).to.equal(8); + expect(bounds.height).to.equal(7); }); @@ -387,4 +459,4 @@ expect(bounds.height).to.equal(50); }); -}); \ No newline at end of file +});