From 1c442ad580a6c8f85b3750097bdf50d2f7f47647 Mon Sep 17 00:00:00 2001 From: Joost De Cock Date: Wed, 14 Sep 2022 12:24:09 +0200 Subject: [PATCH] wip(core): Work on stack-based layouts --- packages/core/src/index.mjs | 4 +- packages/core/src/part.mjs | 9 --- packages/core/src/pattern.mjs | 9 ++- packages/core/src/stack.mjs | 57 ++++++++++-------- packages/core/src/utils.mjs | 4 +- packages/core/tests/part.test.mjs | 70 +++-------------------- packages/core/tests/stacks.test.mjs | 89 ++++++++++++++++++++++++++++- packages/core/tests/utils.test.mjs | 2 +- 8 files changed, 139 insertions(+), 105 deletions(-) diff --git a/packages/core/src/index.mjs b/packages/core/src/index.mjs index 9a3aa19091d..2707e475770 100644 --- a/packages/core/src/index.mjs +++ b/packages/core/src/index.mjs @@ -32,7 +32,7 @@ import { rad2deg, pctBasedOn, Bezier, - generatePartTransform, + generateStackTransform, macroName, } from './utils.mjs' import { version } from '../data.mjs' @@ -71,7 +71,7 @@ export { deg2rad, rad2deg, pctBasedOn, - generatePartTransform, + generateStackTransform, macroName, isCoord, version, diff --git a/packages/core/src/part.mjs b/packages/core/src/part.mjs index 0ef1e047272..4c1e5bd9c8f 100644 --- a/packages/core/src/part.mjs +++ b/packages/core/src/part.mjs @@ -336,15 +336,6 @@ Part.prototype.shorthand = function () { return shorthand } -Part.prototype.generateTransform = function (transforms) { - const { move, rotate, flipX, flipY } = transforms - const generated = utils.generatePartTransform(move.x, move.y, rotate, flipX, flipY, this) - - for (var t in generated) { - this.attr(t, generated[t], true) - } -} - Part.prototype.isEmpty = function () { if (Object.keys(this.snippets).length > 0) return false diff --git a/packages/core/src/pattern.mjs b/packages/core/src/pattern.mjs index bb7aacfc44b..bcc3001d859 100644 --- a/packages/core/src/pattern.mjs +++ b/packages/core/src/pattern.mjs @@ -561,9 +561,12 @@ Pattern.prototype.pack = function () { // First, create all stacks this.stacks = {} for (const [name, part] of Object.entries(this.parts)) { - if (typeof this.stacks[part.stack] === 'undefined') - this.stacks[part.stack] = this.__createStackWithContext(part.stack) - this.stacks[part.stack].addPart(part) + const stackName = (typeof part.stack === 'function') + ? part.stack(this.settings, name) + : part.stack + if (typeof this.stacks[stackName] === 'undefined') + this.stacks[stackName] = this.__createStackWithContext(stackName) + this.stacks[stackName].addPart(part) } let bins = [] diff --git a/packages/core/src/stack.mjs b/packages/core/src/stack.mjs index 7f516a5be6b..134aa835ef3 100644 --- a/packages/core/src/stack.mjs +++ b/packages/core/src/stack.mjs @@ -5,16 +5,16 @@ import * as utils from './utils.mjs' export function Stack(name = null) { // Non-enumerable properties utils.addNonEnumProp(this, 'freeId', 0) - utils.addNonEnumProp(this, 'topLeft', false) - utils.addNonEnumProp(this, 'bottomRight', false) - utils.addNonEnumProp(this, 'width', false) - utils.addNonEnumProp(this, 'height', false) utils.addNonEnumProp(this, 'layout', { move: { x: 0, y: 0 } }) // Enumerable properties this.attributes = new Attributes() this.parts = new Set() this.name = name + this.topLeft = false + this.bottomRight = false + this.width = false + this.height = false return this } @@ -37,24 +37,24 @@ Stack.prototype.getPartNames = function (part) { } /** Homes the stack so that its top left corner is in (0,0) */ -Stack.prototype.home = function () { - const parts = this.getPartList() - if (parts.length < 1) return this - for (const part of this.getPartList()) { - part.home() - } - - if (parts.length === 1) { - this.topLeft = part.topLeft - this.bottomRigth = part.bottomRight - this.width = part.width - this.height = part.height - - return this - } - - return this.boundary() -} +//Stack.prototype.home = function () { +// const parts = this.getPartList() +// if (parts.length < 1) return this +// for (const part of this.getPartList()) { +// part.home() +// } +// +// if (parts.length === 1) { +// this.topLeft = part.topLeft +// this.bottomRigth = part.bottomRight +// this.width = part.width +// this.height = part.height +// +// return this +// } +// +// return this.boundary() +//} /** Calculates the stack's bounding box and sets it */ Stack.prototype.home = function () { @@ -102,7 +102,7 @@ Stack.prototype.home = function () { return this } -/** Finds the anchor to aling parts in this stack */ +/** Finds the anchor to align parts in this stack */ Stack.prototype.getAnchor = function() { let anchorPoint = true let gridAnchorPoint = true @@ -126,4 +126,15 @@ Stack.prototype.attr = function (name, value, overwrite = false) { return this } +/** Generates the transform for a stack */ +Stack.prototype.generateTransform = function (transforms) { + const { move, rotate, flipX, flipY } = transforms + const generated = utils.generateStackTransform(move.x, move.y, rotate, flipX, flipY, this) + + for (var t in generated) { + this.attr(t, generated[t], true) + } +} + + export default Stack diff --git a/packages/core/src/utils.mjs b/packages/core/src/utils.mjs index 81c42741e83..7f2fe765a8b 100644 --- a/packages/core/src/utils.mjs +++ b/packages/core/src/utils.mjs @@ -361,8 +361,8 @@ export function pctBasedOn(measurement) { } } -/** Generates the transform attributes needed for a given part */ -export const generatePartTransform = (x, y, rotate, flipX, flipY, part) => { +/** Generates the transform attributes needed for a given stack */ +export const generateStackTransform = (x, y, rotate, flipX, flipY, part) => { const transforms = [] let xTotal = x || 0 let yTotal = y || 0 diff --git a/packages/core/tests/part.test.mjs b/packages/core/tests/part.test.mjs index ce186ba6930..3dcf6b99d4e 100644 --- a/packages/core/tests/part.test.mjs +++ b/packages/core/tests/part.test.mjs @@ -124,7 +124,7 @@ describe('Part', () => { ) }) - it('Should calculate the part boundary with default margin', () => { + it('Should calculate the part boundary', () => { const design = new Design() const pattern = new design() const part = pattern.__createPartWithContext() @@ -134,52 +134,15 @@ describe('Part', () => { part.points.to = new short.Point(19, 76) part.paths.test = new short.Path().move(part.points.from).line(part.points.to) let boundary = part.boundary() - expect(boundary.topLeft.x).to.equal(17) - expect(boundary.topLeft.y).to.equal(74) - expect(boundary.bottomRight.x).to.equal(125) - expect(boundary.bottomRight.y).to.equal(458) + expect(boundary.topLeft.x).to.equal(19) + expect(boundary.topLeft.y).to.equal(76) + expect(boundary.bottomRight.x).to.equal(123) + expect(boundary.bottomRight.y).to.equal(456) boundary = part.boundary() - expect(boundary.width).to.equal(108) - expect(boundary.height).to.equal(384) + expect(boundary.width).to.equal(104) + expect(boundary.height).to.equal(380) }) - it('Should calculate the part boundary with custom margin', () => { - const design = new Design() - const pattern = new design({ margin: 5 }) - const part = pattern.__createPartWithContext() - pattern.init() - const short = part.shorthand() - part.points.from = new short.Point(123, 456) - part.points.to = new short.Point(19, 76) - part.paths.test = new short.Path().move(part.points.from).line(part.points.to) - let boundary = part.boundary() - expect(boundary.topLeft.x).to.equal(14) - expect(boundary.topLeft.y).to.equal(71) - expect(boundary.bottomRight.x).to.equal(128) - expect(boundary.bottomRight.y).to.equal(461) - boundary = part.boundary() - expect(boundary.width).to.equal(114) - expect(boundary.height).to.equal(390) - }) - - it('Should calculate the part boundary for paperless', () => { - const design = new Design() - const pattern = new design({ paperless: true }) - const part = pattern.__createPartWithContext() - pattern.init() - const short = part.shorthand() - part.points.from = new short.Point(123, 456) - part.points.to = new short.Point(19, 76) - part.paths.test = new short.Path().move(part.points.from).line(part.points.to) - let boundary = part.boundary() - expect(boundary.topLeft.x).to.equal(9) - expect(boundary.topLeft.y).to.equal(66) - expect(boundary.bottomRight.x).to.equal(133) - expect(boundary.bottomRight.y).to.equal(466) - boundary = part.boundary() - expect(boundary.width).to.equal(124) - expect(boundary.height).to.equal(400) - }) /* it('Should stack a part', () => { const part = { @@ -243,25 +206,6 @@ describe('Part', () => { ) }) - it('Should generate the part transforms', () => { - const design = new Design() - const pattern = new design({ margin: 5 }) - const part = pattern.__createPartWithContext() - pattern.init() - let short = part.shorthand() - part.points.from = new short.Point(2, 2) - part.points.to = new short.Point(19, 76) - part.paths.test = new short.Path().move(part.points.from).line(part.points.to) - part.home() - part.generateTransform({ - move: { - x: 10, - y: 20, - }, - }) - expect(part.attributes.list.transform.length).to.equal(1) - expect(part.attributes.list.transform[0]).to.equal('translate(10 20)') - }) describe('isEmpty', () => { it('Should return true if the part has no paths or snippets', () => { const design = new Design() diff --git a/packages/core/tests/stacks.test.mjs b/packages/core/tests/stacks.test.mjs index 1331325baf1..6191ca93e0e 100644 --- a/packages/core/tests/stacks.test.mjs +++ b/packages/core/tests/stacks.test.mjs @@ -68,10 +68,8 @@ describe('Stacks', () => { }, }) pattern.draft() - console.log(pattern.store.logs) //console.log(pattern.parts) //pattern.render() - console.log(pattern.render()) it('Pattern.init() should resolve dependencies', () => { expect(typeof pattern.config.resolvedDependencies).to.equal('object') @@ -89,5 +87,92 @@ describe('Stacks', () => { pattern.config.resolvedDependencies['test.partC'].indexOf('test.partB') !== -1 ).to.equal(true) }) + + + it('Should calculate the part boundary', () => { + const part = { + name: 'test', + draft: ({points, Point, paths, Path, part }) => { + points.from = new Point(123, 456) + points.to = new Point(19, 76) + paths.test = new Path().move(points.from).line(points.to) + + return part + } + } + const design = new Design({ parts: [ part ]}) + const pattern = new design() + pattern.draft().render() + expect(pattern.stacks.test.topLeft.x).to.equal(17) + expect(pattern.stacks.test.topLeft.y).to.equal(74) + expect(pattern.stacks.test.bottomRight.x).to.equal(125) + expect(pattern.stacks.test.bottomRight.y).to.equal(458) + expect(pattern.stacks.test.width).to.equal(108) + expect(pattern.stacks.test.height).to.equal(384) + }) + + it('Should calculate the part boundary with custom margin', () => { + const part = { + name: 'test', + draft: ({points, Point, paths, Path, part }) => { + points.from = new Point(123, 456) + points.to = new Point(19, 76) + paths.test = new Path().move(points.from).line(points.to) + + return part + } + } + const design = new Design({ parts: [ part ]}) + const pattern = new design({ margin: 5 }) + pattern.draft().render() + expect(pattern.stacks.test.topLeft.x).to.equal(14) + expect(pattern.stacks.test.topLeft.y).to.equal(71) + expect(pattern.stacks.test.bottomRight.x).to.equal(128) + expect(pattern.stacks.test.bottomRight.y).to.equal(461) + expect(pattern.stacks.test.width).to.equal(114) + expect(pattern.stacks.test.height).to.equal(390) + }) + + it('Should calculate the part boundary for paperless', () => { + const part = { + name: 'test', + draft: ({points, Point, paths, Path, part }) => { + points.from = new Point(123, 456) + points.to = new Point(19, 76) + paths.test = new Path().move(points.from).line(points.to) + + return part + } + } + const design = new Design({ parts: [ part ]}) + const pattern = new design({ paperless: true }) + pattern.draft().render() + expect(pattern.stacks.test.topLeft.x).to.equal(9) + expect(pattern.stacks.test.topLeft.y).to.equal(66) + }) + it('Should generate the part transforms', () => { + const part = { + name: 'test', + draft: ({points, Point, paths, Path, part }) => { + points.from = new Point(2, 2) + points.to = new Point(19, 76) + paths.test = new Path().move(points.from).line(points.to) + + return part + } + } + const design = new Design({ parts: [ part ] }) + const pattern = new design() + pattern.draft().render() + pattern.stacks.test.generateTransform({ + move: { + x: 10, + y: 20, + }, + }) + expect(pattern.stacks.test.attributes.list.transform.length).to.equal(1) + expect(pattern.stacks.test.attributes.list.transform[0]).to.equal('translate(10 20)') + }) + }) }) diff --git a/packages/core/tests/utils.test.mjs b/packages/core/tests/utils.test.mjs index 22880596544..87ef4e349ba 100644 --- a/packages/core/tests/utils.test.mjs +++ b/packages/core/tests/utils.test.mjs @@ -28,7 +28,7 @@ import { rad2deg, pctBasedOn, Bezier, - generatePartTransform, + generateStackTransform, macroName, Design, } from '../src/index.mjs'