1
0
Fork 0

Merge branch 'develop' into joost

This commit is contained in:
joostdecock 2023-09-28 15:42:16 +02:00
commit 1154d2de93
101 changed files with 3719 additions and 3498 deletions

View file

@ -184,7 +184,7 @@
"design": "Wouter Van Wageningen",
"difficulty": 4,
"tags": ["accessories", "toys"],
"techniques": []
"techniques": ["curvedSeam", "dart"]
},
"holmes": {
"description": "A FreeSewing pattern for a Sherlock Holmes hat",
@ -270,7 +270,7 @@
"design": "Wouter Van Wageningen",
"difficulty": 3,
"tags": ["blocks", "tops"],
"techniques": []
"techniques": ["curvedSeam", "precision", "princessSeam"]
},
"octoplushy": {
"description": "A FreeSewing pattern for an octopus plushy toy",
@ -278,7 +278,7 @@
"design": "Wouter Van Wageningen",
"difficulty": 4,
"tags": ["accessories", "toys"],
"techniques": []
"techniques": ["curvedSeam", "precision"]
},
"paco": {
"description": "A FreeSewing pattern for summer pants",
@ -294,7 +294,7 @@
"design": "Wouter Van Wageningen",
"difficulty": 3,
"tags": ["bottoms", "skirts"],
"techniques": []
"techniques": ["hem", "curvedSeam", "precision", "zipper"]
},
"plugintest": {
"description": "A FreeSewing pattern to test (y)our plugins",

View file

@ -56,7 +56,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -54,7 +54,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -55,7 +55,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -54,7 +54,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -54,7 +54,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -57,7 +57,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -54,7 +54,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -55,7 +55,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -56,7 +56,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -54,7 +54,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -59,7 +59,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -58,7 +58,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -54,7 +54,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -58,7 +58,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -54,7 +54,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -56,7 +56,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -51,7 +51,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -54,7 +54,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -54,7 +54,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -2,21 +2,21 @@
"t": "Hi the shark",
"d": "The world's friendliest shark",
"p": {
"aboveMouth": "Above mouth",
"aboveMouth": "Above mouth piece",
"belly": "Belly",
"body": "Body",
"bottomFin": "Bottom fin",
"lowerTeeth": "Lower teetch",
"bottomOfFin": "Bottom of fin",
"lowerTeeth": "Lower teeth",
"mouth": "Mouth",
"tail": "Tail",
"topFin": "Top fin",
"topOfFin": "Top of fin",
"upperTeeth": "Upper teeth"
},
"s": {},
"o": {
"hungry": {
"t": "Hungry",
"d": "Changes the mouth shape to convey Hi is hungry"
"d": "Changes the belly shape to convey if Hi has just eaten"
},
"nosePointiness": {
"t": "Nose pointiness",
@ -26,6 +26,14 @@
"t": "Aggressive",
"d": "Give Hi pointy teeth, or not"
},
"aggressiveNo": {
"t": "Friendly",
"d": "Hi will have rounded teeth"
},
"aggressiveYes": {
"t": "Aggressive",
"d": "Hi will have pointy teeth"
},
"size": {
"t": "Size",
"d": "Sharks come in all sizes, and so does Hi"

View file

@ -54,7 +54,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -1,38 +1,28 @@
import { body } from './body.mjs'
import { mouth } from './mouth.mjs'
function draftHiAboveMouth({
store,
sa,
Point,
points,
Path,
paths,
Snippet,
snippets,
options,
complete,
paperless,
macro,
part,
}) {
let aboveMouth01_02d = 266.7238454769277 * options.size
const aboveMouth01_02a = 353.4089695458119
const aboveMouth02_03d = 28.348200101593726 * options.size
const aboveMouth02_03a = 233.13495309848912
let aboveMouth01_04d = 57.858419828059574 * options.size
const aboveMouth01_04a = 208.91023166349467
const aboveMouth01cp1d = 62.927189989701574 * options.size
const aboveMouth01cp1a = 298.7196048714283
const aboveMouth02cp2d = 169.53367533325053 * options.size
const aboveMouth02cp2a = 195.1209034747764
const aboveMouth03cp1d = 172.36585117998288 * options.size
const aboveMouth03cp1a = 197.87876803095696
const aboveMouth04cp2d = 66.94005927693816 * options.size
const aboveMouth04cp2a = 308.8121959753343
export const aboveMouth = {
name: 'hi.aboveMouth',
after: [body, mouth],
draft: ({ store, sa, Point, points, Path, paths, Snippet, snippets, macro, part }) => {
const multiplier = store.get('multiplier')
const faceTopLength = store.get('faceTopLength')
let aboveMouth01_02d = 266.7238454769277 * multiplier
const aboveMouth01_02a = 353.4089695458119
const aboveMouth02_03d = 28.348200101593726 * multiplier
const aboveMouth02_03a = 233.13495309848912
let aboveMouth01_04d = 57.858419828059574 * multiplier
const aboveMouth01_04a = 208.91023166349467
const aboveMouth01cp1d = 62.927189989701574 * multiplier
const aboveMouth01cp1a = 298.7196048714283
const aboveMouth02cp2d = 169.53367533325053 * multiplier
const aboveMouth02cp2a = 195.1209034747764
const aboveMouth03cp1d = 172.36585117998288 * multiplier
const aboveMouth03cp1a = 197.87876803095696
const aboveMouth04cp2d = 66.94005927693816 * multiplier
const aboveMouth04cp2a = 308.8121959753343
let diff = 0
let iteration = 0
do {
@ -85,34 +75,43 @@ function draftHiAboveMouth({
store.set('aboveMouthBottomLength', paths.bellyAndMouthAttachment.length())
store.set('aboveMouthFinLength', points.aboveMouth02.dist(points.aboveMouth03))
store.cutlist.addCut({ material: 'color2Belly' })
store.cutlist.addCut({ cut: 2, material: 'color2Belly' })
points.gridAnchor = points.aboveMouth04.clone()
// Complete?
if (complete) {
points.aboveMouthSnippet = new Path()
.move(points.aboveMouth01)
.curve(points.aboveMouth01cp1, points.aboveMouth02cp2, points.aboveMouth02)
.shiftAlong(store.get('mouthTopLength'))
snippets.mouth = new Snippet('bnotch', points.aboveMouthSnippet)
points.aboveMouthBottom = paths.seam.edge('bottom')
points.aboveMouthTop = new Path()
.move(points.aboveMouth01)
.curve(points.aboveMouth01cp1, points.aboveMouth02cp2, points.aboveMouth02)
.edge('bottom')
points.titleAnchor = points.aboveMouth04.shiftFractionTowards(points.aboveMouth01cp1, 0.5)
points.logoAnchor = points.aboveMouth01cp1.shiftFractionTowards(points.aboveMouth02cp2, 0.5)
snippets.logo = new Snippet('logo', points.logoAnchor).attr(
'data-scale',
(options.size > 1 ? 1 : options.size) / 4
(multiplier > 1 ? 1 : multiplier) / 4
)
macro('title', {
at: points.titleAnchor,
nr: 5,
title: 'aboveMouth',
scale: options.size / 2,
scale: multiplier / 2,
})
let split = paths.bellyAndMouthAttachment.split(points.aboveMouthSnippet)
paths.bellyAttachment = split[0].attr('data-text-class', 'text-xs')
paths.mouthAttachment = split[1].attr('data-text-class', 'text-xs')
macro('banner', {
path: paths.aboveMouthAttachment,
text: 'aboveMouth',
id: 'aboveMouth',
dy: -0,
spaces: 0,
repeat: 1,
@ -120,6 +119,7 @@ function draftHiAboveMouth({
macro('banner', {
path: paths.bodyAttachment,
text: 'body',
id: 'body',
dy: 0,
spaces: 10,
repeat: 7,
@ -127,97 +127,80 @@ function draftHiAboveMouth({
macro('banner', {
path: paths.finAttachment,
text: '+',
id: 'plus',
dy: 0,
spaces: 0,
repeat: 4,
})
let split = paths.bellyAndMouthAttachment.split(points.aboveMouthSnippet)
paths.bellyAttachment = split[0].attr('data-text-class', 'text-xs')
macro('banner', {
path: paths.bellyAttachment,
text: 'belly',
id: 'belly',
dy: 0,
spaces: 4,
repeat: 3,
})
paths.mouthAttachment = split[1].attr('data-text-class', 'text-xs')
macro('banner', {
path: paths.mouthAttachment,
text: 'mouth',
id: 'mouth',
dy: 0,
spaces: 4,
repeat: 3,
})
if (paperless) {
macro('hd', {
from: points.aboveMouth04,
to: points.aboveMouth01,
y: points.aboveMouth01.y - sa - 10,
id: 'widthCorners',
})
macro('hd', {
from: points.aboveMouth01,
to: points.aboveMouth02,
y: points.aboveMouth01.y - sa - 10,
id: 'cornerToMid',
})
macro('hd', {
from: points.aboveMouthSnippet,
to: points.aboveMouth02,
y: points.aboveMouth01.y,
id: 'widthToSnippet',
})
macro('vd', {
from: points.aboveMouth04,
to: points.aboveMouth01,
x: points.aboveMouth04.x - sa - 15,
noStartMarker: true,
noEndMarker: true,
})
points.aboveMouthBottom = paths.seam.edge('bottom')
points.aboveMouthTop = new Path()
.move(points.aboveMouth01)
.curve(points.aboveMouth01cp1, points.aboveMouth02cp2, points.aboveMouth02)
.edge('bottom')
macro('vd', {
from: points.aboveMouthBottom,
to: points.aboveMouth04,
x: points.aboveMouth04.x - sa - 15,
noStartMarker: true,
noEndMarker: true,
id: 'bottomToCornerLeft',
})
macro('vd', {
from: points.aboveMouthBottom,
to: points.aboveMouthTop,
x: points.aboveMouth04.x - sa,
noStartMarker: true,
noEndMarker: true,
id: 'minimalHeight',
})
macro('vd', {
from: points.aboveMouth02,
to: points.aboveMouth03,
x: points.aboveMouth02.x + sa + 10,
noStartMarker: true,
noEndMarker: true,
id: 'heightCornersRight',
})
macro('vd', {
from: points.aboveMouth03,
to: points.aboveMouthBottom,
x: points.aboveMouth02.x + sa + 10,
noStartMarker: true,
noEndMarker: true,
id: 'bottomToCornerRight',
})
}
if (sa) {
paths.sa = paths.seam.offset(sa).attr('class', 'fabric sa')
}
}
return part
}
export const aboveMouth = {
name: 'hi.aboveMouth',
after: [body, mouth],
draft: draftHiAboveMouth,
},
}

View file

@ -1,44 +1,39 @@
import { body } from './body.mjs'
import { aboveMouth } from './aboveMouth.mjs'
function draftHiBelly({
store,
sa,
Point,
points,
Path,
paths,
Snippet,
snippets,
options,
complete,
paperless,
macro,
part,
}) {
const belly01_02d = 224.8451041 * options.size
const belly02_03d = 108.1988389 * options.size
const belly03_04d = 216.7485605 * options.size
const belly01_10d = 129.2449198 * options.size
export const belly = {
name: 'hi.belly',
after: [body, aboveMouth],
options: {
hungry: { pct: 50, min: 0, max: 100, menu: 'style' },
},
draft: ({ store, sa, Point, points, Path, paths, Snippet, snippets, options, macro, part }) => {
const multiplier = store.get('multiplier')
const bellyTailLength = store.get('bellyTailLength')
const belly01_02d = 224.8451041 * multiplier
const belly02_03d = 108.1988389 * multiplier
const belly03_04d = 216.7485605 * multiplier
const belly01_10d = 129.2449198 * multiplier
const belly01_02a = 25.7020193
const belly02_03a = 2.2164353
const belly03_04a = 338.0869319
const belly01_10a = 163.4959859
const belly10_05d = 231.4386252 * options.size
const belly10_05d = 231.4386252 * multiplier
const belly10_05a = 0
const belly01cp1d = 65.65512143 * options.size
const belly01cp2d = 38.20949996 * options.size
const belly02cp1d = 37.73513423 * options.size
const belly02cp2d = 118.6453123 * options.size
const belly03cp1d = 54.50254779 * options.size
const belly03cp2d = 40.6827883 * options.size
const belly04cp1d = 52.08589469 * options.size
const belly04cp2d = 62.46560129 * options.size
const belly05cp1d = 48.20828587 * options.size
const belly05cp2d = 68 * options.size
const belly10cp2d = 65.42602302 * options.size
const belly01cp1d = 65.65512143 * multiplier
const belly01cp2d = 38.20949996 * multiplier
const belly02cp1d = 37.73513423 * multiplier
const belly02cp2d = 118.6453123 * multiplier
const belly03cp1d = 54.50254779 * multiplier
const belly03cp2d = 40.6827883 * multiplier
const belly04cp1d = 52.08589469 * multiplier
const belly04cp2d = 62.46560129 * multiplier
const belly05cp1d = 48.20828587 * multiplier
const belly05cp2d = 68 * multiplier
const belly10cp2d = 65.42602302 * multiplier
const belly01cp1a = 60.117233
const belly01cp2a = 327.4394109
@ -97,8 +92,6 @@ function draftHiBelly({
.length()
} while (Math.abs(diff) > store.get('tolerance') && iteration < 100)
const bellyTailLength = store.get('bellyTailLength')
diff = 0
iteration = 0
do {
@ -195,8 +188,22 @@ function draftHiBelly({
store.cutlist.addCut({ cut: 1, material: 'color2Belly' })
// Complete?
if (complete) {
points.titleAnchor = points.belly05.shiftFractionTowards(points.belly10, 0.5)
points.logoAnchor = points.belly10.shiftFractionTowards(points.titleAnchor, 0.5)
points.gridAnchor = points.titleAnchor.clone()
snippets.logo = new Snippet('logo', points.logoAnchor).attr(
'data-scale',
multiplier > 1 ? 1 : multiplier
)
macro('title', {
at: points.titleAnchor,
nr: 2,
title: 'belly',
scale: multiplier,
})
points.bellyMouthSnippet1 = paths.mouthAttachment1
.reverse()
.shiftAlong(store.get('mouthBottomLength'))
@ -210,6 +217,7 @@ function draftHiBelly({
macro('banner', {
path: paths.finAttachmentBelly1,
text: '-o-',
id: 'circles1',
dy: 0,
spaces: 3,
repeat: 7,
@ -217,6 +225,7 @@ function draftHiBelly({
macro('banner', {
path: paths.finAttachmentBelly2,
text: '-o-',
id: 'circles2',
dy: 0,
spaces: 3,
repeat: 7,
@ -232,6 +241,7 @@ function draftHiBelly({
macro('banner', {
path: paths.mouth1,
text: 'mouth',
id: 'mouth1',
dy: 0,
spaces: 3,
repeat: 3,
@ -239,6 +249,7 @@ function draftHiBelly({
macro('banner', {
path: paths.mouth2,
text: 'mouth',
id: 'mouth2',
dy: 0,
spaces: 3,
repeat: 3,
@ -246,6 +257,7 @@ function draftHiBelly({
macro('banner', {
path: paths.body1,
text: 'body',
id: 'body1',
dy: 0,
spaces: 3,
repeat: 3,
@ -253,6 +265,7 @@ function draftHiBelly({
macro('banner', {
path: paths.body2,
text: 'body',
id: 'body2',
dy: 0,
spaces: 3,
repeat: 3,
@ -260,6 +273,7 @@ function draftHiBelly({
macro('banner', {
path: paths.aboveMouth1,
text: 'aboveMouth',
id: 'aboveMouth1',
dy: 0,
spaces: 3,
repeat: 3,
@ -267,139 +281,96 @@ function draftHiBelly({
macro('banner', {
path: paths.aboveMouth2,
text: 'aboveMouth',
id: 'aboveMouth2',
dy: 0,
spaces: 3,
repeat: 3,
})
if (paperless) {
macro('hd', {
from: points.belly01,
to: points.belly10,
y: points.belly01.y,
id: 'depthLeftDart',
})
macro('hd', {
from: points.belly05,
to: points.belly04,
y: points.belly04.y,
id: 'depthRightDart',
})
macro('hd', {
from: points.belly10,
to: points.belly05,
y: (points.belly04.y + points.belly01.y) / 2,
id: 'widthbetweenDarts',
})
macro('hd', {
from: points.belly01,
to: points.belly02,
y: points.belly02.y - sa - 10,
id: 'leftToFin',
})
macro('hd', {
from: points.belly02,
to: points.belly03,
y: points.belly02.y - sa - 10,
id: 'finWidth',
})
macro('hd', {
from: points.belly03,
to: points.belly04,
y: points.belly02.y - sa - 10,
id: 'rightToFin',
})
macro('hd', {
from: points.bellyMouthSnippet1,
to: points.belly02,
y: points.bellyMouthSnippet1.y,
id: 'finToSnippet',
})
macro('vd', {
from: points.belly03,
to: points.belly05,
x: points.belly03.x,
})
macro('vd', {
from: points.belly05,
to: points.belly07,
x: points.belly03.x,
})
macro('vd', {
from: points.belly10,
to: points.belly02,
x: points.belly02.x,
id: 'rightFinToMiddle',
})
macro('vd', {
from: points.belly08,
to: points.belly10,
x: points.belly02.x,
})
macro('vd', {
from: points.belly10,
to: points.belly01,
x: points.belly01.x - sa - 10,
id: 'leftFinToMiddle',
})
macro('vd', {
from: points.belly09,
to: points.belly10,
x: points.belly01.x - sa - 10,
id: 'heightLeftDart',
})
macro('vd', {
from: points.belly09,
to: points.belly08,
x: points.belly01.x - sa - 10,
})
macro('vd', {
from: points.belly02,
to: points.belly01,
x: points.belly01.x - sa - 10,
id: 'heightLeft',
})
macro('vd', {
from: points.belly05,
to: points.belly06,
x: points.belly04.x + sa + 10,
})
macro('vd', {
from: points.belly04,
to: points.belly05,
x: points.belly04.x + sa + 10,
id: 'heightRightDart',
})
macro('vd', {
from: points.belly06,
to: points.belly07,
x: points.belly04.x + sa + 10,
})
macro('vd', {
from: points.belly03,
to: points.belly04,
x: points.belly04.x + sa + 10,
})
points.titleAnchor = points.belly02.shiftFractionTowards(points.belly07, 0.5)
} else {
points.titleAnchor = points.belly03.shiftFractionTowards(points.belly07, 0.5)
points.logoAnchor = points.belly02.shiftFractionTowards(points.belly08, 0.5)
snippets.logo = new Snippet('logo', points.logoAnchor).attr(
'data-scale',
options.size > 1 ? 1 : options.size
)
}
macro('title', {
at: points.titleAnchor,
nr: 2,
title: 'belly',
scale: options.size,
id: 'heightRight',
})
if (sa) {
paths.sa = paths.bottom.join(paths.top).close().offset(sa).attr('class', 'fabric sa')
}
}
return part
}
export const belly = {
name: 'hi.belly',
after: [body, aboveMouth],
options: {
hungry: { pct: 50, min: 0, max: 100, menu: 'style' },
},
draft: draftHiBelly,
}

View file

@ -1,4 +1,24 @@
function draftHiBody({
const length = 1000
export const body = {
name: 'hi.body',
options: {
length,
size: {
pct: 100,
min: 5,
max: 500,
menu: 'style',
toAbs: (val, { options }) => (options?.length ? options.length * val : length * val),
fromAbs: (val, { options }) =>
options?.length
? Math.round((10000 * val) / options.length) / 10000
: Math.round((10000 * val) / length) / 10000,
},
nosePointiness: { pct: 0, min: -5, max: +10, menu: 'style' },
aggressive: { bool: false, menu: 'style' },
},
draft: ({
store,
sa,
Point,
@ -7,75 +27,77 @@ function draftHiBody({
paths,
Snippet,
snippets,
options,
complete,
paperless,
options,
macro,
utils,
part,
}) {
const body01_02d = 117.67274991262845 * options.size
const body02_03d = 124.91298035032229 * options.size
const body03_04d = 255.92397474640785 * options.size
const body04_05d = 201.01260719168837 * options.size
const body05_06d = 134.89080971660005 * options.size
const body06_07d = 49.0386070356816 * options.size
const body07_08d = 225.86340480918992 * options.size
const body08_09d = 66.84760000179512 * options.size
const body09_10d = 40.7278200374142 * options.size
const body10_11d = 23.78799421977402 * options.size
const body11_12d = 57.68530918700182 * options.size
const body12_13d = 98.0662397820983 * options.size
const body13_14d = 91.32736600274856 * options.size
const body14_15d = 295.1097706682888 * options.size
const body15_16d = 209.4263335058177 * options.size
const body16_17d = 152.51537318250902 * options.size
const body17_18d = 255.15294373571314 * options.size
const body18_19d = 71.90453921693678 * options.size
}) => {
const multiplier = (length / 1000) * options.size
store.set('multiplier', multiplier)
const body01cp1d = 32.13103487929059 * options.size
const body01cp2d = 23.72518967258217 * options.size
const body02cp1d = 44.99353642469105 * options.size
const body02cp2d = 42.33568754608812 * options.size
const body03cp1d = 62.59332758369697 * options.size
const body03cp2d = 40.89285869195256 * options.size
const body04cp1d = 176.21501525125487 * options.size
const body04cp2d = 130.11389715553065 * options.size
const body05cp1d = 29.56689479806765 * options.size
const body05cp2d = 104.66860665930352 * options.size
const body06cp1d = 8.03497915367552 * options.size
const body06cp2d = 34.57808908832297 * options.size
const body07cp1d = 89.11908088619404 * options.size
const body07cp2d = 25.54827831772624 * options.size
const body08cp1d = 41.24120086757895 * options.size
const body08cp2d = 158.23693200387828 * options.size
const body09cp1d = 4.87663090668135 * options.size
const body09cp2d = 25.76988630165065 * options.size
const body10cp1d = 4.13950105689086 * options.size
const body10cp2d = 13.2750849338149 * options.size
const body11cp1d = 17.66659910678904 * options.size
const body11cp2d = 17.66533107530116 * options.size
const body12cp1d = 14.46914569005365 * options.size
const body12cp2d = 39.51915145850176 * options.size
const body13cp1d = 35.66832366400192 * options.size
const body13cp2d = 48.53828530139895 * options.size
const body14cp1d = 77.2603605608982 * options.size
const body14cp2d = 37.42741381661305 * options.size
const body15cp1d = 74.89746640634775 * options.size
const body15cp2d = 101.16048880857042 * options.size
const body16cp1d = 36.21092864039804 * options.size
const body16cp2d = 63.69410844026312 * options.size
const body17cp1d = 97.90988675818191 * options.size
const body17cp2d = 62.08991689477443 * options.size
const body18cp1d = 22.74982929606286 * options.size
const body18cp2d = 16.57960183478481 * options.size
const body19cp1d = 23.95674278778315 * options.size
const body19cp2d = 24.49741270011998 * options.size
const body01_02d = 117.67274991262845 * multiplier
const body02_03d = 124.91298035032229 * multiplier
const body03_04d = 255.92397474640785 * multiplier
const body04_05d = 201.01260719168837 * multiplier
const body05_06d = 134.89080971660005 * multiplier
const body06_07d = 49.0386070356816 * multiplier
const body07_08d = 225.86340480918992 * multiplier
const body08_09d = 66.84760000179512 * multiplier
const body09_10d = 40.7278200374142 * multiplier
const body10_11d = 23.78799421977402 * multiplier
const body11_12d = 57.68530918700182 * multiplier
const body12_13d = 98.0662397820983 * multiplier
const body13_14d = 91.32736600274856 * multiplier
const body14_15d = 295.1097706682888 * multiplier
const body15_16d = 209.4263335058177 * multiplier
const body16_17d = 152.51537318250902 * multiplier
const body17_18d = 255.15294373571314 * multiplier
const body18_19d = 71.90453921693678 * multiplier
const eyeBigDist = 180.18315182058507 * options.size
const eyeSmallDist = 2.3629811679317316 * options.size
const body01cp1d = 32.13103487929059 * multiplier
const body01cp2d = 23.72518967258217 * multiplier
const body02cp1d = 44.99353642469105 * multiplier
const body02cp2d = 42.33568754608812 * multiplier
const body03cp1d = 62.59332758369697 * multiplier
const body03cp2d = 40.89285869195256 * multiplier
const body04cp1d = 176.21501525125487 * multiplier
const body04cp2d = 130.11389715553065 * multiplier
const body05cp1d = 29.56689479806765 * multiplier
const body05cp2d = 104.66860665930352 * multiplier
const body06cp1d = 8.03497915367552 * multiplier
const body06cp2d = 34.57808908832297 * multiplier
const body07cp1d = 89.11908088619404 * multiplier
const body07cp2d = 25.54827831772624 * multiplier
const body08cp1d = 41.24120086757895 * multiplier
const body08cp2d = 158.23693200387828 * multiplier
const body09cp1d = 4.87663090668135 * multiplier
const body09cp2d = 25.76988630165065 * multiplier
const body10cp1d = 4.13950105689086 * multiplier
const body10cp2d = 13.2750849338149 * multiplier
const body11cp1d = 17.66659910678904 * multiplier
const body11cp2d = 17.66533107530116 * multiplier
const body12cp1d = 14.46914569005365 * multiplier
const body12cp2d = 39.51915145850176 * multiplier
const body13cp1d = 35.66832366400192 * multiplier
const body13cp2d = 48.53828530139895 * multiplier
const body14cp1d = 77.2603605608982 * multiplier
const body14cp2d = 37.42741381661305 * multiplier
const body15cp1d = 74.89746640634775 * multiplier
const body15cp2d = 101.16048880857042 * multiplier
const body16cp1d = 36.21092864039804 * multiplier
const body16cp2d = 63.69410844026312 * multiplier
const body17cp1d = 97.90988675818191 * multiplier
const body17cp2d = 62.08991689477443 * multiplier
const body18cp1d = 22.74982929606286 * multiplier
const body18cp2d = 16.57960183478481 * multiplier
const body19cp1d = 23.95674278778315 * multiplier
const body19cp2d = 24.49741270011998 * multiplier
const gillLength = 41.01907104018812 * options.size
const eyeBigDist = 180.18315182058507 * multiplier
const eyeSmallDist = 2.3629811679317316 * multiplier
const gillLength = 41.01907104018812 * multiplier
const body01_02a = 170.1382393
const body02_03a = 39.2280236
@ -201,7 +223,7 @@ function draftHiBody({
points.body18cp2 = points.body18.shift(body18cp2a, body18cp2d)
points.body19cp2 = points.body19.shift(body19cp2a, body19cp2d)
//Adjust dart point:
// Adjust dart point:
points.body02 = points.body01.shift(body01_02a - 1.7, body01_02d)
// Front dart adjustments:
@ -259,8 +281,8 @@ function draftHiBody({
)
const c = 0.55191502449351
const eyeBigX = 18.7757 * options.size
const eyeBigY = 11.6262 * options.size
const eyeBigX = 18.7757 * multiplier
const eyeBigY = 11.6262 * multiplier
points.eyeBigT = points.eyeBig.shift(90, eyeBigY / 2)
points.eyeBigB = points.eyeBig
.shift(270, eyeBigY / 2)
@ -278,6 +300,7 @@ function draftHiBody({
points.eyeBigLcp1 = points.eyeBigL.shift(90, (eyeBigX / 2) * c)
points.eyeBigLcp2 = points.eyeBigL.shift(270, (eyeBigX / 2) * c)
if (complete)
paths.eyeBig = new Path()
.move(points.eyeBigT)
.curve(points.eyeBigTcp2, points.eyeBigLcp1, points.eyeBigL)
@ -285,8 +308,8 @@ function draftHiBody({
.curve(points.eyeBigBcp2, points.eyeBigRcp1, points.eyeBigR)
.curve(points.eyeBigRcp2, points.eyeBigTcp1, points.eyeBigT)
const eyeSmallX = 1.87089 * options.size * (options.aggressive ? 1.5 : 1)
const eyeSmallY = 1.5368 * options.size * (options.aggressive ? 1.5 : 1)
const eyeSmallX = 1.87089 * multiplier * (options.aggressive ? 1.5 : 1)
const eyeSmallY = 1.5368 * multiplier * (options.aggressive ? 1.5 : 1)
points.eyeSmallT = points.eyeSmall.shift(270, eyeSmallY / 2)
points.eyeSmallB = points.eyeSmall.shift(90, eyeSmallY / 2)
points.eyeSmallR = points.eyeSmall.shift(0, eyeSmallX / 2)
@ -300,6 +323,7 @@ function draftHiBody({
points.eyeSmallLcp1 = points.eyeSmallL.shift(90, (eyeSmallX / 2) * c)
points.eyeSmallLcp2 = points.eyeSmallL.shift(270, (eyeSmallX / 2) * c)
if (complete)
paths.eyeSmall = new Path()
.move(points.eyeSmallT)
.curve(points.eyeSmallTcp2, points.eyeSmallLcp1, points.eyeSmallL)
@ -349,11 +373,20 @@ function draftHiBody({
points.gill4end = points.gill4start.shift(gillAngle, gillLength * (1 + 3 * 0.08))
points.gill5end = points.gill5start.shift(gillAngle, gillLength * (1 + 4 * 0.08))
if (complete) {
paths.gill1 = new Path().move(points.gill1start).line(points.gill1end)
paths.gill2 = new Path().move(points.gill2start).line(points.gill2end)
paths.gill3 = new Path().move(points.gill3start).line(points.gill3end)
paths.gill4 = new Path().move(points.gill4start).line(points.gill4end)
paths.gill5 = new Path().move(points.gill5start).line(points.gill5end)
}
points.finCurve = utils.beamsIntersect(
points.body05,
points.body05cp2,
points.body04,
points.body04cp1
)
store.set('tailWidth', points.body13.dist(points.body14))
store.set(
@ -362,10 +395,13 @@ function draftHiBody({
)
store.set('tailCpDist', body13cp1d)
store.set('topFinOpening', points.body16.dist(points.body17))
store.set('topOfFinOpening', points.body16.dist(points.body17))
store.set(
'topFinOpeningLength',
new Path().move(points.body16).curve(points.body16cp1, points.body17cp2, points.body17).length()
'topOfFinOpeningLength',
new Path()
.move(points.body16)
.curve(points.body16cp1, points.body17cp2, points.body17)
.length()
)
store.set(
@ -387,11 +423,14 @@ function draftHiBody({
)
store.set(
'bellyTailLength',
new Path().move(points.body15).curve(points.body15cp1, points.body16cp2, points.body16).length()
new Path()
.move(points.body15)
.curve(points.body15cp1, points.body16cp2, points.body16)
.length()
)
// Reduce precision as size goes up coz performance
store.set('tolerance', options.size < 1 ? 1 : options.size * 100)
store.set('tolerance', multiplier < 1 ? 1 : multiplier * 100)
points.grainlineFrom = points.body13.shiftFractionTowards(points.body03, 0.5)
macro('grainline', {
@ -399,19 +438,13 @@ function draftHiBody({
to: points.body03,
})
store.cutlist.addCut({ material: 'color1UpperBody' })
store.cutlist.addCut({ cut: 2, material: 'color1UpperBody' })
// Complete?
if (complete) {
points.bodyTailSnippet = new Path()
.move(points.body13)
.curve(points.body13cp1, points.body14cp2, points.body14)
.shiftFractionAlong(0.25)
snippets.bodyTail = new Snippet('bnotch', points.bodyTailSnippet)
if (sa) {
// paths.sa = paths.seam.offset(sa).trim().attr('class', 'fabric sa')
paths.sa = paths.allButDart.close().offset(sa).attr('class', 'fabric sa')
}
paths.aboveMouth = new Path()
.move(points.body17)
@ -420,6 +453,7 @@ function draftHiBody({
macro('banner', {
path: paths.aboveMouth,
text: 'aboveMouth',
id: 'aboveMouth',
dy: 0,
spaces: 0,
repeat: 1,
@ -431,18 +465,20 @@ function draftHiBody({
macro('banner', {
path: paths.belly,
text: 'belly',
id: 'belly',
dy: 0,
spaces: 10,
repeat: 3,
})
paths.topFin = new Path()
paths.topOfFin = new Path()
.move(points.body16)
.curve(points.body16cp1, points.body17cp2, points.body17)
.attr('class', 'hidden')
.attr('data-text-class', 'text-xs')
macro('banner', {
path: paths.topFin,
text: 'topFin',
path: paths.topOfFin,
text: 'topOfFin',
id: 'topOfFin',
dy: 0,
spaces: 10,
repeat: 3,
@ -455,6 +491,7 @@ function draftHiBody({
macro('banner', {
path: paths.tail,
text: 'tail',
id: 'tail',
dy: 0,
spaces: 14,
repeat: 3,
@ -464,48 +501,54 @@ function draftHiBody({
from: points.body13,
to: points.body01,
d: -5,
id: 'bodyLength',
force: complete,
})
points.titleAnchor = points.body04.shiftFractionTowards(points.body17, 0.4)
points.logoAnchor = points.body06.shiftFractionTowards(points.body16, 0.6)
points.gridAnchor = points.logoAnchor.clone()
if (options.size < 0.35) {
if (multiplier < 0.35) {
points.scaleboxAnchor = new Point(points.body06.x - 60 - sa, points.body11.y - 35 - sa)
} else {
points.scaleboxAnchor = points.titleAnchor.shiftFractionTowards(points.body14, 0.5)
}
snippets.logo = new Snippet('logo', points.logoAnchor).attr(
'data-scale',
options.size > 1 ? 1 : options.size
multiplier > 1 ? 1 : multiplier
)
macro('title', {
at: points.titleAnchor,
nr: 1,
title: 'body',
scale: options.size,
scale: multiplier,
})
if (paperless) {
macro('hd', {
from: points.body14,
to: points.body15,
y: points.body19.y + sa + 10,
id: 'tailToBody',
})
macro('hd', {
from: points.body15,
to: points.body16,
y: points.body19.y + sa + 10,
id: 'bodyWidth',
})
macro('hd', {
from: points.body16,
to: points.body17,
y: points.body19.y + sa + 10,
id: 'finWidth',
})
macro('hd', {
from: points.body17,
to: points.body19,
y: points.body19.y + sa + 10,
id: 'finToMiddle',
})
macro('hd', {
from: points.body19,
@ -513,60 +556,63 @@ function draftHiBody({
y: points.body19.y + sa + 10,
noStartMarker: true,
noEndMarker: true,
id: 'middleToTip',
})
macro('hd', {
from: points.gill1start,
to: points.gill5start,
y: points.body19.y + sa + 20,
id: 'gillWidth',
})
macro('hd', {
from: points.eyeBig,
to: points.body19,
y: points.body19.y + sa + 20,
id: 'eyeToMiddle',
})
macro('hd', {
from: points.eyeBigL,
to: points.eyeBigR,
y: points.eyeBigT.y - 10,
id: 'eyeWidth',
noStartMarker: true,
noEndMarker: true,
})
macro('hd', {
from: points.body14,
to: points.body13,
y: points.body06.y - sa - 5,
id: 'tailWidth',
})
macro('hd', {
from: points.body13,
to: points.body10,
y: points.body06.y - sa - 5,
id: 'tailTo1stFin',
})
macro('hd', {
from: points.body10,
to: points.body06,
y: points.body06.y - sa - 5,
id: '1stFinTo2ndFin',
})
points.finCurve = utils.beamsIntersect(
points.body05,
points.body05cp2,
points.body04,
points.body04cp1
)
macro('hd', {
from: points.body06,
to: points.finCurve,
y: points.body06.y - sa - 5,
id: '2ndFinToBody',
})
macro('hd', {
from: points.finCurve,
to: points.body03,
y: points.body06.y - sa - 5,
id: '2ndFinToTip',
})
macro('hd', {
from: points.body03,
to: points.body01,
y: points.body06.y - sa - 5,
id: 'tipToMiddle',
noStartMarker: true,
noEndMarker: true,
})
@ -574,91 +620,98 @@ function draftHiBody({
from: points.body02,
to: points.body03,
y: points.body06.y - sa + 10,
id: 'topDartDepth',
})
macro('hd', {
from: points.body02,
to: points.body01,
y: points.body06.y - sa + 20,
id: 'bottomDartDepth',
})
macro('vd', {
from: points.body19,
to: points.body14,
x: points.body14.x - sa - 10,
id: 'heightTail',
})
macro('vd', {
from: points.body15,
to: points.body14,
x: points.body14.x - sa - 20,
id: 'bodyToTail',
})
macro('vd', {
from: points.body14,
to: points.body13,
x: points.body14.x - sa - 20,
id: 'tailHeight',
})
macro('vd', {
from: points.body14,
to: points.body10,
x: points.body14.x - sa - 30,
id: 'tailTo1stFin',
})
macro('vd', {
from: points.body14,
to: points.body08,
x: points.body14.x - sa - 10,
id: 'tailToBetweenFins',
})
macro('vd', {
from: points.body10,
to: points.body06,
x: points.body14.x - sa - 30,
id: 'heightFinToFin',
})
macro('vd', {
from: points.body01,
to: points.body19,
x: points.body01.x + sa + 10,
id: 'middleToDart',
})
macro('vd', {
from: points.body02,
to: points.body19,
x: points.body01.x + sa + 20,
id: 'middleToBackOfDart',
})
macro('vd', {
from: points.body03,
to: points.body01,
x: points.body01.x + sa + 10,
id: 'dartToDart',
})
macro('vd', {
from: points.finCurve,
to: points.body02,
x: points.body01.x + sa + 20,
id: 'dartToFinCurve',
})
macro('vd', {
from: points.body06,
to: points.finCurve,
x: points.body01.x + sa + 20,
id: 'finCurveToFin',
})
if (options.size > 0.4) {
if (multiplier > 0.4) {
macro('vd', {
from: points.gill5end,
to: points.gill5start,
x: points.gill5start.x + 5,
id: 'gillHeight',
noStartMarker: true,
noEndMarker: true,
})
}
} else {
macro('scalebox', { at: points.scaleboxAnchor })
}
if (sa) {
paths.sa = paths.allButDart.close().offset(sa).attr('class', 'fabric sa')
}
return part
}
export const body = {
name: 'hi.body',
options: {
size: { pct: 100, min: 5, max: 500, menu: 'style' },
nosePointiness: { pct: 0, min: -5, max: +10, menu: 'style' },
aggressive: { bool: false, menu: 'style' },
},
draft: draftHiBody,
}

View file

@ -2,37 +2,28 @@ import { body } from './body.mjs'
import { belly } from './belly.mjs'
import { aboveMouth } from './aboveMouth.mjs'
function draftHiBottomFin({
store,
sa,
Point,
points,
Path,
paths,
Snippet,
snippets,
options,
complete,
paperless,
macro,
part,
}) {
let bottomFin01_02d = 250.63638754690027 * options.size
const bottomFin01_02a = 119.34849371430543
let bottomFin01_03d = 137.70322741678933 * options.size
const bottomFin01_03a = 175.11970494988498
const bottomFin01cp1d = 133.21819413653674 * options.size
const bottomFin01cp2d = 51.94197687805115 * options.size
const bottomFin01cp1a = 95.20910872095476
const bottomFin01cp2a = 158.66090918215986
const bottomFin02cp1d = 29.25974733588791 * options.size
const bottomFin02cp2d = 31.28292571739416 * options.size
const bottomFin02cp1a = 208.55316756249104
const bottomFin02cp2a = 28.113642612639804
const bottomFin03cp1d = 53.31550082293142 * options.size
const bottomFin03cp2d = 177.65809391356197 * options.size
const bottomFin03cp1a = 9.79694130335566
const bottomFin03cp2a = 80.81868300891519
export const bottomOfFin = {
name: 'hi.bottomOfFin',
after: [body, belly, aboveMouth],
draft: ({ store, sa, Point, points, Path, paths, Snippet, snippets, macro, part }) => {
const multiplier = store.get('multiplier')
let bottomOfFin01_02d = 250.63638754690027 * multiplier
const bottomOfFin01_02a = 119.34849371430543
let bottomOfFin01_03d = 137.70322741678933 * multiplier
const bottomOfFin01_03a = 175.11970494988498
const bottomOfFin01cp1d = 133.21819413653674 * multiplier
const bottomOfFin01cp2d = 51.94197687805115 * multiplier
const bottomOfFin01cp1a = 95.20910872095476
const bottomOfFin01cp2a = 158.66090918215986
const bottomOfFin02cp1d = 29.25974733588791 * multiplier
const bottomOfFin02cp2d = 31.28292571739416 * multiplier
const bottomOfFin02cp1a = 208.55316756249104
const bottomOfFin02cp2a = 28.113642612639804
const bottomOfFin03cp1d = 53.31550082293142 * multiplier
const bottomOfFin03cp2d = 177.65809391356197 * multiplier
const bottomOfFin03cp1a = 9.79694130335566
const bottomOfFin03cp2a = 80.81868300891519
const finLength = store.get('aboveMouthFinLength') + store.get('bellyFinLength')
const finCircumference = store.get('topFinCircumference')
@ -40,72 +31,70 @@ function draftHiBottomFin({
let diff = 0
let iteration = 0
do {
points.bottomFin01 = new Point(0, 0)
points.bottomFin02 = points.bottomFin01.shift(bottomFin01_02a, bottomFin01_02d)
points.bottomFin03 = points.bottomFin01.shift(bottomFin01_03a, bottomFin01_03d)
points.bottomOfFin01 = new Point(0, 0)
points.bottomOfFin02 = points.bottomOfFin01.shift(bottomOfFin01_02a, bottomOfFin01_02d)
points.bottomOfFin03 = points.bottomOfFin01.shift(bottomOfFin01_03a, bottomOfFin01_03d)
points.bottomFin01cp1 = points.bottomFin01.shift(bottomFin01cp1a, bottomFin01cp1d)
points.bottomFin01cp2 = points.bottomFin01.shift(bottomFin01cp2a, bottomFin01cp2d)
points.bottomFin02cp1 = points.bottomFin02.shift(bottomFin02cp1a, bottomFin02cp1d)
points.bottomFin02cp2 = points.bottomFin02.shift(bottomFin02cp2a, bottomFin02cp2d)
points.bottomFin03cp1 = points.bottomFin03.shift(bottomFin03cp1a, bottomFin03cp1d)
points.bottomFin03cp2 = points.bottomFin03.shift(bottomFin03cp2a, bottomFin03cp2d)
points.bottomOfFin01cp1 = points.bottomOfFin01.shift(bottomOfFin01cp1a, bottomOfFin01cp1d)
points.bottomOfFin01cp2 = points.bottomOfFin01.shift(bottomOfFin01cp2a, bottomOfFin01cp2d)
points.bottomOfFin02cp1 = points.bottomOfFin02.shift(bottomOfFin02cp1a, bottomOfFin02cp1d)
points.bottomOfFin02cp2 = points.bottomOfFin02.shift(bottomOfFin02cp2a, bottomOfFin02cp2d)
points.bottomOfFin03cp1 = points.bottomOfFin03.shift(bottomOfFin03cp1a, bottomOfFin03cp1d)
points.bottomOfFin03cp2 = points.bottomOfFin03.shift(bottomOfFin03cp2a, bottomOfFin03cp2d)
diff =
finLength -
new Path()
.move(points.bottomFin03)
.curve(points.bottomFin03cp1, points.bottomFin01cp2, points.bottomFin01)
.move(points.bottomOfFin03)
.curve(points.bottomOfFin03cp1, points.bottomOfFin01cp2, points.bottomOfFin01)
.length()
bottomFin01_03d = bottomFin01_03d + diff
bottomOfFin01_03d = bottomOfFin01_03d + diff
iteration++
} while (Math.abs(diff) > store.get('tolerance') && iteration < 100)
diff = 0
iteration = 0
do {
points.bottomFin01 = new Point(0, 0)
points.bottomFin02 = points.bottomFin01.shift(bottomFin01_02a, bottomFin01_02d)
points.bottomFin03 = points.bottomFin01.shift(bottomFin01_03a, bottomFin01_03d)
points.bottomOfFin01 = new Point(0, 0)
points.bottomOfFin02 = points.bottomOfFin01.shift(bottomOfFin01_02a, bottomOfFin01_02d)
points.bottomOfFin03 = points.bottomOfFin01.shift(bottomOfFin01_03a, bottomOfFin01_03d)
points.bottomFin01cp1 = points.bottomFin01.shift(bottomFin01cp1a, bottomFin01cp1d)
points.bottomFin01cp2 = points.bottomFin01.shift(bottomFin01cp2a, bottomFin01cp2d)
points.bottomFin02cp1 = points.bottomFin02.shift(bottomFin02cp1a, bottomFin02cp1d)
points.bottomFin02cp2 = points.bottomFin02.shift(bottomFin02cp2a, bottomFin02cp2d)
points.bottomFin03cp1 = points.bottomFin03.shift(bottomFin03cp1a, bottomFin03cp1d)
points.bottomFin03cp2 = points.bottomFin03.shift(bottomFin03cp2a, bottomFin03cp2d)
points.bottomOfFin01cp1 = points.bottomOfFin01.shift(bottomOfFin01cp1a, bottomOfFin01cp1d)
points.bottomOfFin01cp2 = points.bottomOfFin01.shift(bottomOfFin01cp2a, bottomOfFin01cp2d)
points.bottomOfFin02cp1 = points.bottomOfFin02.shift(bottomOfFin02cp1a, bottomOfFin02cp1d)
points.bottomOfFin02cp2 = points.bottomOfFin02.shift(bottomOfFin02cp2a, bottomOfFin02cp2d)
points.bottomOfFin03cp1 = points.bottomOfFin03.shift(bottomOfFin03cp1a, bottomOfFin03cp1d)
points.bottomOfFin03cp2 = points.bottomOfFin03.shift(bottomOfFin03cp2a, bottomOfFin03cp2d)
diff =
finCircumference -
new Path()
.move(points.bottomFin01)
.curve(points.bottomFin01cp1, points.bottomFin02cp2, points.bottomFin02)
.curve(points.bottomFin02cp1, points.bottomFin03cp2, points.bottomFin03)
.move(points.bottomOfFin01)
.curve(points.bottomOfFin01cp1, points.bottomOfFin02cp2, points.bottomOfFin02)
.curve(points.bottomOfFin02cp1, points.bottomOfFin03cp2, points.bottomOfFin03)
.length()
bottomFin01_02d = bottomFin01_02d + diff
bottomOfFin01_02d = bottomOfFin01_02d + diff
iteration++
} while (Math.abs(diff) > store.get('tolerance') && iteration < 100)
paths.seam = new Path()
.move(points.bottomFin01)
.curve(points.bottomFin01cp1, points.bottomFin02cp2, points.bottomFin02)
.curve(points.bottomFin02cp1, points.bottomFin03cp2, points.bottomFin03)
.curve(points.bottomFin03cp1, points.bottomFin01cp2, points.bottomFin01)
.move(points.bottomOfFin01)
.curve(points.bottomOfFin01cp1, points.bottomOfFin02cp2, points.bottomOfFin02)
.curve(points.bottomOfFin02cp1, points.bottomOfFin03cp2, points.bottomOfFin03)
.curve(points.bottomOfFin03cp1, points.bottomOfFin01cp2, points.bottomOfFin01)
.close()
store.cutlist.addCut({ material: 'color1UpperBody' })
store.cutlist.addCut({ cut: 2, material: 'color1UpperBody' })
// Complete?
if (complete) {
const finAttachment = new Path()
.move(points.bottomFin01)
.curve(points.bottomFin01cp2, points.bottomFin03cp1, points.bottomFin03)
points.bottomFinSnippet = finAttachment.shiftAlong(store.get('aboveMouthFinLength'))
snippets.bottomFin = new Snippet('bnotch', points.bottomFinSnippet)
.move(points.bottomOfFin01)
.curve(points.bottomOfFin01cp2, points.bottomOfFin03cp1, points.bottomOfFin03)
points.bottomOfFinSnippet = finAttachment.shiftAlong(store.get('aboveMouthFinLength'))
snippets.bottomOfFin = new Snippet('bnotch', points.bottomOfFinSnippet)
const attachments = finAttachment.split(points.bottomFinSnippet)
const attachments = finAttachment.split(points.bottomOfFinSnippet)
paths.finAttachmentAboveMouth = attachments[0].reverse().attr('data-text-class', 'text-xs')
paths.finAttachmentBelly = attachments[1].reverse().attr('data-text-class', 'text-xs')
macro('banner', {
@ -114,6 +103,7 @@ function draftHiBottomFin({
dy: 0,
spaces: 0,
repeat: 4,
id: 'plusses',
})
macro('banner', {
path: paths.finAttachmentBelly,
@ -121,98 +111,90 @@ function draftHiBottomFin({
dy: 0,
spaces: 4,
repeat: 7,
id: 'circles',
})
points.titleAnchor = points.bottomFin02
.shiftFractionTowards(points.bottomFin01, 0.4)
.shiftFractionTowards(points.bottomFin03, 0.1)
points.logoAnchor = points.titleAnchor.shiftFractionTowards(points.bottomFin03, 0.4)
points.titleAnchor = points.bottomOfFin02
.shiftFractionTowards(points.bottomOfFin01, 0.4)
.shiftFractionTowards(points.bottomOfFin03, 0.1)
points.logoAnchor = points.titleAnchor.shiftFractionTowards(points.bottomOfFin03, 0.4)
points.gridAnchor = points.titleAnchor.clone()
snippets.logo = new Snippet('logo', points.logoAnchor).attr(
'data-scale',
(options.size > 1 ? 1 : options.size) / 2
(multiplier > 1 ? 1 : multiplier) / 2
)
macro('title', {
at: points.titleAnchor,
nr: 6,
title: 'bottomFin',
scale: (options.size > 1 ? 1 : options.size) / 2,
title: 'bottomOfFin',
scale: (multiplier > 1 ? 1 : multiplier) / 2,
})
if (paperless) {
points.bottomFinTop = paths.seam.edge('top')
points.bottomOfFinTop = paths.seam.edge('top')
let tempPath = new Path()
.move(points.bottomFin03)
.curve(points.bottomFin03cp2, points.bottomFin02cp1, points.bottomFin02)
.move(points.bottomOfFin03)
.curve(points.bottomOfFin03cp2, points.bottomOfFin02cp1, points.bottomOfFin02)
const tempPoint = tempPath.shiftFractionAlong(0.8)
points.bottomFinInsideLeft = tempPath.split(tempPoint)[0].edge('right')
points.bottomOfFinInsideLeft = tempPath.split(tempPoint)[0].edge('right')
tempPath = new Path()
.move(points.bottomFin01)
.curve(points.bottomFin01cp2, points.bottomFin03cp1, points.bottomFin03)
points.bottomFinInsideBottom = tempPath.edge('top')
.move(points.bottomOfFin01)
.curve(points.bottomOfFin01cp2, points.bottomOfFin03cp1, points.bottomOfFin03)
points.bottomOfFinInsideBottom = tempPath.edge('top')
macro('hd', {
from: points.bottomFin03,
to: points.bottomFin01,
y: points.bottomFin01.y + sa + 20,
from: points.bottomOfFin03,
to: points.bottomOfFin01,
y: points.bottomOfFin01.y + sa + 20,
id: 'width',
})
macro('hd', {
from: points.bottomFinTop,
to: points.bottomFin01,
y: points.bottomFinTop.y - sa - 10,
// id: 'smallTop',
// noStartMarker: true,
// noEndMarker: true,
from: points.bottomOfFinTop,
to: points.bottomOfFin01,
y: points.bottomOfFinTop.y - sa - 10,
id: 'smallTop',
})
macro('hd', {
from: points.bottomFinInsideLeft,
to: points.bottomFin01,
y: points.bottomFin03.y + sa + 20,
// id: 'smallBottom',
// noStartMarker: true,
// noEndMarker: true,
from: points.bottomOfFinInsideLeft,
to: points.bottomOfFin01,
y: points.bottomOfFin03.y + sa + 20,
id: 'widthToSmallest',
})
macro('hd', {
from: points.bottomFin03,
to: points.bottomFinSnippet,
y: points.bottomFin03.y + sa + 10,
from: points.bottomOfFin03,
to: points.bottomOfFinSnippet,
y: points.bottomOfFin03.y + sa + 10,
id: 'widthToSnippet',
})
macro('vd', {
from: points.bottomFin03,
to: points.bottomFinTop,
x: points.bottomFin03.x - sa - 10,
from: points.bottomOfFin03,
to: points.bottomOfFinTop,
x: points.bottomOfFin03.x - sa - 10,
id: 'heightLeft',
})
macro('vd', {
from: points.bottomFinTop,
to: points.bottomFin01,
x: points.bottomFin01.x + sa + 20,
from: points.bottomOfFinTop,
to: points.bottomOfFin01,
x: points.bottomOfFin01.x + sa + 20,
id: 'heightRight',
})
macro('vd', {
from: points.bottomFinTop,
to: points.bottomFinInsideBottom,
x: points.bottomFin01.x + sa + 10,
// id: 'smallRight',
// noStartMarker: true,
// noEndMarker: true,
from: points.bottomOfFinTop,
to: points.bottomOfFinInsideBottom,
x: points.bottomOfFin01.x + sa + 10,
id: 'heightToSmallest',
})
// if( options.size < 1.5 ) {
// if( multiplier < 1.5 ) {
// paths.smallTop.attr('data-text-class', 'text-xs')
// paths.smallBottom.attr('data-text-class', 'text-xs')
// paths.smallRight.attr('data-text-class', 'text-xs')
// }
}
if (sa) {
paths.sa = paths.seam.offset(sa).attr('class', 'fabric sa')
}
}
return part
}
export const bottomFin = {
name: 'hi.bottomFin',
after: [body, belly, aboveMouth],
draft: draftHiBottomFin,
},
}

View file

@ -7,16 +7,28 @@ import { tail } from './tail.mjs'
import { mouth } from './mouth.mjs'
import { aboveMouth } from './aboveMouth.mjs'
import { belly } from './belly.mjs'
import { topFin } from './topFin.mjs'
import { bottomFin } from './bottomFin.mjs'
import { topOfFin } from './topFin.mjs'
import { bottomOfFin } from './bottomFin.mjs'
import { lowerTeeth } from './lowerTeeth.mjs'
import { upperTeeth } from './upperTeeth.mjs'
// Create design
const Hi = new Design({
data,
parts: [body, tail, mouth, aboveMouth, belly, topFin, bottomFin, lowerTeeth, upperTeeth],
parts: [body, tail, mouth, aboveMouth, belly, topOfFin, bottomOfFin, lowerTeeth, upperTeeth],
})
// Named exports
export { body, tail, mouth, aboveMouth, belly, topFin, bottomFin, lowerTeeth, upperTeeth, Hi, i18n }
export {
body,
tail,
mouth,
aboveMouth,
belly,
topOfFin,
bottomOfFin,
lowerTeeth,
upperTeeth,
Hi,
i18n,
}

View file

@ -1,25 +1,17 @@
import { body } from './body.mjs'
import { createTeeth } from './teeth.mjs'
function draftHiLowerTeeth({
store,
sa,
Point,
points,
Path,
paths,
Snippet,
snippets,
options,
complete,
paperless,
macro,
part,
}) {
const lowerTeeth01_02d = 75.74338717643937 * options.size
export const lowerTeeth = {
name: 'hi.lowerTeeth',
after: body,
draft: ({ store, sa, Point, points, Path, paths, Snippet, snippets, macro, part }) => {
const multiplier = store.get('multiplier')
const lowerTeeth01_02d = 75.74338717643937 * multiplier
const lowerTeeth01_02a = 25.414236606099728 + 180
const lowerTeeth02cp1d = 47.74891452755759 * options.size
const lowerTeeth02cp1d = 47.74891452755759 * multiplier
const lowerTeeth02cp1a = 42.59332849750379
const lowerTeeth01cp2d = 27.774046078481962 * options.size
const lowerTeeth01cp2d = 27.774046078481962 * multiplier
const lowerTeeth01cp2a = 180
points.lowerTeeth01 = new Point(0, 0)
@ -51,18 +43,17 @@ function draftHiLowerTeeth({
points.lowerTeeth01, // end
],
10, // number of teeth
8 * options.size, // starting size
16 * options.size, // ending size
8 * multiplier, // starting size
16 * multiplier, // ending size
part
)
store.cutlist.addCut({ cut: 1, material: 'color4Teeth' })
// Complete?
if (complete) {
snippets.lowerTeeth = new Snippet('bnotch', points.lowerTeeth01)
points.titleAnchor = points.lowerTeeth02.shiftFractionTowards(points.lowerTeeth03, 0.5) //.shiftFractionTowards(points.lowerTeeth01, 0.5)
points.gridAnchor = points.titleAnchor.clone()
// Bounding box to prevent title clipping
paths.bbox = new Path()
@ -73,16 +64,16 @@ function draftHiLowerTeeth({
at: points.titleAnchor,
nr: 9,
title: 'lowerTeeth',
scale: options.size / 2,
scale: multiplier / 2,
})
if (paperless) {
macro('hd', {
from: points.lowerTeeth01,
to: points.lowerTeeth03,
y: points.lowerTeeth02.y + sa + 10,
noStartMarker: true,
noEndMarker: true,
id: 'right',
})
macro('hd', {
from: points.lowerTeeth02,
@ -90,13 +81,16 @@ function draftHiLowerTeeth({
y: points.lowerTeeth02.y + sa + 10,
noStartMarker: true,
noEndMarker: true,
id: 'left',
})
macro('vd', {
from: points.lowerTeeth02,
to: points.lowerTeeth01,
x: points.lowerTeeth02.x - sa - 10,
noStartMarker: true,
noEndMarker: true,
id: 'height',
})
macro('vd', {
from: points.lowerTeeth01,
@ -104,8 +98,8 @@ function draftHiLowerTeeth({
x: points.lowerTeeth02.x - sa - 10,
noStartMarker: true,
noEndMarker: true,
id: 'teethHeight',
})
}
if (sa) {
let pSA = paths.seam.offset(sa)
@ -116,12 +110,7 @@ function draftHiLowerTeeth({
.line(paths.seam.end())
.attr('class', 'fabric sa')
}
}
return part
}
export const lowerTeeth = {
name: 'hi.lowerTeeth',
draft: draftHiLowerTeeth,
},
}

View file

@ -1,32 +1,23 @@
import { lowerTeeth } from './lowerTeeth.mjs'
import { upperTeeth } from './upperTeeth.mjs'
function draftHiMouth({
store,
sa,
Point,
points,
Path,
paths,
Snippet,
snippets,
options,
complete,
paperless,
macro,
part,
}) {
const mouth01_02d = 141.93684055893488 * options.size
export const mouth = {
name: 'hi.mouth',
after: [lowerTeeth, upperTeeth],
draft: ({ store, sa, Point, points, Path, paths, Snippet, snippets, macro, part }) => {
const multiplier = store.get('multiplier')
const mouth01_02d = 141.93684055893488 * multiplier
const mouth01_02a = 312.8254216093024
const mouth01_03d = 42.496 * options.size
const mouth01_03d = 42.496 * multiplier
const mouth01_03a = 270
const mouth01cp1d = 38.6204 * options.size
const mouth01cp1d = 38.6204 * multiplier
const mouth01cp1a = 0
const mouth02cp1d = 59.58739935676417 * options.size
const mouth02cp2d = 73.53520117766728 * options.size
const mouth02cp1d = 59.58739935676417 * multiplier
const mouth02cp2d = 73.53520117766728 * multiplier
const mouth02cp1a = 128.07726051101747
const mouth02cp2a = 95.21339058299296
const mouth03cp2d = 33.142 * options.size
const mouth03cp2d = 33.142 * multiplier
const mouth03cp2a = 0
points.mouth01 = new Point(0, 0)
@ -74,8 +65,6 @@ function draftHiMouth({
store.cutlist.addCut({ cut: 1, material: 'color3Mouth' })
// Complete?
if (complete) {
points.mouthUpperTeeth1 = new Path()
.move(points.mouth01)
.curve(points.mouth01cp1, points.mouth02cp2, points.mouth02)
@ -102,6 +91,7 @@ function draftHiMouth({
macro('banner', {
path: paths.aboveMouth,
text: 'aboveMouth',
id: 'aboveMouth',
dy: 0,
spaces: 4,
repeat: 6,
@ -109,6 +99,7 @@ function draftHiMouth({
macro('banner', {
path: paths.belly,
text: 'belly',
id: 'belly',
dy: 0,
spaces: 4,
repeat: 6,
@ -116,51 +107,50 @@ function draftHiMouth({
points.titleAnchor = points.mouth01.shiftFractionTowards(points.mouth02, 0.33)
points.logoAnchor = points.mouth01.shiftFractionTowards(points.mouth04, 0.3)
points.gridAnchor = points.mouth03.clone()
snippets.logo = new Snippet('logo', points.logoAnchor).attr(
'data-scale',
(options.size > 1 ? 1 : options.size) / 2
(multiplier > 1 ? 1 : multiplier) / 2
)
macro('title', {
at: points.titleAnchor,
nr: 4,
title: 'mouth',
scale: (options.size > 1 ? 1 : options.size) / 2,
scale: (multiplier > 1 ? 1 : multiplier) / 2,
})
if (paperless) {
macro('hd', {
from: points.mouth03,
to: points.mouth02,
y: points.mouth02.y + sa + 10,
id: 'right',
})
macro('hd', {
from: points.mouth04,
to: points.mouth03,
y: points.mouth02.y + sa + 10,
id: 'left',
})
macro('vd', {
from: points.mouth04,
to: points.mouth03,
x: points.mouth04.x - sa - 10,
id: 'heightInside',
})
macro('vd', {
from: points.mouth03,
to: points.mouth01,
x: points.mouth04.x - sa - 10,
id: 'heightOutside',
})
}
if (sa) {
paths.sa = paths.seam.offset(sa).attr('class', 'fabric sa')
}
}
return part
}
export const mouth = {
name: 'hi.mouth',
after: [lowerTeeth, upperTeeth],
draft: draftHiMouth,
},
}

View file

@ -1,46 +1,37 @@
import { body } from './body.mjs'
function draftHiTail({
store,
sa,
Point,
points,
Path,
paths,
Snippet,
snippets,
options,
complete,
paperless,
macro,
part,
}) {
const tail01_02d = 192.0129724628 * options.size
export const tail = {
name: 'hi.tail',
after: body,
draft: ({ store, sa, Point, points, Path, paths, Snippet, snippets, macro, part }) => {
const multiplier = store.get('multiplier')
const tail01_02d = 192.0129724628 * multiplier
const tail01_02a = 53.242955551234914
const tail01_03d = 115.38057785000036 * options.size
const tail01_03d = 115.38057785000036 * multiplier
const tail01_03a = 106.95066736265407
const tail01_04d = 230.05210782342334 * options.size
const tail01_04d = 230.05210782342334 * multiplier
const tail01_04a = 138.66344842617497
const tail01_05d = 95.12771141996424 * options.size
const tail01_05d = 95.12771141996424 * multiplier
const tail01_05a = 173.38284569091573
const tail01cp1d = 156.52907796955816 * options.size
const tail01cp2d = 33.33694275124821 * options.size
const tail01cp1d = 156.52907796955816 * multiplier
const tail01cp2d = 33.33694275124821 * multiplier
const tail01cp1a = 40.69161792982998
const tail01cp2a = 150.8191939475001
const tail02cp1d = 20.1307852802616 * options.size
const tail02cp2d = 26.418081118809575 * options.size
const tail02cp1d = 20.1307852802616 * multiplier
const tail02cp2d = 26.418081118809575 * multiplier
const tail02cp1a = 129.66709301725697
const tail02cp2a = 303.9168409570558
const tail03cp1d = 41.577 * options.size
const tail03cp2d = 41.575999999999965 * options.size
const tail03cp1d = 41.577 * multiplier
const tail03cp2d = 41.575999999999965 * multiplier
const tail03cp1a = 180
const tail03cp2a = -0
const tail04cp1d = 18.83137554720844 * options.size
const tail04cp2d = 18.830271479721173 * options.size
const tail04cp1d = 18.83137554720844 * multiplier
const tail04cp2d = 18.830271479721173 * multiplier
const tail04cp1a = 218.47354143777738
const tail04cp2a = 38.483984913053284
const tail05cp1d = 38.59528397356339 * options.size
const tail05cp2d = 126.7372982195849 * options.size
const tail05cp1d = 38.59528397356339 * multiplier
const tail05cp2d = 126.7372982195849 * multiplier
const tail05cp1a = 14.169822482118544
const tail05cp2a = 128.3396902984
@ -83,8 +74,6 @@ function draftHiTail({
store.cutlist.addCut({ material: 'color1UpperBody' })
// Complete?
if (complete) {
points.tailSnippet = new Path()
.move(points.tail01)
.curve(points.tail01cp2, points.tail05cp1, points.tail05)
@ -96,30 +85,11 @@ function draftHiTail({
.curve(points.tail05cp1, points.tail01cp2, points.tail01)
.attr('class', 'hidden')
.attr('data-text-class', 'text-xs')
macro('banner', {
path: paths.body,
text: 'body',
dy: 0,
spaces: 10,
repeat: 3,
})
points.titleAnchor = points.tail03.shiftFractionTowards(points.tail01, 0.4)
points.logoAnchor = points.tail03.shiftFractionTowards(points.tail05, 0.5)
points.gridAnchor = points.tail03.clone()
snippets.logo = new Snippet('logo', points.logoAnchor).attr(
'data-scale',
(options.size > 1 ? 1 : options.size) / 2
)
macro('title', {
at: points.titleAnchor,
nr: 3,
title: 'tail',
scale: (options.size > 1 ? 1 : options.size) / 2,
})
if (paperless) {
points.tailLeft = new Path()
.move(points.tail03)
.curve(points.tail03cp1, points.tail04cp2, points.tail04)
@ -140,73 +110,94 @@ function draftHiTail({
.curve(points.tail01cp1, points.tail02cp2, points.tail02)
.curve(points.tail02cp1, points.tail03cp2, points.tail03)
.edge('top')
snippets.logo = new Snippet('logo', points.logoAnchor).attr(
'data-scale',
(multiplier > 1 ? 1 : multiplier) / 2
)
macro('title', {
at: points.titleAnchor,
nr: 3,
title: 'tail',
scale: (multiplier > 1 ? 1 : multiplier) / 2,
})
macro('banner', {
path: paths.body,
text: 'body',
id: 'body',
dy: 0,
spaces: 10,
repeat: 3,
})
macro('hd', {
from: points.tailLeft,
to: points.tail05,
y: points.tail01.y + sa + 10,
id: 'leftToBody',
})
macro('hd', {
from: points.tail05,
to: points.tail01,
y: points.tail01.y + sa + 10,
id: 'bodyWidth',
})
macro('hd', {
from: points.tail01,
to: points.tailRight,
y: points.tail01.y + sa + 10,
id: 'bodyToRight',
})
macro('hd', {
from: points.tailLeft,
to: points.tail03,
y: points.tailTopLeft.y - sa - 10,
y: points.tailTopRight.y - sa - 10,
id: 'leftToMid',
})
macro('hd', {
from: points.tail03,
to: points.tailRight,
y: points.tailTopRight.y - sa - 10,
id: 'midToRight',
})
macro('vd', {
from: points.tailTopLeft,
to: points.tail03,
x: points.tail03.x - 20,
id: 'leftToMid',
})
macro('vd', {
from: points.tail05,
to: points.tailTopLeft,
x: points.tailLeft.x - sa - 20,
id: 'heightLeft',
})
macro('vd', {
from: points.tailTopRight,
to: points.tail01,
x: points.tailRight.x + sa + 20,
})
macro('vd', {
from: points.tail01,
to: points.tailTopRight,
x: points.tail03.x + 20,
id: 'heightRight',
})
macro('vd', {
from: points.tail03,
to: points.tail01,
x: points.tail01.x + 20,
id: 'rightToMid',
})
macro('vd', {
from: points.tail05,
to: points.tail03,
x: points.tail05.x - 20,
id: 'leftToMid',
})
}
if (sa) {
paths.sa = paths.seam.offset(sa).attr('class', 'fabric sa')
}
}
return part
}
export const tail = {
name: 'hi.tail',
after: body,
draft: draftHiTail,
},
}

View file

@ -1,87 +1,76 @@
import { body } from './body.mjs'
function draftHiTopFin({
store,
sa,
Point,
points,
Path,
paths,
Snippet,
snippets,
options,
complete,
paperless,
macro,
part,
}) {
let topFinOpening = store.get('topFinOpening')
const topFinOpeningLength = store.get('topFinOpeningLength')
export const topOfFin = {
name: 'hi.topOfFin',
after: body,
draft: ({ store, sa, Point, points, Path, paths, Snippet, snippets, macro, part }) => {
const multiplier = store.get('multiplier')
const topFin01_02d = 256.9537569065251 * options.size
const topFin01_02a = 325.46697637215823
const topFin01_03a = 275.4353725228365
const topFin01cp1d = 178.52481158058 * options.size
const topFin01cp2d = 27.240286624072077 * options.size
const topFin01cp1a = 346.31732410079576
const topFin01cp2a = 254.05347154462484
const topFin02cp1d = 25.871054481794893 * options.size
const topFin02cp2d = 12.154549189501026 * options.size
const topFin02cp1a = 236.80010054081936
const topFin02cp2a = 56.66685795767527
const topFin03cp1d = 39.024661651837555 * options.size
const topFin03cp2d = 76.08965682877273 * options.size
const topFin03cp1a = 113.40393219481112
const topFin03cp2a = 22.511206474810457
let topOfFinOpening = store.get('topOfFinOpening')
const topOfFinOpeningLength = store.get('topOfFinOpeningLength')
const topOfFin01_02d = 256.9537569065251 * multiplier
const topOfFin01_02a = 325.46697637215823
const topOfFin01_03a = 275.4353725228365
const topOfFin01cp1d = 178.52481158058 * multiplier
const topOfFin01cp2d = 27.240286624072077 * multiplier
const topOfFin01cp1a = 346.31732410079576
const topOfFin01cp2a = 254.05347154462484
const topOfFin02cp1d = 25.871054481794893 * multiplier
const topOfFin02cp2d = 12.154549189501026 * multiplier
const topOfFin02cp1a = 236.80010054081936
const topOfFin02cp2a = 56.66685795767527
const topOfFin03cp1d = 39.024661651837555 * multiplier
const topOfFin03cp2d = 76.08965682877273 * multiplier
const topOfFin03cp1a = 113.40393219481112
const topOfFin03cp2a = 22.511206474810457
let diff = 0
let iteration = 0
do {
points.topFin01 = new Point(0, 0)
points.topFin02 = points.topFin01.shift(topFin01_02a, topFin01_02d)
points.topFin03 = points.topFin01.shift(topFin01_03a, topFinOpening) // topFin01_03d
points.topOfFin01 = new Point(0, 0)
points.topOfFin02 = points.topOfFin01.shift(topOfFin01_02a, topOfFin01_02d)
points.topOfFin03 = points.topOfFin01.shift(topOfFin01_03a, topOfFinOpening) // topOfFin01_03d
points.topFin01cp1 = points.topFin01.shift(topFin01cp1a, topFin01cp1d)
points.topFin01cp2 = points.topFin01.shift(topFin01cp2a, topFin01cp2d)
points.topFin02cp1 = points.topFin02.shift(topFin02cp1a, topFin02cp1d)
points.topFin02cp2 = points.topFin02.shift(topFin02cp2a, topFin02cp2d)
points.topFin03cp1 = points.topFin03.shift(topFin03cp1a, topFin03cp1d)
points.topFin03cp2 = points.topFin03.shift(topFin03cp2a, topFin03cp2d)
points.topOfFin01cp1 = points.topOfFin01.shift(topOfFin01cp1a, topOfFin01cp1d)
points.topOfFin01cp2 = points.topOfFin01.shift(topOfFin01cp2a, topOfFin01cp2d)
points.topOfFin02cp1 = points.topOfFin02.shift(topOfFin02cp1a, topOfFin02cp1d)
points.topOfFin02cp2 = points.topOfFin02.shift(topOfFin02cp2a, topOfFin02cp2d)
points.topOfFin03cp1 = points.topOfFin03.shift(topOfFin03cp1a, topOfFin03cp1d)
points.topOfFin03cp2 = points.topOfFin03.shift(topOfFin03cp2a, topOfFin03cp2d)
diff =
topFinOpeningLength -
topOfFinOpeningLength -
new Path()
.move(points.topFin03)
.curve(points.topFin03cp1, points.topFin01cp2, points.topFin01)
.move(points.topOfFin03)
.curve(points.topOfFin03cp1, points.topOfFin01cp2, points.topOfFin01)
.length()
topFinOpening = topFinOpening + diff
topOfFinOpening = topOfFinOpening + diff
iteration++
} while (Math.abs(diff) > store.get('tolerance') && iteration < 100)
paths.seam = new Path()
.move(points.topFin01)
.curve(points.topFin01cp2, points.topFin03cp1, points.topFin03)
.curve(points.topFin03cp2, points.topFin02cp1, points.topFin02)
.curve(points.topFin02cp2, points.topFin01cp1, points.topFin01)
.move(points.topOfFin01)
.curve(points.topOfFin01cp2, points.topOfFin03cp1, points.topOfFin03)
.curve(points.topOfFin03cp2, points.topOfFin02cp1, points.topOfFin02)
.curve(points.topOfFin02cp2, points.topOfFin01cp1, points.topOfFin01)
.close()
store.set(
'topFinCircumference',
'topOfFinCircumference',
new Path()
.move(points.topFin01)
.curve(points.topFin01cp1, points.topFin02cp2, points.topFin02)
.curve(points.topFin02cp1, points.topFin03cp2, points.topFin03)
.move(points.topOfFin01)
.curve(points.topOfFin01cp1, points.topOfFin02cp2, points.topOfFin02)
.curve(points.topOfFin02cp1, points.topOfFin03cp2, points.topOfFin03)
.length()
)
store.cutlist.addCut({ material: 'color1UpperBody' })
store.cutlist.addCut({ cut: 2, material: 'color1UpperBody' })
// Complete?
if (complete) {
paths.body = new Path()
.move(points.topFin01)
.curve(points.topFin01cp2, points.topFin03cp1, points.topFin03)
.move(points.topOfFin01)
.curve(points.topOfFin01cp2, points.topOfFin03cp1, points.topOfFin03)
.attr('class', 'hidden')
.attr('data-text-class', 'text-xs')
macro('banner', {
@ -92,85 +81,75 @@ function draftHiTopFin({
repeat: 3,
})
points.titleAnchor = points.topFin01
.shiftFractionTowards(points.topFin02, 0.5)
.shiftFractionTowards(points.topFin03, 0.1)
points.logoAnchor = points.titleAnchor.shiftFractionTowards(points.topFin03, 0.4)
points.titleAnchor = points.topOfFin01
.shiftFractionTowards(points.topOfFin02, 0.5)
.shiftFractionTowards(points.topOfFin03, 0.1)
points.logoAnchor = points.titleAnchor.shiftFractionTowards(points.topOfFin03, 0.4)
points.gridAnchor = points.titleAnchor.clone()
snippets.logo = new Snippet('logo', points.logoAnchor).attr(
'data-scale',
(options.size > 1 ? 1 : options.size) / 2
(multiplier > 1 ? 1 : multiplier) / 2
)
macro('title', {
at: points.titleAnchor,
nr: 7,
title: 'topFin',
scale: (options.size > 1 ? 1 : options.size) / 2,
title: 'topOfFin',
scale: (multiplier > 1 ? 1 : multiplier) / 2,
})
if (paperless) {
points.topFinLeft = paths.seam.edge('left')
points.topOfFinLeft = paths.seam.edge('left')
const tempPath = new Path()
.move(points.topFin02)
.curve(points.topFin02cp1, points.topFin03cp2, points.topFin03)
points.topFinInsideTop = tempPath.edge('top')
.move(points.topOfFin02)
.curve(points.topOfFin02cp1, points.topOfFin03cp2, points.topOfFin03)
points.topOfFinInsideTop = tempPath.edge('top')
const tempPoint = tempPath.shiftFractionAlong(0.5)
points.topFinInsideBottom = tempPath.split(tempPoint)[0].edge('bottom')
points.topFinRight = paths.seam.edge('right')
points.topOfFinInsideBottom = tempPath.split(tempPoint)[0].edge('bottom')
points.topOfFinRight = paths.seam.edge('right')
macro('hd', {
from: points.topFin01,
to: points.topFinRight,
y: points.topFin01.y - sa - 10,
// id: 'smallTop',
// noStartMarker: true,
// noEndMarker: true,
from: points.topOfFin01,
to: points.topOfFinRight,
y: points.topOfFin01.y - sa - 10,
id: 'topWidth',
})
macro('hd', {
from: points.topFin03,
to: points.topFinRight,
y: points.topFin03.y + sa + 20,
from: points.topOfFin03,
to: points.topOfFinRight,
y: points.topOfFin03.y + sa + 20,
id: 'bottomWidth',
})
macro('hd', {
from: points.topFinLeft,
to: points.topFinRight,
y: points.topFin03.y + sa + 10,
// id: 'smallBottom',
// noStartMarker: true,
// noEndMarker: true,
from: points.topOfFinLeft,
to: points.topOfFinRight,
y: points.topOfFin03.y + sa + 10,
id: 'width',
})
macro('vd', {
from: points.topOfFin03,
to: points.topOfFin01,
x: points.topOfFinLeft.x - sa - 10,
id: 'leftHeight',
})
macro('vd', {
from: points.topFin03,
to: points.topFin01,
x: points.topFinLeft.x - sa - 10,
from: points.topOfFin01,
to: points.topOfFinInsideBottom,
x: points.topOfFin02.x + sa + 10,
id: 'rightHeight',
})
macro('vd', {
from: points.topFin01,
to: points.topFinInsideBottom,
x: points.topFin02.x + sa + 10,
from: points.topOfFinInsideTop,
to: points.topOfFin01,
x: points.topOfFinLeft.x - sa - 20,
id: 'minHeight',
})
macro('vd', {
from: points.topFinInsideTop,
to: points.topFin01,
x: points.topFinLeft.x - sa - 20,
})
}
// if( options.size < 1.5 ) {
// paths.smallTop.attr('data-text-class', 'text-xs')
// paths.smallBottom.attr('data-text-class', 'text-xs')
// }
if (sa) {
paths.sa = paths.seam.offset(sa).attr('class', 'fabric sa')
}
}
return part
}
export const topFin = {
name: 'hi.topFin',
after: body,
draft: draftHiTopFin,
},
}

View file

@ -1,25 +1,17 @@
import { body } from './body.mjs'
import { createTeeth } from './teeth.mjs'
function draftHiUpperTeeth({
store,
sa,
Point,
points,
Path,
paths,
Snippet,
snippets,
options,
complete,
paperless,
macro,
part,
}) {
const upperTeeth01_02d = 131.305041182736 * options.size
export const upperTeeth = {
name: 'hi.upperTeeth',
after: body,
draft: ({ store, sa, Point, points, Path, paths, Snippet, snippets, macro, part }) => {
const multiplier = store.get('multiplier')
const upperTeeth01_02d = 131.305041182736 * multiplier
const upperTeeth01_02a = 34.147056946748805
const upperTeeth02cp1d = 64.30113337316406 * options.size
const upperTeeth02cp1d = 64.30113337316406 * multiplier
const upperTeeth02cp1a = 55.1335930733262 + 180
const upperTeeth01cp2d = 48.331000000000017 * options.size
const upperTeeth01cp2d = 48.331000000000017 * multiplier
const upperTeeth01cp2a = 0
points.upperTeeth01 = new Point(0, 0)
@ -42,8 +34,6 @@ function draftHiUpperTeeth({
store.set('upperTeethLength', paths.seam.length())
//paths.teeth = new Path().move(paths.seam.start())
paths.teeth = createTeeth(
[
// Array holding the points for half a mouth (bezier, not path)
@ -53,59 +43,51 @@ function draftHiUpperTeeth({
points.upperTeeth01, // start
],
14, // number of teeth
9 * options.size, // start size
18 * options.size, // end size
9 * multiplier, // start size
18 * multiplier, // end size
part
)
//createTeeth(paths.seam, 18 * options.size, 9 * options.size, 15, options.aggressive, paths.teeth)
store.cutlist.addCut({ cut: 1, material: 'color4Teeth' })
// Complete?
if (complete) {
snippets.upperTeeth = new Snippet('bnotch', points.upperTeeth01)
points.titleAnchor = points.upperTeeth02
.shiftFractionTowards(points.upperTeeth03, 0.5)
.shiftFractionTowards(points.upperTeeth01, 0.5)
points.gridAnchor = points.upperTeeth01
macro('title', {
at: points.titleAnchor,
nr: 8,
title: 'upperTeeth',
scale: options.size / 2,
scale: multiplier / 2,
})
if (paperless) {
macro('hd', {
from: points.upperTeeth03,
to: points.upperTeeth01,
y: points.upperTeeth02.y - 10,
noStartMarker: true,
noEndMarker: true,
id: 'left',
})
macro('hd', {
from: points.upperTeeth01,
to: points.upperTeeth03,
y: points.upperTeeth02.y + sa + 10,
noStartMarker: true,
noEndMarker: true,
})
macro('hd', {
from: points.upperTeeth02,
to: points.upperTeeth01,
y: points.upperTeeth02.y + sa + 10,
noStartMarker: true,
noEndMarker: true,
})
macro('vd', {
from: points.upperTeeth02,
to: points.upperTeeth01,
x: points.upperTeeth02.x - sa - 10,
to: points.upperTeeth02,
y: points.upperTeeth02.y - 10,
noStartMarker: true,
noEndMarker: true,
id: 'right',
})
macro('vd', {
from: points.upperTeeth01,
to: paths.teeth.edge('top'),
x: points.upperTeeth02.x - sa - 10,
x: points.leftTooth0.x - sa - 10,
noStartMarker: true,
noEndMarker: true,
id: 'height',
})
}
if (sa) {
let pSA = paths.seam.reverse().offset(sa)
@ -116,12 +98,7 @@ function draftHiUpperTeeth({
.line(paths.seam.start())
.attr('class', 'fabric sa')
}
}
return part
}
export const upperTeeth = {
name: 'hi.upperTeeth',
draft: draftHiUpperTeeth,
},
}

View file

@ -57,7 +57,7 @@
},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -54,7 +54,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -56,7 +56,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -56,7 +56,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -58,7 +58,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -54,7 +54,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -54,7 +54,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -54,7 +54,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -54,7 +54,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -2,9 +2,11 @@
"t": "Noble body block",
"d": "Noble is a body block with prince(ess) seams",
"p": {
"back": "Back",
"backInside": "Back inside",
"backOutside": "Back outside",
"backPoints": "Back base",
"front": "Front",
"frontInside": "Front inside",
"frontOutside": "Front outside",
"frontPoints": "Front base"
@ -15,6 +17,14 @@
"t": "Dart position",
"d": "Controls whether to split at the shoulder or armhole"
},
"dartPosition.armhole": {
"t": "Dart position at the armhole",
"d": "This moves the prince(ss) seam to the armhole"
},
"dartPosition.shoulder": {
"t": "Dart position at the shoulder",
"d": "This moves the prince(ss) seam to the shoulder"
},
"chestEase": {
"t": "Chest ease",
"d": "Controls the amount of ease at the chest"
@ -93,7 +103,7 @@
},
"fullChestEaseReduction": {
"t": "Full chest ease reduction",
"d": "FIXME: Document this option"
"d": "Allows you to independently reduce the ease around the chest to make it fit tight(er) in that area"
}
}
}

View file

@ -55,7 +55,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -1,19 +1,9 @@
import { backPoints } from './backpoints.mjs'
function nobleBackInside({
sa,
Point,
points,
Path,
paths,
Snippet,
snippets,
options,
complete,
paperless,
macro,
part,
}) {
export const backInside = {
name: 'noble.backInside',
from: backPoints,
draft: ({ sa, Point, points, Path, paths, Snippet, snippets, options, macro, part }) => {
if (options.dartPosition != 'shoulder') {
paths.insideSeam = paths.seam.clone().unhide()
} else {
@ -40,18 +30,17 @@ function nobleBackInside({
to: points.grainlineTo,
})
if (complete) {
snippets.dartTip = new Snippet('notch', points.dartTip)
macro('title', {
at: points.titleAnchor,
nr: 3,
title: options.dartPosition != 'shoulder' ? 'Back' : 'Inside Back',
title: options.dartPosition != 'shoulder' ? 'back' : 'backInside',
})
points.gridAnchor = points.hps.clone()
if (sa) paths.sa = paths.insideSeam.offset(sa).attr('class', 'fabric sa')
if (paperless) {
if (options.dartPosition == 'shoulder') {
points.shoulderPoint = points.shoulderDart.clone()
} else {
@ -61,47 +50,56 @@ function nobleBackInside({
from: points.waistCenter,
to: points.shoulderPoint,
y: points.waistCenter.y + sa + 15,
id: 'middleToShoulder',
})
macro('hd', {
from: points.waistCenter,
to: points.dartTip,
y: points.waistCenter.y + sa + 25,
id: 'middleToDartPoint',
})
macro('hd', {
from: points.waistCenter,
to: points.dartBottomLeft,
y: points.waistCenter.y + sa + 35,
id: 'middleToDart',
})
macro('hd', {
from: points.cbNeck,
to: points.dartBottomLeft,
y: points.waistCenter.y + sa + 45,
id: 'neckToDart',
})
macro('hd', {
from: points.cbNeck,
to: points.hps,
y: points.hps.y - sa - 15,
id: 'neckToHps',
})
macro('hd', {
from: points.hps,
to: points.shoulderPoint,
y: points.hps.y - sa - 15,
id: 'hpsToShoulder',
})
if (options.dartPosition != 'shoulder') {
macro('hd', {
from: points.dartTip,
to: points.waistSide,
y: points.waistCenter.y + sa + 25,
id: 'dartPointToSide',
})
macro('hd', {
from: points.dartBottomRight,
to: points.waistSide,
y: points.waistCenter.y + sa + 35,
id: 'dartToSide',
})
macro('hd', {
from: points.dartBottomRight,
to: points.armhole,
y: points.waistCenter.y + sa + 45,
id: 'dartToArmhole',
})
}
@ -111,11 +109,13 @@ function nobleBackInside({
from: points.shoulderPoint,
to: points.waistSide,
x: points.shoulderPoint.x + sa + 25,
id: 'sideToShoulder',
})
macro('vd', {
from: points.armhole,
to: points.waistSide,
x: points.shoulderPoint.x + sa + 15,
id: 'sideToArmhole',
})
extraOffset = 10
}
@ -124,40 +124,39 @@ function nobleBackInside({
from: points.shoulderPoint,
to: points.dartTip,
x: points.shoulderPoint.x + sa + 15,
id: 'dartPointToShoulder',
})
macro('vd', {
from: points.shoulderPoint,
to: points.dartBottomLeft,
x: points.shoulderPoint.x + sa + 25 + extraOffset,
id: 'dartToShoulder',
})
macro('vd', {
from: points.shoulderPoint,
to: points.waistCenter,
x: points.shoulderPoint.x + sa + 35 + extraOffset,
id: 'middleToShoulder',
})
macro('vd', {
from: points.hps,
to: points.waistCenter,
x: points.shoulderPoint.x + sa + 45 + extraOffset,
id: 'middleToHps',
})
macro('vd', {
from: points.waistCenter,
to: points.cbNeck,
x: points.cbNeck.x - sa - 15,
id: 'hemToNeck',
})
macro('vd', {
from: points.waistCenter,
to: points.hps,
x: points.cbNeck.x - sa - 25,
id: 'hemToHps',
})
}
}
return part
}
export const backInside = {
name: 'noble.backInside',
from: backPoints,
draft: nobleBackInside,
},
}

View file

@ -1,19 +1,9 @@
import { backPoints } from './backpoints.mjs'
function nobleBackOutside({
sa,
Point,
points,
Path,
paths,
Snippet,
snippets,
options,
complete,
paperless,
macro,
part,
}) {
export const backOutside = {
name: 'noble.backOutside',
from: backPoints,
draft: ({ sa, Point, points, Path, paths, Snippet, snippets, options, macro, part }) => {
if (options.dartPosition != 'shoulder') {
return part
}
@ -49,7 +39,6 @@ function nobleBackOutside({
to: points.grainlineTo,
})
if (complete) {
snippets.dartTip = new Snippet('notch', points.dartTip)
points.titleAnchor = points.dartBottomRight
@ -58,81 +47,87 @@ function nobleBackOutside({
macro('title', {
at: points.titleAnchor,
nr: 4,
title: 'Outside Back',
title: 'backOutside',
})
points.gridAnchor = points.armholeCpTarget.clone()
if (sa) paths.sa = paths.outsideSeam.offset(sa).attr('class', 'fabric sa')
if (paperless) {
let pLeft = paths.dart.edge('left')
macro('hd', {
from: pLeft,
to: points.waistSide,
y: points.waistCenter.y + sa + 15,
id: 'leftToSide',
})
macro('hd', {
from: points.dartBottomRight,
to: points.armhole,
y: points.waistCenter.y + sa + 25,
id: 'dartToArmhole',
})
macro('hd', {
from: points.dartTip,
to: points.waistSide,
y: points.waistCenter.y + sa + 35,
id: 'leftToSide',
})
macro('hd', {
from: points.dartBottomRight,
to: points.waistSide,
y: points.waistCenter.y + sa + 45,
id: 'dartToSide',
})
macro('hd', {
from: pLeft,
to: points.shoulder,
y: points.shoulderDart.y - sa - 15,
id: 'leftToShoulder',
})
macro('hd', {
from: points.shoulderDart,
to: points.shoulder,
y: points.shoulderDart.y - sa - 25,
id: 'dartToShoulder',
})
macro('hd', {
from: points.shoulderDart,
to: points.armhole,
y: points.shoulderDart.y - sa - 35,
id: 'dartToArmhole',
})
macro('vd', {
from: points.shoulder,
to: points.dartTip,
x: points.armhole.x + sa + 15,
id: 'dartPointToShoulder',
})
macro('vd', {
from: points.armhole,
to: points.waistSide,
x: points.armhole.x + sa + 15,
id: 'sideToArmhole',
})
macro('vd', {
from: points.shoulder,
to: points.waistSide,
x: points.armhole.x + sa + 25,
id: 'sideToShoulder',
})
macro('vd', {
from: points.shoulder,
to: points.dartBottomRight,
x: points.armhole.x + sa + 35,
id: 'dartToShoulder',
})
macro('vd', {
from: points.shoulderDart,
to: points.dartBottomRight,
x: points.armhole.x + sa + 45,
id: 'dartToDart',
})
}
}
return part
}
export const backOutside = {
name: 'noble.backOutside',
from: backPoints,
draft: nobleBackOutside,
},
}

View file

@ -2,10 +2,15 @@ import { back as bellaBack } from '@freesewing/bella'
import { hidePresets } from '@freesewing/core'
import * as options from './options.mjs'
function nobleBackPoints({ points, Path, paths, options, snippets, log, part }) {
export const backPoints = {
name: 'noble.backPoints',
from: bellaBack,
hide: hidePresets.HIDE_ALL,
options,
draft: ({ points, Path, paths, options, snippets, log, part }) => {
// Hide Bella paths
for (let key of Object.keys(paths)) paths[key].hide()
for (let i in snippets) delete snippets[i]
for (const key of Object.keys(paths)) paths[key].hide()
for (const i in snippets) delete snippets[i]
delete points.bustDartLeft
delete points.bustDartLeftCp
@ -15,12 +20,12 @@ function nobleBackPoints({ points, Path, paths, options, snippets, log, part })
options.shoulderDartPosition
)
let aUp = points.dartTip.angle(points.shoulderDart)
let aDown = points.dartBottomRight.angle(points.dartTip)
let aDiff = Math.abs(aUp - aDown)
const aUp = points.dartTip.angle(points.shoulderDart)
const aDown = points.dartBottomRight.angle(points.dartTip)
const aDiff = Math.abs(aUp - aDown)
// let dartCpAdjustment = Math.abs( options.shoulderDartPosition -.5) +.05
let dartCpAdjustment = aDiff / 50
const dartCpAdjustment = aDiff / 50
points.shoulderDartCpUp = points.shoulderDart.shiftFractionTowards(
points.dartTip,
@ -61,12 +66,5 @@ function nobleBackPoints({ points, Path, paths, options, snippets, log, part })
}
return part
}
export const backPoints = {
name: 'noble.backPoints',
from: bellaBack,
hide: hidePresets.HIDE_ALL,
options,
draft: nobleBackPoints,
},
}

View file

@ -1,20 +1,9 @@
import { frontPoints } from './frontpoints.mjs'
function nobleFrontInside({
store,
sa,
Point,
points,
Path,
paths,
Snippet,
snippets,
options,
complete,
paperless,
macro,
part,
}) {
export const frontInside = {
name: 'noble.frontInside',
from: frontPoints,
draft: ({ store, sa, Point, points, Path, paths, Snippet, snippets, options, macro, part }) => {
delete points.waistDartHem
delete points.waistDartRight
delete points.waistDartRightCp
@ -66,7 +55,11 @@ function nobleFrontInside({
paths.insideSeam = new Path()
.move(points.cfHem)
.line(points.waistDartLeft)
.curve(points.waistDartLeftCp, points.armholeDartTipCpDownInside, points.armholeDartTipInside)
.curve(
points.waistDartLeftCp,
points.armholeDartTipCpDownInside,
points.armholeDartTipInside
)
.curve(points.waistCircleInsideCp1, points.armholeCircleInsideCp1, points.armholeDartInside)
.join(paths.armholeInside)
.line(points.hps)
@ -96,7 +89,6 @@ function nobleFrontInside({
grainline: true,
})
if (complete) {
if (options.dartPosition == 'shoulder') {
snippets.shoulderDartTip = new Snippet('notch', points.shoulderDartTip)
} else {
@ -106,8 +98,10 @@ function nobleFrontInside({
macro('title', {
at: points.titleAnchor,
nr: 1,
title: 'Inside Front',
title: 'frontInside',
})
points.gridAnchor = points.hps.clone()
points.scaleboxAnchor = points.titleAnchor.shift(-90, 90).shift(0, 10)
macro('scalebox', { at: points.scaleboxAnchor, rotate: 270 })
@ -116,81 +110,97 @@ function nobleFrontInside({
paths.sa = paths.sa.move(points.cfHem).line(paths.sa.start())
}
if (paperless) {
let extraOffset = 0
if (options.dartPosition == 'shoulder') {
macro('hd', {
from: points.cfNeck,
to: points.shoulderDartInside,
y: points.hps.y - 25,
id: 'hpsToDart',
})
macro('vd', {
from: points.cfHem,
to: points.shoulderDartInside,
x: 0 - 30,
id: 'hemToDart',
})
macro('vd', {
from: points.cfHem,
to: points.shoulderDartTip,
x: 0 - 10,
id: 'hemToDartTip',
})
macro('hd', {
from: points.cfBust,
to: points.shoulderDartTip,
y: points.cfHem.y + sa + 25,
id: 'middleToDartTip',
})
} else {
extraOffset = 10
macro('hd', {
from: points.cfNeck,
from: points.hps,
to: points.shoulderCp1,
y: points.hps.y - 35,
id: 'hpsToShoulder',
})
macro('hd', {
from: points.cfNeck,
from: points.hps,
to: points.armholeDartInsideCp2,
y: points.hps.y - 25,
id: 'hpsToDart',
})
macro('vd', {
from: points.cfHem,
to: points.armholeDartInsideCp2,
x: 0 - 20,
id: 'hemToDart',
})
macro('vd', {
from: points.cfHem,
to: points.shoulderCp1,
x: 0 - 40,
id: 'hemToShoulder',
})
}
macro('vd', {
from: points.cfHem,
to: points.armholeDartTipInside,
x: 0 - 10,
})
macro('vd', {
from: points.cfHem,
to: points.cfNeck,
x: 0 - 20 - extraOffset,
})
macro('vd', {
from: points.cfHem,
to: points.hps,
x: 0 - 40 - extraOffset,
id: 'hemToDartTip',
})
macro('hd', {
from: points.cfBust,
to: points.armholeDartTipInside,
y: points.cfHem.y + sa + 25,
id: 'middleToDartTip',
})
}
macro('vd', {
from: points.cfHem,
to: points.cfNeck,
x: 0 - 20 - extraOffset,
id: 'hemToNeck',
})
macro('vd', {
from: points.cfHem,
to: points.hps,
x: 0 - 40 - extraOffset,
id: 'hemToHps',
})
macro('hd', {
from: points.cfHem,
to: points.waistDartLeft,
y: points.cfHem.y + sa + 15,
id: 'middleToDart',
})
macro('hd', {
from: points.cfNeck,
to: points.hps,
y: points.hps.y - sa - 15,
id: 'middleToHps',
})
}
}
return part
}
export const frontInside = {
name: 'noble.frontInside',
from: frontPoints,
draft: nobleFrontInside,
},
}

View file

@ -1,20 +1,11 @@
import { frontPoints } from './frontpoints.mjs'
import { frontInside } from './frontinside.mjs'
function nobleFrontOutside({
store,
sa,
points,
Path,
paths,
Snippet,
snippets,
options,
complete,
paperless,
macro,
part,
}) {
export const frontOutside = {
name: 'noble.frontOutside',
from: frontPoints,
after: frontInside,
draft: ({ store, sa, points, Path, paths, Snippet, snippets, options, macro, part }) => {
delete points.bustDartTop
delete points.bustSide
delete points.bustDartMiddle
@ -22,7 +13,8 @@ function nobleFrontOutside({
delete points.bustDartCpBottom
delete points.bustB
delete points.bustDartEdge
macro('cutonfold', false)
macro('rmcutonfold')
if (options.dartPosition == 'shoulder') {
paths.princessSeam = new Path()
@ -52,7 +44,11 @@ function nobleFrontOutside({
} else {
paths.princessSeam = new Path()
.move(points.armholeDartOutside)
.curve(points.armholeCircleOutsideCp1, points.waistCircleOutsideCp1, points.waistUpDartRight)
.curve(
points.armholeCircleOutsideCp1,
points.waistCircleOutsideCp1,
points.waistUpDartRight
)
.curve(points.waistUpDartRightCpDown, points.waistCpUp, points.waistDartRight)
.hide()
@ -76,7 +72,6 @@ function nobleFrontOutside({
store.cutlist.removeCut()
store.cutlist.addCut()
if (complete) {
points.snippet = paths.princessSeam.shiftAlong(
paths.princessSeam.length() - store.get('shoulderDartTipNotch')
)
@ -88,38 +83,43 @@ function nobleFrontOutside({
macro('title', {
at: points.titleAnchor,
nr: 2,
title: 'Outside Front',
title: 'frontOutside',
})
points.gridAnchor = points.armholeCpTarget.clone()
if (sa) paths.sa = paths.seam.offset(sa).attr('class', 'fabric sa')
if (paperless) {
let pLeft = paths.princessSeam.edge('left')
macro('hd', {
from: points.waistDartRight,
to: points.armholeOutsidePitchCp1,
y: points.sideHemInitial.y + sa + 35,
id: 'dartToArmhole',
})
macro('hd', {
from: points.waistDartRight,
to: points.sideHemInitial,
y: points.sideHemInitial.y + sa + 25,
id: 'dartToSide',
})
macro('hd', {
from: pLeft,
to: points.sideHemInitial,
y: points.sideHemInitial.y + sa + 15,
id: 'leftToSide',
})
macro('vd', {
from: points.armholeOutsidePitchCp1,
to: points.sideHemInitial,
x: points.sideHemInitial.x + sa + 15,
id: 'hemToArmhole',
})
macro('vd', {
from: points.waistDartRight,
to: pLeft,
x: pLeft.x - sa - 15,
id: 'hemToLeft',
})
if (options.dartPosition == 'shoulder') {
@ -127,53 +127,63 @@ function nobleFrontOutside({
from: points.shoulderDartOutside,
to: points.shoulder,
y: points.shoulderDartOutside.y - sa - 15,
id: 'dartToShoulder',
})
macro('hd', {
from: points.snippet,
to: points.shoulder,
y: points.shoulderDartOutside.y - sa - 25,
id: 'dartPointToShoulder',
})
macro('hd', {
from: pLeft,
to: points.shoulder,
y: points.shoulderDartOutside.y - sa - 35,
id: 'leftToShoulder',
})
macro('hd', {
from: points.waistDartRight,
to: points.shoulder,
y: points.sideHemInitial.y + sa + 45,
id: 'hemDartToShoulder',
})
macro('vd', {
from: points.shoulder,
to: points.sideHemInitial,
x: points.shoulder.x, //+sa + 15,
x: points.shoulder.x,
id: 'hemToShoulder',
})
macro('vd', {
from: points.shoulderDartOutside,
to: points.sideHemInitial,
x: points.shoulder.x + sa + 15,
x: points.shoulderDartOutside.x,
id: 'sideHemToShoulderDart',
})
macro('vd', {
from: points.waistDartRight,
to: points.shoulderDartOutside,
x: pLeft.x - sa - 25,
id: 'hemToShoulderDart',
})
macro('vd', {
from: points.snippet,
to: points.shoulderDartOutside,
x: pLeft.x - sa - 15,
id: 'shoulderDartToDartPoint',
})
let pArmholeLeft = paths.armhole.edge('left')
const pArmholeLeft = paths.armhole.edge('left')
macro('hd', {
from: points.waistDartRight,
to: pArmholeLeft,
y: points.sideHemInitial.y + sa + 5,
id: 'hemDartToRight',
})
macro('vd', {
from: pArmholeLeft,
to: points.sideHemInitial,
x: points.sideHemInitial.x + sa + 25,
id: 'hemSideToRight',
})
} else {
let pTop = paths.princessSeam.edge('top')
@ -181,47 +191,46 @@ function nobleFrontOutside({
from: pLeft,
to: points.armholeOutsidePitchCp1,
y: pTop.y - sa - 35,
id: 'leftToArmhole',
})
macro('hd', {
from: pLeft,
to: points.armholeDartOutside,
y: pTop.y - sa - 25,
id: 'leftToArmholeDart',
})
macro('hd', {
from: pLeft,
to: pTop,
y: pTop.y - sa - 15,
id: 'leftToTop',
})
macro('vd', {
from: points.waistDartRight,
to: pTop,
x: pLeft.x - sa - 25,
id: 'hemToTop',
})
macro('vd', {
from: points.snippet,
to: pTop,
x: pLeft.x - sa - 15,
id: 'topToDartPoint',
})
macro('vd', {
from: points.armholeDartOutside,
to: points.sideHemInitial,
x: points.sideHemInitial.x + sa + 25,
id: 'sideHemToArmholeDart',
})
macro('vd', {
from: pTop,
to: points.sideHemInitial,
x: points.sideHemInitial.x + sa + 35,
id: 'sideHemToTop',
})
}
}
}
return part
}
export const frontOutside = {
name: 'noble.frontOutside',
from: frontPoints,
after: frontInside,
draft: nobleFrontOutside,
},
}

View file

@ -2,16 +2,21 @@ import { frontSideDart as bellaFront } from '@freesewing/bella'
import { hidePresets } from '@freesewing/core'
import * as options from './options.mjs'
function nobleFrontPoints({ log, points, Path, paths, snippets, options, macro, part }) {
export const frontPoints = {
name: 'noble.frontPoints',
from: bellaFront,
hide: hidePresets.HIDE_ALL,
options,
draft: ({ log, points, Path, paths, snippets, options, macro, part }) => {
const bCircle = 0.552284749831
// Hide Bella paths
for (let key of Object.keys(paths)) paths[key].hide()
for (let i in snippets) delete snippets[i]
for (const key of Object.keys(paths)) paths[key].hide()
for (const i in snippets) delete snippets[i]
// Remove macros from Bella
macro('title', false)
macro('scalebox', false)
macro('rmtitle')
macro('rmscalebox')
points.shoulderDartInside = points.hps.shiftFractionTowards(
points.shoulder,
@ -23,7 +28,7 @@ function nobleFrontPoints({ log, points, Path, paths, snippets, options, macro,
points.orgArmholePitch = points.armholePitch.clone()
points.orgArmholePitchCp1 = points.armholePitchCp1.clone()
points.orgArmholePitchCp2 = points.armholePitchCp2.clone()
let armholePath = new Path()
const armholePath = new Path()
.move(points.shoulder)
._curve(points.armholePitchCp2, points.armholePitch)
.curve(points.armholePitchCp1, points.armholeCp2, points.armhole)
@ -31,11 +36,11 @@ function nobleFrontPoints({ log, points, Path, paths, snippets, options, macro,
points.armholeDartInside = armholePath.shiftFractionAlong(options.armholeDartPosition)
points.armholeDartOutside = points.armholeDartInside.clone()
let armholePaths = armholePath.split(points.armholeDartInside)
const armholePaths = armholePath.split(points.armholeDartInside)
let armholePathInside = armholePaths[0].clone().hide()
let armholePathOutside = armholePaths[1].clone().hide()
let armholeDartAngle =
const armholePathInside = armholePaths[0].clone().hide()
const armholePathOutside = armholePaths[1].clone().hide()
const armholeDartAngle =
armholePathInside.reverse().shiftAlong(1).angle(armholePathOutside.shiftAlong(1)) - 90
points.armholeDartArmhole = points.armholeDartInside.shiftFractionTowards(
@ -111,7 +116,7 @@ function nobleFrontPoints({ log, points, Path, paths, snippets, options, macro,
points.armholeDartCpTop = points.bustDartCpTop.rotate(rotateAngle, points.bustA)
points.armholeDartCpBottom = points.bustDartCpBottom.rotate(rotateAngle, points.bustA)
let spreadAngle =
const spreadAngle =
/*360 -*/ points.bustA.angle(points.bustDartBottom) - points.bustA.angle(points.bustDartTop)
points.shoulderDartOutside = points.shoulderDartInside.rotate(spreadAngle, points.bustA)
@ -124,7 +129,7 @@ function nobleFrontPoints({ log, points, Path, paths, snippets, options, macro,
points.bust,
options.upperDartLength
)
let dartRatio =
const dartRatio =
new Path().move(points.waistDartHem).line(points.waistDartTip).length() /
new Path().move(points.shoulderDartShoulder).line(points.shoulderDartTip).length()
@ -134,7 +139,10 @@ function nobleFrontPoints({ log, points, Path, paths, snippets, options, macro,
points.armholePitch = points.armholePitch.rotate(spreadAngle, points.bustA)
points.armholePitchCp1 = points.armholePitchCp1.rotate(spreadAngle, points.bustA)
points.armholePitchCp2 = points.armholePitchCp2.rotate(spreadAngle, points.bustA)
points.armholeCircleOutsideCp1 = points.armholeCircleOutsideCp1.rotate(spreadAngle, points.bustA)
points.armholeCircleOutsideCp1 = points.armholeCircleOutsideCp1.rotate(
spreadAngle,
points.bustA
)
points.armholeDartOutside = points.armholeDartOutside.rotate(spreadAngle, points.bustA)
points.armholeDartOutsideCp1 = points.armholeDartOutsideCp1.rotate(spreadAngle, points.bustA)
points.armholeOutsidePitchCp2 = points.armholeOutsidePitchCp2.rotate(spreadAngle, points.bustA)
@ -200,7 +208,7 @@ function nobleFrontPoints({ log, points, Path, paths, snippets, options, macro,
points.waistDartRightCp = points.bustAcp.clone()
let shoulderInsideSeam = new Path()
const shoulderInsideSeam = new Path()
.move(points.waistDartLeft)
.curve(points.waistDartLeftCp, points.shoulderDartTipCpDownInside, points.shoulderDartTip)
.line(points.shoulderDartInside)
@ -274,7 +282,7 @@ function nobleFrontPoints({ log, points, Path, paths, snippets, options, macro,
diff = 0
iteration = 0
do {
let dist = points.armholeDartTipInside.dist(points.armholeDartTipCpDownInside)
const dist = points.armholeDartTipInside.dist(points.armholeDartTipCpDownInside)
if (points.armholeDartTipInside.x > points.waistCircleOutsideCp1) {
points.armholeDartTipInside.x = points.armholeDartTipInside.x - 0.5
points.armholeDartTipInside.y = points.armholeDartTipInside.y + 0.5
@ -291,7 +299,11 @@ function nobleFrontPoints({ log, points, Path, paths, snippets, options, macro,
paths.armholeTempCircleOutside = new Path()
.move(points.armholeDartOutside)
.curve(points.armholeCircleOutsideCp1, points.waistCircleOutsideCp1, points.waistUpDartRight)
.curve(
points.armholeCircleOutsideCp1,
points.waistCircleOutsideCp1,
points.waistUpDartRight
)
.curve(points.waistUpDartRightCpDown, points.waistCpUp, points.waistDartRight)
.hide()
.attr('class', 'lining')
@ -314,12 +326,5 @@ function nobleFrontPoints({ log, points, Path, paths, snippets, options, macro,
}
return part
}
export const frontPoints = {
name: 'noble.frontPoints',
from: bellaFront,
hide: hidePresets.HIDE_ALL,
options,
draft: nobleFrontPoints,
},
}

View file

@ -1,9 +1,11 @@
import { pctBasedOn } from '@freesewing/core'
// Constants
export const shoulderToShoulderCorrection = 0.995
export const bustDartCurve = 1
export const bustDartLength = 0.9
// Percentages
export const bustSpanEase = { pct: 0, min: -5, max: 20, menu: 'fit' }
export const bustSpanEase = { pct: 0, min: -5, max: 20, ...pctBasedOn('bustSpan'), menu: 'fit' }
export const backHemSlope = { deg: 2.5, min: 0, max: 5, menu: 'advanced' }
export const upperDartLength = { pct: 90, min: 80, max: 95, menu: 'darts' }
export const dartPosition = { dflt: 'shoulder', list: ['shoulder', 'armhole'], menu: 'darts' }
@ -11,13 +13,11 @@ export const shoulderDartPosition = {
pct: 50,
min: 10,
max: 90,
// eslint-disable-next-line no-unused-vars
menu: (settings, mergedOptions) => (mergedOptions?.dartPosition != 'shoulder' ? 'darts' : false),
menu: (settings, mergedOptions) => (mergedOptions.dartPosition === 'shoulder' ? 'darts' : false),
}
export const armholeDartPosition = {
pct: 50,
min: 10,
max: 90,
// eslint-disable-next-line no-unused-vars
menu: (settings, mergedOptions) => (mergedOptions?.dartPosition == 'shoulder' ? 'darts' : false),
menu: (settings, mergedOptions) => (mergedOptions.dartPosition === 'armhole' ? 'darts' : false),
}

View file

@ -10,16 +10,45 @@
"headSection1": "Head section 1",
"headSection2": "Head section 2"
},
"s": {},
"s": {
"eye": "Eye",
"mouth": "Mouth",
"stichLine": "Stitch line",
"foldLine": "Fold lines",
"octopusEye.t": "The octopus eye is not shown",
"octopusEye.d": "The **Octopus eye** is a circular piece of fabric with a diameter of {{{ width }}} (this includes seam allowance). It is not shown because the **expand** core setting is currently disabled. Enable it to show this pattern part.",
"octopusPupil.t": "The octopus pupil is not shown",
"octopusPupil.d": "The **Octopus pupil** is a circular piece of fabric with a diameter of {{{ width }}} (this includes seam allowance). It is not shown because the **expand** core setting is currently disabled. Enable it to show this pattern part.",
"octopusEyebrow.t": "The octopus eyebrow is not shown",
"octopusEyebrow.d": "The **Octopus eyebrow** is a rectangular piece of fabric {{{ width }}} wide and {{{ length }}} long (this includes seam allowance). It is not shown because the **expand** core setting is currently disabled. Enable it to show this pattern part.",
"squidEye.t": "The squid eye is not shown",
"squidEye.d": "The **Squid eye** is a circular piece of fabric with a diameter of {{{ width }}} (this includes seam allowance). It is not shown because the **expand** core setting is currently disabled. Enable it to show this pattern part.",
"squidPupil.t": "The squid pupil is not shown",
"squidPupil.d": "The **Squid pupil** is a circular piece of fabric with a diameter of {{{ width }}} (this includes seam allowance). It is not shown because the **expand** core setting is currently disabled. Enable it to show this pattern part.",
"squidEyebrow.t": "The squid eyebrow is not shown",
"squidEyebrow.d": "The **Squid eyebrow** is a rectangular piece of fabric {{{ width }}} wide and {{{ length }}} long (this includes seam allowance). It is not shown because the **expand** core setting is currently disabled. Enable it to show this pattern part."
},
"o": {
"size": {
"t": "Size",
"d": "Controls the overall size"
"d": "Controls the overall size (value shown is the size of the head)"
},
"type": {
"t": "Type",
"d": "Allows you to choose one of the variants of this design"
},
"type.octoplushy": {
"t": "Octoplushy",
"d": "Draft the octoplushy variant"
},
"type.octopus": {
"t": "Octopus",
"d": "Draft the octopus variant"
},
"type.squid": {
"t": "Squid",
"d": "Draft the squid variant"
},
"armWidth": {
"t": "Arm width",
"d": "Controls the width of the arms"
@ -38,15 +67,15 @@
},
"bottomTopArmRatio": {
"t": "Bottom/Top arm ratio",
"d": "FIXME: No idea what this does"
"d": "Changes the ratio between the fabric on the top of the arms versus that on the bottom of the arms"
},
"bottomArmReduction": {
"t": "Bottom arm reduction",
"d": "FIXME: No idea what this does"
"d": "This changes how long the bottom fabric of the arms is compared to the top fabric. It makes the arms more curly"
},
"bottomArmReductionPlushy": {
"t": "Bottom arm reduction (plushy)",
"d": "FIXME: No idea what this does"
"d": "This changes how long the bottom fabric of the arms is compared to the top fabric. It makes the arms more curly"
}
}
}

View file

@ -54,7 +54,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -10,12 +10,11 @@ function octoplushyArmSection(
paths,
Snippet,
snippets,
complete,
sa,
paperless,
macro,
utils,
store,
complete,
part,
}
) {
@ -27,9 +26,9 @@ function octoplushyArmSection(
const w = options.sizeConstant * options.size
const sections = options.type == 'squid' ? 10 : 8
let sectionWidth = (w * 2) / sections
let armWidth = (w * options.armWidth * options.bottomTopArmRatio * 3.1415) / 2
let armAdjustedWidth = armWidth * options.bottomTopArmRatio
const sectionWidth = (w * 2) / sections
const armWidth = w * options.armWidth * (1 - options.bottomTopArmRatio) * 3.1415
const armAdjustedWidth = armWidth * (1 - options.bottomTopArmRatio)
let armLength = ((w * 2) / 3.1415) * options.armLength
switch (options.type) {
case 'octopus':
@ -67,7 +66,8 @@ function octoplushyArmSection(
points.armMiddleCp1 = points.armMiddle.shiftFractionTowards(points.skirtLeft2, c)
points.skirtLeft3 = new Point((-1 * armAdjustedWidth) / 2, points.skirtLeft2.y)
points.skirtLeft = points.skirtLeft3.clone()
let pHelper = points.skirtLeft.shift(store.get('armSkirtToTopAngle'), 10)
const pHelper = points.skirtLeft.shift(store.get('armSkirtToTopAngle'), 10)
if (Math.round(pHelper.x * 1000) <= Math.round((armAdjustedWidth / -2) * 1000)) {
points.armTopLeft = points.skirtLeft.clone()
} else {
@ -98,7 +98,7 @@ function octoplushyArmSection(
)
if (options.type == 'octopus') {
let pSkirtLeft = new Path()
const pSkirtLeft = new Path()
.move(points.armTopLeft)
.curve(points.armTopLeftCp2, points.armMiddleCp1, points.armMiddle)
@ -195,14 +195,15 @@ function octoplushyArmSection(
.join(paths.topRight)
.close()
// Complete?
if (complete) {
points.logo = points.armMiddle.shiftFractionTowards(points.armBottom, 0.08)
snippets.logo = new Snippet('logo', points.logo).attr('data-scale', 0.4)
points.gridAnchor = points.logo.clone()
points.armMiddle.attr('data-text', 'C').attr('data-text-class', 'center')
points.armTopLeft.attr('data-text', 'D').attr('data-text-class', 'center')
points.armTopRight.attr('data-text', 'D').attr('data-text-class', 'center')
if (complete) {
points.armMiddle.addText('C', 'center')
points.armTopLeft.addText('D', 'center')
points.armTopRight.addText('D', 'center')
}
points.titleAnchor = points.armMiddle
.shiftFractionTowards(points.armBottom, 0.2)
@ -211,11 +212,17 @@ function octoplushyArmSection(
macro('title', {
at: points.titleAnchor,
nr: 2 + partNumber * 3,
title: 'Arm' + (partNumber == 0 ? '' : ' (a)'),
title: 'arm' + (partNumber == 0 ? '' : ' (a)'),
rotation: 90,
scale: 0.3,
})
if (partNumber == 1) {
store.cutlist.addCut({ cut: 2, from: 'undersideFabric', identical: true })
} else {
store.cutlist.addCut({ cut: 8, from: 'undersideFabric', identical: true })
}
for (var i = 0; i < 4; i++) {
snippets[`armLeft${i}`] = new Snippet(
'notch',
@ -235,40 +242,42 @@ function octoplushyArmSection(
points.armTopLeft.x
)
points.skirtArmRight = points.skirtArmLeft.flipX(points.sectionTop)
if (complete) {
paths.armLeftLine = new Path()
.move(points.skirtArmLeft)
.line(points.armTopLeft)
.attr('data-text', 'stitch line')
.attr('data-text-class', 'center')
.attr('class', 'hint dotted')
.addClass('hint dotted')
.addText('stitchLine', 'center')
paths.armRightLine = new Path()
.move(points.armTopRight)
.line(points.skirtArmRight)
.attr('data-text', 'stitch line')
.attr('data-text-class', 'center')
.attr('class', 'hint dotted')
.addClass('hint dotted')
.addText('stitchLine', 'center')
}
}
if (sa) {
paths.sa = paths.section.offset(sa).attr('class', 'fabric sa')
}
if (paperless) {
macro('hd', {
from: points.armTopLeft,
to: points.armTopRight,
y: points.armMiddle.y - sa,
id: 'topWidth',
})
macro('hd', {
from: points.armBottomLeft,
to: points.armBottomRight,
y: points.armBottom.y + sa + 10,
id: 'bottomWidth',
})
macro('vd', {
from: points.armBottom,
to: points.armMiddle,
x: points.skirtLeft.x - sa - 20,
id: 'height',
})
if (options.type == 'octopus') {
@ -276,22 +285,26 @@ function octoplushyArmSection(
from: points.skirtLeft,
to: points.skirtRight,
y: points.skirtRight.y,
id: 'skirtWidth',
})
macro('vd', {
from: points.skirtLeft,
to: points.armMiddle,
x: points.skirtLeft.x - sa - 10,
id: 'skirtHeight',
})
macro('vd', {
from: points.armTopLeft,
to: points.skirtLeft,
x: points.skirtLeft.x - sa - 10,
id: 'skirtToArm',
})
} else {
macro('vd', {
from: points.armTopLeft,
to: points.armMiddle,
x: points.skirtLeft.x - sa - 10,
id: 'topToArm',
})
}
if (options.type == 'squid') {
@ -300,16 +313,16 @@ function octoplushyArmSection(
from: points.tentacleLeft,
to: points.tentacleRight,
y: points.tentacleRight.y,
id: 'tentacleWidth',
})
macro('vd', {
from: points.armBottom,
to: points.tentacleLeft,
x: points.tentacleLeft.x - sa - 10,
id: 'tentacleHeight',
})
}
}
}
}
return part
}

View file

@ -2,23 +2,9 @@ import { headSection1 } from './head.mjs'
function octoplushyEye(
partNumber,
{
options,
Point,
Path,
points,
paths,
Snippet,
snippets,
complete,
sa,
paperless,
macro,
store,
part,
}
{ options, Point, Path, points, paths, Snippet, snippets, sa, macro, expand, units, store, part }
) {
if (options.type != 'squid' && options.type != 'octopus') {
if (options.type == 'octoplushy') {
return part
}
if (partNumber > (options.type == 'squid' ? 1 : 2)) {
@ -27,14 +13,39 @@ function octoplushyEye(
const c = 0.55191502449351
let sectionWidth = store.get('sectionWidth')
let eyeSize = sectionWidth / 1.5
let logoScale = 0.25
let titleScale = 0.25
if (partNumber == 1) {
eyeSize *= 0.65
logoScale = 0.15
titleScale = 0.16
const sectionWidth = store.get('sectionWidth')
const logoScale = 0.35
const titleScale = 0.25
const eyeSize = (sectionWidth / 1.5) * (partNumber === 1 ? 0.65 : 1)
const eyeBrowWidth = eyeSize * 0.375
const eyeCirc = (eyeSize + eyeBrowWidth * 2) * Math.PI
if (expand) {
// Hint about expand
store.flag.preset('expandIsOn')
} else {
// Expand is off, do not draw the part but flag this to the user
const message =
(options.type == 'squid' ? `squid` : 'octopus') +
(partNumber == 2 ? 'Eyebrow' : partNumber == 1 ? 'Pupil' : 'Eye')
store.flag.note({
msg: message,
replace: {
width: units(eyeCirc + 2 * sa),
length: units(eyeBrowWidth * 2 + 2 * sa),
},
suggest: {
text: 'flag:show',
icon: 'expand',
update: {
settings: ['expand', 1],
},
},
})
// Also hint about expand
store.flag.preset('expandIsOff')
return part.hide()
}
if (partNumber < 2) {
@ -60,16 +71,12 @@ function octoplushyEye(
.curve(points.rightCp1, points.topCp2, points.top)
.close()
.attr('class', 'fabric')
.hide()
points.logo = points.top.shiftFractionTowards(points.bottom, 0.3)
points.titleAnchor = points.bottom
.shiftFractionTowards(points.top, 0.25)
.shift(180, eyeSize / 10)
} else {
logoScale = 0.35
titleScale = 0.25
let eyeBrowWidth = eyeSize * 0.375
let eyeCirc = (eyeSize + eyeBrowWidth * 2) * Math.PI
points.tl = new Point(0, 0)
points.tr = points.tl.shift(0, eyeCirc)
points.bl = points.tl.shift(270, eyeBrowWidth * 2)
@ -83,7 +90,6 @@ function octoplushyEye(
.line(points.tl)
.close()
.attr('class', 'fabric')
.hide()
points.logo = points.tl
.shiftFractionTowards(points.bl, 0.5)
@ -92,7 +98,8 @@ function octoplushyEye(
.shiftFractionTowards(points.br, 0.5)
.shiftFractionTowards(points.bl, 0.3)
}
if (complete) {
points.gridAnchor = points.logo.clone()
snippets.logo = new Snippet('logo', points.logo).attr('data-scale', logoScale)
macro('title', {
@ -102,32 +109,36 @@ function octoplushyEye(
scale: titleScale,
})
store.cutlist.addCut({
cut: 2,
from: partNumber == 2 ? 'fabric' : partNumber == 1 ? 'pupilFabric' : 'eyeFabric',
})
if (sa) {
paths.sa = paths.eye.offset(Math.min(sa, 6)).attr('class', 'fabric sa')
}
}
// Paperless?
if (paperless) {
if (partNumber < 2) {
macro('hd', {
from: points.left,
to: points.right,
y: points.top.y - sa,
id: 'width',
})
} else {
macro('hd', {
from: points.tl,
to: points.tr,
y: points.tl.y - sa,
id: 'width',
})
macro('vd', {
from: points.bl,
to: points.tl,
x: points.tl.x - sa,
id: 'height',
})
}
}
return part
}

View file

@ -8,12 +8,11 @@ function octoplushyHeadSection(
paths,
Snippet,
snippets,
complete,
sa,
paperless,
macro,
utils,
store,
complete,
part,
}
) {
@ -26,10 +25,10 @@ function octoplushyHeadSection(
const h = options.sizeConstant * options.size * 0.5
const sections = options.type == 'squid' ? 10 : 8
let sectionWidth = (w * 2) / sections
let neckWidth = sectionWidth * options.neckWidth
let armWidth = (w * options.armWidth * options.bottomTopArmRatio * 3.1415) / 2
let armAdjustedWidth = armWidth * options.bottomTopArmRatio
const sectionWidth = (w * 2) / sections
const neckWidth = sectionWidth * options.neckWidth
const armWidth = w * options.armWidth * options.bottomTopArmRatio * 3.1415
const armAdjustedWidth = armWidth * options.bottomTopArmRatio
let armLength = ((w * 2) / 3.1415) * options.armLength
if (options.type == 'octopus') {
armLength *= 2
@ -41,13 +40,6 @@ function octoplushyHeadSection(
}
}
// console.log({ w: w })
// console.log({ sectionWidth: sectionWidth })
// console.log({ neckWidth: neckWidth })
// console.log({ armAdjustedWidth: w * options.armWidth * options.bottomTopArmRatio })
// console.log({ toparmWidth: armAdjustedWidth })
// console.log({ armLength: armLength })
points.topLeft = new Point(-1 * w, -1 * h)
points.topRight = new Point(w, -1 * h)
points.bottomLeft = new Point(-1 * w, h)
@ -58,11 +50,10 @@ function octoplushyHeadSection(
points.sectionTop = new Point(0, -1 * h)
points.sectionBottom = new Point(0, h)
points.sectionLeft = new Point((-1 * sectionWidth) / 2, 0)
let sectionMid = points.sectionLeft.shiftFractionTowards(points.sectionTop, 0.5)
const sectionMid = points.sectionLeft.shiftFractionTowards(points.sectionTop, 0.5)
const sectionAngle = sectionMid.angle(points.sectionTop)
let lineEnd = sectionMid.shift(sectionAngle - 90, 1000)
const lineEnd = sectionMid.shift(sectionAngle - 90, 1000)
points.circleCenter = utils.beamIntersectsY(sectionMid, lineEnd, 0)
const circleRadius = points.circleCenter.dist(points.sectionTop)
@ -95,7 +86,7 @@ function octoplushyHeadSection(
points.lowerLeft.y
)
let currentNeckWidth = (points.sectionTop.x - points.sectionBottomLeft.x) * 2
const currentNeckWidth = (points.sectionTop.x - points.sectionBottomLeft.x) * 2
diff = neckWidth - currentNeckWidth
div = div * (currentNeckWidth / neckWidth)
@ -116,7 +107,7 @@ function octoplushyHeadSection(
points.lowerLeft.y
)
let sectionLeft = paths.circle.split(points.sectionTop)[1].split(points.sectionBottomLeft)[0]
const sectionLeft = paths.circle.split(points.sectionTop)[1].split(points.sectionBottomLeft)[0]
points.sectionTop = sectionLeft.ops[0].to.clone()
points.sectionTopCp1 = sectionLeft.ops[1].cp1.clone()
@ -178,8 +169,8 @@ function octoplushyHeadSection(
)
if (options.type == 'octopus') {
let octopusHeadFactor = 0.7
let sectionHeight = points.sectionBottom.dist(points.sectionTop)
const octopusHeadFactor = 0.7
const sectionHeight = points.sectionBottom.dist(points.sectionTop)
points.sectionTop = points.sectionTop.shift(90, sectionHeight * octopusHeadFactor)
points.sectionTopCp1 = points.sectionTopCp1.shift(90, sectionHeight * octopusHeadFactor)
points.sectionLeft = points.sectionLeft.shift(90, (sectionHeight * octopusHeadFactor) / 1.1)
@ -192,7 +183,7 @@ function octoplushyHeadSection(
(sectionHeight * octopusHeadFactor) / 1.1
)
let pSkirtLeft = new Path()
const pSkirtLeft = new Path()
.move(points.skirtBottomLeft)
.curve(points.skirtBottomLeft, points.sectionBottomLeftCp1, points.sectionBottomLeft)
@ -233,19 +224,19 @@ function octoplushyHeadSection(
points.armBottom = points.armBottom.flipY(points.tentacleLeft)
points.armBottomCp2 = points.armBottomCp2.flipY(points.tentacleLeft)
let pLeftSection = new Path()
const pLeftSection = new Path()
.move(points.sectionLeft)
.curve(points.sectionLeftCp2, points.sectionTopCp1, points.sectionTop)
points.finSection = pLeftSection.shiftFractionAlong(0.45)
let pLeftCurves = pLeftSection.split(points.finSection)
const pLeftCurves = pLeftSection.split(points.finSection)
points.sectionLeftCp2 = pLeftCurves[0].ops[1].cp1.clone()
points.finSectionCp1 = pLeftCurves[0].ops[1].cp2.clone()
points.finFold = points.finSection.rotate(-20, points.sectionTop)
points.finSeam = points.finSection.rotate(-40, points.sectionTop)
let foldAngle = points.sectionTop.angle(points.finFold)
let aCp1 = points.sectionTop.angle(pLeftCurves[1].ops[1].cp1) - foldAngle
let aCp2 = points.sectionTop.angle(pLeftCurves[1].ops[1].cp2) - foldAngle
const foldAngle = points.sectionTop.angle(points.finFold)
const aCp1 = points.sectionTop.angle(pLeftCurves[1].ops[1].cp1) - foldAngle
const aCp2 = points.sectionTop.angle(pLeftCurves[1].ops[1].cp2) - foldAngle
points.finSeamCp2 = points.sectionTop.shift(
foldAngle - aCp1,
points.sectionTop.dist(pLeftCurves[1].ops[1].cp1)
@ -385,13 +376,18 @@ function octoplushyHeadSection(
.close()
.attr('class', 'fabric')
// Complete?
if (complete) {
points.logo = points.sectionTop.shiftFractionTowards(
points.sectionBottom,
options.type == 'octoplushy' ? 0.3 : 0.5
)
snippets.logo = new Snippet('logo', points.logo).attr('data-scale', 0.4)
points.gridAnchor = points.skirtTopMiddle.clone()
if (partNumber == 1) {
store.cutlist.addCut({ cut: 2, from: 'fabric', identical: true })
} else {
store.cutlist.addCut({ cut: 8, from: 'fabric', identical: true })
}
points.titleAnchor = points.sectionBottom
.shiftFractionTowards(points.sectionTop, options.type == 'octoplushy' ? 0.3 : 0.4)
@ -399,20 +395,18 @@ function octoplushyHeadSection(
macro('title', {
at: points.titleAnchor,
nr: 1 + partNumber * 3,
title: 'Head' + (partNumber == 0 ? '' : ' (a)'),
title: 'head' + (partNumber == 0 ? '' : ' (a)'),
rotation: 90,
scale: options.type == 'octoplushy' ? 0.35 : 0.5,
})
if (options.type == 'octoplushy') {
points.eyeLeft = paths.sectionLeft
.shiftFractionAlong(0.465)
.attr('data-text', 'eye')
.attr('data-text-class', 'center')
points.eyeRight = points.eyeLeft
.flipX(points.sectionTop)
.attr('data-text', 'eye')
.attr('data-text-class', 'center')
points.eyeLeft = paths.sectionLeft.shiftFractionAlong(0.465)
points.eyeRight = points.eyeLeft.flipX(points.sectionTop)
if (complete) {
points.eyeLeft.addText('eye', 'center')
points.eyeRight.addText('eye', 'center')
}
snippets.eyeLeft = new Snippet('button', points.eyeLeft)
snippets.eyeRight = new Snippet('button', points.eyeRight)
@ -428,18 +422,16 @@ function octoplushyHeadSection(
.move(points.mouthLeft)
.curve(points.mouthLeftCp1, points.mouthBottomCp2, points.mouthBottom)
.curve(points.mouthBottomCp1, points.mouthRightCp2, points.mouthRight)
.attr('data-text', 'mouth')
.attr('data-text-class', 'text-xs center')
.attr('class', 'stroke-lg')
if (complete) paths.mouth.addText('mouth', 'text-xs center')
}
if (options.type == 'squid' && partNumber == 1) {
if (options.type == 'squid' && partNumber == 1 && complete) {
paths.fold = new Path()
.move(points.sectionTop)
.line(points.finFold)
.attr('data-text', 'fold line')
.attr('data-text-class', 'center')
.attr('class', 'hint dotted')
.addClass('hint dotted')
.addText('foldLine', 'center')
}
if (options.type == 'octopus') {
points.skirtArmLeft = utils.curveIntersectsX(
@ -450,22 +442,24 @@ function octoplushyHeadSection(
points.armTopLeft.x
)
points.skirtArmRight = points.skirtArmLeft.flipX(points.sectionTop)
if (complete) {
paths.armLeftLine = new Path()
.move(points.skirtArmLeft)
.line(points.armTopLeft)
.attr('data-text', 'stitch line')
.attr('data-text-class', 'center')
.attr('class', 'hint dotted')
.addClass('class', 'hint dotted')
.addText('stitchLine', 'center')
paths.armRightLine = new Path()
.move(points.armTopRight)
.line(points.skirtArmRight)
.attr('data-text', 'stitch line')
.attr('data-text-class', 'center')
.attr('class', 'hint dotted')
.addClass('class', 'hint dotted')
.addText('stitchLine', 'center')
}
}
if (complete) {
points.sectionTop.addText('A', 'center')
points.armTopLeft.addText('B', 'center')
points.armTopRight.addText('B', 'center')
}
points.sectionTop.attr('data-text', 'A').attr('data-text-class', 'center')
points.armTopLeft.attr('data-text', 'B').attr('data-text-class', 'center')
points.armTopRight.attr('data-text', 'B').attr('data-text-class', 'center')
snippets.left = new Snippet('notch', points.sectionLeft)
snippets.right = new Snippet('notch', points.sectionRight)
@ -485,45 +479,49 @@ function octoplushyHeadSection(
if (sa) {
paths.sa = paths.section.offset(sa).attr('class', 'fabric sa')
}
}
// Paperless?
if (paperless) {
macro('hd', {
from: points.sectionLeft,
to: points.sectionRight,
y: points.sectionTop.y - sa,
id: 'headWidth',
})
macro('hd', {
from: points.armTopLeft,
to: points.armTopRight,
y: points.armTopRight.y,
id: 'topArmWidth',
})
macro('hd', {
from: points.armBottomLeft,
to: points.armBottomRight,
y: points.armBottom.y + sa + 10,
id: 'bottomArmWidth',
})
macro('vd', {
from: points.sectionTop,
to: points.sectionRight,
x: points.skirtBottomRight.x + sa + 10,
id: 'headMidHeight',
})
macro('vd', {
from: points.sectionTop,
to: points.sectionBottomRight,
x: points.skirtBottomRight.x + sa + 20,
id: 'topToNeckHeight',
})
macro('vd', {
from: points.sectionTop,
to: points.skirtBottomRight,
x: points.skirtBottomRight.x + sa + 30,
id: 'topToArmHeight',
})
macro('vd', {
from: points.sectionTop,
to: points.armBottom,
x: points.skirtBottomRight.x + sa + 40,
id: 'totalHeight',
})
if (options.type == 'octopus') {
@ -531,11 +529,13 @@ function octoplushyHeadSection(
from: points.skirtBottomLeft,
to: points.skirtBottomRight,
y: points.skirtBottomRight.y,
id: 'skirtWidth',
})
macro('vd', {
from: points.skirtBottomRight,
to: points.armTopRight,
x: points.skirtBottomRight.x + sa + 30,
id: 'skirtHeight',
})
}
if (options.type == 'squid') {
@ -543,68 +543,109 @@ function octoplushyHeadSection(
from: points.armTopLeft,
to: points.sectionBottomLeft,
x: points.armTopLeft.x - sa - 10,
id: 'neckToArm',
})
macro('vd', {
from: points.sectionBottomLeft,
to: points.sectionMidLeft,
x: points.armTopLeft.x - sa - 10,
id: 'sectionHeight',
})
if (partNumber == 1) {
macro('hd', {
from: points.tentacleLeft,
to: points.tentacleRight,
y: points.tentacleRight.y,
id: 'tentacleWidth',
})
macro('hd', {
from: points.finSeam,
to: points.sectionTop,
y: points.sectionTop.y,
id: 'finWidth',
})
macro('hd', {
from: points.finSeam,
to: points.finSection,
y: points.finSection.y,
id: 'finToHead',
})
macro('hd', {
from: points.finFold,
to: points.finSection,
y: points.finFold.y,
id: 'foldToHead',
})
macro('vd', {
from: points.armBottom,
to: points.tentacleLeft,
x: points.tentacleLeft.x - sa - 10,
id: 'tentacleHeight',
})
macro('vd', {
from: points.finSeam,
to: points.sectionTop,
x: points.finSeam.x - sa,
id: 'finHeight',
})
macro('vd', {
from: points.finFold,
to: points.sectionTop,
x: points.finSeam.x - sa - 10,
id: 'finFoldHeight',
})
macro('vd', {
from: points.finSection,
to: points.sectionTop,
x: points.finSeam.x - sa - 20,
id: 'finToHeadHeight',
})
}
}
}
return part
}
const options = {
sizeConstant: 200,
size: { pct: 100, min: 5, max: 500, menu: 'style' },
size: {
pct: 100,
min: 5,
max: 500,
menu: 'style',
toAbs: (val, { options }, mergedOptions) =>
((mergedOptions.sizeConstant * val * 2) / 3.1415) *
(options.type === undefined
? 1
: options.type == 'octopus'
? 1.7
: options.type == 'squid'
? 2
: 1),
},
type: { dflt: 'octoplushy', list: ['octoplushy', 'octopus', 'squid'], menu: 'style' },
armWidth: { pct: 15, min: 10, max: 30, menu: 'style' },
armLength: { pct: 200, min: 100, max: 500, menu: 'style' },
armLength: {
pct: 200,
min: 100,
max: 500,
menu: 'style',
toAbs: (val, { options }, mergedOptions) =>
((mergedOptions.sizeConstant *
(options.size === undefined ? mergedOptions.size : options.size) *
2) /
3.1415) *
val *
(options.type === undefined
? 1
: options.type == 'octopus'
? 2
: options.type == 'squid'
? 1.8
: 1),
},
neckWidth: { pct: 25, min: 25, max: 45, menu: 'style' },
armTaper: { pct: 25, min: 0, max: 50, menu: 'style' },
bottomTopArmRatio: { pct: 87, min: 75, max: 100, menu: 'style' },
bottomTopArmRatio: { pct: 57, min: 25, max: 75, menu: 'style' },
bottomArmReduction: {
pct: 90,
min: 75,

View file

@ -56,7 +56,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -16,6 +16,14 @@
"t": "Back vent",
"d": "Add a vent in the back of the skirt."
},
"backVentNo": {
"t": "No vent in the back",
"d": "This will be the challenging way to walk."
},
"backVentYes": {
"t": "A vent in the back",
"d": "Making it easier to walk."
},
"backVentLength": {
"t": "Back vent length",
"d": "Length of the Back Vent as a percentage of the skirt length."
@ -24,6 +32,14 @@
"t": "Curved darts",
"d": "Whether or not to used curved darts."
},
"curvedDartsNo": {
"t": "Straight darts",
"d": "The darts will be straight, for the standard look."
},
"curvedDartsYes": {
"t": "Curved darts",
"d": "The darts will be curved, making the shape in the back and front more round."
},
"dartToSideSeamFactor": {
"t": "Dart to side seam factor",
"d": "Percentage of how much of the hip to waist reduction has to be taken in by the darts versus the side seam."
@ -52,13 +68,25 @@
"t": "Seat ease",
"d": "Amount of ease at the seat level."
},
"waistBand": {
"t": "Waist band",
"waistband": {
"t": "Waistband",
"d": "Add a waistband to the pattern."
},
"waistBandWidth": {
"t": "Waist band width",
"d": "The width of the waist band."
"waistbandNo": {
"t": "No waistband",
"d": "Just the skirt, nothing else."
},
"waistbandYes": {
"t": "Skirt with a waistband",
"d": "Add a waistband."
},
"waistbandOverlap": {
"t": "Waistband overlap",
"d": "How much the waistband should overlap at the front."
},
"waistbandWidth": {
"t": "Waistband width",
"d": "The width of the waistband."
},
"waistEase": {
"t": "Waist ease",
@ -67,6 +95,14 @@
"zipperLocation": {
"t": "Zipper location",
"d": "The location of the zipper."
},
"zipperLocation.backSeam": {
"t": "Add the zipper to the back seam",
"d": "Good option with the back vent."
},
"zipperLocation.sideSeam": {
"t": "Add the zipper to the side seam",
"d": "Allows you to cut the back on fold, removing the seam from the back."
}
}
}

View file

@ -54,7 +54,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -1,6 +1,11 @@
import { measurements, optionalMeasurements, options, BuildMainShape } from './shape.mjs'
function penelopeBack(params) {
export const back = {
name: 'penelope.back',
measurements,
optionalMeasurements,
options,
draft: (params) => {
const {
options,
measurements,
@ -10,9 +15,7 @@ function penelopeBack(params) {
Snippet,
snippets,
store,
complete,
sa,
paperless,
macro,
part,
} = params
@ -20,8 +23,7 @@ function penelopeBack(params) {
BuildMainShape(params, false)
if (options.backVent == true) {
// I don't care what you're trying to create, the vent will not go higher than your hips.
let backVentLength = Math.min(
const backVentLength = Math.min(
store.get('skirtLength') - measurements.waistToHips,
options.backVentLength * store.get('skirtLength')
)
@ -52,8 +54,6 @@ function penelopeBack(params) {
.join(paths.waist)
.attr('class', 'fabric')
// Complete?
if (complete) {
macro('grainline', {
from: points.grainlineTop,
to: points.grainlineBottom,
@ -61,12 +61,16 @@ function penelopeBack(params) {
snippets.logo = new Snippet('logo', points.logoAnchor)
store.cutlist.addCut({
cut: options.backVent == false && options.zipperLocation != 'backSeam' ? 1 : 2,
from: 'fabric',
})
if (options.backVent == false && options.zipperLocation != 'backSeam') {
macro('cutonfold', {
from: points.lWaist,
to: points.lLeg,
margin: 5,
offset: 10,
id: 'back',
})
}
macro('title', {
@ -94,47 +98,58 @@ function penelopeBack(params) {
.attr('class', 'fabric sa')
}
}
}
if (paperless) {
if (options.backVent) {
macro('hd', {
from: points.vHem,
to: points.rHem,
y: points.rHem.y - options.paperlessOffset - sa,
})
macro('hd', {
from: points.vTop,
to: points.lVent,
y: points.vTop.y,
id: 'ventWidth',
noStartMarker: true,
noEndMarker: true,
})
macro('vd', {
from: points.lSeat,
to: points.lVent,
x: points.lWaist.x - options.paperlessOffset - sa,
id: 'seatToVent',
})
macro('vd', {
from: points.lVent,
to: points.vTop,
x: points.lVent.x,
id: 'ventDiagonalHeight',
noStartMarker: true,
noEndMarker: true,
})
macro('hd', {
from: points.vLeg,
to: points.rLeg,
y: points.rHem.y + sa + options.paperlessOffset,
id: 'legWidth',
})
macro('hd', {
from: points.vHem,
to: points.rHem,
y: points.rHem.y + sa + options.paperlessOffset * 2,
id: 'hemWidth',
})
} else {
macro('hd', {
from: points.lLeg,
to: points.rLeg,
y: points.rHem.y + sa + options.paperlessOffset,
id: 'legWidth',
})
macro('hd', {
from: points.lHem,
to: points.rHem,
y: points.rHem.y - options.paperlessOffset - sa,
y: points.rHem.y + sa + options.paperlessOffset * 2,
id: 'hemWidth',
})
}
}
return part
}
export const back = {
name: 'penelope.back',
measurements,
optionalMeasurements,
options,
draft: penelopeBack,
},
}

View file

@ -1,8 +1,12 @@
import { measurements, optionalMeasurements, options, BuildMainShape } from './shape.mjs'
function penelopeFront(params) {
const { options, Path, points, paths, Snippet, snippets, complete, sa, paperless, macro, part } =
params
export const front = {
name: 'penelope.front',
measurements,
optionalMeasurements,
options,
draft: (params) => {
const { options, Path, points, paths, Snippet, snippets, sa, macro, store, part } = params
BuildMainShape(params, true)
@ -13,13 +17,10 @@ function penelopeFront(params) {
.join(paths.waist)
.attr('class', 'fabric')
// Complete?
if (complete) {
macro('cutonfold', {
from: points.lWaist,
to: points.lLeg,
margin: 5,
offset: 10,
id: 'front',
})
macro('title', {
nr: 1,
@ -36,6 +37,8 @@ function penelopeFront(params) {
snippets.logo = new Snippet('logo', points.logoAnchor)
store.cutlist.addCut({ cut: 1, from: 'fabric' })
if (sa) {
paths.sa = new Path()
.move(points.lHem)
@ -44,22 +47,19 @@ function penelopeFront(params) {
.attr('class', 'fabric sa')
}
if (paperless) {
macro('hd', {
from: points.lLeg,
to: points.rLeg,
y: points.rHem.y + sa + options.paperlessOffset,
id: 'legWidth',
})
macro('hd', {
from: points.lHem,
to: points.rHem,
y: points.rHem.y - options.paperlessOffset,
y: points.rHem.y + sa + options.paperlessOffset * 2,
id: 'hemWidth',
})
}
}
return part
}
export const front = {
name: 'penelope.front',
measurements,
optionalMeasurements,
options,
draft: penelopeFront,
},
}

View file

@ -1,3 +1,4 @@
import { pctBasedOn } from '@freesewing/core'
import { addDartToCurve, dartCalc } from './utils.mjs'
export const measurements = ['waist', 'seat', 'waistToHips', 'waistToSeat', 'waistToKnee']
@ -23,32 +24,53 @@ export const options = {
curvedDartTopControlOffset: 0.2,
curvedDartBottomControlOffset: 0.4,
curvedDarts: { bool: true, menu: 'style' },
lengthBonus: { pct: 0, min: -50, max: 50, menu: 'style' },
hemBonus: { pct: 0, min: -35, max: 0, menu: 'style' },
hem: { pct: 2, min: 0, max: 5, menu: 'style' },
lengthBonus: { pct: 0, min: -50, max: 50, ...pctBasedOn('waistToKnee'), menu: 'style' },
hemBonus: { pct: 0, min: -35, max: 0, ...pctBasedOn('seat'), menu: 'style' },
hem: { pct: 2, min: 0, max: 5, ...pctBasedOn('waistToKnee'), menu: 'style' },
backVent: { bool: true, menu: 'style' },
backVentLength: { pct: 40, min: 5, max: 70, menu: 'style' },
backVentLength: {
pct: 40,
min: 5,
max: 70,
// eslint-disable-next-line no-unused-vars
toAbs: (value, { measurements, options }, mergedOptions) =>
value * (measurements.waistToKnee * (1 + options.lengthBonus)),
// eslint-disable-next-line no-unused-vars
menu: (settings, mergedOptions) => (settings?.options?.backVent === false ? false : 'style'),
},
zipperLocation: { dflt: 'backSeam', list: ['backSeam', 'sideSeam'], menu: 'style' },
nrOfDarts: { count: 2, min: 1, max: 2, menu: 'style' },
seatEase: { pct: 1, min: 0, max: 8, menu: 'fit' },
waistEase,
backDartDepthFactor: { pct: 50, min: 35, max: 70, menu: 'advanced' },
frontDartDepthFactor: { pct: 45, min: 30, max: 65, menu: 'advanced' },
seatEase: { pct: 1, min: 0, max: 8, ...pctBasedOn('seat'), menu: 'fit' },
waistEase: { pct: 1, min: 0, max: 8, ...pctBasedOn('waist'), menu: 'fit' },
backDartDepthFactor: {
pct: 50,
min: 35,
max: 70,
...pctBasedOn('waistToSeat'),
menu: 'advanced',
},
frontDartDepthFactor: {
pct: 45,
min: 30,
max: 65,
...pctBasedOn('waistToSeat'),
menu: 'advanced',
},
dartToSideSeamFactor: { pct: 50, min: 30, max: 70, menu: 'advanced' },
}
export function BuildMainShape(
{ sa, options, measurements, Point, Path, points, paths, store, paperless, macro, part, log },
{ sa, options, measurements, Point, Path, points, paths, store, macro, part, log },
frontPart
) {
let skirtLength = measurements.waistToKnee * (1 + options.lengthBonus) // + options.hem;
const skirtLength = measurements.waistToKnee * (1 + options.lengthBonus) // + options.hem;
store.set('skirtLength', skirtLength)
store.set('waistEase', measurements.waist * options.waistEase)
store.set('seatEase', measurements.seat * options.seatEase)
store.set('hem', measurements.waistToKnee * options.hem)
let dartDepthFactor = frontPart ? options.frontDartDepthFactor : options.backDartDepthFactor
const dartDepthFactor = frontPart ? options.frontDartDepthFactor : options.backDartDepthFactor
let waist = measurements.waist
let seat = measurements.seat > waist ? measurements.seat : waist
@ -85,7 +107,7 @@ export function BuildMainShape(
seat += store.get('seatEase')
waist += store.get('waistEase')
let sideSeam = seat / 4 //+ sideSeamShift
const sideSeam = seat / 4 //+ sideSeamShift
points.lWaist = new Point(0, 0)
points.lLeg = new Point(0, skirtLength)
@ -246,12 +268,14 @@ export function BuildMainShape(
// Create the inverse of the curve from the leg to the waist
// Then split it at the hem level
points.lHem = points.lLeg.shift(270, store.get('hem'))
let rInverseSeat = points.rSeat.shift(270, (points.rLeg.y - points.rSeat.y) * 2)
let rInverseSeatCP = rInverseSeat.shift(90, points.rSeatCPdown.y - points.rSeat.y)
let rInversePath = new Path().move(rInverseSeat).curve(rInverseSeatCP, points.rLeg, points.rLeg)
const rInverseSeat = points.rSeat.shift(270, (points.rLeg.y - points.rSeat.y) * 2)
const rInverseSeatCP = rInverseSeat.shift(90, points.rSeatCPdown.y - points.rSeat.y)
const rInversePath = new Path()
.move(rInverseSeat)
.curve(rInverseSeatCP, points.rLeg, points.rLeg)
points.rHem = rInversePath.intersectsY(points.lHem.y)[0]
let sideSeamHemPath = rInversePath.split(points.rHem)[1]
const sideSeamHemPath = rInversePath.split(points.rHem)[1]
sideSeamPath = sideSeamHemPath.join(sideSeamPath)
@ -270,31 +294,39 @@ export function BuildMainShape(
points.titleAnchor = new Point(measurements.waist / 6, measurements.waistToSeat)
points.logoAnchor = points.titleAnchor.shift(270, 75)
points.gridAnchor = points.logoAnchor.clone()
points.grainlineTop = points.lWaist.shift(0, 50).shift(270, 50)
points.grainlineBottom = points.lLeg.shift(0, 50).shift(90, 50)
if (paperless) {
macro('hd', {
from: points.lSeat,
to: points.rSeat,
y: points.rSeat.y,
id: 'seatWidth',
})
macro('vd', {
from: points.lWaist,
to: points.rWaist,
x: points.rWaist.x + options.paperlessOffset + sa,
id: 'sideWaistHeight',
noStartMarker: true,
noEndMarker: true,
})
macro('vd', {
from: points.lWaist,
to: points.lLeg,
x: points.lLeg.x + options.paperlessOffset + sa,
id: 'heightToHem',
})
if (store.get('hem') > 0) {
macro('vd', {
from: points.lLeg,
to: points.lHem,
x: points.lLeg.x + options.paperlessOffset + sa,
id: 'heightHem',
noStartMarker: true,
noEndMarker: true,
})
}
@ -303,68 +335,89 @@ export function BuildMainShape(
from: points.lWaist,
to: points.dart1Middle,
y: points.dart1Middle.y,
id: 'dart1Middle',
})
macro('hd', {
from: points.lWaist,
to: points.dart1Start,
y: points.dart1Start.y - options.paperlessOffset - sa,
id: 'middleToDart1',
})
macro('hd', {
from: points.dart1Start,
to: points.dart1End,
y: points.dart1End.y - options.paperlessOffset - sa,
id: 'widthDart1',
noStartMarker: true,
noEndMarker: true,
})
if (store.get('nrOfDarts') > 1) {
macro('hd', {
from: points.lWaist,
to: points.dart2Middle,
y: points.dart2Middle.y,
id: 'middleToDart2',
})
macro('hd', {
from: points.dart1End,
to: points.dart2Start,
y: points.dart2Start.y - options.paperlessOffset - sa,
id: 'dart1toDart2',
noStartMarker: true,
noEndMarker: true,
})
macro('hd', {
from: points.dart2Start,
to: points.dart2End,
y: points.dart2End.y - options.paperlessOffset - sa,
id: 'widthDart2',
noStartMarker: true,
noEndMarker: true,
})
macro('hd', {
from: points.dart2End,
to: points.rWaist,
y: points.rWaist.y - options.paperlessOffset - sa,
id: 'dart2toSide',
})
macro('vd', {
from: points.lWaist,
to: points.dart2Middle,
x: points.lWaist.x - options.paperlessOffset - sa,
id: 'heightDart2',
})
macro('vd', {
from: points.dart2Middle,
to: points.dart1Middle,
x: points.lWaist.x - options.paperlessOffset - sa,
id: 'heightDart1toDart2',
noStartMarker: true,
noEndMarker: true,
})
macro('vd', {
from: points.dart1Middle,
to: points.lSeat,
x: points.lWaist.x - options.paperlessOffset - sa,
id: 'dart1ToSeat',
})
} else {
macro('vd', {
from: points.lWaist,
to: points.dart1Middle,
x: points.lWaist.x - options.paperlessOffset - sa,
id: 'heightDart1',
})
macro('hd', {
from: points.dart1End,
to: points.rWaist,
y: points.rWaist.y - options.paperlessOffset - sa,
id: 'dart1toSide',
})
macro('vd', {
from: points.dart1Middle,
to: points.lSeat,
x: points.lWaist.x - options.paperlessOffset - sa,
id: 'dart1toSeat',
})
}
} else {
@ -372,12 +425,13 @@ export function BuildMainShape(
from: points.lWaist,
to: points.rWaist,
y: points.rWaist.y - options.paperlessOffset - sa,
id: 'waistWidth',
})
macro('vd', {
from: points.lWaist,
to: points.lSeat,
x: points.lWaist.x - options.paperlessOffset - sa,
id: 'waistToSeat',
})
}
}
}

View file

@ -27,7 +27,7 @@ function dartCalcBack(options, seatWaistDiff, waist, nrOfDarts) {
function dartCalc(store, options, seat, seatEase, waist, waistEase) {
seat += seatEase
waist += waistEase
let seatWaistDiff = Math.max(seat - waist, 0)
const seatWaistDiff = Math.max(seat - waist, 0)
let nrOfDarts = options.nrOfDarts
@ -81,41 +81,41 @@ function addDartToCurve(part, curvePath, distance, dartSize, dartDepth) {
if (curvePath.length() - distance < dartSize) {
distance = curvePath.length() - dartSize / 1.95
}
let dartMiddle = curvePath.shiftAlong(distance)
let curvePaths = curvePath.split(dartMiddle)
const dartMiddle = curvePath.shiftAlong(distance)
const curvePaths = curvePath.split(dartMiddle)
if (curvePaths[0].length() < dartSize / 2 || curvePaths[1].length() < dartSize / 2) {
// Curve too small to fit dart!
return null
}
let dartLeft = curvePaths[0].reverse().shiftAlong(dartSize / 2)
let dartRight = curvePaths[1].shiftAlong(dartSize / 2)
const dartLeft = curvePaths[0].reverse().shiftAlong(dartSize / 2)
const dartRight = curvePaths[1].shiftAlong(dartSize / 2)
let distanceFactor = 0.0015
let leftCPdistance = Math.min(
const distanceFactor = 0.0015
const leftCPdistance = Math.min(
curvePaths[0].length() * distanceFactor,
curvePaths[0].ops[1].to.dist(curvePaths[0].ops[1].cp2)
)
let rightCPdistance = Math.min(
const rightCPdistance = Math.min(
curvePaths[1].length() * distanceFactor,
curvePaths[1].ops[0].to.dist(curvePaths[1].ops[1].cp1)
)
let dartBottom = dartMiddle.shift(dartLeft.angle(dartRight) - 90, dartDepth)
const dartBottom = dartMiddle.shift(dartLeft.angle(dartRight) - 90, dartDepth)
let leftDartCP = dartLeft.shift(dartLeft.angle(dartBottom) - 90, leftCPdistance)
let rightDartCP = dartRight.shift(dartRight.angle(dartBottom) + 90, rightCPdistance)
const leftDartCP = dartLeft.shift(dartLeft.angle(dartBottom) - 90, leftCPdistance)
const rightDartCP = dartRight.shift(dartRight.angle(dartBottom) + 90, rightCPdistance)
let curveLeftOfDart = new part.Path()
const curveLeftOfDart = new part.Path()
.move(curvePaths[0].ops[0].to)
.curve(curvePaths[0].ops[1].cp1, leftDartCP, dartLeft)
.hide()
let curveRightOfDart = new part.Path()
const curveRightOfDart = new part.Path()
.move(dartRight)
.curve(rightDartCP, curvePaths[1].ops[1].cp2, curvePaths[1].ops[1].to)
.hide()
let dart
let dart = null
if (options.curvedDarts) {
if (
dartBottom.angle(dartLeft) - dartBottom.angle(dartRight) <
@ -123,17 +123,17 @@ function addDartToCurve(part, curvePath, distance, dartSize, dartDepth) {
) {
dart = new part.Path().move(dartLeft).line(dartBottom).line(dartRight).hide()
} else {
let dartBottomCp2 = dartBottom
const dartBottomCp2 = dartBottom
.shiftFractionTowards(dartMiddle, options.curvedDartBottomControlOffset)
.rotate(options.curvedDartControlAngle, dartBottom)
let dartBottomCp1 = dartBottom
const dartBottomCp1 = dartBottom
.shiftFractionTowards(dartMiddle, options.curvedDartBottomControlOffset)
.rotate(360 - options.curvedDartControlAngle, dartBottom)
let dartLeftCp1 = dartLeft.shiftFractionTowards(
const dartLeftCp1 = dartLeft.shiftFractionTowards(
dartBottom,
options.curvedDartTopControlOffset
)
let dartRightCp2 = dartRight.shiftFractionTowards(
const dartRightCp2 = dartRight.shiftFractionTowards(
dartBottom,
options.curvedDartTopControlOffset
)
@ -148,7 +148,7 @@ function addDartToCurve(part, curvePath, distance, dartSize, dartDepth) {
dart = new part.Path().move(dartLeft).line(dartBottom).line(dartRight).hide()
}
let curveWithDart = {
const curveWithDart = {
left: curveLeftOfDart,
dart: dart,
right: curveRightOfDart,

View file

@ -1,6 +1,32 @@
import { waistEase } from './shape.mjs'
import { pctBasedOn } from '@freesewing/core'
import { options } from './shape.mjs'
function penelopeWaistband({
const { waistEase } = options
export const waistband = {
name: 'penelope.waistband',
measurements: ['waist', 'waistToKnee'],
options: {
waistEase,
waistband: { bool: true, menu: 'style' },
waistbandWidth: {
pct: 10,
min: 5,
max: 20,
...pctBasedOn('waistToKnee'),
// eslint-disable-next-line no-unused-vars
menu: (settings, mergedOptions) => (settings?.options?.waistband === false ? false : 'style'),
},
waistbandOverlap: {
pct: 3.5,
min: 0,
max: 10,
...pctBasedOn('waist'),
// eslint-disable-next-line no-unused-vars
menu: (settings, mergedOptions) => (settings?.options?.waistband === false ? false : 'style'),
},
},
draft: ({
options,
measurements,
Point,
@ -9,26 +35,51 @@ function penelopeWaistband({
paths,
Snippet,
snippets,
complete,
sa,
paperless,
macro,
store,
expand,
units,
part,
}) {
if (!options.waistBand) return part.hide()
}) => {
if (!options.waistband) return part.hide()
let waist = measurements.waist
waist += measurements.waist * options.waistEase
store.set('waistBandWidth', options.waistBandWidth * measurements.waistToKnee)
const waistbandWidth = options.waistbandWidth * measurements.waistToKnee
const waistbandLength = waist / 2 + measurements.waist * options.waistbandOverlap
store.set('waistbandWidth', waistbandWidth)
if (!expand) {
// Expand is on, do not draw the part but flag this to the user
store.flag.note({
msg: `penelope:cutWaistband`,
replace: {
width: units(waistbandLength),
length: units(waistbandWidth),
},
suggest: {
text: 'flag:show',
icon: 'expand',
update: {
settings: ['expand', 1],
},
},
})
// Also hint about expand
store.flag.preset('expand')
return part.hide()
}
points.TL = new Point(0, 0)
points.BL = new Point(0, waist / 2 + options.waistBandOverlap)
points.TR = new Point(store.get('waistBandWidth'), 0)
points.BR = new Point(store.get('waistBandWidth'), waist / 2 + options.waistBandOverlap)
points.BL = new Point(0, waist / 2 + options.waistbandOverlap)
points.TR = new Point(waistbandWidth, 0)
points.BR = new Point(waistbandWidth, waist / 2 + options.waistbandOverlap)
points.titleAnchor = new Point(store.get('waistBandWidth') / 2, waist / 6)
points.logoAnchor = new Point(store.get('waistBandWidth') / 2, waist / 3)
points.titleAnchor = new Point(waistbandWidth / 2, waist / 6)
points.logoAnchor = new Point(waistbandWidth / 2, waist / 3)
points.gridAnchor = points.logoAnchor.clone()
paths.outline = new Path()
.move(points.TL)
@ -39,18 +90,17 @@ function penelopeWaistband({
.close()
.attr('class', 'fabric')
// Complete?
if (complete) {
macro('cutonfold', {
from: points.TR,
to: points.TL,
margin: 15,
offset: 15,
grainline: true,
reverse: true,
})
snippets.logo = new Snippet('logo', points.logoAnchor)
store.cutlist.addCut({ cut: 1, from: 'fabric' })
macro('title', {
nr: 3,
at: points.titleAnchor,
@ -66,32 +116,20 @@ function penelopeWaistband({
.line(points.TR)
.attr('class', 'fabric sa')
}
}
if (paperless) {
macro('vd', {
from: points.TL,
to: points.BL,
x: points.TL.x + options.paperlessOffset,
id: 'height',
})
macro('hd', {
from: points.BL,
to: points.BR,
y: points.BR.y - options.paperlessOffset,
id: 'width',
})
}
return part
}
export const waistband = {
name: 'penelope.waistband',
measurements: ['waist', 'waistToKnee'],
options: {
waistEase,
waistBandOverlap: 25,
waistBand: { bool: true, menu: 'style' },
waistBandWidth: { pct: 10, min: 5, max: 20, menu: 'style' },
},
draft: penelopeWaistband,
}

View file

@ -65,7 +65,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -54,7 +54,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -55,7 +55,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -55,7 +55,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -57,7 +57,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -58,7 +58,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -56,7 +56,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -55,7 +55,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -56,7 +56,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -54,7 +54,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -55,7 +55,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -55,7 +55,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -54,7 +54,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -54,7 +54,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -56,7 +56,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -54,7 +54,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -54,7 +54,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -56,7 +56,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/models": "3.0.0-alpha.10",
"@freesewing/plugin-timing": "3.0.0-alpha.10"
},

View file

@ -0,0 +1,11 @@
---
title: "Curved darts"
---
The darts can be straight, or curved. Straight darts is what you see in most
pencil skirt patterns. Curved darts shape the top of the skirt slightly, hopefully
giving a better fit.
## Effect of this option on the pattern

View file

@ -0,0 +1,10 @@
---
title: "Waist band overlap"
---
The width of the overlap by the zipper. This is normally used to hide snaps, buttons, or hooks that
reinforce the zipper at the waistband.
## Effect of this option on the pattern

View file

@ -63,11 +63,11 @@
"lodash.clonedeep": "^4.5.0"
},
"devDependencies": {
"eslint": "8.48.0",
"eslint": "8.50.0",
"nyc": "15.1.0",
"mocha": "10.2.0",
"chai": "4.3.7",
"sinon": "^15.0.1"
"chai": "4.3.9",
"sinon": "^16.0.0"
},
"files": [
"dist/*",

View file

@ -54,7 +54,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7",
"chai": "4.3.9",
"@freesewing/plugin-annotations": "3.0.0-alpha.10",
"@freesewing/plugin-mirror": "3.0.0-alpha.10",
"@freesewing/plugin-round": "3.0.0-alpha.10",

View file

@ -54,7 +54,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7"
"chai": "4.3.9"
},
"files": [
"dist/*",

View file

@ -54,7 +54,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7"
"chai": "4.3.9"
},
"files": [
"dist/*",

View file

@ -54,7 +54,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7"
"chai": "4.3.9"
},
"files": [
"dist/*",

View file

@ -54,7 +54,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7"
"chai": "4.3.9"
},
"files": [
"dist/*",

View file

@ -54,7 +54,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7"
"chai": "4.3.9"
},
"files": [
"dist/*",

View file

@ -54,7 +54,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7"
"chai": "4.3.9"
},
"files": [
"dist/*",

View file

@ -54,7 +54,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7"
"chai": "4.3.9"
},
"files": [
"dist/*",

View file

@ -54,7 +54,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7"
"chai": "4.3.9"
},
"files": [
"dist/*",

View file

@ -54,7 +54,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7"
"chai": "4.3.9"
},
"files": [
"dist/*",

View file

@ -54,7 +54,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7"
"chai": "4.3.9"
},
"files": [
"dist/*",

View file

@ -54,7 +54,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7"
"chai": "4.3.9"
},
"files": [
"dist/*",

View file

@ -54,7 +54,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7"
"chai": "4.3.9"
},
"files": [
"dist/*",

View file

@ -54,7 +54,7 @@
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.7"
"chai": "4.3.9"
},
"files": [
"dist/*",

View file

@ -48,7 +48,7 @@
"swagger-ui-express": "5.0.0"
},
"devDependencies": {
"chai": "4.3.7",
"chai": "4.3.9",
"chai-http": "4.4.0",
"esbuild": "0.19.2",
"mocha": "10.2.0",

View file

@ -80,10 +80,10 @@ export const DesignInfo = ({ design, docs = false }) => {
// Translate measurements
const measies = { required: {}, optional: {} }
if (config.measurements) {
if (config?.measurements) {
for (const m of config.measurements) measies.required[m] = t(`measurements:${m}`)
}
if (config.optionalMeasurements) {
if (config?.optionalMeasurements) {
for (const m of config.optionalMeasurements) measies.optional[m] = t(`measurements:${m}`)
}

Some files were not shown because too many files have changed in this diff Show more