Merge branch 'develop' into more-lint
This commit is contained in:
commit
c0ede14d74
118 changed files with 2870 additions and 4892 deletions
|
@ -4,12 +4,12 @@ export const plugin = {
|
|||
name,
|
||||
version,
|
||||
hooks: {
|
||||
preDraft: ({ settings }) => {
|
||||
for (const set of settings) {
|
||||
if (set.measurements) {
|
||||
if (typeof set.measurements.bust === 'undefined') {
|
||||
set.measurements.bust = set.measurements.chest
|
||||
set.measurements.chest = set.measurements.highBust
|
||||
preDraft: function ({ settings }) {
|
||||
for (const i in settings) {
|
||||
if (settings[i].measurements) {
|
||||
if (typeof settings[i].measurements.bust === 'undefined') {
|
||||
settings[i].measurements.bust = settings[i].measurements.chest
|
||||
settings[i].measurements.chest = settings[i].measurements.highBust
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,55 +4,48 @@ export const plugin = {
|
|||
name,
|
||||
version,
|
||||
macros: {
|
||||
gore: function (so) {
|
||||
gore: function (so, { points, paths, Path }) {
|
||||
const from = so.from
|
||||
const gores = so.gores
|
||||
const radius = so.radius //radius of the sphere
|
||||
const prefix = so.prefix
|
||||
const extraLength = so.extraLength //the length of the straight section after a complete semisphere
|
||||
|
||||
this.points[prefix + 'p1'] = from.shift(0, (radius * Math.PI) / 2 + extraLength)
|
||||
this.points[prefix + 'Cp1'] = this.points[prefix + 'p1'].shift(
|
||||
points[prefix + 'p1'] = from.shift(0, (radius * Math.PI) / 2 + extraLength)
|
||||
points[prefix + 'Cp1'] = points[prefix + 'p1'].shift(
|
||||
180 - 180 / gores,
|
||||
radius / 2 / Math.cos(Math.PI / gores)
|
||||
)
|
||||
this.points[prefix + 'p3'] = from.shift(90, (radius * Math.PI) / gores)
|
||||
this.points[prefix + 'p2'] = this.points[prefix + 'p3'].shift(0, extraLength)
|
||||
this.points[prefix + 'Cp2'] = this.points[prefix + 'p2'].shift(
|
||||
0,
|
||||
(radius * (Math.PI - 2)) / 2
|
||||
)
|
||||
points[prefix + 'p3'] = from.shift(90, (radius * Math.PI) / gores)
|
||||
points[prefix + 'p2'] = points[prefix + 'p3'].shift(0, extraLength)
|
||||
points[prefix + 'Cp2'] = points[prefix + 'p2'].shift(0, (radius * (Math.PI - 2)) / 2)
|
||||
|
||||
if (extraLength < 0) {
|
||||
//top curve used to calculate the new points if extraLength < 0
|
||||
this.paths.auxiliaryPath = new this.Path()
|
||||
.move(this.points[prefix + 'p1'])
|
||||
.curve(
|
||||
this.points[prefix + 'Cp1'],
|
||||
this.points[prefix + 'Cp2'],
|
||||
this.points[prefix + 'p2']
|
||||
)
|
||||
paths.auxiliaryPath = new Path()
|
||||
.move(points[prefix + 'p1'])
|
||||
.curve(points[prefix + 'Cp1'], points[prefix + 'Cp2'], points[prefix + 'p2'])
|
||||
.hide()
|
||||
|
||||
this.points[prefix + 'p2'] = this.paths.auxiliaryPath.intersectsX(0)[0] //the new point p2 is the one in which the auxiliary curve intersects x=0
|
||||
this.paths.auxiliaryPath = this.paths.auxiliaryPath.split(this.points[prefix + 'p2'])[0] //the auxiliary curve is split
|
||||
this.points[prefix + 'Cp1'] = this.paths.auxiliaryPath.ops[1].cp1 //the new control points are those of the new curve
|
||||
this.points[prefix + 'Cp2'] = this.paths.auxiliaryPath.ops[1].cp2
|
||||
this.points[prefix + 'p3'] = this.points[prefix + 'p2'].clone()
|
||||
points[prefix + 'p2'] = paths.auxiliaryPath.intersectsX(0)[0] //the new point p2 is the one in which the auxiliary curve intersects x=0
|
||||
paths.auxiliaryPath = paths.auxiliaryPath.split(points[prefix + 'p2'])[0] //the auxiliary curve is split
|
||||
points[prefix + 'Cp1'] = paths.auxiliaryPath.ops[1].cp1 //the new control points are those of the new curve
|
||||
points[prefix + 'Cp2'] = paths.auxiliaryPath.ops[1].cp2
|
||||
points[prefix + 'p3'] = points[prefix + 'p2'].clone()
|
||||
}
|
||||
|
||||
//the seam path is generated
|
||||
this.paths[prefix + 'seam'] = new this.Path()
|
||||
paths[prefix + 'seam'] = new Path()
|
||||
.move(from)
|
||||
.line(this.points[prefix + 'p1'])
|
||||
.curve(this.points[prefix + 'Cp1'], this.points[prefix + 'Cp2'], this.points[prefix + 'p2'])
|
||||
.line(this.points[prefix + 'p3'])
|
||||
.line(points[prefix + 'p1'])
|
||||
.curve(points[prefix + 'Cp1'], points[prefix + 'Cp2'], points[prefix + 'p2'])
|
||||
.line(points[prefix + 'p3'])
|
||||
.line(from)
|
||||
.close()
|
||||
.attr('class', so.class ? so.class : '')
|
||||
|
||||
if (so?.hidden) this.paths[prefix + 'seam'].hide()
|
||||
else this.paths[prefix + 'seam'].unhide()
|
||||
if (so?.hidden) paths[prefix + 'seam'].hide()
|
||||
else paths[prefix + 'seam'].unhide()
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ describe('Gore Plugin Tests', () => {
|
|||
it('Should create a default gore', () => {
|
||||
const part = {
|
||||
name: 'test',
|
||||
draft: ({ Point, points, macro }) => {
|
||||
draft: ({ Point, points, macro, part }) => {
|
||||
points.anchorPoint = new Point(50, 50)
|
||||
macro('gore', {
|
||||
from: points.anchorPoint,
|
||||
|
@ -17,12 +17,15 @@ describe('Gore Plugin Tests', () => {
|
|||
extraLength: 0,
|
||||
prefix: 'gore',
|
||||
})
|
||||
|
||||
return part
|
||||
},
|
||||
plugins: [plugin],
|
||||
}
|
||||
const Test = new Design({ plugins: [plugin], parts: [part] })
|
||||
const Test = new Design({ parts: [part] })
|
||||
const pattern = new Test()
|
||||
pattern.draft()
|
||||
let c = pattern.parts.test.points
|
||||
let c = pattern.parts[0].test.points
|
||||
expect(round(c.gorep1.y)).to.equal(50)
|
||||
expect(round(c.gorep2.x)).to.equal(50)
|
||||
expect(round(c.gorep2.y)).to.equal(30.37)
|
||||
|
@ -33,7 +36,7 @@ describe('Gore Plugin Tests', () => {
|
|||
it('Should use a configurable number of gores', () => {
|
||||
const part = {
|
||||
name: 'test',
|
||||
draft: ({ Point, points, macro }) => {
|
||||
draft: ({ Point, points, macro, part }) => {
|
||||
points.anchorPoint = new Point(50, 50)
|
||||
macro('gore', {
|
||||
from: points.anchorPoint,
|
||||
|
@ -42,12 +45,15 @@ describe('Gore Plugin Tests', () => {
|
|||
extraLength: 0,
|
||||
prefix: 'gore',
|
||||
})
|
||||
|
||||
return part
|
||||
},
|
||||
plugins: [plugin],
|
||||
}
|
||||
const Test = new Design({ plugins: [plugin], parts: [part] })
|
||||
const Test = new Design({ parts: [part] })
|
||||
const pattern = new Test()
|
||||
pattern.draft()
|
||||
let c = pattern.parts.test.points
|
||||
let c = pattern.parts[0].test.points
|
||||
expect(round(c.gorep1.x)).to.equal(89.27)
|
||||
expect(round(c.gorep1.y)).to.equal(50)
|
||||
expect(round(c.gorep2.x)).to.equal(50)
|
||||
|
@ -59,7 +65,7 @@ describe('Gore Plugin Tests', () => {
|
|||
it('Should use a configurable extra length', () => {
|
||||
const part = {
|
||||
name: 'test',
|
||||
draft: ({ Point, points, macro }) => {
|
||||
draft: ({ Point, points, macro, part }) => {
|
||||
points.anchorPoint = new Point(50, 50)
|
||||
macro('gore', {
|
||||
from: points.anchorPoint,
|
||||
|
@ -68,12 +74,15 @@ describe('Gore Plugin Tests', () => {
|
|||
extraLength: 20,
|
||||
prefix: 'gore',
|
||||
})
|
||||
|
||||
return part
|
||||
},
|
||||
plugins: [plugin],
|
||||
}
|
||||
const Test = new Design({ plugins: [plugin], parts: [part] })
|
||||
const Test = new Design({ parts: [part] })
|
||||
const pattern = new Test()
|
||||
pattern.draft()
|
||||
let c = pattern.parts.test.points
|
||||
let c = pattern.parts[0].test.points
|
||||
expect(round(c.gorep1.x)).to.equal(109.27)
|
||||
expect(round(c.gorep1.y)).to.equal(50)
|
||||
expect(round(c.gorep2.x)).to.equal(70)
|
||||
|
@ -85,7 +94,7 @@ describe('Gore Plugin Tests', () => {
|
|||
it('Should use a configurable radius', () => {
|
||||
const part = {
|
||||
name: 'test',
|
||||
draft: ({ Point, points, macro }) => {
|
||||
draft: ({ Point, points, macro, part }) => {
|
||||
points.anchorPoint = new Point(50, 50)
|
||||
macro('gore', {
|
||||
from: points.anchorPoint,
|
||||
|
@ -94,12 +103,15 @@ describe('Gore Plugin Tests', () => {
|
|||
extraLength: 0,
|
||||
prefix: 'gore',
|
||||
})
|
||||
|
||||
return part
|
||||
},
|
||||
plugins: [plugin],
|
||||
}
|
||||
const Test = new Design({ plugins: [plugin], parts: [part] })
|
||||
const Test = new Design({ parts: [part] })
|
||||
const pattern = new Test()
|
||||
pattern.draft()
|
||||
let c = pattern.parts.test.points
|
||||
let c = pattern.parts[0].test.points
|
||||
expect(round(c.gorep1.x)).to.equal(97.12)
|
||||
expect(round(c.gorep1.y)).to.equal(50)
|
||||
expect(round(c.gorep2.x)).to.equal(50)
|
||||
|
@ -111,7 +123,7 @@ describe('Gore Plugin Tests', () => {
|
|||
it('Should generate a seam path', () => {
|
||||
const part = {
|
||||
name: 'test',
|
||||
draft: ({ Point, points, macro }) => {
|
||||
draft: ({ Point, points, macro, part }) => {
|
||||
points.anchorPoint = new Point(50, 50)
|
||||
macro('gore', {
|
||||
from: points.anchorPoint,
|
||||
|
@ -120,12 +132,15 @@ describe('Gore Plugin Tests', () => {
|
|||
extraLength: 0,
|
||||
prefix: 'gore',
|
||||
})
|
||||
|
||||
return part
|
||||
},
|
||||
plugins: [plugin],
|
||||
}
|
||||
const Test = new Design({ plugins: [plugin], parts: [part] })
|
||||
const Test = new Design({ parts: [part] })
|
||||
const pattern = new Test()
|
||||
pattern.draft()
|
||||
let c = pattern.parts.test.paths.goreseam.ops
|
||||
let c = pattern.parts[0].test.paths.goreseam.ops
|
||||
expect(round(c[1].to.x)).to.equal(89.27)
|
||||
expect(round(c[1].to.y)).to.equal(50)
|
||||
expect(round(c[2].to.x)).to.equal(50)
|
||||
|
|
|
@ -19,19 +19,18 @@ export const plugin = {
|
|||
},
|
||||
},
|
||||
macros: {
|
||||
grainline: function (so = {}) {
|
||||
grainline: function (so = {}, { points, paths, Path, complete, setGrain }) {
|
||||
if (so === false) {
|
||||
delete this.points.grainlineFrom
|
||||
delete this.points.grainlineTo
|
||||
delete this.paths.grainline
|
||||
this.setGrain(90) // Restoring default
|
||||
delete points.grainlineFrom
|
||||
delete points.grainlineTo
|
||||
delete paths.grainline
|
||||
setGrain(90) // Restoring default
|
||||
return true
|
||||
}
|
||||
so = {
|
||||
...dflts,
|
||||
...so,
|
||||
}
|
||||
const { points, complete, setGrain } = this.shorthand()
|
||||
// setGrain relies on plugin-cutlist
|
||||
if (typeof setGrain === 'function') {
|
||||
setGrain(so.from.angle(so.to))
|
||||
|
@ -39,7 +38,7 @@ export const plugin = {
|
|||
if (complete) {
|
||||
points.grainlineFrom = so.from.shiftFractionTowards(so.to, 0.05)
|
||||
points.grainlineTo = so.to.shiftFractionTowards(so.from, 0.05)
|
||||
this.paths.grainline = new this.Path()
|
||||
paths.grainline = new Path()
|
||||
.move(points.grainlineFrom)
|
||||
.line(points.grainlineTo)
|
||||
.attr('class', 'note')
|
||||
|
|
|
@ -8,19 +8,22 @@ describe('Grainline Plugin Tests', () => {
|
|||
it('Should run the default grainline macro', () => {
|
||||
const part = {
|
||||
name: 'test',
|
||||
draft: ({ points, Point, macro }) => {
|
||||
draft: ({ points, Point, macro, part }) => {
|
||||
points.from = new Point(10, 20)
|
||||
points.to = new Point(10, 230)
|
||||
macro('grainline', {
|
||||
from: points.from,
|
||||
to: points.to,
|
||||
})
|
||||
|
||||
return part
|
||||
},
|
||||
plugins: [plugin],
|
||||
}
|
||||
const Pattern = new Design({ plugins: [plugin], parts: [part] })
|
||||
const Pattern = new Design({ parts: [part] })
|
||||
const pattern = new Pattern()
|
||||
pattern.draft()
|
||||
const c = pattern.parts.test.paths.grainline
|
||||
const c = pattern.parts[0].test.paths.grainline
|
||||
expect(c.attributes.get('class')).to.equal('note')
|
||||
expect(c.attributes.get('marker-start')).to.equal('url(#grainlineFrom)')
|
||||
expect(c.attributes.get('marker-end')).to.equal('url(#grainlineTo)')
|
||||
|
|
|
@ -5,31 +5,31 @@ export const plugin = {
|
|||
version,
|
||||
hooks: {
|
||||
preDraft: function ({ settings }) {
|
||||
if (settings.measurements) {
|
||||
if (
|
||||
typeof settings.measurements.seatBack !== 'undefined' &&
|
||||
typeof settings.measurements.seat !== 'undefined'
|
||||
) {
|
||||
settings.measurements.seatFront =
|
||||
settings.measurements.seat - settings.measurements.seatBack
|
||||
settings.measurements.seatBackArc = settings.measurements.seatBack / 2
|
||||
settings.measurements.seatFrontArc = settings.measurements.seatFront / 2
|
||||
}
|
||||
if (
|
||||
typeof settings.measurements.waist !== 'undefined' &&
|
||||
typeof settings.measurements.waistBack !== 'undefined'
|
||||
) {
|
||||
settings.measurements.waistFront =
|
||||
settings.measurements.waist - settings.measurements.waistBack
|
||||
settings.measurements.waistBackArc = settings.measurements.waistBack / 2
|
||||
settings.measurements.waistFrontArc = settings.measurements.waistFront / 2
|
||||
}
|
||||
if (
|
||||
typeof settings.measurements.crossSeam !== 'undefined' &&
|
||||
typeof settings.measurements.crossSeamFront !== 'undefined'
|
||||
) {
|
||||
settings.measurements.crossSeamBack =
|
||||
settings.measurements.crossSeam - settings.measurements.crossSeamFront
|
||||
for (const set of settings) {
|
||||
if (set.measurements) {
|
||||
if (
|
||||
typeof set.measurements.seatBack !== 'undefined' &&
|
||||
typeof set.measurements.seat !== 'undefined'
|
||||
) {
|
||||
set.measurements.seatFront = set.measurements.seat - set.measurements.seatBack
|
||||
set.measurements.seatBackArc = set.measurements.seatBack / 2
|
||||
set.measurements.seatFrontArc = set.measurements.seatFront / 2
|
||||
}
|
||||
if (
|
||||
typeof set.measurements.waist !== 'undefined' &&
|
||||
typeof set.measurements.waistBack !== 'undefined'
|
||||
) {
|
||||
set.measurements.waistFront = set.measurements.waist - set.measurements.waistBack
|
||||
set.measurements.waistBackArc = set.measurements.waistBack / 2
|
||||
set.measurements.waistFrontArc = set.measurements.waistFront / 2
|
||||
}
|
||||
if (
|
||||
typeof set.measurements.crossSeam !== 'undefined' &&
|
||||
typeof set.measurements.crossSeamFront !== 'undefined'
|
||||
) {
|
||||
set.measurements.crossSeamBack =
|
||||
set.measurements.crossSeam - set.measurements.crossSeamFront
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -12,62 +12,47 @@ const measurements = {
|
|||
crossSeam: 100,
|
||||
crossSeamFront: 42,
|
||||
}
|
||||
|
||||
const part = {
|
||||
name: 'test',
|
||||
draft: ({ points, Point }) => {
|
||||
draft: ({ points, Point, part }) => {
|
||||
points.from = new Point(10, 20)
|
||||
points.to = new Point(10, 230)
|
||||
|
||||
return part
|
||||
},
|
||||
measurements: Object.keys(measurements),
|
||||
plugins: [plugin],
|
||||
}
|
||||
const Pattern = new Design({ plugins: [plugin], parts: [part] })
|
||||
const pattern = new Pattern({ measurements })
|
||||
pattern.draft()
|
||||
const Pattern = new Design({ parts: [part] })
|
||||
|
||||
describe('Measurements Plugin Tests', () => {
|
||||
it('Should set the extra measurements', () => {
|
||||
expect(pattern.settings.measurements.seatFront).to.equal(40)
|
||||
expect(pattern.settings.measurements.seatFrontArc).to.equal(20)
|
||||
expect(pattern.settings.measurements.seatBackArc).to.equal(30)
|
||||
expect(pattern.settings.measurements.waistFront).to.equal(55)
|
||||
expect(pattern.settings.measurements.waistFrontArc).to.equal(27.5)
|
||||
expect(pattern.settings.measurements.crossSeamBack).to.equal(58)
|
||||
const pattern = new Pattern({ measurements })
|
||||
pattern.draft()
|
||||
expect(pattern.settings[0].measurements.seatFront).to.equal(40)
|
||||
expect(pattern.settings[0].measurements.seatFrontArc).to.equal(20)
|
||||
expect(pattern.settings[0].measurements.seatBackArc).to.equal(30)
|
||||
expect(pattern.settings[0].measurements.waistFront).to.equal(55)
|
||||
expect(pattern.settings[0].measurements.waistFrontArc).to.equal(27.5)
|
||||
expect(pattern.settings[0].measurements.crossSeamBack).to.equal(58)
|
||||
})
|
||||
|
||||
it('Should calculate seatFront from seat and seatBack', function () {
|
||||
const testPattern = new Design({
|
||||
measurements: {},
|
||||
plugins: [plugin],
|
||||
})
|
||||
const pattern = new testPattern()
|
||||
const userMeasurements = { seat: 50, seatBack: 20 }
|
||||
pattern.settings.measurements = userMeasurements
|
||||
const pattern = new Pattern({ measurements: { seat: 50, seatBack: 20 } })
|
||||
pattern.draft()
|
||||
expect(pattern.settings.measurements.seatFront).to.equal(30)
|
||||
expect(pattern.settings[0].measurements.seatFront).to.equal(30)
|
||||
})
|
||||
|
||||
it('Should calculate waistFrontArc and waistBackArc from waist and waistBack', function () {
|
||||
const testPattern = new Design({
|
||||
measurements: {},
|
||||
plugins: [plugin],
|
||||
})
|
||||
const pattern = new testPattern()
|
||||
const userMeasurements = { waist: 50, waistBack: 20 }
|
||||
pattern.settings.measurements = userMeasurements
|
||||
const pattern = new Pattern({ measurements: { waist: 50, waistBack: 20 } })
|
||||
pattern.draft()
|
||||
expect(pattern.settings.measurements.waistFrontArc).to.equal(15)
|
||||
expect(pattern.settings.measurements.waistBackArc).to.equal(10)
|
||||
expect(pattern.settings[0].measurements.waistFrontArc).to.equal(15)
|
||||
expect(pattern.settings[0].measurements.waistBackArc).to.equal(10)
|
||||
})
|
||||
|
||||
it('Should calculate crossSeamBack from crossSeam and crossSeamFront', function () {
|
||||
const testPattern = new Design({
|
||||
measurements: {},
|
||||
plugins: [plugin],
|
||||
})
|
||||
const pattern = new testPattern()
|
||||
const userMeasurements = { crossSeam: 50, crossSeamFront: 20 }
|
||||
pattern.settings.measurements = userMeasurements
|
||||
const pattern = new Pattern({ measurements: { crossSeam: 50, crossSeamFront: 20 } })
|
||||
pattern.draft()
|
||||
expect(pattern.settings.measurements.crossSeamBack).to.equal(30)
|
||||
expect(pattern.settings[0].measurements.crossSeamBack).to.equal(30)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -7,7 +7,7 @@ const expect = chai.expect
|
|||
describe('Mirror Plugin Tests', () => {
|
||||
const part = {
|
||||
name: 'test',
|
||||
draft: ({ points, Point, macro, paths, Path }) => {
|
||||
draft: ({ points, Point, macro, paths, Path, part }) => {
|
||||
points.mirrorA = new Point(-100, -100)
|
||||
points.mirrorB = new Point(100, 100)
|
||||
points.a = new Point(10, 20)
|
||||
|
@ -23,58 +23,61 @@ describe('Mirror Plugin Tests', () => {
|
|||
macro('mirror', settings)
|
||||
macro('mirror', { ...settings, prefix: 'test' })
|
||||
macro('mirror', { ...settings, clone: false })
|
||||
|
||||
return part
|
||||
},
|
||||
plugins: [plugin],
|
||||
}
|
||||
const Pattern = new Design({ plugins: [plugin], parts: [part] })
|
||||
const Pattern = new Design({ parts: [part] })
|
||||
const pattern = new Pattern()
|
||||
pattern.draft()
|
||||
|
||||
it('Should mirror points', () => {
|
||||
expect(pattern.parts.test.points.mirroredA.x).to.equal(20)
|
||||
expect(pattern.parts.test.points.mirroredA.y).to.equal(10)
|
||||
expect(pattern.parts.test.points.mirroredB.x).to.equal(40)
|
||||
expect(pattern.parts.test.points.mirroredB.y).to.equal(30)
|
||||
expect(pattern.parts[0].test.points.mirroredA.x).to.equal(20)
|
||||
expect(pattern.parts[0].test.points.mirroredA.y).to.equal(10)
|
||||
expect(pattern.parts[0].test.points.mirroredB.x).to.equal(40)
|
||||
expect(pattern.parts[0].test.points.mirroredB.y).to.equal(30)
|
||||
})
|
||||
it('Should mirror points with custom prefix', () => {
|
||||
expect(pattern.parts.test.points.testA.x).to.equal(20)
|
||||
expect(pattern.parts.test.points.testA.y).to.equal(10)
|
||||
expect(pattern.parts.test.points.testB.x).to.equal(40)
|
||||
expect(pattern.parts.test.points.testB.y).to.equal(30)
|
||||
expect(pattern.parts[0].test.points.testA.x).to.equal(20)
|
||||
expect(pattern.parts[0].test.points.testA.y).to.equal(10)
|
||||
expect(pattern.parts[0].test.points.testB.x).to.equal(40)
|
||||
expect(pattern.parts[0].test.points.testB.y).to.equal(30)
|
||||
})
|
||||
it('Should mirror points without cloning them', () => {
|
||||
expect(pattern.parts.test.points.a.x).to.equal(20)
|
||||
expect(pattern.parts.test.points.a.y).to.equal(10)
|
||||
expect(pattern.parts.test.points.b.x).to.equal(40)
|
||||
expect(pattern.parts.test.points.b.y).to.equal(30)
|
||||
expect(pattern.parts[0].test.points.a.x).to.equal(20)
|
||||
expect(pattern.parts[0].test.points.a.y).to.equal(10)
|
||||
expect(pattern.parts[0].test.points.b.x).to.equal(40)
|
||||
expect(pattern.parts[0].test.points.b.y).to.equal(30)
|
||||
})
|
||||
it('Should mirror paths', () => {
|
||||
expect(pattern.parts.test.paths.mirroredTest.ops[0].to.x).to.equal(2)
|
||||
expect(pattern.parts.test.paths.mirroredTest.ops[0].to.y).to.equal(1)
|
||||
expect(pattern.parts.test.paths.mirroredTest.ops[1].cp1.x).to.equal(20)
|
||||
expect(pattern.parts.test.paths.mirroredTest.ops[1].cp1.y).to.equal(10)
|
||||
expect(pattern.parts.test.paths.mirroredTest.ops[1].cp2.x).to.equal(40)
|
||||
expect(pattern.parts.test.paths.mirroredTest.ops[1].cp2.y).to.equal(30)
|
||||
expect(pattern.parts.test.paths.mirroredTest.ops[1].to.x).to.equal(60)
|
||||
expect(pattern.parts.test.paths.mirroredTest.ops[1].to.y).to.equal(50)
|
||||
expect(pattern.parts[0].test.paths.mirroredTest.ops[0].to.x).to.equal(2)
|
||||
expect(pattern.parts[0].test.paths.mirroredTest.ops[0].to.y).to.equal(1)
|
||||
expect(pattern.parts[0].test.paths.mirroredTest.ops[1].cp1.x).to.equal(20)
|
||||
expect(pattern.parts[0].test.paths.mirroredTest.ops[1].cp1.y).to.equal(10)
|
||||
expect(pattern.parts[0].test.paths.mirroredTest.ops[1].cp2.x).to.equal(40)
|
||||
expect(pattern.parts[0].test.paths.mirroredTest.ops[1].cp2.y).to.equal(30)
|
||||
expect(pattern.parts[0].test.paths.mirroredTest.ops[1].to.x).to.equal(60)
|
||||
expect(pattern.parts[0].test.paths.mirroredTest.ops[1].to.y).to.equal(50)
|
||||
})
|
||||
it('Should mirror paths with custom prefix', () => {
|
||||
expect(pattern.parts.test.paths.testTest.ops[0].to.x).to.equal(2)
|
||||
expect(pattern.parts.test.paths.testTest.ops[0].to.y).to.equal(1)
|
||||
expect(pattern.parts.test.paths.testTest.ops[1].cp1.x).to.equal(20)
|
||||
expect(pattern.parts.test.paths.testTest.ops[1].cp1.y).to.equal(10)
|
||||
expect(pattern.parts.test.paths.testTest.ops[1].cp2.x).to.equal(40)
|
||||
expect(pattern.parts.test.paths.testTest.ops[1].cp2.y).to.equal(30)
|
||||
expect(pattern.parts.test.paths.testTest.ops[1].to.x).to.equal(60)
|
||||
expect(pattern.parts.test.paths.testTest.ops[1].to.y).to.equal(50)
|
||||
expect(pattern.parts[0].test.paths.testTest.ops[0].to.x).to.equal(2)
|
||||
expect(pattern.parts[0].test.paths.testTest.ops[0].to.y).to.equal(1)
|
||||
expect(pattern.parts[0].test.paths.testTest.ops[1].cp1.x).to.equal(20)
|
||||
expect(pattern.parts[0].test.paths.testTest.ops[1].cp1.y).to.equal(10)
|
||||
expect(pattern.parts[0].test.paths.testTest.ops[1].cp2.x).to.equal(40)
|
||||
expect(pattern.parts[0].test.paths.testTest.ops[1].cp2.y).to.equal(30)
|
||||
expect(pattern.parts[0].test.paths.testTest.ops[1].to.x).to.equal(60)
|
||||
expect(pattern.parts[0].test.paths.testTest.ops[1].to.y).to.equal(50)
|
||||
})
|
||||
it('Should mirror paths without cloning them', () => {
|
||||
expect(pattern.parts.test.paths.test.ops[0].to.x).to.equal(2)
|
||||
expect(pattern.parts.test.paths.test.ops[0].to.y).to.equal(1)
|
||||
expect(pattern.parts.test.paths.test.ops[1].cp1.x).to.equal(20)
|
||||
expect(pattern.parts.test.paths.test.ops[1].cp1.y).to.equal(10)
|
||||
expect(pattern.parts.test.paths.test.ops[1].cp2.x).to.equal(40)
|
||||
expect(pattern.parts.test.paths.test.ops[1].cp2.y).to.equal(30)
|
||||
expect(pattern.parts.test.paths.test.ops[1].to.x).to.equal(60)
|
||||
expect(pattern.parts.test.paths.test.ops[1].to.y).to.equal(50)
|
||||
expect(pattern.parts[0].test.paths.test.ops[0].to.x).to.equal(2)
|
||||
expect(pattern.parts[0].test.paths.test.ops[0].to.y).to.equal(1)
|
||||
expect(pattern.parts[0].test.paths.test.ops[1].cp1.x).to.equal(20)
|
||||
expect(pattern.parts[0].test.paths.test.ops[1].cp1.y).to.equal(10)
|
||||
expect(pattern.parts[0].test.paths.test.ops[1].cp2.x).to.equal(40)
|
||||
expect(pattern.parts[0].test.paths.test.ops[1].cp2.y).to.equal(30)
|
||||
expect(pattern.parts[0].test.paths.test.ops[1].to.x).to.equal(60)
|
||||
expect(pattern.parts[0].test.paths.test.ops[1].to.y).to.equal(50)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -9,8 +9,9 @@ const part = {
|
|||
draft: ({ Point, snippets, Snippet }) => {
|
||||
snippets.button = new Snippet('notch', new Point(10, 20))
|
||||
},
|
||||
plugins: [plugin],
|
||||
}
|
||||
const Pattern = new Design({ plugins: [plugin], parts: [part] })
|
||||
const Pattern = new Design({ parts: [part] })
|
||||
const pattern = new Pattern()
|
||||
pattern.draft().render()
|
||||
|
||||
|
@ -26,11 +27,14 @@ describe('Notches Plugin Test', () => {
|
|||
it('Draws a notch on an anchor point', () => {
|
||||
const part = {
|
||||
name: 'test',
|
||||
draft: ({ Point, snippets, Snippet }) => {
|
||||
draft: ({ Point, snippets, Snippet, part }) => {
|
||||
snippets.button = new Snippet('notch', new Point(10, 20))
|
||||
|
||||
return part
|
||||
},
|
||||
plugins: [plugin],
|
||||
}
|
||||
const Pattern = new Design({ plugins: [plugin], parts: [part] })
|
||||
const Pattern = new Design({ parts: [part] })
|
||||
const pattern = new Pattern()
|
||||
pattern.draft().render()
|
||||
const c = pattern.svg
|
||||
|
|
|
@ -6,6 +6,7 @@ export const plugin = {
|
|||
macros: {
|
||||
round: function (so) {
|
||||
const C = 0.55191502449
|
||||
const { hide = true } = so
|
||||
// Find angle between points
|
||||
let from = so.from
|
||||
let to = so.to
|
||||
|
@ -31,7 +32,7 @@ export const plugin = {
|
|||
this.points[prefix + 'End']
|
||||
)
|
||||
.attr('class', so.class ? so.class : '')
|
||||
if (so?.hidden) this.paths[prefix + 'Rounded'].hide()
|
||||
if (hide) this.paths[prefix + 'Rounded'].hide()
|
||||
else this.paths[prefix + 'Rounded'].unhide()
|
||||
},
|
||||
},
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
export function miniscale(so) {
|
||||
export function miniscale(so, { points, paths, Point, Path, scale }) {
|
||||
// Passing `false` will remove the miniscale
|
||||
if (so === false) {
|
||||
for (let id of [
|
||||
for (const id of [
|
||||
'__miniscaleMetricTopLeft',
|
||||
'__miniscaleMetricTopRight',
|
||||
'__miniscaleMetricBottomRight',
|
||||
|
@ -13,15 +13,13 @@ export function miniscale(so) {
|
|||
'__miniscaleMetric',
|
||||
'__miniscaleImperial',
|
||||
])
|
||||
delete this.points[id]
|
||||
for (let id of ['__miniscaleMetric', '__miniscaleImperial']) delete this.paths[id]
|
||||
delete points[id]
|
||||
for (const id of ['__miniscaleMetric', '__miniscaleImperial']) delete paths[id]
|
||||
return true
|
||||
}
|
||||
|
||||
const scale = this.context.settings.scale
|
||||
|
||||
// Convert scale to a value between 0 and 5, inclusive.
|
||||
const scaleIndex = Math.ceil(6 * Math.max(0.1, Math.min(1, this.context.settings.scale))) - 1
|
||||
const scaleIndex = Math.ceil(6 * Math.max(0.1, Math.min(1, scale))) - 1
|
||||
|
||||
// Metric size in mm / display value and imperial size in mm / display value for each scale index.
|
||||
const sizes = [
|
||||
|
@ -37,20 +35,21 @@ export function miniscale(so) {
|
|||
const metricDisplaySize = sizes[scaleIndex][1]
|
||||
const imperialDisplaySize = sizes[scaleIndex][3]
|
||||
// Box points
|
||||
this.points.__miniscaleMetricTopLeft = new this.Point(so.at.x - m, so.at.y - m)
|
||||
this.points.__miniscaleMetricTopRight = new this.Point(so.at.x + m, so.at.y - m)
|
||||
this.points.__miniscaleMetricBottomLeft = new this.Point(so.at.x - m, so.at.y + m)
|
||||
this.points.__miniscaleMetricBottomRight = new this.Point(so.at.x + m, so.at.y + m)
|
||||
this.points.__miniscaleImperialTopLeft = new this.Point(so.at.x - i, so.at.y - i)
|
||||
this.points.__miniscaleImperialTopRight = new this.Point(so.at.x + i, so.at.y - i)
|
||||
this.points.__miniscaleImperialBottomLeft = new this.Point(so.at.x - i, so.at.y + i)
|
||||
this.points.__miniscaleImperialBottomRight = new this.Point(so.at.x + i, so.at.y + i)
|
||||
points.__miniscaleMetricTopLeft = new Point(so.at.x - m, so.at.y - m)
|
||||
points.__miniscaleMetricTopRight = new Point(so.at.x + m, so.at.y - m)
|
||||
points.__miniscaleMetricBottomLeft = new Point(so.at.x - m, so.at.y + m)
|
||||
points.__miniscaleMetricBottomRight = new Point(so.at.x + m, so.at.y + m)
|
||||
points.__miniscaleImperialTopLeft = new Point(so.at.x - i, so.at.y - i)
|
||||
points.__miniscaleImperialTopRight = new Point(so.at.x + i, so.at.y - i)
|
||||
points.__miniscaleImperialBottomLeft = new Point(so.at.x - i, so.at.y + i)
|
||||
points.__miniscaleImperialBottomRight = new Point(so.at.x + i, so.at.y + i)
|
||||
// Text anchor points
|
||||
this.points.__miniscaleMetric = new this.Point(so.at.x, so.at.y - 2 * scale)
|
||||
this.points.__miniscaleImperial = new this.Point(so.at.x, so.at.y + 8 * scale)
|
||||
points.__miniscaleMetric = new Point(so.at.x, so.at.y - 2 * scale)
|
||||
points.__miniscaleImperial = new Point(so.at.x, so.at.y + 8 * scale)
|
||||
// Rotation
|
||||
if (so.rotate) {
|
||||
let points = [
|
||||
so.rotate = Number(so.rotate)
|
||||
let toRotate = [
|
||||
'__miniscaleMetricTopLeft',
|
||||
'__miniscaleMetricTopRight',
|
||||
'__miniscaleMetricBottomLeft',
|
||||
|
@ -62,34 +61,34 @@ export function miniscale(so) {
|
|||
'__miniscaleMetric',
|
||||
'__miniscaleImperial',
|
||||
]
|
||||
for (let pid of points) this.points[pid] = this.points[pid].rotate(so.rotate, so.at)
|
||||
for (let pid of points.slice(8)) {
|
||||
this.points[pid].attributes.set(
|
||||
for (const pid of toRotate) points[pid] = points[pid].rotate(so.rotate, so.at)
|
||||
for (const pid of toRotate.slice(8)) {
|
||||
points[pid].attributes.set(
|
||||
'data-text-transform',
|
||||
`rotate(${so.rotate * -1}, ${this.points[pid].x}, ${this.points[pid].y})`
|
||||
`rotate(${so.rotate * -1}, ${points[pid].x}, ${points[pid].y})`
|
||||
)
|
||||
}
|
||||
}
|
||||
// Paths
|
||||
this.paths.__miniscaleImperial = new this.Path()
|
||||
paths.__miniscaleImperial = new Path()
|
||||
.attr('class', 'scalebox imperial fill-current')
|
||||
.move(this.points.__miniscaleImperialTopLeft)
|
||||
.line(this.points.__miniscaleImperialBottomLeft)
|
||||
.line(this.points.__miniscaleImperialBottomRight)
|
||||
.line(this.points.__miniscaleImperialTopRight)
|
||||
.move(points.__miniscaleImperialTopLeft)
|
||||
.line(points.__miniscaleImperialBottomLeft)
|
||||
.line(points.__miniscaleImperialBottomRight)
|
||||
.line(points.__miniscaleImperialTopRight)
|
||||
.close()
|
||||
this.paths.__miniscaleMetric = new this.Path()
|
||||
paths.__miniscaleMetric = new Path()
|
||||
.attr('class', 'scalebox metric fill-bg')
|
||||
.move(this.points.__miniscaleMetricTopLeft)
|
||||
.line(this.points.__miniscaleMetricBottomLeft)
|
||||
.line(this.points.__miniscaleMetricBottomRight)
|
||||
.line(this.points.__miniscaleMetricTopRight)
|
||||
.move(points.__miniscaleMetricTopLeft)
|
||||
.line(points.__miniscaleMetricBottomLeft)
|
||||
.line(points.__miniscaleMetricBottomRight)
|
||||
.line(points.__miniscaleMetricTopRight)
|
||||
.close()
|
||||
// Text
|
||||
this.points.__miniscaleMetric = this.points.__miniscaleMetric
|
||||
points.__miniscaleMetric = points.__miniscaleMetric
|
||||
.attr('data-text', `${metricDisplaySize} x ${metricDisplaySize}`)
|
||||
.attr('data-text-class', 'text-xs center')
|
||||
this.points.__miniscaleImperial = this.points.__miniscaleImperial
|
||||
points.__miniscaleImperial = points.__miniscaleImperial
|
||||
.attr('data-text', `${imperialDisplaySize} x ${imperialDisplaySize}`)
|
||||
.attr('data-text-class', 'text-xs center ')
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
export function scalebox(so) {
|
||||
export function scalebox(so, { store, points, paths, scale, Point, Path }) {
|
||||
// Passing `false` will remove the scalebox
|
||||
if (so === false) {
|
||||
for (let id of [
|
||||
|
@ -17,15 +17,13 @@ export function scalebox(so) {
|
|||
'__scaleboxMetric',
|
||||
'__scaleboxImperial',
|
||||
])
|
||||
delete this.points[id]
|
||||
for (let id of ['__scaleboxMetric', '__scaleboxImperial']) delete this.paths[id]
|
||||
delete points[id]
|
||||
for (let id of ['__scaleboxMetric', '__scaleboxImperial']) delete paths[id]
|
||||
return true
|
||||
}
|
||||
|
||||
const scale = this.context.settings.scale
|
||||
|
||||
// Convert scale to a value between 0 and 9, inclusive.
|
||||
const scaleIndex = Math.round(10 * Math.max(0.1, Math.min(1, this.context.settings.scale))) - 1
|
||||
const scaleIndex = Math.round(10 * Math.max(0.1, Math.min(1, scale))) - 1
|
||||
|
||||
// Metric width and height in mm and display width and height for each scale index.
|
||||
const metricSizes = [
|
||||
|
@ -66,48 +64,43 @@ export function scalebox(so) {
|
|||
const imperialDisplayHeight = imperialSizes[scaleIndex][3]
|
||||
|
||||
// Box points
|
||||
this.points.__scaleboxMetricTopLeft = new this.Point(
|
||||
so.at.x - metricWidth / 2,
|
||||
so.at.y - metricHeight / 2
|
||||
)
|
||||
this.points.__scaleboxMetricTopRight = new this.Point(
|
||||
so.at.x + metricWidth / 2,
|
||||
so.at.y - metricHeight / 2
|
||||
)
|
||||
this.points.__scaleboxMetricBottomLeft = new this.Point(
|
||||
points.__scaleboxMetricTopLeft = new Point(so.at.x - metricWidth / 2, so.at.y - metricHeight / 2)
|
||||
points.__scaleboxMetricTopRight = new Point(so.at.x + metricWidth / 2, so.at.y - metricHeight / 2)
|
||||
points.__scaleboxMetricBottomLeft = new Point(
|
||||
so.at.x - metricWidth / 2,
|
||||
so.at.y + metricHeight / 2
|
||||
)
|
||||
this.points.__scaleboxMetricBottomRight = new this.Point(
|
||||
points.__scaleboxMetricBottomRight = new Point(
|
||||
so.at.x + metricWidth / 2,
|
||||
so.at.y + metricHeight / 2
|
||||
)
|
||||
this.points.__scaleboxImperialTopLeft = new this.Point(
|
||||
points.__scaleboxImperialTopLeft = new Point(
|
||||
so.at.x - imperialWidth / 2,
|
||||
so.at.y - imperialHeight / 2
|
||||
)
|
||||
this.points.__scaleboxImperialTopRight = new this.Point(
|
||||
points.__scaleboxImperialTopRight = new Point(
|
||||
so.at.x + imperialWidth / 2,
|
||||
so.at.y - imperialHeight / 2
|
||||
)
|
||||
this.points.__scaleboxImperialBottomLeft = new this.Point(
|
||||
points.__scaleboxImperialBottomLeft = new Point(
|
||||
so.at.x - imperialWidth / 2,
|
||||
so.at.y + imperialHeight / 2
|
||||
)
|
||||
this.points.__scaleboxImperialBottomRight = new this.Point(
|
||||
points.__scaleboxImperialBottomRight = new Point(
|
||||
so.at.x + imperialWidth / 2,
|
||||
so.at.y + imperialHeight / 2
|
||||
)
|
||||
// Text anchor points
|
||||
this.points.__scaleboxLead = new this.Point(so.at.x - 45 * scale, so.at.y - 15 * scale)
|
||||
this.points.__scaleboxTitle = this.points.__scaleboxLead.shift(-90, 10 * scale)
|
||||
this.points.__scaleboxText = this.points.__scaleboxTitle.shift(-90, 12 * scale)
|
||||
this.points.__scaleboxLink = this.points.__scaleboxText.shift(-90, 5 * scale)
|
||||
this.points.__scaleboxMetric = new this.Point(so.at.x, so.at.y + 20 * scale)
|
||||
this.points.__scaleboxImperial = new this.Point(so.at.x, so.at.y + 24 * scale)
|
||||
points.__scaleboxLead = new Point(so.at.x - 45 * scale, so.at.y - 15 * scale)
|
||||
points.__scaleboxTitle = points.__scaleboxLead.shift(-90, 10 * scale)
|
||||
points.__scaleboxText = points.__scaleboxTitle.shift(-90, 12 * scale)
|
||||
points.__scaleboxLink = points.__scaleboxText.shift(-90, 5 * scale)
|
||||
points.__scaleboxMetric = new Point(so.at.x, so.at.y + 20 * scale)
|
||||
points.__scaleboxImperial = new Point(so.at.x, so.at.y + 24 * scale)
|
||||
// Rotation
|
||||
if (so.rotate) {
|
||||
let points = [
|
||||
so.rotate = Number(so.rotate)
|
||||
let toRotate = [
|
||||
'__scaleboxMetricTopLeft',
|
||||
'__scaleboxMetricTopRight',
|
||||
'__scaleboxMetricBottomLeft',
|
||||
|
@ -123,61 +116,61 @@ export function scalebox(so) {
|
|||
'__scaleboxMetric',
|
||||
'__scaleboxImperial',
|
||||
]
|
||||
for (let pid of points) this.points[pid] = this.points[pid].rotate(so.rotate, so.at)
|
||||
for (let pid of points.slice(8)) {
|
||||
this.points[pid].attributes.set(
|
||||
for (let pid of toRotate) points[pid] = points[pid].rotate(so.rotate, so.at)
|
||||
for (let pid of toRotate.slice(8)) {
|
||||
points[pid].attributes.set(
|
||||
'data-text-transform',
|
||||
`rotate(${so.rotate * -1}, ${this.points[pid].x}, ${this.points[pid].y})`
|
||||
`rotate(${so.rotate * -1}, ${points[pid].x}, ${points[pid].y})`
|
||||
)
|
||||
}
|
||||
}
|
||||
// Paths
|
||||
this.paths.__scaleboxImperial = new this.Path()
|
||||
paths.__scaleboxImperial = new Path()
|
||||
.attr('class', 'scalebox imperial fill-current')
|
||||
.move(this.points.__scaleboxImperialTopLeft)
|
||||
.line(this.points.__scaleboxImperialBottomLeft)
|
||||
.line(this.points.__scaleboxImperialBottomRight)
|
||||
.line(this.points.__scaleboxImperialTopRight)
|
||||
.move(points.__scaleboxImperialTopLeft)
|
||||
.line(points.__scaleboxImperialBottomLeft)
|
||||
.line(points.__scaleboxImperialBottomRight)
|
||||
.line(points.__scaleboxImperialTopRight)
|
||||
.close()
|
||||
this.paths.__scaleboxMetric = new this.Path()
|
||||
paths.__scaleboxMetric = new Path()
|
||||
.attr('class', 'scalebox metric fill-bg')
|
||||
.move(this.points.__scaleboxMetricTopLeft)
|
||||
.line(this.points.__scaleboxMetricBottomLeft)
|
||||
.line(this.points.__scaleboxMetricBottomRight)
|
||||
.line(this.points.__scaleboxMetricTopRight)
|
||||
.move(points.__scaleboxMetricTopLeft)
|
||||
.line(points.__scaleboxMetricBottomLeft)
|
||||
.line(points.__scaleboxMetricBottomRight)
|
||||
.line(points.__scaleboxMetricTopRight)
|
||||
.close()
|
||||
// Lead
|
||||
this.points.__scaleboxLead = this.points.__scaleboxLead
|
||||
points.__scaleboxLead = points.__scaleboxLead
|
||||
.attr('data-text', so.lead || 'FreeSewing')
|
||||
.attr('data-text-class', 'text-sm')
|
||||
// Title
|
||||
if (so.title) this.points.__scaleboxTitle.attributes.set('data-text', so.title)
|
||||
if (so.title) points.__scaleboxTitle.attributes.set('data-text', so.title)
|
||||
else {
|
||||
let name = this.context.config?.data?.name || 'No Name'
|
||||
let name = store.data?.name || 'No Name'
|
||||
if (name.indexOf('@freesewing/') !== -1) name = name.replace('@freesewing/', '')
|
||||
this.points.__scaleboxTitle = this.points.__scaleboxTitle
|
||||
points.__scaleboxTitle = points.__scaleboxTitle
|
||||
.attr('data-text', name)
|
||||
.attr('data-text', 'v' + (this.context.config?.data?.version || 'No Version'))
|
||||
.attr('data-text', 'v' + (store.data?.version || 'No Version'))
|
||||
}
|
||||
this.points.__scaleboxTitle.attributes.add('data-text-class', 'text-lg')
|
||||
points.__scaleboxTitle.attributes.add('data-text-class', 'text-lg')
|
||||
// Text
|
||||
if (typeof so.text === 'string') {
|
||||
this.points.__scaleboxText.attr('data-text', so.text)
|
||||
points.__scaleboxText.attr('data-text', so.text)
|
||||
} else {
|
||||
this.points.__scaleboxText.attr('data-text', 'supportFreesewingBecomeAPatron')
|
||||
this.points.__scaleboxLink = this.points.__scaleboxLink
|
||||
points.__scaleboxText.attr('data-text', 'supportFreesewingBecomeAPatron')
|
||||
points.__scaleboxLink = points.__scaleboxLink
|
||||
.attr('data-text', 'freesewing.org/patrons/join')
|
||||
.attr('data-text-class', 'text-sm fill-note')
|
||||
}
|
||||
this.points.__scaleboxText.attr('data-text-class', 'text-xs').attr('data-text-lineheight', 4)
|
||||
points.__scaleboxText.attr('data-text-class', 'text-xs').attr('data-text-lineheight', 4)
|
||||
// Instructions
|
||||
this.points.__scaleboxMetric = this.points.__scaleboxMetric
|
||||
points.__scaleboxMetric = points.__scaleboxMetric
|
||||
.attr('data-text', 'theWhiteInsideOfThisBoxShouldMeasure')
|
||||
.attr('data-text', `${metricDisplayWidth}`)
|
||||
.attr('data-text', 'x')
|
||||
.attr('data-text', `${metricDisplayHeight}`)
|
||||
.attr('data-text-class', 'text-xs center')
|
||||
this.points.__scaleboxImperial = this.points.__scaleboxImperial
|
||||
points.__scaleboxImperial = points.__scaleboxImperial
|
||||
.attr('data-text', 'theBlackOutsideOfThisBoxShouldMeasure')
|
||||
.attr('data-text', `${imperialDisplayWidth}`)
|
||||
.attr('data-text', 'x')
|
||||
|
|
|
@ -8,17 +8,20 @@ describe('Scalebox Plugin Tests', () => {
|
|||
it('Should run the default scalebox macro', () => {
|
||||
const part = {
|
||||
name: 'test',
|
||||
draft: ({ points, Point, macro }) => {
|
||||
draft: ({ points, Point, macro, part }) => {
|
||||
points.anchor = new Point(100, 200)
|
||||
macro('scalebox', {
|
||||
at: points.anchor,
|
||||
})
|
||||
|
||||
return part
|
||||
},
|
||||
plugins: [plugin],
|
||||
}
|
||||
const Pattern = new Design({ parts: [part], plugins: [plugin] })
|
||||
const Pattern = new Design({ parts: [part] })
|
||||
const pattern = new Pattern()
|
||||
pattern.draft()
|
||||
let p = pattern.parts.test.points
|
||||
let p = pattern.parts[0].test.points
|
||||
expect(p.__scaleboxMetricTopLeft.x).to.equal(50)
|
||||
expect(p.__scaleboxMetricTopLeft.y).to.equal(175)
|
||||
expect(p.__scaleboxMetricTopRight.x).to.equal(150)
|
||||
|
@ -47,7 +50,7 @@ describe('Scalebox Plugin Tests', () => {
|
|||
expect(p.__scaleboxMetric.y).to.equal(220)
|
||||
expect(p.__scaleboxImperial.x).to.equal(100)
|
||||
expect(p.__scaleboxImperial.y).to.equal(224)
|
||||
p = pattern.parts.test.paths.__scaleboxMetric
|
||||
p = pattern.parts[0].test.paths.__scaleboxMetric
|
||||
expect(p.ops[0].type).to.equal('move')
|
||||
expect(p.ops[1].type).to.equal('line')
|
||||
expect(p.ops[2].type).to.equal('line')
|
||||
|
@ -61,7 +64,7 @@ describe('Scalebox Plugin Tests', () => {
|
|||
expect(p.ops[2].to.y).to.equal(225)
|
||||
expect(p.ops[3].to.x).to.equal(150)
|
||||
expect(p.ops[3].to.y).to.equal(175)
|
||||
p = pattern.parts.test.paths.__scaleboxImperial
|
||||
p = pattern.parts[0].test.paths.__scaleboxImperial
|
||||
expect(p.ops[0].type).to.equal('move')
|
||||
expect(p.ops[1].type).to.equal('line')
|
||||
expect(p.ops[2].type).to.equal('line')
|
||||
|
@ -87,11 +90,12 @@ describe('Scalebox Plugin Tests', () => {
|
|||
rotate: 90,
|
||||
})
|
||||
},
|
||||
plugins: [plugin],
|
||||
}
|
||||
const Pattern = new Design({ parts: [part], plugins: [plugin] })
|
||||
const Pattern = new Design({ parts: [part] })
|
||||
const pattern = new Pattern()
|
||||
pattern.draft()
|
||||
const p = pattern.parts.test.points
|
||||
const p = pattern.parts[0].test.points
|
||||
expect(round(p.__scaleboxMetricTopLeft.x)).to.equal(75)
|
||||
expect(round(p.__scaleboxMetricTopLeft.y)).to.equal(250)
|
||||
expect(round(p.__scaleboxMetricTopRight.x)).to.equal(75)
|
||||
|
@ -125,27 +129,29 @@ describe('Scalebox Plugin Tests', () => {
|
|||
it('Should run the scalebox macro with default text', () => {
|
||||
const part = {
|
||||
name: 'test',
|
||||
draft: ({ points, Point, macro }) => {
|
||||
draft: ({ points, Point, macro, part }) => {
|
||||
points.anchor = new Point(100, 200)
|
||||
macro('scalebox', {
|
||||
at: points.anchor,
|
||||
})
|
||||
|
||||
return part
|
||||
},
|
||||
plugins: [plugin],
|
||||
}
|
||||
const Pattern = new Design({
|
||||
parts: [part],
|
||||
plugins: [plugin],
|
||||
data: { name: 'test', version: '1.2.3' },
|
||||
})
|
||||
const pattern = new Pattern()
|
||||
pattern.draft()
|
||||
let p = pattern.parts.test.points.__scaleboxLead.attributes
|
||||
let p = pattern.parts[0].test.points.__scaleboxLead.attributes
|
||||
expect(p.get('data-text')).to.equal('FreeSewing')
|
||||
expect(p.get('data-text-class')).to.equal('text-sm')
|
||||
p = pattern.parts.test.points.__scaleboxTitle.attributes
|
||||
p = pattern.parts[0].test.points.__scaleboxTitle.attributes
|
||||
expect(p.get('data-text')).to.equal('test v1.2.3')
|
||||
expect(p.get('data-text-class')).to.equal('text-lg')
|
||||
p = pattern.parts.test.points.__scaleboxText.attributes
|
||||
p = pattern.parts[0].test.points.__scaleboxText.attributes
|
||||
expect(p.get('data-text-class')).to.equal('text-xs')
|
||||
expect(p.get('data-text-lineheight')).to.equal('4')
|
||||
expect(p.list['data-text'][0]).to.equal('supportFreesewingBecomeAPatron')
|
||||
|
@ -154,7 +160,7 @@ describe('Scalebox Plugin Tests', () => {
|
|||
it('Should run the scalebox macro with custom text', () => {
|
||||
const part = {
|
||||
name: 'test',
|
||||
draft: ({ points, Point, macro }) => {
|
||||
draft: ({ points, Point, macro, part }) => {
|
||||
points.anchor = new Point(100, 200)
|
||||
macro('scalebox', {
|
||||
at: points.anchor,
|
||||
|
@ -162,22 +168,24 @@ describe('Scalebox Plugin Tests', () => {
|
|||
title: 'theTitle',
|
||||
text: 'theText',
|
||||
})
|
||||
|
||||
return part
|
||||
},
|
||||
plugins: [plugin],
|
||||
}
|
||||
const Pattern = new Design({
|
||||
parts: [part],
|
||||
plugins: [plugin],
|
||||
data: { name: 'test', version: '1.2.3' },
|
||||
})
|
||||
const pattern = new Pattern()
|
||||
pattern.draft()
|
||||
let p = pattern.parts.test.points.__scaleboxLead.attributes
|
||||
let p = pattern.parts[0].test.points.__scaleboxLead.attributes
|
||||
expect(p.get('data-text')).to.equal('theLead')
|
||||
expect(p.get('data-text-class')).to.equal('text-sm')
|
||||
p = pattern.parts.test.points.__scaleboxTitle.attributes
|
||||
p = pattern.parts[0].test.points.__scaleboxTitle.attributes
|
||||
expect(p.get('data-text')).to.equal('theTitle')
|
||||
expect(p.get('data-text-class')).to.equal('text-lg')
|
||||
p = pattern.parts.test.points.__scaleboxText.attributes
|
||||
p = pattern.parts[0].test.points.__scaleboxText.attributes
|
||||
expect(p.get('data-text')).to.equal('theText')
|
||||
expect(p.get('data-text-class')).to.equal('text-xs')
|
||||
expect(p.get('data-text-lineheight')).to.equal('4')
|
||||
|
@ -186,7 +194,7 @@ describe('Scalebox Plugin Tests', () => {
|
|||
it('Should apply scale to the scalebox macro', () => {
|
||||
const part = {
|
||||
name: 'test',
|
||||
draft: ({ points, Point, macro }) => {
|
||||
draft: ({ points, Point, macro, part }) => {
|
||||
points.anchor = new Point(100, 200)
|
||||
macro('scalebox', {
|
||||
at: points.anchor,
|
||||
|
@ -194,7 +202,10 @@ describe('Scalebox Plugin Tests', () => {
|
|||
title: 'theTitle',
|
||||
text: 'theText',
|
||||
})
|
||||
|
||||
return part
|
||||
},
|
||||
plugins: [plugin],
|
||||
}
|
||||
const Pattern = new Design({
|
||||
parts: [part],
|
||||
|
@ -203,7 +214,7 @@ describe('Scalebox Plugin Tests', () => {
|
|||
})
|
||||
const pattern = new Pattern({ scale: 0.5 })
|
||||
pattern.draft()
|
||||
let p = pattern.parts.test.points
|
||||
let p = pattern.parts[0].test.points
|
||||
expect(p.__scaleboxMetricTopLeft.x).to.equal(75)
|
||||
expect(p.__scaleboxMetricTopLeft.y).to.equal(187.5)
|
||||
expect(p.__scaleboxMetricTopRight.x).to.equal(125)
|
||||
|
@ -231,12 +242,15 @@ describe('Scalebox Plugin Tests', () => {
|
|||
it('Should apply scale to the miniscale macro', () => {
|
||||
const part = {
|
||||
name: 'test',
|
||||
draft: ({ points, Point, macro }) => {
|
||||
draft: ({ points, Point, macro, part }) => {
|
||||
points.anchor = new Point(100, 200)
|
||||
macro('miniscale', {
|
||||
at: points.anchor,
|
||||
})
|
||||
|
||||
return part
|
||||
},
|
||||
plugins: [plugin],
|
||||
}
|
||||
const Pattern = new Design({
|
||||
parts: [part],
|
||||
|
@ -245,7 +259,7 @@ describe('Scalebox Plugin Tests', () => {
|
|||
})
|
||||
const pattern = new Pattern({ scale: 0.5 })
|
||||
pattern.draft()
|
||||
let p = pattern.parts.test.points
|
||||
let p = pattern.parts[0].test.points
|
||||
expect(p.__miniscaleMetricTopLeft.x).to.equal(92)
|
||||
expect(p.__miniscaleMetricTopLeft.y).to.equal(192)
|
||||
expect(p.__miniscaleMetricTopRight.x).to.equal(108)
|
||||
|
|
|
@ -4,11 +4,11 @@ export const plugin = {
|
|||
name,
|
||||
version,
|
||||
macros: {
|
||||
sprinkle: function (so) {
|
||||
sprinkle: function (so, { snippets, Snippet, points }) {
|
||||
for (let pid of so.on) {
|
||||
this.snippets[pid + '-' + so.snippet] = new this.Snippet(so.snippet, this.points[pid])
|
||||
if (so.scale) this.snippets[pid + '-' + so.snippet].attr('data-scale', so.scale)
|
||||
if (so.rotate) this.snippets[pid + '-' + so.snippet].attr('data-rotate', so.rotate)
|
||||
snippets[pid + '-' + so.snippet] = new Snippet(so.snippet, points[pid])
|
||||
if (so.scale) snippets[pid + '-' + so.snippet].attr('data-scale', so.scale)
|
||||
if (so.rotate) snippets[pid + '-' + so.snippet].attr('data-rotate', so.rotate)
|
||||
}
|
||||
},
|
||||
},
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
export const paperless = `
|
||||
export const paperlessStyle = `
|
||||
/* Paperless grid */
|
||||
svg.freesewing path.grid {
|
||||
fill: none;
|
||||
|
@ -26,7 +26,7 @@ svg.freesewing path.gridline-xs {
|
|||
svg.freesewing path.gridbox {
|
||||
fill: url(#grid);
|
||||
}`
|
||||
export const sample = `
|
||||
export const sampleStyle = `
|
||||
/* Sample classes */
|
||||
svg.freesewing path.sample {
|
||||
stroke-width: 0.75
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { name, version } from '../data.mjs'
|
||||
import { sample, paperless, buildStylesheet } from './css.mjs'
|
||||
import { sampleStyle, paperlessStyle, buildStylesheet } from './css.mjs'
|
||||
|
||||
const grid = {
|
||||
metric: `
|
||||
|
@ -28,16 +28,18 @@ export const plugin = {
|
|||
const current = svg.attributes.get('class')
|
||||
if (!current || current.indexOf('freesewing') !== -1) {
|
||||
svg.attributes.set('class', 'freesewing')
|
||||
svg.style += sample
|
||||
svg.style += paperless
|
||||
svg.style += sampleStyle
|
||||
svg.style += paperlessStyle
|
||||
svg.style += buildStylesheet(svg.pattern.settings.scale, data.stripped)
|
||||
// FIXME : Re-implement this for v3
|
||||
/*
|
||||
if (svg.pattern.settings[0].paperless) {
|
||||
svg.pattern.settings.units === 'imperial'
|
||||
let paperless = false
|
||||
for (const set of svg.pattern.settings) {
|
||||
if (set.paperless) paperless = true
|
||||
}
|
||||
if (paperless) {
|
||||
svg.pattern.settings[0].units === 'imperial'
|
||||
? (svg.defs += grid.imperial)
|
||||
: (svg.defs += grid.metric)
|
||||
for (const key in svg.pattern.parts) {
|
||||
for (const key in svg.pattern.parts[0]) {
|
||||
const part = svg.pattern.parts[key]
|
||||
if (!part.hidden && svg.pattern.__needs(key)) {
|
||||
let anchor = new svg.pattern.Point(0, 0)
|
||||
|
@ -57,7 +59,6 @@ export const plugin = {
|
|||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
},
|
||||
},
|
||||
|
|
|
@ -31,7 +31,7 @@ export const plugin = {
|
|||
},
|
||||
},
|
||||
macros: {
|
||||
title: function (so) {
|
||||
title: function (so, { points, scale, locale, store }) {
|
||||
const prefix = so.prefix || ''
|
||||
|
||||
// Passing `false` will remove the title
|
||||
|
@ -43,7 +43,7 @@ export const plugin = {
|
|||
`_${prefix}_titleFor`,
|
||||
`_${prefix}_exportDate`,
|
||||
])
|
||||
delete this.points[id]
|
||||
delete points[id]
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -59,36 +59,36 @@ export const plugin = {
|
|||
}
|
||||
|
||||
so = { ...defaults, ...so }
|
||||
so.scale = so.scale * this.context.settings.scale
|
||||
so.scale = so.scale * scale
|
||||
let overwrite = true
|
||||
if (so.append) overwrite = false
|
||||
this.points[`_${prefix}_titleNr`] = so.at
|
||||
points[`_${prefix}_titleNr`] = so.at
|
||||
.clone()
|
||||
.attr('data-text', so.nr, overwrite)
|
||||
.attr('data-text-class', 'text-4xl fill-note font-bold')
|
||||
.attr('data-text-transform', transform(so.at))
|
||||
let shift = 8
|
||||
if (so.title) {
|
||||
this.points[`_${prefix}_titleName`] = so.at
|
||||
points[`_${prefix}_titleName`] = so.at
|
||||
.shift(-90 - so.rotation, shift * so.scale)
|
||||
.attr('data-text', so.title)
|
||||
.attr('data-text-class', 'text-lg fill-current font-bold')
|
||||
.attr('data-text-transform', transform(so.at.shift(-90 - so.rotation, 13 * so.scale)))
|
||||
shift += 8
|
||||
}
|
||||
let name = this.context.config?.data?.name || 'No Name'
|
||||
let name = store.data?.name || 'No Name'
|
||||
name = name.replace('@freesewing/', '')
|
||||
this.points[`_${prefix}_titlePattern`] = so.at
|
||||
points[`_${prefix}_titlePattern`] = so.at
|
||||
.shift(-90 - so.rotation, shift * so.scale)
|
||||
.attr('data-text', name)
|
||||
.attr('data-text', 'v' + (this.context.config?.data?.version || 'No Version'))
|
||||
.attr('data-text', 'v' + (store.data?.version || 'No Version'))
|
||||
.attr('data-text-class', 'fill-note')
|
||||
.attr('data-text-transform', transform(so.at.shift(-90 - so.rotation, shift * so.scale)))
|
||||
if (this.context.settings.metadata && this.context.settings.metadata.for) {
|
||||
if (store.data.for) {
|
||||
shift += 8
|
||||
this.points[`_${prefix}_titleFor`] = so.at
|
||||
points[`_${prefix}_titleFor`] = so.at
|
||||
.shift(-90 - so.rotation, shift * so.scale)
|
||||
.attr('data-text', '( ' + this.context.settings.metadata.for + ' )')
|
||||
.attr('data-text', '( ' + store.data.for + ' )')
|
||||
.attr('data-text-class', 'fill-current font-bold')
|
||||
.attr('data-text-transform', transform(so.at.shift(-90 - so.rotation, shift * so.scale)))
|
||||
}
|
||||
|
@ -98,11 +98,11 @@ export const plugin = {
|
|||
let mins = now.getMinutes()
|
||||
if (hours < 10) hours = `0${hours}`
|
||||
if (mins < 10) mins = `0${mins}`
|
||||
this.points[`_${prefix}_exportDate`] = so.at
|
||||
points[`_${prefix}_exportDate`] = so.at
|
||||
.shift(-90 - so.rotation, shift * so.scale)
|
||||
.attr(
|
||||
'data-text',
|
||||
now.toLocaleDateString(this.context.settings.locale || 'en', {
|
||||
now.toLocaleDateString(locale || 'en', {
|
||||
weekday: 'long',
|
||||
year: 'numeric',
|
||||
month: 'short',
|
||||
|
|
|
@ -8,35 +8,37 @@ describe('Title Plugin Tests', () => {
|
|||
it('Should run the title macro', () => {
|
||||
const part = {
|
||||
name: 'test',
|
||||
draft: ({ points, Point, macro }) => {
|
||||
draft: ({ points, Point, macro, part }) => {
|
||||
points.anchor = new Point(-12, -34)
|
||||
macro('title', {
|
||||
at: points.anchor,
|
||||
nr: 3,
|
||||
title: 'unitTest',
|
||||
})
|
||||
|
||||
return part
|
||||
},
|
||||
plugins: [plugin],
|
||||
}
|
||||
const Pattern = new Design({
|
||||
data: { name: 'testPattern', version: 99 },
|
||||
parts: [part],
|
||||
plugins: [plugin],
|
||||
})
|
||||
const pattern = new Pattern()
|
||||
pattern.draft().render()
|
||||
let p = pattern.parts.test.points.__titleNr
|
||||
let p = pattern.parts[0].test.points.__titleNr
|
||||
expect(p.x).to.equal(-12)
|
||||
expect(p.y).to.equal(-34)
|
||||
expect(p.attributes.get('data-text')).to.equal('3')
|
||||
expect(p.attributes.get('data-text-class')).to.equal('text-4xl fill-note font-bold')
|
||||
expect(p.attributes.get('data-text-x')).to.equal('-12')
|
||||
expect(p.attributes.get('data-text-y')).to.equal('-34')
|
||||
p = pattern.parts.test.points.__titleName
|
||||
p = pattern.parts[0].test.points.__titleName
|
||||
expect(p.attributes.get('data-text')).to.equal('unitTest')
|
||||
expect(p.attributes.get('data-text-class')).to.equal('text-lg fill-current font-bold')
|
||||
expect(p.attributes.get('data-text-x')).to.equal('-12')
|
||||
expect(p.attributes.get('data-text-y')).to.equal('-26')
|
||||
p = pattern.parts.test.points.__titlePattern
|
||||
p = pattern.parts[0].test.points.__titlePattern
|
||||
expect(p.attributes.get('data-text')).to.equal('testPattern v99')
|
||||
expect(p.attributes.get('data-text-class')).to.equal('fill-note')
|
||||
expect(p.attributes.get('data-text-x')).to.equal('-12')
|
||||
|
@ -46,7 +48,7 @@ describe('Title Plugin Tests', () => {
|
|||
it('Should run the title macro with append flag', () => {
|
||||
const part = {
|
||||
name: 'test',
|
||||
draft: ({ points, Point, macro }) => {
|
||||
draft: ({ points, Point, macro, part }) => {
|
||||
points.anchor = new Point(-12, -34).attr('data-text', '#')
|
||||
macro('title', {
|
||||
at: points.anchor,
|
||||
|
@ -54,16 +56,18 @@ describe('Title Plugin Tests', () => {
|
|||
title: 'unitTest',
|
||||
append: true,
|
||||
})
|
||||
|
||||
return part
|
||||
},
|
||||
plugins: [plugin],
|
||||
}
|
||||
const Pattern = new Design({
|
||||
data: { name: 'testPattern', version: 99 },
|
||||
parts: [part],
|
||||
plugins: [plugin],
|
||||
})
|
||||
const pattern = new Pattern()
|
||||
pattern.draft().render()
|
||||
let p = pattern.parts.test.points.__titleNr
|
||||
let p = pattern.parts[0].test.points.__titleNr
|
||||
expect(p.x).to.equal(-12)
|
||||
expect(p.y).to.equal(-34)
|
||||
expect(p.attributes.get('data-text')).to.equal('# 3')
|
||||
|
@ -75,7 +79,7 @@ describe('Title Plugin Tests', () => {
|
|||
it('Should run the title macro with point prefix', () => {
|
||||
const part = {
|
||||
name: 'test',
|
||||
draft: ({ points, Point, macro }) => {
|
||||
draft: ({ points, Point, macro, part }) => {
|
||||
points.anchor = new Point(-12, -34).attr('data-text', '#')
|
||||
macro('title', {
|
||||
at: points.anchor,
|
||||
|
@ -83,28 +87,30 @@ describe('Title Plugin Tests', () => {
|
|||
title: 'unitTest',
|
||||
prefix: 'foo',
|
||||
})
|
||||
|
||||
return part
|
||||
},
|
||||
plugins: [plugin],
|
||||
}
|
||||
const Pattern = new Design({
|
||||
data: { name: 'testPattern', version: 99 },
|
||||
parts: [part],
|
||||
plugins: [plugin],
|
||||
})
|
||||
const pattern = new Pattern()
|
||||
pattern.draft().render()
|
||||
let p = pattern.parts.test.points._foo_titleNr
|
||||
let p = pattern.parts[0].test.points._foo_titleNr
|
||||
expect(p.x).to.equal(-12)
|
||||
expect(p.y).to.equal(-34)
|
||||
expect(p.attributes.get('data-text')).to.equal('3')
|
||||
expect(p.attributes.get('data-text-class')).to.equal('text-4xl fill-note font-bold')
|
||||
expect(p.attributes.get('data-text-x')).to.equal('-12')
|
||||
expect(p.attributes.get('data-text-y')).to.equal('-34')
|
||||
p = pattern.parts.test.points._foo_titleName
|
||||
p = pattern.parts[0].test.points._foo_titleName
|
||||
expect(p.attributes.get('data-text')).to.equal('unitTest')
|
||||
expect(p.attributes.get('data-text-class')).to.equal('text-lg fill-current font-bold')
|
||||
expect(p.attributes.get('data-text-x')).to.equal('-12')
|
||||
expect(p.attributes.get('data-text-y')).to.equal('-26')
|
||||
p = pattern.parts.test.points._foo_titlePattern
|
||||
p = pattern.parts[0].test.points._foo_titlePattern
|
||||
expect(p.attributes.get('data-text')).to.equal('testPattern v99')
|
||||
expect(p.attributes.get('data-text-class')).to.equal('fill-note')
|
||||
expect(p.attributes.get('data-text-x')).to.equal('-12')
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue