diff --git a/src/core/graphics/Graphics.js b/src/core/graphics/Graphics.js index e256c80..f6d338e 100644 --- a/src/core/graphics/Graphics.js +++ b/src/core/graphics/Graphics.js @@ -944,17 +944,41 @@ { // POLY const points = shape.points; + let x2 = 0; + let y2 = 0; + let dx = 0; + let dy = 0; + let rw = 0; + let rh = 0; + let cx = 0; + let cy = 0; - for (let j = 0; j < points.length; j += 2) + for (let j = 0; j + 2 < points.length; j += 2) { x = points[j]; y = points[j + 1]; + x2 = points[j + 2]; + y2 = points[j + 3]; + dx = Math.abs(x2 - x); + dy = Math.abs(y2 - y); + h = lineWidth; + w = Math.sqrt((dx * dx) + (dy * dy)); - minX = x - lineWidth < minX ? x - lineWidth : minX; - maxX = x + lineWidth > maxX ? x + lineWidth : maxX; + if (w < 1e-9) + { + continue; + } - minY = y - lineWidth < minY ? y - lineWidth : minY; - maxY = y + lineWidth > maxY ? y + lineWidth : maxY; + rw = ((h / w * dy) + dx) / 2; + rh = ((h / w * dx) + dy) / 2; + cx = (x2 + x) / 2; + cy = (y2 + y) / 2; + + minX = cx - rw < minX ? cx - rw : minX; + maxX = cx + rw > maxX ? cx + rw : maxX; + + minY = cy - rh < minY ? cy - rh : minY; + maxY = cy + rh > maxY ? cy + rh : maxY; } } } diff --git a/src/core/graphics/Graphics.js b/src/core/graphics/Graphics.js index e256c80..f6d338e 100644 --- a/src/core/graphics/Graphics.js +++ b/src/core/graphics/Graphics.js @@ -944,17 +944,41 @@ { // POLY const points = shape.points; + let x2 = 0; + let y2 = 0; + let dx = 0; + let dy = 0; + let rw = 0; + let rh = 0; + let cx = 0; + let cy = 0; - for (let j = 0; j < points.length; j += 2) + for (let j = 0; j + 2 < points.length; j += 2) { x = points[j]; y = points[j + 1]; + x2 = points[j + 2]; + y2 = points[j + 3]; + dx = Math.abs(x2 - x); + dy = Math.abs(y2 - y); + h = lineWidth; + w = Math.sqrt((dx * dx) + (dy * dy)); - minX = x - lineWidth < minX ? x - lineWidth : minX; - maxX = x + lineWidth > maxX ? x + lineWidth : maxX; + if (w < 1e-9) + { + continue; + } - minY = y - lineWidth < minY ? y - lineWidth : minY; - maxY = y + lineWidth > maxY ? y + lineWidth : maxY; + rw = ((h / w * dy) + dx) / 2; + rh = ((h / w * dx) + dy) / 2; + cx = (x2 + x) / 2; + cy = (y2 + y) / 2; + + minX = cx - rw < minX ? cx - rw : minX; + maxX = cx + rw > maxX ? cx + rw : maxX; + + minY = cy - rh < minY ? cy - rh : minY; + maxY = cy + rh > maxY ? cy + rh : maxY; } } } diff --git a/test/core/Graphics.js b/test/core/Graphics.js index 5058fe5..020ecaf 100644 --- a/test/core/Graphics.js +++ b/test/core/Graphics.js @@ -15,4 +15,92 @@ expect(graphics.blendMode).to.be.equals(PIXI.BLEND_MODES.NORMAL); }); }); + + describe('lineTo', () => + { + it('should return correct bounds - north', () => + { + const graphics = new PIXI.Graphics(); + + graphics.moveTo(0, 0); + graphics.lineStyle(1); + graphics.lineTo(0, 10); + + expect(graphics.width).to.be.below(1.00001); + expect(graphics.width).to.be.above(0.99999); + expect(graphics.height).to.be.equals(10); + }); + + it('should return correct bounds - south', () => + { + const graphics = new PIXI.Graphics(); + + graphics.moveTo(0, 0); + graphics.lineStyle(1); + graphics.lineTo(0, -10); + + expect(graphics.width).to.be.below(1.00001); + expect(graphics.width).to.be.above(0.99999); + expect(graphics.height).to.be.equals(10); + }); + + it('should return correct bounds - east', () => + { + const graphics = new PIXI.Graphics(); + + graphics.moveTo(0, 0); + graphics.lineStyle(1); + graphics.lineTo(10, 0); + + expect(graphics.height).to.be.equals(1); + expect(graphics.width).to.be.equals(10); + }); + + it('should return correct bounds - west', () => + { + const graphics = new PIXI.Graphics(); + + graphics.moveTo(0, 0); + graphics.lineStyle(1); + graphics.lineTo(-10, 0); + + expect(graphics.height).to.be.above(0.9999); + expect(graphics.height).to.be.below(1.0001); + expect(graphics.width).to.be.equals(10); + }); + + it('should return correct bounds when stacked with circle', () => + { + const graphics = new PIXI.Graphics(); + + graphics.beginFill(0xFF0000); + graphics.drawCircle(50, 50, 50); + graphics.endFill(); + + expect(graphics.width).to.be.equals(100); + expect(graphics.height).to.be.equals(100); + + graphics.lineStyle(20, 0); + graphics.moveTo(25, 50); + graphics.lineTo(75, 50); + + expect(graphics.width).to.be.equals(100); + expect(graphics.height).to.be.equals(100); + }); + + it('should return correct bounds when square', () => + { + const graphics = new PIXI.Graphics(); + + graphics.lineStyle(20, 0, 0.5); + graphics.moveTo(0, 0); + graphics.lineTo(50, 0); + graphics.lineTo(50, 50); + graphics.lineTo(0, 50); + graphics.lineTo(0, 0); + + expect(graphics.width).to.be.equals(70); + expect(graphics.height).to.be.equals(70); + }); + }); });