diff --git a/packages/core/src/stack.mjs b/packages/core/src/stack.mjs index 127ea41c6aa..1a60c7ab5c3 100644 --- a/packages/core/src/stack.mjs +++ b/packages/core/src/stack.mjs @@ -52,30 +52,27 @@ Stack.prototype.home = function () { for (const part of this.getPartList()) { part.__boundary() - const transforms = part.attributes.get('transform') + // get all corners of the part's bounds let tl = part.topLeft || this.topLeft let br = part.bottomRight || this.bottomRight let tr = new Point(br.x, tl.y) let bl = new Point(tl.x, br.y) + // if there are transforms on the part, apply them to the corners so that we have the correct bounds + const transforms = part.attributes.getAsArray('transform') if (transforms) { - const combinedTransform = - typeof transforms === 'string' ? transforms : utils.combineTransforms(transforms) + const combinedTransform = utils.combineTransforms(transforms) - tl = utils.applyTransformToPoint(combinedTransform, part.topLeft.copy()) - br = utils.applyTransformToPoint(combinedTransform, part.bottomRight.copy()) - bl = utils.applyTransformToPoint( - combinedTransform, - new Point(part.topLeft.x, part.bottomRight.y) - ) - tr = utils.applyTransformToPoint( - combinedTransform, - new Point(part.bottomRight.x, part.topLeft.y) - ) + tl = utils.applyTransformToPoint(combinedTransform, tl.copy()) + br = utils.applyTransformToPoint(combinedTransform, br.copy()) + tr = utils.applyTransformToPoint(combinedTransform, tr.copy()) + bl = utils.applyTransformToPoint(combinedTransform, bl.copy()) } + // get the top left, the minimum x and y values of any corner this.topLeft.x = Math.min(this.topLeft.x, tl.x, br.x, bl.x, tr.x) this.topLeft.y = Math.min(this.topLeft.y, tl.y, br.y, bl.y, tr.y) + // get the bottom right, the maximum x and y values of any corner this.bottomRight.x = Math.max(this.bottomRight.x, tl.x, br.x, bl.x, tr.x) this.bottomRight.y = Math.max(this.bottomRight.y, tl.y, br.y, bl.y, tr.y) } diff --git a/packages/core/tests/stacks.test.mjs b/packages/core/tests/stacks.test.mjs index 54b0bf53bd1..6c0f369d24c 100644 --- a/packages/core/tests/stacks.test.mjs +++ b/packages/core/tests/stacks.test.mjs @@ -1,5 +1,6 @@ import chai from 'chai' -import { Design } from '../src/index.mjs' +import { Design, Point, Attributes } from '../src/index.mjs' +import { Stack } from '../src/stack.mjs' const expect = chai.expect @@ -173,6 +174,52 @@ describe('Stacks', () => { }) }) + describe('Stack.prototype.home()', () => { + function dummyPart(tl, br) { + return { + __boundary: () => null, + topLeft: new Point(tl.x, tl.y), + bottomRight: new Point(br.x, br.y), + attributes: new Attributes(), + } + } + + it('Should calculate the bounds using all part bounds', () => { + const stack = new Stack('test') + stack.context = { settings: [{ margin: 0 }] } + const expectedTlX = -1 + const expectedTlY = -2 + const expectedBrX = 20 + const expectedBrY = 20 + + stack.addPart(dummyPart({ x: 0, y: expectedTlY }, { x: expectedBrX, y: 10 })) + + stack.addPart(dummyPart({ x: expectedTlX, y: 0 }, { x: expectedBrX, y: expectedBrY })) + + stack.home() + expect(stack.topLeft.x).to.equal(expectedTlX) + expect(stack.topLeft.y).to.equal(expectedTlY) + expect(stack.bottomRight.x).to.equal(expectedBrX) + expect(stack.bottomRight.y).to.equal(expectedBrY) + }) + + it('Should calculate the bounds using all transformed part bounds', () => { + const stack = new Stack('test') + stack.context = { settings: [{ margin: 0 }] } + + const part1 = dummyPart({ x: 0, y: 0 }, { x: 10, y: 10 }) + part1.attributes.add('transform', 'scale(1, -1)') + part1.attributes.add('transform', 'rotate(45)') + stack.addPart(part1) + + stack.home() + expect(stack.topLeft.x).to.equal(-7.071067811865475) + expect(stack.topLeft.y).to.equal(-14.142135623730951) + expect(stack.bottomRight.x).to.equal(7.0710678118654755) + expect(stack.bottomRight.y).to.equal(0) + }) + }) + it('Should get the anchor for the stack', () => { const part = { name: 'test',