1
0
Fork 0

Merge pull request #5802 from woutervdub/lumina

Lumina
This commit is contained in:
Joost De Cock 2024-02-04 10:12:42 +01:00 committed by GitHub
commit 6afc699fc3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
136 changed files with 3561 additions and 9 deletions

View file

@ -0,0 +1,17 @@
# Change log for: @freesewing/lumina
## 3.0.0 (2022-09-30)
### Changed
- All FreeSewing pacakges are now ESM only.
- All FreeSewing pacakges now use named exports.
- Dropped support for NodeJS 14. NodeJS 18 (LTS/hydrogen) or more recent is now required.
This is the **initial release**, and the start of this change log.
> Prior to version 2, FreeSewing was not a JavaScript project.
> As such, that history is out of scope for this change log.

143
designs/lumina/README.md Normal file
View file

@ -0,0 +1,143 @@
![FreeSewing](https://static.freesewing.org/banner.png)
<p align='center'><a
href="https://www.npmjs.com/package/@freesewing/lumina"
title="@freesewing/lumina on NPM"
><img src="https://img.shields.io/npm/v/@freesewing/lumina.svg"
alt="@freesewing/lumina on NPM"/>
</a><a
href="https://opensource.org/licenses/MIT"
title="License: MIT"
><img src="https://img.shields.io/npm/l/@freesewing/lumina.svg?label=License"
alt="License: MIT"/>
</a><a
href="https://deepscan.io/dashboard#view=project&tid=2114&pid=2993&bid=23256"
title="Code quality on DeepScan"
><img src="https://deepscan.io/api/teams/2114/projects/2993/branches/23256/badge/grade.svg"
alt="Code quality on DeepScan"/>
</a><a
href="https://github.com/freesewing/freesewing/issues?q=is%3Aissue+is%3Aopen+label%3Apkg%3Alumina"
title="Open issues tagged pkg:lumina"
><img src="https://img.shields.io/github/issues/freesewing/freesewing/pkg:lumina.svg?label=Issues"
alt="Open issues tagged pkg:lumina"/>
</a><a
href="#contributors-"
title="All Contributors"
><img src="https://img.shields.io/badge/all_contributors-118-pink.svg"
alt="All Contributors"/>
</a></p><p align='center'><a
href="https://twitter.com/freesewing_org"
title="Follow @freesewing_org on Twitter"
><img src="https://img.shields.io/badge/%F3%A0%80%A0-Follow%20us-blue.svg?logo=twitter&logoColor=white&logoWidth=15"
alt="Follow @freesewing_org on Twitter"/>
</a><a
href="https://chat.freesewing.org"
title="Chat with us on Discord"
><img src="https://img.shields.io/discord/698854858052075530?label=Chat%20on%20Discord"
alt="Chat with us on Discord"/>
</a><a
href="https://freesewing.org/patrons/join"
title="Become a FreeSewing Patron"
><img src="https://img.shields.io/badge/%F3%A0%80%A0-Support%20us-blueviolet.svg?logo=cash-app&logoColor=white&logoWidth=15"
alt="Become a FreeSewing Patron"/>
</a><a
href="https://instagram.com/freesewing_org"
title="Follow @freesewing_org on Twitter"
><img src="https://img.shields.io/badge/%F3%A0%80%A0-Follow%20us-E4405F.svg?logo=instagram&logoColor=white&logoWidth=15"
alt="Follow @freesewing_org on Twitter"/>
</a></p>
# @freesewing/lumina
A FreeSewing pattern that needs a description
## What am I looking at? 🤔
This repository is the FreeSewing *monorepo* holding all FreeSewing's websites, documentation, designs, plugins, and other NPM packages.
This folder holds: @freesewing/lumina
If you're not entirely sure what to do or how to start, type this command:
```
npm run tips
```
> If you don't want to set up a dev environment, you can run it in your browser:
>
> [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/freesewing/freesewing)
>
> We recommend that you fork our repository and then
> put `gitpod.io/#<entire-url-of-your-fork` into a browser
> to start up a browser-based dev environment of your own.
## About FreeSewing 💀
Where the world of makers and developers collide, that's where you'll find FreeSewing.
If you're a maker, checkout [freesewing.org](https://freesewing.org/) where you can generate
sewing patterns adapted to your measurements.
If you're a developer, the FreeSewing documentation lives at [freesewing.dev](https://freesewing.dev/).
The FreeSewing [core library](https://freesewing.dev/reference/api/) is a *batteries-included* toolbox
for parametric design of sewing patterns. But FreeSewing also provides a range
of [plugins](https://freesewing.dev/reference/plugins/) that further extend the
functionality of the platform.
If you have NodeJS installed, you can try it right now by running:
```bash
npx create-freesewing-pattern
```
Getting started guides are available for:
- [Linux](https://freesewing.dev/tutorials/getting-started-linux/)
- [MacOS](https://freesewing.dev/tutorials/getting-started-mac/)
- [Windows](https://freesewing.dev/tutorials/getting-started-windows/)
The [pattern design tutorial](https://freesewing.dev/tutorials/pattern-design/) will
show you how to create your first parametric design.
## Support FreeSewing: Become a patron 🥰
FreeSewing is an open source project maintained by Joost De Cock and financially supported by the FreeSewing patrons.
If you feel FreeSewing is worthwhile, and you can spend a few coins without
hardship, then you should [join us and become a patron](https://freesewing.org/community/join).
## Links 👩‍💻
**Official channels**
- 💻 Makers website: [FreeSewing.org](https://freesewing.org)
- 💻 Developers website: [FreeSewing.dev](https://freesewing.dev)
- ✅ [Support](https://github.com/freesewing/freesewing/issues/new/choose),
[Issues](https://github.com/freesewing/freesewing/issues) &
[Discussions](https://github.com/freesewing/freesewing/discussions) on
[GitHub](https://github.com/freesewing/freesewing)
**Social media**
- 🐦 Twitter: [@freesewing_org](https://twitter.com/freesewing_org)
- 📷 Instagram: [@freesewing_org](https://instagram.com/freesewing_org)
**Places the FreeSewing community hangs out**
- 💬 [Discord](https://discord.freesewing.org/)
- 💬 [Facebook](https://www.facebook.com/groups/627769821272714/)
- 💬 [Reddit](https://www.reddit.com/r/freesewing/)
## License: MIT 🤓
© [Joost De Cock](https://github.com/joostdecock).
See [the license file](https://github.com/freesewing/freesewing/blob/develop/LICENSE) for details.
## Where to get help 🤯
For [Support](https://github.com/freesewing/freesewing/issues/new/choose),
please use the [Issues](https://github.com/freesewing/freesewing/issues) &
[Discussions](https://github.com/freesewing/freesewing/discussions) on
[GitHub](https://github.com/freesewing/freesewing).

35
designs/lumina/build.mjs Normal file
View file

@ -0,0 +1,35 @@
/* This script will build the package with esbuild */
import esbuild from 'esbuild'
import pkg from './package.json' assert { type: 'json' }
// Create banner based on package info
const banner = `/**
* ${pkg.name} | v${pkg.version}
* ${pkg.description}
* (c) ${new Date().getFullYear()} ${pkg.author}
* @license ${pkg.license}
*/`
// Shared esbuild options
const options = {
banner: { js: banner },
bundle: true,
entryPoints: ['src/index.mjs'],
format: 'esm',
outfile: 'dist/index.mjs',
external: ['@freesewing'],
metafile: process.env.VERBOSE ? true : false,
minify: process.env.NO_MINIFY ? false : true,
sourcemap: true,
}
// Let esbuild generate the build
const build = async () => {
const result = await esbuild.build(options).catch(() => process.exit(1))
if (process.env.VERBOSE) {
const info = await esbuild.analyzeMetafile(result.metafile)
console.log(info)
}
}
build()

4
designs/lumina/data.mjs Normal file
View file

@ -0,0 +1,4 @@
// This file is auto-generated | All changes you make will be overwritten.
export const name = '@freesewing/lumina'
export const version = '3.0.0'
export const data = { name, version }

View file

@ -0,0 +1,7 @@
{
"t": "Lumina",
"d": "A FreeSewing pattern that needs a description",
"p": { },
"s": { },
"o": { }
}

101
designs/lumina/i18n/en.json Normal file
View file

@ -0,0 +1,101 @@
{
"t": "Lumina leggings",
"d": "A FreeSewing pattern for a pair of leggings",
"p": {
"shape": "Shape",
"leg": "Leg",
"panel": "Side panel",
"pocket": "Pocket",
"waistband": "Waistband"
},
"s": {
"couldNotLowerWaist.t": "Could not lower the waist",
"cantFitTheWaistPoint.t": "Cannot fit the waist point",
"couldNoFitWaistband.t": "Could not fit the waistband",
"couldNotCreatePocket.t": "Could not create the pocket",
"dimensions.d": "Dimensions",
"dimensions.t": "Waistband will be {{{ waistbandlength }}} long total.\nThe length of the garment along the side will be {{{ length }}}."
},
"o": {
"ease": {
"t": "Ease",
"d": "This controls the amount of ease. Since this is a pattern for leggings that is normally made of stretch fabric, the ease is negative, meaning the fabric is stretched around the body."
},
"length": {
"t": "Leg length",
"d": "The length of the legs. Look in the Messages from the designer for the exact length."
},
"waistlowering": {
"t": "Waist lowering",
"d": "Lowering of the waist. This is a percentage of the Waist-To-Hips measurement."
},
"waistband": {
"t": "Waistband",
"d": "Add a separate waistband to the design."
},
"waistbandYes": {
"t": "With a Waistband",
"d": "Add a separate waistband."
},
"waistbandNo": {
"t": "Without a Waistband",
"d": "Do not add a separate waistband."
},
"lowerwaistbandback": {
"t": "Waistband Lowering",
"d": "Lower the waistband in the back."
},
"lowerwaistbandbackYes": {
"t": "Lower the Waistband",
"d": "Lower the waistband in the back, creating a 'V' shape."
},
"lowerwaistbandbackNo": {
"t": "Straight waistband",
"d": "Do not lower the waistband in the back."
},
"waistbandsize": {
"t": "Waistband size",
"d": "Size (height) of the waistband. This is a percentage of the Waist-To-Hips measurement."
},
"waistreduction": {
"t": "Waist circumference reduction",
"d": "The amount by which the waist should be reduced. This is a percentage of the waist circumference. Only available when the waistband option is selected. Look in the Messages from the designer for the exact size."
},
"pocket": {
"t": "Pocket",
"d": "Add pockets"
},
"pocketYes": {
"t": "Add pockets",
"d": "Add pockets in the side panel"
},
"pocketNo": {
"t": "No pockets",
"d": "Pockets are not added"
},
"pocketdepth": {
"t": "Pocket depth",
"d": "Depth (height) of the pocket. This is a percentage of the Waist-To-Seat measurement."
},
"fixedsidepanel": {
"t": "Side panel",
"d": "Fixed-width, or shaped side panel"
},
"fixedsidepanelYes": {
"t": "Fixed side panel",
"d": "Create a fixed-width side panel"
},
"fixedsidepanelNo": {
"t": "Shaped side panel",
"d": "Create a shaped side panel, consisting of a percentage of the leg circumference"
},
"sidepanel": {
"t": "Side Panel size",
"d": "Size (width) of the side panel. This is a percentage of the waist circumference."
},
"smoothing": {
"t": "Smoothing",
"d": "This setting controls the amount of smoothing that is done to create the side seams (and overall shape of the leggings)."
}
}
}

View file

@ -0,0 +1,7 @@
{
"t": "Lumina",
"d": "A FreeSewing pattern that needs a description",
"p": { },
"s": { },
"o": { }
}

View file

@ -0,0 +1,7 @@
{
"t": "Lumina",
"d": "A FreeSewing pattern that needs a description",
"p": { },
"s": { },
"o": { }
}

View file

@ -0,0 +1,8 @@
import en from './en.json' assert { type: 'json' }
import de from './de.json' assert { type: 'json' }
import es from './es.json' assert { type: 'json' }
import fr from './fr.json' assert { type: 'json' }
import nl from './nl.json' assert { type: 'json' }
import uk from './uk.json' assert { type: 'json' }
export const i18n = { en, de, es, fr, nl, uk }

View file

@ -0,0 +1,7 @@
{
"t": "Lumina",
"d": "A FreeSewing pattern that needs a description",
"p": { },
"s": { },
"o": { }
}

View file

@ -0,0 +1,7 @@
{
"t": "Lumina",
"d": "A FreeSewing pattern that needs a description",
"p": { },
"s": { },
"o": { }
}

View file

@ -0,0 +1,73 @@
{
"name": "@freesewing/lumina",
"version": "3.0.0",
"description": "A FreeSewing pattern that needs a description",
"author": "Joost De Cock <joost@joost.at> (https://github.com/joostdecock)",
"homepage": "https://freesewing.org/",
"repository": "github:freesewing/freesewing",
"license": "MIT",
"bugs": {
"url": "https://github.com/freesewing/freesewing/issues"
},
"funding": {
"type": "individual",
"url": "https://freesewing.org/patrons/join"
},
"keywords": [
"freesewing",
"design",
"diy",
"fashion",
"made to measure",
"parametric design",
"pattern",
"sewing",
"sewing pattern"
],
"type": "module",
"module": "dist/index.mjs",
"exports": {
".": {
"internal": "./src/index.mjs",
"default": "./dist/index.mjs"
}
},
"scripts": {
"build": "node build.mjs",
"build:all": "yarn build",
"clean": "rimraf dist",
"mbuild": "NO_MINIFY=1 node build.mjs",
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -",
"test": "npx mocha tests/*.test.mjs",
"vbuild": "VERBOSE=1 node build.mjs",
"lab": "cd ../../sites/lab && yarn start",
"tips": "node ../../scripts/help.mjs",
"lint": "npx eslint 'src/**' 'tests/*.mjs'",
"prettier": "npx prettier --write 'src/*.mjs' 'tests/*.mjs'",
"testci": "NODE_OPTIONS=\"--conditions=internal\" npx mocha tests/*.test.mjs --reporter ../../tests/reporters/terse.js",
"wbuild": "node build.mjs",
"wbuild:all": "yarn wbuild"
},
"peerDependencies": {
"@freesewing/core": "3.0.0"
},
"dependencies": {},
"devDependencies": {
"mocha": "10.2.0",
"chai": "4.3.10",
"@freesewing/models": "3.0.0",
"@freesewing/plugin-timing": "3.0.0"
},
"files": [
"dist/*",
"README.md"
],
"publishConfig": {
"access": "public",
"tag": "latest"
},
"engines": {
"node": "18",
"npm": "9"
}
}

View file

@ -0,0 +1,20 @@
//
import { Design } from '@freesewing/core'
import { i18n } from '../i18n/index.mjs'
import { data } from '../data.mjs'
// Parts
import { shape } from './shape.mjs'
import { panel } from './panel.mjs'
import { leg } from './leg.mjs'
import { pocket } from './pocket.mjs'
import { waistband } from './waistband.mjs'
// Create new design
const Lumina = new Design({
data,
parts: [shape, panel, leg, waistband, pocket],
})
// Named exports
export { i18n, Lumina, shape, panel, leg, waistband, pocket }

151
designs/lumina/src/leg.mjs Normal file
View file

@ -0,0 +1,151 @@
import { shape } from './shape.mjs'
export const leg = {
name: 'lumina.leg',
from: shape,
draft: ({ sa, points, Path, paths, Snippet, snippets, macro, store, part }) => {
paths.front = paths.front.reverse().unhide().addText('front', 'note center').setClass('hidden')
paths.frontSplit.unhide().addText('front', 'note center').setClass('hidden')
paths.back.unhide().addText('back', 'note center').setClass('hidden')
paths.backSplit = paths.backSplit
.reverse()
.unhide()
.addText('back', 'note center')
.setClass('hidden')
paths.seam = new Path()
.move(points.frontSplitHem)
.join(paths.backSplit)
.join(paths.backWaistband.reverse())
.join(paths.back)
.join(paths.front)
.join(paths.frontWaistband)
.join(paths.frontSplit)
.close()
if (sa) paths.sa = paths.seam.offset(sa).attr('class', 'fabric sa')
store.cutlist.addCut({ cut: 2, from: 'fabric' })
points.gridAnchor = points.middleUpperLeg.clone()
points.logo = points.middleUpperLeg.shiftFractionTowards(points.frontSplitUpperLeg, 0.5)
snippets.logo = new Snippet('logo', points.logo)
points.title = points.middleUpperLeg.shiftFractionTowards(points.backSplitUpperLeg, 0.6)
macro('title', {
at: points.title,
nr: 1,
title: 'leg',
align: 'center',
})
points.scalebox = points.middleUpperLeg.shift(270, 50)
macro('scalebox', {
at: points.scalebox,
})
snippets.middle = new Snippet('notch', points.frontUpperLeg)
snippets.front0 = new Snippet('notch', paths.front.shiftFractionAlong(0.5))
snippets.front1 = new Snippet('notch', paths.frontSplit.shiftFractionAlong(0.2))
snippets.front2 = new Snippet('notch', paths.frontSplit.shiftFractionAlong(0.4))
snippets.front3 = new Snippet('notch', paths.frontSplit.shiftFractionAlong(0.6))
snippets.front4 = new Snippet('notch', paths.frontSplit.shiftFractionAlong(0.8))
snippets.back0 = new Snippet('notch', paths.back.shiftFractionAlong(0.5))
snippets.back1 = new Snippet('notch', paths.backSplit.shiftFractionAlong(0.25))
snippets.back2 = new Snippet('notch', paths.backSplit.shiftFractionAlong(0.5))
snippets.back3 = new Snippet('notch', paths.backSplit.shiftFractionAlong(0.75))
const middleBottom = points.frontSplitHem.shiftFractionTowards(points.backSplitHem, 0.5)
middleBottom.x = 0
const top = paths.seam.edge('top')
top.x = 0
const back = paths.seam.edge('right')
const front = paths.seam.edge('left')
if (!points.frontSplitWaistband.sitsRoughlyOn(front)) {
macro('hd', {
id: 'middleToFront',
from: front,
to: points.middleUpperLeg,
y: top.y - sa - 35,
})
}
if (!points.backSplitWaistband.sitsRoughlyOn(back)) {
macro('hd', {
id: 'middleToBack',
from: points.middleUpperLeg,
to: back,
y: top.y - sa - 35,
})
}
macro('hd', {
id: 'middleToFrontSplitWaistband',
from: points.frontSplitWaistband,
to: points.middleUpperLeg,
y: top.y - sa - 25,
})
macro('hd', {
id: 'middleToBackSplitWaistband',
from: points.middleUpperLeg,
to: points.backSplitWaistband,
y: top.y - sa - 25,
})
macro('hd', {
id: 'middleToFrontWaistband',
from: points.frontWaistband,
to: points.middleUpperLeg,
y: top.y - sa - 15,
})
macro('hd', {
id: 'middleToBackWaistband',
from: points.middleUpperLeg,
to: points.backWaistband,
y: top.y - sa - 15,
})
macro('hd', {
id: 'bottomFront',
from: points.frontSplitHem,
to: middleBottom,
y: middleBottom.y + sa + 15,
})
macro('hd', {
id: 'bottomBack',
from: middleBottom,
to: points.backSplitHem,
y: middleBottom.y + sa + 15,
})
macro('vd', {
id: 'middle',
from: points.middleUpperLeg,
to: middleBottom,
x: 0,
})
macro('vd', {
id: 'front',
from: points.frontWaistband,
to: points.middleUpperLeg,
x: -15,
})
macro('vd', {
id: 'back',
from: points.backWaistband,
to: points.middleUpperLeg,
x: 15,
})
macro('vd', {
id: 'frontSplit',
from: points.frontSplitWaistband,
to: points.frontSplitHem,
x: front.x - sa - 15,
})
macro('vd', {
id: 'backSplit',
from: points.backSplitWaistband,
to: points.backSplitHem,
x: back.x + sa + 15,
})
return part
},
}

View file

@ -0,0 +1,109 @@
import { shape } from './shape.mjs'
export const panel = {
name: 'lumina.panel',
from: shape,
draft: ({ sa, Point, points, Path, paths, Snippet, snippets, macro, store, part }) => {
paths.panelWaistband = new Path()
.move(points.frontPanelWaistband)
.line(points.backPanelWaistband)
.setText('top', 'note center')
.setClass('hidden')
paths.panelHem = new Path()
.move(points.backPanelHem)
.line(points.frontPanelHem)
.setText('bottom', 'note center')
.setClass('hidden')
paths.frontPanel.reverse().setText('front', 'note center').setClass('hidden')
paths.backPanel = paths.backPanel.unhide().setText('back', 'note center').setClass('hidden')
paths.seam = new Path()
.move(points.backPanelHem)
.join(paths.backPanel.reverse())
.join(paths.panelWaistband.reverse())
.join(paths.frontPanel)
.join(paths.panelHem.reverse())
.reverse()
.close()
if (sa) paths.sa = paths.seam.offset(sa).attr('class', 'fabric sa')
snippets.front1 = new Snippet('notch', paths.frontPanel.shiftFractionAlong(0.2))
snippets.front2 = new Snippet('notch', paths.frontPanel.shiftFractionAlong(0.4))
snippets.front3 = new Snippet('notch', paths.frontPanel.shiftFractionAlong(0.6))
snippets.front4 = new Snippet('notch', paths.frontPanel.shiftFractionAlong(0.8))
snippets.back1 = new Snippet('notch', paths.backPanel.shiftFractionAlong(0.25))
snippets.back2 = new Snippet('notch', paths.backPanel.shiftFractionAlong(0.5))
snippets.back3 = new Snippet('notch', paths.backPanel.shiftFractionAlong(0.75))
store.cutlist.addCut({ cut: 2, from: 'fabric' })
points.gridAnchor = points.middleSeat.clone()
points.title = points.middleSeat.clone()
macro('title', {
at: points.title,
nr: 2,
title: 'panel',
align: 'center',
})
const middleTop = points.frontPanelWaistband.shiftFractionTowards(
points.backPanelWaistband,
0.5
)
const middleBottom = new Point(middleTop.x, points.frontPanelHem.y)
const back = paths.backPanel.edge('left')
const front = paths.frontPanel.edge('right')
macro('hd', {
id: 'topFront',
from: middleTop,
to: points.frontPanelWaistband,
y: middleTop.y - sa - 15,
})
macro('hd', {
id: 'topBack',
from: points.backPanelWaistband,
to: middleTop,
y: middleTop.y - sa - 15,
})
macro('hd', {
id: 'middleFront',
from: middleBottom,
to: front,
y: middleBottom.y + sa + 25,
})
macro('hd', {
id: 'middleBack',
from: back,
to: middleBottom,
y: middleBottom.y + sa + 25,
})
macro('hd', {
id: 'bottomFront',
from: middleBottom,
to: points.frontPanelHem,
y: middleBottom.y + sa + 15,
})
macro('hd', {
id: 'bottomBack',
from: points.backPanelHem,
to: middleBottom,
y: middleBottom.y + sa + 15,
})
macro('vd', {
id: 'front',
from: points.frontPanelWaistband,
to: points.frontPanelHem,
x: front.x + sa + 15,
})
macro('vd', {
id: 'back',
from: points.backPanelWaistband,
to: points.backPanelHem,
x: back.x - sa - 15,
})
return part
},
}

View file

@ -0,0 +1,154 @@
import { pctBasedOn } from '@freesewing/core'
import { panel } from './panel.mjs'
import { shape } from './shape.mjs'
export const pocket = {
name: 'lumina.pocket',
after: panel,
from: shape,
options: {
pocket: { bool: true, menu: 'style' },
pocketdepth: {
pct: 90,
min: 20,
max: 120,
...pctBasedOn('waistToSeat'),
// eslint-disable-next-line no-unused-vars
menu: (settings, mergedOptions) => (mergedOptions?.pocket ? 'style' : false),
},
},
draft: ({
measurements,
sa,
Point,
points,
Path,
paths,
Snippet,
snippets,
options,
macro,
store,
log,
part,
}) => {
if (!options.pocket) {
return part.hide()
}
const pocketDepth = measurements.waistToSeat * options.pocketdepth
paths.pocketWaistband = new Path()
.move(points.frontPanelWaistband)
.line(points.backPanelWaistband)
.addText('top', 'note center')
.setClass('hidden')
points.frontPocketHem = paths.frontPanel.shiftAlong(pocketDepth)
points.backPocketHem = paths.backPanel.shiftAlong(pocketDepth)
paths.pocketHem = new Path()
.move(points.backPocketHem)
.line(points.frontPocketHem)
.addText('bottom', 'note center')
.setClass('hidden')
const frontPocketSplit = paths.frontPanel.split(points.frontPocketHem)
if (frontPocketSplit) {
paths.frontPocket = frontPocketSplit[0]
.reverse()
.unhide()
.addText('front', 'note center')
.setClass('hidden')
} else {
log.info('lumina:couldNotCreatePocket')
return part.hide()
}
const backPocketSplit = paths.backPanel.split(points.backPocketHem)
if (backPocketSplit) {
paths.backPocket = backPocketSplit[0]
.unhide()
.addText('back', 'note center')
.setClass('hidden')
} else {
log.info('lumina:couldNotCreatePocket')
return part.hide()
}
paths.seam = new Path()
.move(points.frontPocketHem)
.join(paths.pocketHem.reverse())
.join(paths.backPocket.reverse())
.join(paths.pocketWaistband.reverse())
.join(paths.frontPocket.reverse())
.close()
.reverse()
if (sa) paths.sa = paths.seam.offset(sa).attr('class', 'fabric sa')
for (var i = 1; i < 4; i++) {
if (paths.frontPanel.length() * (0.2 * i) < pocketDepth) {
snippets['front' + i] = new Snippet('notch', paths.frontPanel.shiftFractionAlong(0.2 * i))
}
if (paths.backPanel.length() * (0.25 * i) < pocketDepth) {
snippets['back' + i] = new Snippet('notch', paths.backPanel.shiftFractionAlong(0.25 * i))
}
}
store.cutlist.addCut({ cut: 2, from: 'fabric' })
points.gridAnchor = points.middleSeat.clone()
points.title = points.frontPocketHem.shiftFractionTowards(points.backPanelWaistband, 0.5)
macro('title', {
at: points.title,
nr: 4,
title: 'pocket',
align: 'center',
})
const middleTop = points.frontPanelWaistband.shiftFractionTowards(
points.backPanelWaistband,
0.5
)
const middleBottom = new Point(middleTop.x, points.frontPocketHem.y)
const back = paths.backPocket.edge('left')
const front = paths.frontPocket.edge('right')
macro('hd', {
id: 'topFront',
from: middleTop,
to: points.frontPanelWaistband,
y: middleTop.y - sa - 15,
})
macro('hd', {
id: 'topBack',
from: points.backPanelWaistband,
to: middleTop,
y: middleTop.y - sa - 15,
})
macro('hd', {
id: 'bottomFront',
from: middleBottom,
to: front,
y: middleBottom.y + sa + 15,
})
macro('hd', {
id: 'bottomBack',
from: back,
to: middleBottom,
y: middleBottom.y + sa + 15,
})
macro('vd', {
id: 'front',
from: points.frontPanelWaistband,
to: points.frontPocketHem,
x: points.frontPocketHem.x + sa + 15,
})
macro('vd', {
id: 'back',
from: points.backPanelWaistband,
to: points.backPocketHem,
x: points.backPocketHem.x - sa - 15,
})
return part
},
}

View file

@ -0,0 +1,631 @@
import { pctBasedOn } from '@freesewing/core'
import { extendPath, createControlPoints } from '@freesewing/lumira'
export const createPath = (paths, Path, points, pathName, names) => {
let i
paths[pathName] = new Path()
.move(points[names[0]])
._curve(points[names[1] + 'Cp2'], points[names[1]])
for (i = 2; i < names.length - 1; i++) {
paths[pathName].curve(points[names[i - 1] + 'Cp1'], points[names[i] + 'Cp2'], points[names[i]])
}
paths[pathName].curve_(points[names[i - 1] + 'Cp1'], points[names[i]])
return paths[pathName]
}
const lowerWaist = (paths, Path, points, log, waistLowering, pathName, pointName) => {
const newPath = extendPath(Path, paths[pathName], 100, 0)
const newWaist = newPath.shiftAlong(waistLowering + 100)
if (newWaist.sitsRoughlyOn(points[pathName + pointName])) {
return
}
points[pathName + pointName] = newWaist
const pTemp = newPath.split(points[pathName + pointName])
if (pTemp.length != 2) {
log.info('lumina:couldNotLowerWaist')
}
paths[pathName] = pTemp[1].hide()
}
const createWaistPoint = (options, measurements, Path, points, utils, log, front) => {
const kneeTemp = points.middleCrossSeam.shiftFractionTowards(
points.middleKnee,
options.crotchToKnee
)
const angle =
90 +
(front
? options.crossSeamAngle * (measurements.waistBack / measurements.waist)
: -1 * options.crossSeamAngle * (1 - measurements.waistBack / measurements.waist))
const crossSeam = front
? measurements.crossSeamFront
: measurements.crossSeam - measurements.crossSeamFront
let waist = kneeTemp.shift(angle, measurements.waistToKnee)
const crossSeamCp = points.middleCrossSeam.shiftFractionTowards(
utils.beamIntersectsY(kneeTemp, waist, points.middleCrossSeam.y),
options.crotchPointsCP
)
let waistCp = waist.shiftFractionTowards(points.middleKnee, options.waistToKneeCP)
const kneeToWaist = measurements.waistToKnee * 0.75
let diff = 0
let iter = 0
do {
// waist = kneeTemp.shift(angle, kneeToWaist +((diff > 0 ? 1 : -1) *iter))
waist = kneeTemp.shift(angle, kneeToWaist + diff * 1.03)
// waist = kneeTemp.shift(angle, kneeToWaist *ratio)
waistCp = waist.shiftFractionTowards(points.middleKnee, options.waistToKneeCP)
const crossSeamPath = new Path().move(points.middleCrossSeam).curve(crossSeamCp, waistCp, waist)
diff = crossSeam - crossSeamPath.length()
// console.log({i:iter,d:diff,cs:crossSeam,csl:crossSeamPath.length()})
} while (++iter < 100 && (diff > 1 || diff < -1))
if (iter >= 100) {
log.error('lumina:cantFitTheWaistPoint')
}
if (front) {
points.frontWaist = waist.clone()
points.frontWaistband = waist.clone()
points.frontWaistCp = waistCp.clone()
points.frontCrossSeamCp = crossSeamCp.clone()
} else {
points.backWaist = waist.clone()
points.backWaistband = waist.clone()
points.backWaistCp = waistCp.clone()
points.backCrossSeamCp = crossSeamCp.clone()
}
}
const createSidePoints = ({
measurements,
points,
utils,
prefix,
postfix,
names,
ratio,
ratioFixed,
ease,
waistReduction,
distanceCompensation,
fixedSidePanel,
}) => {
let measurement
let lastGood = 0
for (let i = 0; i < names.length; i++) {
let m1 = 0,
m2 = 0
if (names[i] != 'Waist') {
m1 = measurements['waistTo' + names[i]]
}
if (names[lastGood] != 'Waist') {
m2 = measurements['waistTo' + names[lastGood]]
}
let distance = m2 - m1
switch (names[i]) {
case 'UpperLeg': {
measurement = measurements['upperLeg']
const intersect = utils.beamIntersectsCurve(
points[prefix + names[i]],
points[prefix + names[i]].shift(prefix == 'front' ? 180 : 0, ratioFixed * 100),
points.middleCrossSeam,
points[prefix + 'CrossSeamCp'],
points[prefix + 'WaistCp'],
points[prefix + 'Waist']
)
if (false !== intersect) {
if (intersect.constructor === Array) {
measurement += intersect[0].dist(points[prefix + names[i]])
} else {
measurement += intersect.dist(points[prefix + names[i]])
}
}
break
}
case 'Waist': {
measurement =
(prefix == 'front'
? measurements.waist - measurements.waistBack
: measurements.waistBack) -
waistReduction * 0.5
break
}
case 'Seat': {
measurement =
prefix == 'front' ? measurements.seat - measurements.seatBack : measurements.seatBack
distance *= distanceCompensation
break
}
default: {
measurement = measurements[names[i].toLowerCase()]
// Adjust for thigh size when using positive ease
if (ease > 1 && (names[i] == 'Ankle' || names[i] == 'Knee')) {
measurement *= 1.2
}
}
}
measurement /= 2
measurement *= ease
let ci
const width = measurement * ratio
const reduction =
ratio == 0
? measurement
: fixedSidePanel > 0
? width < measurement - fixedSidePanel
? measurement - fixedSidePanel
: width
: width
if (i == 0) {
points[prefix + postfix + names[i]] = points[prefix + names[i]].shift(
prefix == 'front' ? 180 : 0,
reduction
)
} else {
let iter = 0
do {
ci = utils.circlesIntersect(
points[prefix + names[i]],
reduction * (1 + iter * 0.02),
points[prefix + postfix + names[lastGood]],
distance
)
if (false !== ci) {
points[prefix + postfix + names[i]] = ci[prefix == 'front' ? 0 : 1]
}
} while (iter++ < 100 && (false == ci || isNaN(ci[prefix == 'front' ? 0 : 1].x)))
lastGood = i
}
}
}
const smoothPoints = (points, prefix, postfix, names, smoothness) => {
let adjust
for (let i = 0; i < names.length - 2; i++) {
adjust = false
if (prefix == 'front') {
adjust =
points[prefix + postfix + names[i]].angle(points[prefix + postfix + names[i + 1]]) >
points[prefix + postfix + names[i]].angle(points[prefix + postfix + names[i + 2]])
} else {
adjust =
points[prefix + postfix + names[i]].angle(points[prefix + postfix + names[i + 1]]) <
points[prefix + postfix + names[i]].angle(points[prefix + postfix + names[i + 2]])
}
if (adjust) {
const angleDiff =
points[prefix + postfix + names[i]].angle(points[prefix + postfix + names[i + 2]]) -
points[prefix + postfix + names[i]].angle(points[prefix + postfix + names[i + 1]])
points[prefix + postfix + names[i + 1]] = points[prefix + postfix + names[i]].shift(
points[prefix + postfix + names[i]].angle(points[prefix + postfix + names[i + 1]]) +
smoothness * angleDiff,
points[prefix + postfix + names[i]].dist(points[prefix + postfix + names[i + 1]])
)
}
}
}
export const shape = {
name: 'lumina.shape',
measurements: [
'waist',
'waistBack',
'hips',
'seat',
'seatBack',
'inseam',
'waistToSeat',
'waistToUpperLeg',
'waistToKnee',
'waistToHips',
'waistToFloor',
'knee',
'ankle',
'crossSeam',
'crossSeamFront',
'heel',
'upperLeg',
],
options: {
waistband: { bool: true, menu: 'style' },
lowerwaistbandback: {
bool: true,
// eslint-disable-next-line no-unused-vars
menu: (settings, mergedOptions) => (mergedOptions?.waistband ? 'style' : false),
},
ease: { pct: -8, min: -25, max: 10, menu: 'fit' },
length: { pct: 35, min: 10, max: 100, menu: 'style' },
waistbandsize: {
pct: 50,
min: 0,
max: 150,
...pctBasedOn('waistToHips'),
// eslint-disable-next-line no-unused-vars
menu: (settings, mergedOptions) => (mergedOptions?.waistband ? 'style' : false),
},
waistlowering: { pct: 35, min: -10, max: 60, ...pctBasedOn('waistToHips'), menu: 'style' },
waistreduction: {
pct: 4,
min: 0,
max: 10,
...pctBasedOn('waist'),
// eslint-disable-next-line no-unused-vars
menu: (settings, mergedOptions) => (mergedOptions?.waistband ? 'fit' : false),
},
sidepanel: { pct: 25, min: 10, max: 40, menu: 'style' },
smoothing: { pct: 85, min: 50, max: 100, menu: 'advanced' },
fixedsidepanel: { bool: false, menu: 'style' },
crossSeamAngle: 35,
crotchToKnee: 0.4,
waistToKneeCP: 0.4,
kneeToWaistLength: 400,
crotchPointsCP: 2,
},
draft: ({
measurements,
options,
Point,
Path,
points,
paths,
utils,
store,
units,
log,
part,
}) => {
const inseam =
measurements.inseam > measurements.waistToFloor - measurements.waistToUpperLeg
? measurements.waistToFloor - measurements.waistToUpperLeg
: measurements.inseam
const crotchOffset = measurements.waistToFloor - inseam
const waistLowering = measurements.waistToHips * options.waistlowering
const waistReduction = options.waistband ? measurements.waist * options.waistreduction : 0
const waistbandSize = options.waistband
? measurements.waistToHips *
(options.waistlowering + options.waistbandsize > 1.5
? 1.5 - options.waistlowering
: options.waistbandsize)
: 0
const sideRatio = 1 - options.sidepanel
// const sideRatio = 3 / 5
const ease = options.ease + 1
const waistToAnkle = measurements.waistToFloor - measurements.heel / Math.PI
store.set('waistbandSize', waistbandSize)
store.set('waistLowering', waistLowering)
measurements['waistToAnkle'] = measurements.waistToFloor - measurements.heel / Math.PI
const sideFixed = (((measurements.waist - measurements.waistBack) * ease) / 2) * sideRatio
const fixedSidePanel =
(((measurements.waist - measurements.waistBack - waistReduction) * ease) / 2) *
options.sidepanel
points.middleWaist = new Point(0, 0)
points.middleHips = points.middleWaist.shift(270, measurements.waistToHips)
points.middleSeat = points.middleWaist.shift(270, measurements.waistToSeat)
points.frontCrossSeam =
points.backCrossSeam =
points.middleCrossSeam =
points.middleWaist.shift(270, crotchOffset)
points.frontUpperLeg =
points.backUpperLeg =
points.middleUpperLeg =
points.middleWaist.shift(270, measurements.waistToUpperLeg)
points.frontKnee =
points.backKnee =
points.middleKnee =
points.middleWaist.shift(270, measurements.waistToKnee)
points.frontAnkle =
points.backAnkle =
points.middleAnkle =
points.middleWaist.shift(270, waistToAnkle)
points.frontFloor =
points.backFloor =
points.middleFloor =
points.middleWaist.shift(270, measurements.waistToFloor)
createWaistPoint(options, measurements, Path, points, utils, log, true)
createWaistPoint(options, measurements, Path, points, utils, log, false)
const frontCrossSeam = new Path()
.move(points.frontWaist)
.curve(points.frontWaistCp, points.frontCrossSeamCp, points.middleCrossSeam)
const backCrossSeam = new Path()
.move(points.backWaist)
.curve(points.backWaistCp, points.backCrossSeamCp, points.middleCrossSeam)
points.frontSeat = frontCrossSeam.shiftAlong(
measurements.waistToSeat * (measurements.crossSeamFront / measurements.waistToUpperLeg) * 0.8
)
points.frontHips = frontCrossSeam.shiftAlong(
measurements.waistToHips * (measurements.crossSeamFront / measurements.waistToUpperLeg)
)
points.backSeat = backCrossSeam.shiftAlong(
measurements.waistToSeat * (measurements.waistToSeat / measurements.waistToUpperLeg)
)
points.backHips = backCrossSeam.shiftAlong(
measurements.waistToHips * (measurements.waistToSeat / measurements.waistToUpperLeg)
)
;['front', 'back'].forEach((prefix) => {
createSidePoints({
measurements: measurements,
points: points,
utils: utils,
prefix: prefix,
postfix: 'Side',
names: ['Ankle', 'Knee', 'UpperLeg', 'Seat', 'Waist'],
ratio: 0,
ratioFixed: 0.1,
ease: ease,
waistReduction: waistReduction,
distanceCompensation: 1,
fixedSidePanel: 0,
})
points[prefix + 'SideWaistband'] = points[prefix + 'SideWaist'].clone()
})
points.middleWaistband = points.middleWaist.clone()
;['front', 'back'].forEach((prefix) => {
createSidePoints({
measurements: measurements,
points: points,
utils: utils,
prefix: prefix,
postfix: 'Split',
names: ['Ankle', 'Knee', 'UpperLeg', 'Seat', 'Waist'],
ratio: sideRatio,
ratioFixed: sideFixed,
ease: ease,
waistReduction: waistReduction,
distanceCompensation:
(points.frontAnkle.dist(points.frontCrossSeam) + frontCrossSeam.length()) /
(measurements.waistToFloor - measurements.heel / Math.PI),
fixedSidePanel: options.fixedsidepanel ? fixedSidePanel : 0,
})
points[prefix + 'SplitWaistband'] = points[prefix + 'SplitWaist'].clone()
})
points.backHipsCp1 = points.backWaistCp.clone()
points.backWaistCp = points.backWaist.shift(
points.backWaist.angle(points.backSplitWaist) - 90,
points.backWaist.dist(points.backHips) / 3
)
points.backHipsCp2 = points.backSeat.shiftOutwards(
points.backHips,
points.backWaist.dist(points.backHips) / 4
)
points.frontHipsCp1 = points.frontWaistCp.clone()
points.frontWaistCp = points.frontWaist.shift(
points.frontWaist.angle(points.frontSplitWaist) + 90,
points.frontWaist.dist(points.frontHips) / 3
)
points.frontHipsCp2 = points.frontSeat.shiftOutwards(
points.frontHips,
points.frontWaist.dist(points.frontHips) / 4
)
paths.front = new Path()
.move(points.frontWaist)
.curve(points.frontWaistCp, points.frontHipsCp2, points.frontHips)
.curve(points.frontHipsCp1, points.frontCrossSeamCp, points.middleCrossSeam)
paths.back = new Path()
.move(points.backWaist)
.curve(points.backWaistCp, points.backHipsCp2, points.backHips)
.curve(points.backHipsCp1, points.backCrossSeamCp, points.middleCrossSeam)
;['front', 'back'].forEach((prefix) => {
// eslint-disable-next-line no-extra-semi
;['Side', 'Split'].forEach((type) => {
smoothPoints(
points,
prefix,
type,
['Ankle', 'Knee', 'UpperLeg', 'Seat', 'Waist'],
options.smoothing
)
})
})
paths.middle = new Path().move(points.middleWaist).line(points.middleFloor).setHidden()
;['front', 'back'].forEach((prefix) => {
// eslint-disable-next-line no-extra-semi
;['Side', 'Split'].forEach((type) => {
createControlPoints(points, 3, [
prefix + type + 'Waist',
prefix + type + 'Seat',
prefix + type + 'UpperLeg',
prefix + type + 'Knee',
prefix + type + 'Ankle',
])
})
})
;['front', 'back'].forEach((prefix) => {
// eslint-disable-next-line no-extra-semi
;['Side', 'Split'].forEach((type) => {
createPath(paths, Path, points, prefix + type, [
prefix + type + 'Waist',
prefix + type + 'Seat',
prefix + type + 'UpperLeg',
prefix + type + 'Knee',
prefix + type + 'Ankle',
])
})
})
;['front', 'back'].forEach((prefix) => {
// eslint-disable-next-line no-extra-semi
;['Waist', 'Waistband', 'Seat', 'UpperLeg', 'Knee', 'Ankle'].forEach((name) => {
points[prefix + 'Panel' + name] = points['middle' + name].shift(
prefix == 'front' ? 0 : 180,
points[prefix + 'Side' + name].dist(points[prefix + 'Split' + name])
)
})
})
;['front', 'back'].forEach((prefix) => {
createControlPoints(points, 3, [
prefix + 'Panel' + 'Waist',
prefix + 'Panel' + 'Seat',
prefix + 'Panel' + 'UpperLeg',
prefix + 'Panel' + 'Knee',
prefix + 'Panel' + 'Ankle',
])
})
;['front', 'back'].forEach((prefix) => {
createPath(paths, Path, points, prefix + 'Panel', [
prefix + 'Panel' + 'Waist',
prefix + 'Panel' + 'Seat',
prefix + 'Panel' + 'UpperLeg',
prefix + 'Panel' + 'Knee',
prefix + 'Panel' + 'Ankle',
])
})
const frontSplitlength = paths.frontSplit.length()
while (Math.abs(frontSplitlength - paths.frontPanel.length()) > 1) {
// eslint-disable-next-line no-extra-semi
;['front', 'back'].forEach((prefix) => {
const diff = paths[prefix + 'Split'].length() / paths[prefix + 'Panel'].length()
const names = ['Waist', 'Seat', 'UpperLeg', 'Knee', 'Ankle']
for (let i = 0; i < names.length - 1; i++) {
points[prefix + 'Panel' + names[i]] = points[
prefix + 'Panel' + names[i + 1]
].shiftFractionTowards(points[prefix + 'Panel' + names[i]], diff)
}
})
;['front', 'back'].forEach((prefix) => {
createControlPoints(points, 3, [
prefix + 'Panel' + 'Waist',
prefix + 'Panel' + 'Seat',
prefix + 'Panel' + 'UpperLeg',
prefix + 'Panel' + 'Knee',
prefix + 'Panel' + 'Ankle',
])
})
;['front', 'back'].forEach((prefix) => {
createPath(paths, Path, points, prefix + 'Panel', [
prefix + 'Panel' + 'Waist',
prefix + 'Panel' + 'Seat',
prefix + 'Panel' + 'UpperLeg',
prefix + 'Panel' + 'Knee',
prefix + 'Panel' + 'Ankle',
])
})
}
if (options.length < 1) {
const length = (1 - options.length) * (inseam - (measurements.waistToFloor - waistToAnkle))
;['front', 'back'].forEach((prefix) => {
// eslint-disable-next-line no-extra-semi
;['Side', 'Split', 'Panel'].forEach((type) => {
points[prefix + type + 'Hem'] = paths[prefix + type].reverse().shiftAlong(length)
paths[prefix + type] = paths[prefix + type].split(points[prefix + type + 'Hem'])[0]
})
})
} else {
// eslint-disable-next-line no-extra-semi
;['front', 'back'].forEach((prefix) => {
// eslint-disable-next-line no-extra-semi
;['Side', 'Split', 'Panel'].forEach((type) => {
points[prefix + type + 'Hem'] = points[prefix + type + 'Ankle']
})
})
}
lowerWaist(paths, Path, points, log, waistLowering, 'middle', 'Waist')
;['front', 'back'].forEach((prefix) => {
// eslint-disable-next-line no-extra-semi
;['Side', 'Split', 'Panel'].forEach((type) => {
lowerWaist(paths, Path, points, log, waistLowering, prefix + type, 'Waist')
})
lowerWaist(paths, Path, points, log, waistLowering, prefix, 'Waist')
})
;['front', 'back'].forEach((prefix) => {
// eslint-disable-next-line no-extra-semi
;['Side', 'Split', 'Panel'].forEach((type) => {
lowerWaist(paths, Path, points, log, waistbandSize, prefix + type, 'Waistband')
})
lowerWaist(paths, Path, points, log, waistbandSize, prefix, 'Waistband')
})
store.set(
'waistLength',
points.backWaist.dist(points.backSideWaist) + points.frontWaist.dist(points.frontSideWaist)
)
;['front', 'back'].forEach((prefix) => {
const waistbandLength = points[prefix + 'Waistband'].dist(points[prefix + 'SplitWaistband'])
const direction = prefix == 'front' ? 90 : -90
let angle = paths[prefix].shiftAlong(1).angle(points[prefix + 'Waistband'])
points[prefix + 'WaistbandCp'] = points[prefix + 'Waistband'].shift(
angle + direction,
waistbandLength * 0.35
)
angle = paths[prefix + 'Split'].shiftAlong(1).angle(points[prefix + 'SplitWaistband'])
points[prefix + 'SplitWaistbandCp'] = points[prefix + 'SplitWaistband'].shift(
angle + direction * -1,
waistbandLength * 0.35
)
paths[prefix + 'Waistband'] = new Path()
.move(points[prefix + 'Waistband'])
.curve(
points[prefix + 'WaistbandCp'],
points[prefix + 'SplitWaistbandCp'],
points[prefix + 'SplitWaistband']
)
.hide()
})
store.set(
'waistbandLength',
paths.backWaistband.length() +
paths.frontWaistband.length() +
points.frontPanelWaistband.dist(points.backPanelWaistband)
)
if (options.waistband && options.lowerwaistbandback) {
// Lower the back a little more to get a V-shape in the back
// lowerWaist(paths, Path, points, waistLowering * 0.5, 'back', 'Waistband')
lowerWaist(
paths,
Path,
points,
log,
(waistLowering + waistbandSize) * 0.5,
'back',
'Waistband'
)
paths.backWaistband = new Path()
.move(points.backWaistband)
._curve(points.backSplitWaistbandCp, points.backSplitWaistband)
.hide()
}
store.set('waistbandBackLength', paths.backWaistband.length())
store.set('waistbandFrontLength', paths.frontWaistband.length())
store.set('waistbandPanelLength', points.frontPanelWaistband.dist(points.backPanelWaistband))
store.flag.note({
msg: `lumina:dimensions`,
replace: {
waistbandlength: units(
(store.get('waistbandBackLength') +
store.get('waistbandFrontLength') +
store.get('waistbandPanelLength')) *
2
),
length: units(
store.get('waistbandSize') + points.frontPanelWaistband.dist(points.frontPanelHem)
),
},
})
return part //.hide()
},
}

View file

@ -0,0 +1,208 @@
import { shape } from './shape.mjs'
export const waistband = {
name: 'lumina.waistband',
after: shape,
draft: ({
store,
sa,
Point,
points,
Path,
paths,
Snippet,
snippets,
options,
macro,
log,
utils,
part,
}) => {
if (false === options.waistband) {
return part.hide()
}
const waistLength = store.get('waistLength')
const waistbandFrontLength = store.get('waistbandFrontLength')
const waistbandPanelLength = store.get('waistbandPanelLength')
const waistbandLength = store.get('waistbandLength')
const waistbandSize = store.get('waistbandSize')
const waistLowering = store.get('waistLowering')
if (waistbandSize <= 0) {
return part.hide()
}
points.origin = new Point(0, 0)
const angleRad = Math.asin((Math.abs(waistbandLength - waistLength) * 0.5) / waistbandSize)
const radius = (waistLength * 0.5) / Math.sin(angleRad)
const baseAngle = waistLength < waistbandLength ? 270 : 90
let angle = utils.rad2deg(angleRad)
if (isNaN(angle)) {
log.info('lumina:couldNoFitWaistband')
store.flag.note({
msg: `lumina:couldNoFitWaistband`,
})
return part.hide()
}
let diff = 0
let iter = 0
let segments, cpDistance
do {
angle += diff * 0.025
segments = 360 / angle
cpDistance = (4 / 3) * Math.tan(Math.PI / (segments * 2)) * radius
points.waistFront = points.origin.shift(baseAngle + angle, radius)
points.waistBack = points.origin.shift(baseAngle - angle, radius)
points.waistFrontCP = points.waistFront.shift(baseAngle - 90 + angle, cpDistance)
points.waistBackCP = points.waistBack.shift(baseAngle + 90 - angle, cpDistance)
paths.waist = new Path()
.move(points.waistBack)
.curve(points.waistBackCP, points.waistFrontCP, points.waistFront)
diff = waistLength - paths.waist.length()
} while (iter++ < 100 && (diff < -0.5 || diff > 0.5))
if (iter >= 100) {
log.info('lumina:couldNoFitWaistband')
return part.hide()
}
points.waistbandFront = points.waistFront.shift(270 + angle, waistbandSize)
points.waistbandBack = points.waistBack.shift(270 - angle, waistbandSize)
cpDistance =
(4 / 3) *
Math.tan(Math.PI / (segments * 2)) *
(radius + waistbandSize * (waistLength < waistbandLength ? 1 : -1))
points.waistbandFrontCP = points.waistbandFront.shift(baseAngle - 90 + angle, cpDistance)
points.waistbandBackCP = points.waistbandBack.shift(baseAngle + 90 - angle, cpDistance)
paths.waistband = new Path()
.move(points.waistbandBack)
.curve(points.waistbandBackCP, points.waistbandFrontCP, points.waistbandFront)
diff = waistbandLength - paths.waistband.length()
const rWaistband = paths.waistband.reverse()
points.snippetPanelBack = rWaistband.shiftAlong(waistbandFrontLength + waistbandPanelLength)
snippets.panelBack = new Snippet('notch', points.snippetPanelBack)
points.snippetPanelFront = rWaistband.shiftAlong(waistbandFrontLength)
snippets.panelFront = new Snippet('notch', points.snippetPanelFront)
if (options.lowerwaistbandback) {
paths.waistband = rWaistband.split(points.snippetPanelBack)[0]
points.waistbandBackPanel = points.snippetPanelBack.copy()
points.waistbandBackPanelCP = points.snippetPanelFront.shiftFractionTowards(
points.waistbandBackPanel,
1.4
)
points.waistbandBack = points.waistBack.shiftOutwards(
points.waistbandBack,
(waistLowering + waistbandSize) * 0.5
)
paths.waistband = new Path()
.move(points.waistbandBack)
._curve(points.waistbandBackPanelCP, points.waistbandBackPanel)
.join(paths.waistband.reverse())
}
paths.front = new Path()
.move(points.waistbandFront)
.line(points.waistFront)
.setText('front', 'note center')
.setClass('hidden')
paths.back = new Path()
.move(points.waistBack)
.line(points.waistbandBack)
.setText('back', 'note center')
.setClass('hidden')
let top = paths.waist.edge('top')
if (top.y == points.waistBack.y) {
top = paths.waist.edge('bottom')
}
let bottom = paths.waistband.shiftFractionAlong(0.5)
if (bottom.y == points.waistbandFront.y) {
bottom = paths.waistband.edge('top')
}
macro('cutonfold', {
from: points.waistbandFront,
to: points.waistFront,
})
store.cutlist.addCut({ cut: 2, from: 'fabric', onFold: true })
points.title = points.snippetPanelFront.shiftFractionTowards(points.snippetPanelBack, 0.5)
points.title.y = top.y + 20
macro('title', {
at: points.title,
nr: 3,
title: 'waistband',
align: 'center',
scale: 0.35,
})
paths.seamSA = new Path()
.move(points.waistFront)
.join(paths.waist.reverse())
.line(points.waistbandBack)
.join(paths.waistband)
.hide()
paths.seam = new Path().move(points.waistbandFront).line(points.waistFront).join(paths.seamSA)
if (sa) {
const seamSA = paths.seamSA.offset(sa)
paths.sa = new Path()
.move(points.waistFront)
.line(seamSA.start())
.join(seamSA)
.line(points.waistbandFront)
.attr('class', 'fabric sa')
}
macro('hd', {
id: 'top',
from: points.waistBack,
to: points.waistFront,
y: Math.min(points.waistFront.y, top.y) - sa - 15,
})
macro('hd', {
id: 'bottom',
from: points.waistbandBack,
to: points.waistbandFront,
y: Math.max(points.waistbandFront.y, Math.max(bottom.y, points.waistbandBack.y)) + sa + 15,
})
macro('vd', {
id: 'top',
from: points.waistBack,
to: top,
x: top.x - 15,
noStartMarker: true,
noEndMarker: true,
})
macro('vd', {
id: 'bottom',
from: points.waistFront,
to: bottom,
x: top.x + 15,
})
macro('ld', {
id: 'front',
from: points.waistFront,
to: points.waistbandFront,
d: 15,
})
macro('ld', {
id: 'back',
from: points.waistBack,
to: points.waistbandBack,
d: -15,
})
return part
},
}

View file

@ -0,0 +1,20 @@
// This file is auto-generated | Any changes you make will be overwritten.
import { Lumina, i18n } from '../src/index.mjs'
// Shared tests
import { testPatternConfig } from '../../../tests/designs/config.mjs'
import { testPatternI18n } from '../../../tests/designs/i18n.mjs'
import { testPatternDrafting } from '../../../tests/designs/drafting.mjs'
import { testPatternSampling } from '../../../tests/designs/sampling.mjs'
// Test config
testPatternConfig(Lumina)
// Test translation
testPatternI18n(Lumina, i18n)
// Test drafting - Change the second parameter to `true` to log errors
testPatternDrafting(Lumina, false)
// Test sampling - Change the second parameter to `true` to log errors
testPatternSampling(Lumina, false)

View file

@ -20,16 +20,17 @@ export const controlPoints = (p1, p2, p3, cpDistanceDivider) => {
} else {
angle = Math.abs(p2.angle(p1) - p2.angle(p3)) / 2
}
return {
cp1:
p3 !== undefined
? p2.shift(p2.angle(p3) - angle + 90, p2.dist(p3) / cpDistanceDivider)
: null,
cp2:
p1 !== undefined
? p2.shift(p2.angle(p1) + angle - 90, p2.dist(p1) / cpDistanceDivider)
: null,
let cp1 =
p3 !== undefined ? p2.shift(p2.angle(p3) - angle + 90, p2.dist(p3) / cpDistanceDivider) : null
let cp2 =
p1 !== undefined ? p2.shift(p2.angle(p1) + angle - 90, p2.dist(p1) / cpDistanceDivider) : null
if (p1 !== undefined && p2.sitsRoughlyOn(p1)) {
return { cp1: p1.clone(), cp2: cp2 }
}
if (p3 !== undefined && p2.sitsRoughlyOn(p3)) {
return { cp1: cp1, cp2: p3.clone() }
}
return { cp1: cp1, cp2: cp2 }
}
export const createControlPoints = (points, cpDistanceDivider, names) => {
for (let i = 0; i < names.length; i++) {

View file

@ -0,0 +1,14 @@
---
title: "Lumina leggings: Cutting Instructions"
---
### Materials
- **Main fabric**
- Cut **2 leg** parts
- Cut **2 panel** parts
Optionally
- Cut **2 waistband** parts on the fold
- Cut **2 pocket** parts

View file

@ -0,0 +1,14 @@
---
title: "Lumina leggings: Cutting Instructions"
---
### Materials
- **Main fabric**
- Cut **2 leg** parts
- Cut **2 panel** parts
Optionally
- Cut **2 waistband** parts on the fold
- Cut **2 pocket** parts

View file

@ -0,0 +1,14 @@
---
title: "Lumina leggings: Cutting Instructions"
---
### Materials
- **Main fabric**
- Cut **2 leg** parts
- Cut **2 panel** parts
Optionally
- Cut **2 waistband** parts on the fold
- Cut **2 pocket** parts

View file

@ -0,0 +1,14 @@
---
title: "Lumina leggings: Cutting Instructions"
---
### Materials
- **Main fabric**
- Cut **2 leg** parts
- Cut **2 panel** parts
Optionally
- Cut **2 waistband** parts on the fold
- Cut **2 pocket** parts

View file

@ -0,0 +1,14 @@
---
title: "Lumina leggings: Cutting Instructions"
---
### Materials
- **Main fabric**
- Cut **2 leg** parts
- Cut **2 panel** parts
Optionally
- Cut **2 waistband** parts on the fold
- Cut **2 pocket** parts

View file

@ -0,0 +1,14 @@
---
title: "Lumina leggings: Cutting Instructions"
---
### Materials
- **Main fabric**
- Cut **2 leg** parts
- Cut **2 panel** parts
Optionally
- Cut **2 waistband** parts on the fold
- Cut **2 pocket** parts

View file

@ -0,0 +1,8 @@
---
title: "Lumina leggings"
---
<DesignInfo design='lumina' docs />

View file

@ -0,0 +1,8 @@
---
title: "Lumina leggings"
---
<DesignInfo design='lumina' docs />

View file

@ -0,0 +1,8 @@
---
title: "Lumina leggings"
---
<DesignInfo design='lumina' docs />

View file

@ -0,0 +1,30 @@
---
title: "Lumina leggings: Fabric Options"
---
### Main Fabric
This pattern requires a stretch fabric. The stretch needs to be perpendicular to the grainline. There is no stretch required along
the grainline, but a 4-way stretch fabric can definitely be used. Not all stretch fabrics have the same amount of stretch. The default
ease value of -5% works well for fabrics that have 60% stretch. If your fabric has a different amount of stretch, you may want to
adjust this setting accordingly. Reduce the ease when your fabric has more stretch. Getting the ease right is *very* important for
getting a good fit.
<Note>
If the ease setting is larger than 0 (positive ease), any type of knit fabric can be used. Keep in mind that even with the ease
set at the maximum, you probably will not be able to use a fabric with no stretch at all (a wovel fabric).
</Note>
These fabrics come in different weights. Pick one that works for how you intent to use it. Thicker fabrics provide more support
and warmth.
For yoga pants, take something that has a medium thickness. Supplex is a good choice for this. It also works well for cycling. For
other athletic use fabrics that would be appropriate for that. Most fabrics that contain spandex will work.
<Note>
Since this pattern has an outside panel, you can use contrasting fabrics to make interesting effects.
</Note>

View file

@ -0,0 +1,30 @@
---
title: "Lumina leggings: Fabric Options"
---
### Main Fabric
This pattern requires a stretch fabric. The stretch needs to be perpendicular to the grainline. There is no stretch required along
the grainline, but a 4-way stretch fabric can definitely be used. Not all stretch fabrics have the same amount of stretch. The default
ease value of -5% works well for fabrics that have 60% stretch. If your fabric has a different amount of stretch, you may want to
adjust this setting accordingly. Reduce the ease when your fabric has more stretch. Getting the ease right is *very* important for
getting a good fit.
<Note>
If the ease setting is larger than 0 (positive ease), any type of knit fabric can be used. Keep in mind that even with the ease
set at the maximum, you probably will not be able to use a fabric with no stretch at all (a woven fabric).
</Note>
These fabrics come in different weights. Pick one that works for how you intend to use it. Thicker fabrics provide more support
and warmth.
For yoga pants, take something that has a medium thickness. Supplex is a good choice for this. It also works well for cycling. For
other athletics use fabrics that would be appropriate for that. Most fabrics that contain spandex will work.
<Note>
Since this pattern has an outside panel, you can use contrasting fabrics to make interesting effects.
</Note>

View file

@ -0,0 +1,30 @@
---
title: "Lumina leggings: Fabric Options"
---
### Main Fabric
This pattern requires a stretch fabric. The stretch needs to be perpendicular to the grainline. There is no stretch required along
the grainline, but a 4-way stretch fabric can definitely be used. Not all stretch fabrics have the same amount of stretch. The default
ease value of -5% works well for fabrics that have 60% stretch. If your fabric has a different amount of stretch, you may want to
adjust this setting accordingly. Reduce the ease when your fabric has more stretch. Getting the ease right is *very* important for
getting a good fit.
<Note>
If the ease setting is larger than 0 (positive ease), any type of knit fabric can be used. Keep in mind that even with the ease
set at the maximum, you probably will not be able to use a fabric with no stretch at all (a wovel fabric).
</Note>
These fabrics come in different weights. Pick one that works for how you intent to use it. Thicker fabrics provide more support
and warmth.
For yoga pants, take something that has a medium thickness. Supplex is a good choice for this. It also works well for cycling. For
other athletic use fabrics that would be appropriate for that. Most fabrics that contain spandex will work.
<Note>
Since this pattern has an outside panel, you can use contrasting fabrics to make interesting effects.
</Note>

View file

@ -0,0 +1,30 @@
---
title: "Lumina leggings: Fabric Options"
---
### Main Fabric
This pattern requires a stretch fabric. The stretch needs to be perpendicular to the grainline. There is no stretch required along
the grainline, but a 4-way stretch fabric can definitely be used. Not all stretch fabrics have the same amount of stretch. The default
ease value of -5% works well for fabrics that have 60% stretch. If your fabric has a different amount of stretch, you may want to
adjust this setting accordingly. Reduce the ease when your fabric has more stretch. Getting the ease right is *very* important for
getting a good fit.
<Note>
If the ease setting is larger than 0 (positive ease), any type of knit fabric can be used. Keep in mind that even with the ease
set at the maximum, you probably will not be able to use a fabric with no stretch at all (a wovel fabric).
</Note>
These fabrics come in different weights. Pick one that works for how you intent to use it. Thicker fabrics provide more support
and warmth.
For yoga pants, take something that has a medium thickness. Supplex is a good choice for this. It also works well for cycling. For
other athletic use fabrics that would be appropriate for that. Most fabrics that contain spandex will work.
<Note>
Since this pattern has an outside panel, you can use contrasting fabrics to make interesting effects.
</Note>

View file

@ -0,0 +1,30 @@
---
title: "Lumina leggings: Fabric Options"
---
### Main Fabric
This pattern requires a stretch fabric. The stretch needs to be perpendicular to the grainline. There is no stretch required along
the grainline, but a 4-way stretch fabric can definitely be used. Not all stretch fabrics have the same amount of stretch. The default
ease value of -5% works well for fabrics that have 60% stretch. If your fabric has a different amount of stretch, you may want to
adjust this setting accordingly. Reduce the ease when your fabric has more stretch. Getting the ease right is *very* important for
getting a good fit.
<Note>
If the ease setting is larger than 0 (positive ease), any type of knit fabric can be used. Keep in mind that even with the ease
set at the maximum, you probably will not be able to use a fabric with no stretch at all (a wovel fabric).
</Note>
These fabrics come in different weights. Pick one that works for how you intent to use it. Thicker fabrics provide more support
and warmth.
For yoga pants, take something that has a medium thickness. Supplex is a good choice for this. It also works well for cycling. For
other athletic use fabrics that would be appropriate for that. Most fabrics that contain spandex will work.
<Note>
Since this pattern has an outside panel, you can use contrasting fabrics to make interesting effects.
</Note>

View file

@ -0,0 +1,30 @@
---
title: "Lumina leggings: Fabric Options"
---
### Main Fabric
This pattern requires a stretch fabric. The stretch needs to be perpendicular to the grainline. There is no stretch required along
the grainline, but a 4-way stretch fabric can definitely be used. Not all stretch fabrics have the same amount of stretch. The default
ease value of -5% works well for fabrics that have 60% stretch. If your fabric has a different amount of stretch, you may want to
adjust this setting accordingly. Reduce the ease when your fabric has more stretch. Getting the ease right is *very* important for
getting a good fit.
<Note>
If the ease setting is larger than 0 (positive ease), any type of knit fabric can be used. Keep in mind that even with the ease
set at the maximum, you probably will not be able to use a fabric with no stretch at all (a wovel fabric).
</Note>
These fabrics come in different weights. Pick one that works for how you intent to use it. Thicker fabrics provide more support
and warmth.
For yoga pants, take something that has a medium thickness. Supplex is a good choice for this. It also works well for cycling. For
other athletic use fabrics that would be appropriate for that. Most fabrics that contain spandex will work.
<Note>
Since this pattern has an outside panel, you can use contrasting fabrics to make interesting effects.
</Note>

View file

@ -0,0 +1,8 @@
---
title: "Lumina leggings"
---
<DesignInfo design='lumina' docs />

View file

@ -0,0 +1,67 @@
---
title: "Lumina leggings: Sewing Instructions"
---
<Note>
This is a garment made from a stretch fabric. So use appropriate seam solutions. A serger is a good way to do this, as
are specific stitches that certain sewing machines provide. A zigzag stitch will do if that's all you have.
Keep in mind that since these seams are always under tension, it may be a good idea to double them up, or
provide a zigzag in addition to serging the seam.
</Note>
### Step 1: The waistband (optional)
- Sew the two pieces to each other, right sides together, along the top seam.
- Press the seam open
- Sew the back seam, right sides together. This creates a loop.
<Note>
If you want to include elastic into the waistband, now is a good time to do so. You should
add it to the seam you just sewed.
</Note>
### Step 2: The cross seam
- Sew both leg pieces together along the cross seam.
### Step 3: Pockets
- Serge the top of the two panels.
- Fold this top over onto itself, and stitch in place. Using a double needle is a good way to do this.
Zigzag works too. Make sure that you fold it slightly more than the seam allowance.
- Lay the panel down with the right side down.
- Lay the pocket part on top, right side down, aligning the notches. Pin in place
- Stitch the bottom of the pocket to the panel. Again, a double needle or zigzag works well.
### Step 4: Panels
- Align all the front notches of the panel to the front of the leg panel, right sides together.
If you included the pocket option, make sure you treat the pocket and panel pieces as one piece.
- Seam this seam on both legs.
- Repeat for the back side of the panel and leg parts
<Note>
The number and distance of the notches on the front and back seams are different.
</Note>
### Step 5: Attaching the waistband
- Align the waistband seam with the seam in the back. Align the notches with the panel seams.
- Sew all the way around, attaching the waistband to the legs. Make sure you sew both pieces of the waistband
into this seam. This seam will combine three layers, both layers of the waistband, and one layer of the leg
pieces.
<Note>
If you have included the pocket option, take extra care not to sew the folded over part of the panel into
the waistband seam.
</Note>
### Step 6: Finish up
Now you can add the elastic to the leg openings. Otherwise finish those in any way you like.
You're all done! Enjoy your Lumina leggings!

View file

@ -0,0 +1,67 @@
---
title: "Lumina leggings: Sewing Instructions"
---
<Note>
This is a garment made from a stretch fabric. So use appropriate seam solutions. A serger is a good way to do this, as
are specific stitches that certain sewing machines provide. A zigzag stitch will do if that's all you have.
Keep in mind that since these seams are always under tension, it may be a good idea to double them up, or
provide a zigzag in addition to serging the seam.
</Note>
### Step 1: The waistband (optional)
- Sew the two pieces to each other, right sides together, along the top seam.
- Press the seam open
- Sew the back seam, right sides together. This creates a loop.
<Note>
If you want to include elastic into the waistband, now is a good time to do so. You should
add it to the seam you just sewed.
</Note>
### Step 2: The cross seam
- Sew both leg pieces together along the cross seam.
### Step 3: Pockets
- Serge the top of the two panels.
- Fold this top over onto itself, and stitch in place. Using a double needle is a good way to do this.
Zigzag works too. Make sure that you fold it slightly more than the seam allowance.
- Lay the panel down with the right side down.
- Lay the pocket part on top, right side down, aligning the notches. Pin in place
- Stitch the bottom of the pocket to the panel. Again, a double needle or zigzag works well.
### Step 4: Panels
- Align all the front notches of the panel to the front of the leg panel, right sides together.
If you included the pocket option, make sure you treat the pocket and panel pieces as one piece.
- Seam this seam on both legs.
- Repeat for the back side of the panel and leg parts
<Note>
The number and distance of the notches on the front and back seams are different.
</Note>
### Step 5: Attaching the waistband
- Align the waistband seam with the seam in the back. Align the notches with the panel seams.
- Sew all the way around, attaching the waistband to the legs. Make sure you sew both pieces of the waistband
into this seam. This seam will combine three layers, both layers of the waistband, and one layer of the leg
pieces.
<Note>
If you have included the pocket option, take extra care not to sew the folded over part of the panel into
the waistband seam.
</Note>
### Step 6: Finish up
Now you can add the elastic to the leg openings. Otherwise finish those in any way you like.
You're all done! Enjoy your Lumina leggings!

View file

@ -0,0 +1,67 @@
---
title: "Lumina leggings: Sewing Instructions"
---
<Note>
This is a garment made from a stretch fabric. So use appropriate seam solutions. A serger is a good way to do this, as
are specific stitches that certain sewing machines provide. A zigzag stitch will do if that's all you have.
Keep in mind that since these seams are always under tension, it may be a good idea to double them up, or
provide a zigzag in addition to serging the seam.
</Note>
### Step 1: The waistband (optional)
- Sew the two pieces to each other, right sides together, along the top seam.
- Press the seam open
- Sew the back seam, right sides together. This creates a loop.
<Note>
If you want to include elastic into the waistband, now is a good time to do so. You should
add it to the seam you just sewed.
</Note>
### Step 2: The cross seam
- Sew both leg pieces together along the cross seam.
### Step 3: Pockets
- Serge the top of the two panels.
- Fold this top over onto itself, and stitch in place. Using a double needle is a good way to do this.
Zigzag works too. Make sure that you fold it slightly more than the seam allowance.
- Lay the panel down with the right side down.
- Lay the pocket part on top, right side down, aligning the notches. Pin in place
- Stitch the bottom of the pocket to the panel. Again, a double needle or zigzag works well.
### Step 4: Panels
- Align all the front notches of the panel to the front of the leg panel, right sides together.
If you included the pocket option, make sure you treat the pocket and panel pieces as one piece.
- Seam this seam on both legs.
- Repeat for the back side of the panel and leg parts
<Note>
The number and distance of the notches on the front and back seams are different.
</Note>
### Step 5: Attaching the waistband
- Align the waistband seam with the seam in the back. Align the notches with the panel seams.
- Sew all the way around, attaching the waistband to the legs. Make sure you sew both pieces of the waistband
into this seam. This seam will combine three layers, both layers of the waistband, and one layer of the leg
pieces.
<Note>
If you have included the pocket option, take extra care not to sew the folded over part of the panel into
the waistband seam.
</Note>
### Step 6: Finish up
Now you can add the elastic to the leg openings. Otherwise finish those in any way you like.
You're all done! Enjoy your Lumina leggings!

View file

@ -0,0 +1,67 @@
---
title: "Lumina leggings: Sewing Instructions"
---
<Note>
This is a garment made from a stretch fabric. So use appropriate seam solutions. A serger is a good way to do this, as
are specific stitches that certain sewing machines provide. A zigzag stitch will do if that's all you have.
Keep in mind that since these seams are always under tension, it may be a good idea to double them up, or
provide a zigzag in addition to serging the seam.
</Note>
### Step 1: The waistband (optional)
- Sew the two pieces to each other, right sides together, along the top seam.
- Press the seam open
- Sew the back seam, right sides together. This creates a loop.
<Note>
If you want to include elastic into the waistband, now is a good time to do so. You should
add it to the seam you just sewed.
</Note>
### Step 2: The cross seam
- Sew both leg pieces together along the cross seam.
### Step 3: Pockets
- Serge the top of the two panels.
- Fold this top over onto itself, and stitch in place. Using a double needle is a good way to do this.
Zigzag works too. Make sure that you fold it slightly more than the seam allowance.
- Lay the panel down with the right side down.
- Lay the pocket part on top, right side down, aligning the notches. Pin in place
- Stitch the bottom of the pocket to the panel. Again, a double needle or zigzag works well.
### Step 4: Panels
- Align all the front notches of the panel to the front of the leg panel, right sides together.
If you included the pocket option, make sure you treat the pocket and panel pieces as one piece.
- Seam this seam on both legs.
- Repeat for the back side of the panel and leg parts
<Note>
The number and distance of the notches on the front and back seams are different.
</Note>
### Step 5: Attaching the waistband
- Align the waistband seam with the seam in the back. Align the notches with the panel seams.
- Sew all the way around, attaching the waistband to the legs. Make sure you sew both pieces of the waistband
into this seam. This seam will combine three layers, both layers of the waistband, and one layer of the leg
pieces.
<Note>
If you have included the pocket option, take extra care not to sew the folded over part of the panel into
the waistband seam.
</Note>
### Step 6: Finish up
Now you can add the elastic to the leg openings. Otherwise finish those in any way you like.
You're all done! Enjoy your Lumina leggings!

View file

@ -0,0 +1,67 @@
---
title: "Lumina leggings: Sewing Instructions"
---
<Note>
This is a garment made from a stretch fabric. So use appropriate seam solutions. A serger is a good way to do this, as
are specific stitches that certain sewing machines provide. A zigzag stitch will do if that's all you have.
Keep in mind that since these seams are always under tension, it may be a good idea to double them up, or
provide a zigzag in addition to serging the seam.
</Note>
### Step 1: The waistband (optional)
- Sew the two pieces to each other, right sides together, along the top seam.
- Press the seam open
- Sew the back seam, right sides together. This creates a loop.
<Note>
If you want to include elastic into the waistband, now is a good time to do so. You should
add it to the seam you just sewed.
</Note>
### Step 2: The cross seam
- Sew both leg pieces together along the cross seam.
### Step 3: Pockets
- Serge the top of the two panels.
- Fold this top over onto itself, and stitch in place. Using a double needle is a good way to do this.
Zigzag works too. Make sure that you fold it slightly more than the seam allowance.
- Lay the panel down with the right side down.
- Lay the pocket part on top, right side down, aligning the notches. Pin in place
- Stitch the bottom of the pocket to the panel. Again, a double needle or zigzag works well.
### Step 4: Panels
- Align all the front notches of the panel to the front of the leg panel, right sides together.
If you included the pocket option, make sure you treat the pocket and panel pieces as one piece.
- Seam this seam on both legs.
- Repeat for the back side of the panel and leg parts
<Note>
The number and distance of the notches on the front and back seams are different.
</Note>
### Step 5: Attaching the waistband
- Align the waistband seam with the seam in the back. Align the notches with the panel seams.
- Sew all the way around, attaching the waistband to the legs. Make sure you sew both pieces of the waistband
into this seam. This seam will combine three layers, both layers of the waistband, and one layer of the leg
pieces.
<Note>
If you have included the pocket option, take extra care not to sew the folded over part of the panel into
the waistband seam.
</Note>
### Step 6: Finish up
Now you can add the elastic to the leg openings. Otherwise finish those in any way you like.
You're all done! Enjoy your Lumina leggings!

View file

@ -0,0 +1,67 @@
---
title: "Lumina leggings: Sewing Instructions"
---
<Note>
This is a garment made from a stretch fabric. So use appropriate seam solutions. A serger is a good way to do this, as
are specific stitches that certain sewing machines provide. A zigzag stitch will do if that's all you have.
Keep in mind that since these seams are always under tension, it may be a good idea to double them up, or
provide a zigzag in addition to serging the seam.
</Note>
### Step 1: The waistband (optional)
- Sew the two pieces to each other, right sides together, along the top seam.
- Press the seam open
- Sew the back seam, right sides together. This creates a loop.
<Note>
If you want to include elastic into the waistband, now is a good time to do so. You should
add it to the seam you just sewed.
</Note>
### Step 2: The cross seam
- Sew both leg pieces together along the cross seam.
### Step 3: Pockets
- Serge the top of the two panels.
- Fold this top over onto itself, and stitch in place. Using a double needle is a good way to do this.
Zigzag works too. Make sure that you fold it slightly more than the seam allowance.
- Lay the panel down with the right side down.
- Lay the pocket part on top, right side down, aligning the notches. Pin in place
- Stitch the bottom of the pocket to the panel. Again, a double needle or zigzag works well.
### Step 4: Panels
- Align all the front notches of the panel to the front of the leg panel, right sides together.
If you included the pocket option, make sure you treat the pocket and panel pieces as one piece.
- Seam this seam on both legs.
- Repeat for the back side of the panel and leg parts
<Note>
The number and distance of the notches on the front and back seams are different.
</Note>
### Step 5: Attaching the waistband
- Align the waistband seam with the seam in the back. Align the notches with the panel seams.
- Sew all the way around, attaching the waistband to the legs. Make sure you sew both pieces of the waistband
into this seam. This seam will combine three layers, both layers of the waistband, and one layer of the leg
pieces.
<Note>
If you have included the pocket option, take extra care not to sew the folded over part of the panel into
the waistband seam.
</Note>
### Step 6: Finish up
Now you can add the elastic to the leg openings. Otherwise finish those in any way you like.
You're all done! Enjoy your Lumina leggings!

View file

@ -0,0 +1,5 @@
---
title: "Lumina leggings: Required Measurements"
---
<DesignMeasurements design='lumina' />

View file

@ -0,0 +1,5 @@
---
title: "Lumina leggings: Required Measurements"
---
<DesignMeasurements design='lumina' />

View file

@ -0,0 +1,5 @@
---
title: "Lumina leggings: Required Measurements"
---
<DesignMeasurements design='lumina' />

View file

@ -0,0 +1,5 @@
---
title: "Lumina leggings: Required Measurements"
---
<DesignMeasurements design='lumina' />

View file

@ -0,0 +1,5 @@
---
title: "Lumina leggings: Required Measurements"
---
<DesignMeasurements design='lumina' />

View file

@ -0,0 +1,5 @@
---
title: "Lumina leggings: Required Measurements"
---
<DesignMeasurements design='lumina' />

View file

@ -0,0 +1,10 @@
---
title: "Lumina leggings: What You Need"
---
To make Lumina, you will need the following:
- Basic sewing supplies
- About 1.5 metres (1.7 yards) of a suitable fabric ([see Lumina Fabric options](/docs/designs/lumina/fabric/))
- Elastic for the leg openings and waist.

View file

@ -0,0 +1,10 @@
---
title: "Lumina leggings: What You Need"
---
To make Lumina, you will need the following:
- Basic sewing supplies
- About 1.5 metres (1.7 yards) of a suitable fabric ([see Lumina Fabric options](/docs/designs/lumina/fabric/))
- Elastic for the leg openings and waist.

View file

@ -0,0 +1,10 @@
---
title: "Lumina leggings: What You Need"
---
To make Lumina, you will need the following:
- Basic sewing supplies
- About 1.5 metres (1.7 yards) of a suitable fabric ([see Lumina Fabric options](/docs/designs/lumina/fabric/))
- Elastic for the leg openings and waist.

View file

@ -0,0 +1,10 @@
---
title: "Lumina leggings: What You Need"
---
To make Lumina, you will need the following:
- Basic sewing supplies
- About 1.5 metres (1.7 yards) of a suitable fabric ([see Lumina Fabric options](/docs/designs/lumina/fabric/))
- Elastic for the leg openings and waist.

View file

@ -0,0 +1,10 @@
---
title: "Lumina leggings: What You Need"
---
To make Lumina, you will need the following:
- Basic sewing supplies
- About 1.5 metres (1.7 yards) of a suitable fabric ([see Lumina Fabric options](/docs/designs/lumina/fabric/))
- Elastic for the leg openings and waist.

View file

@ -0,0 +1,10 @@
---
title: "Lumina leggings: What You Need"
---
To make Lumina, you will need the following:
- Basic sewing supplies
- About 1.5 metres (1.7 yards) of a suitable fabric ([see Lumina Fabric options](/docs/designs/lumina/fabric/))
- Elastic for the leg openings and waist.

View file

@ -0,0 +1,8 @@
---
title: "Lumina leggings"
---
<DesignInfo design='lumina' docs />

View file

@ -0,0 +1,21 @@
---
title: "Lumina leggings: Designer Notes"
---
I started working on this design when I wanted to make a pair of cycling shorts. I had made a pair in the past,
using a commercial pattern. And since you can buy the chamois separately, this is a great garment to make.
After starting this, I realized that there would be people who would want a more traditional leggings pattern.
So I decided to make two patterns, one with a seam on the inside of the leg (traditional), and one without a
seam on the inside (this one). I played with the idea to keep both patterns under one name, but it became
obvious that it would be better to have two different patterns instead. Since this one was called `lumina`, I
named the other `lumira`. As it may be, I quickly got distracted by the other version, and that one was
published first.
Since this pattern has a panel on the side, it seemed easy to add a pocket option. So if you want to keep
your mobile phone on you while working out, this is the pattern to use.
I was also in need of a pair of gym climbing pants. So this pattern has the option to have a positive ease
setting, allowing you to use a non-stretch knit fabric. This makes for loose-fitting workout pants.
Wouter

View file

@ -0,0 +1,21 @@
---
title: "Lumina leggings: Designer Notes"
---
I started working on this design when I wanted to make a pair of cycling shorts. I had made a pair in the past,
using a commercial pattern. And since you can buy the chamois separately, this is a great garment to make.
After starting this, I realized that there would be people who would want a more traditional leggings pattern.
So I decided to make two patterns, one with a seam on the inside of the leg (traditional), and one without a
seam on the inside (this one). I played with the idea to keep both patterns under one name, but it became
obvious that it would be better to have two different patterns instead. Since this one was called `lumina`, I
named the other `lumira`. As it may be, I quickly got distracted by the other version, and that one was
published first.
Since this pattern has a panel on the side, it seemed easy to add a pocket option. So if you want to keep
your mobile phone on you while working out, this is the pattern to use.
I was also in need of a pair of gym climbing pants. So this pattern has the option to have a positive ease
setting, allowing you to use a non-stretch knit fabric. This makes for loose-fitting workout pants.
Wouter

View file

@ -0,0 +1,21 @@
---
title: "Lumina leggings: Designer Notes"
---
I started working on this design when I wanted to make a pair of cycling shorts. I had made a pair in the past,
using a commercial pattern. And since you can buy the chamois separately, this is a great garment to make.
After starting this, I realized that there would be people who would want a more traditional leggings pattern.
So I decided to make two patterns, one with a seam on the inside of the leg (traditional), and one without a
seam on the inside (this one). I played with the idea to keep both patterns under one name, but it became
obvious that it would be better to have two different patterns instead. Since this one was called `lumina`, I
named the other `lumira`. As it may be, I quickly got distracted by the other version, and that one was
published first.
Since this pattern has a panel on the side, it seemed easy to add a pocket option. So if you want to keep
your mobile phone on you while working out, this is the pattern to use.
I was also in need of a pair of gym climbing pants. So this pattern has the option to have a positive ease
setting, allowing you to use a non-stretch knit fabric. This makes for loose-fitting workout pants.
Wouter

View file

@ -0,0 +1,21 @@
---
title: "Lumina leggings: Designer Notes"
---
I started working on this design when I wanted to make a pair of cycling shorts. I had made a pair in the past,
using a commercial pattern. And since you can buy the chamois separately, this is a great garment to make.
After starting this, I realized that there would be people who would want a more traditional leggings pattern.
So I decided to make two patterns, one with a seam on the inside of the leg (traditional), and one without a
seam on the inside (this one). I played with the idea to keep both patterns under one name, but it became
obvious that it would be better to have two different patterns instead. Since this one was called `lumina`, I
named the other `lumira`. As it may be, I quickly got distracted by the other version, and that one was
published first.
Since this pattern has a panel on the side, it seemed easy to add a pocket option. So if you want to keep
your mobile phone on you while working out, this is the pattern to use.
I was also in need of a pair of gym climbing pants. So this pattern has the option to have a positive ease
setting, allowing you to use a non-stretch knit fabric. This makes for loose-fitting workout pants.
Wouter

View file

@ -0,0 +1,21 @@
---
title: "Lumina leggings: Designer Notes"
---
I started working on this design when I wanted to make a pair of cycling shorts. I had made a pair in the past,
using a commercial pattern. And since you can buy the chamois separately, this is a great garment to make.
After starting this, I realized that there would be people who would want a more traditional leggings pattern.
So I decided to make two patterns, one with a seam on the inside of the leg (traditional), and one without a
seam on the inside (this one). I played with the idea to keep both patterns under one name, but it became
obvious that it would be better to have two different patterns instead. Since this one was called `lumina`, I
named the other `lumira`. As it may be, I quickly got distracted by the other version, and that one was
published first.
Since this pattern has a panel on the side, it seemed easy to add a pocket option. So if you want to keep
your mobile phone on you while working out, this is the pattern to use.
I was also in need of a pair of gym climbing pants. So this pattern has the option to have a positive ease
setting, allowing you to use a non-stretch knit fabric. This makes for loose-fitting workout pants.
Wouter

View file

@ -0,0 +1,21 @@
---
title: "Lumina leggings: Designer Notes"
---
I started working on this design when I wanted to make a pair of cycling shorts. I had made a pair in the past,
using a commercial pattern. And since you can buy the chamois separately, this is a great garment to make.
After starting this, I realized that there would be people who would want a more traditional leggings pattern.
So I decided to make two patterns, one with a seam on the inside of the leg (traditional), and one without a
seam on the inside (this one). I played with the idea to keep both patterns under one name, but it became
obvious that it would be better to have two different patterns instead. Since this one was called `lumina`, I
named the other `lumira`. As it may be, I quickly got distracted by the other version, and that one was
published first.
Since this pattern has a panel on the side, it seemed easy to add a pocket option. So if you want to keep
your mobile phone on you while working out, this is the pattern to use.
I was also in need of a pair of gym climbing pants. So this pattern has the option to have a positive ease
setting, allowing you to use a non-stretch knit fabric. This makes for loose-fitting workout pants.
Wouter

View file

@ -0,0 +1,5 @@
---
title: "Lumina leggings: Design Options"
---
<DesignOptions design='lumina' />

View file

@ -0,0 +1,19 @@
---
title: "Ease"
---
***
Controls the amount of ease built into the pattern. Since these are leggings that are to be made of stretch fabric,
the ease is nagative. So the completed garment will be narrower than the measurements would dictate.
<Note>
Getting the ease right for your type of fabric is essential for getting a good fit. If you make the ease
too negative, the leggings will be too constricting, and limiting movement. If you don't make the ease
negative enough, the leggings will not hug your legs and torso. The fabric should be stretched in all
places, without being too tight.
</Note>
<Note>
With a positive ease, these leggings will turn into slightly loose fitting pants
</Note>

View file

@ -0,0 +1,19 @@
---
title: "Ease"
---
***
Controls the amount of ease built into the pattern. Since these are leggings that are to be made of stretch fabric,
the ease is nagative. So the completed garment will be narrower than the measurements would dictate.
<Note>
Getting the ease right for your type of fabric is essential for getting a good fit. If you make the ease
too negative, the leggings will be too constricting, and limiting movement. If you don't make the ease
negative enough, the leggings will not hug your legs and torso. The fabric should be stretched in all
places, without being too tight.
</Note>
<Note>
With a positive ease, these leggings will turn into slightly loose fitting pants
</Note>

View file

@ -0,0 +1,19 @@
---
title: "Ease"
---
***
Controls the amount of ease built into the pattern. Since these are leggings that are to be made of stretch fabric,
the ease is nagative. So the completed garment will be narrower than the measurements would dictate.
<Note>
Getting the ease right for your type of fabric is essential for getting a good fit. If you make the ease
too negative, the leggings will be too constricting, and limiting movement. If you don't make the ease
negative enough, the leggings will not hug your legs and torso. The fabric should be stretched in all
places, without being too tight.
</Note>
<Note>
With a positive ease, these leggings will turn into slightly loose fitting pants
</Note>

View file

@ -0,0 +1,19 @@
---
title: "Ease"
---
***
Controls the amount of ease built into the pattern. Since these are leggings that are to be made of stretch fabric,
the ease is nagative. So the completed garment will be narrower than the measurements would dictate.
<Note>
Getting the ease right for your type of fabric is essential for getting a good fit. If you make the ease
too negative, the leggings will be too constricting, and limiting movement. If you don't make the ease
negative enough, the leggings will not hug your legs and torso. The fabric should be stretched in all
places, without being too tight.
</Note>
<Note>
With a positive ease, these leggings will turn into slightly loose fitting pants
</Note>

View file

@ -0,0 +1,19 @@
---
title: "Ease"
---
***
Controls the amount of ease built into the pattern. Since these are leggings that are to be made of stretch fabric,
the ease is nagative. So the completed garment will be narrower than the measurements would dictate.
<Note>
Getting the ease right for your type of fabric is essential for getting a good fit. If you make the ease
too negative, the leggings will be too constricting, and limiting movement. If you don't make the ease
negative enough, the leggings will not hug your legs and torso. The fabric should be stretched in all
places, without being too tight.
</Note>
<Note>
With a positive ease, these leggings will turn into slightly loose fitting pants
</Note>

View file

@ -0,0 +1,19 @@
---
title: "Ease"
---
***
Controls the amount of ease built into the pattern. Since these are leggings that are to be made of stretch fabric,
the ease is nagative. So the completed garment will be narrower than the measurements would dictate.
<Note>
Getting the ease right for your type of fabric is essential for getting a good fit. If you make the ease
too negative, the leggings will be too constricting, and limiting movement. If you don't make the ease
negative enough, the leggings will not hug your legs and torso. The fabric should be stretched in all
places, without being too tight.
</Note>
<Note>
With a positive ease, these leggings will turn into slightly loose fitting pants
</Note>

View file

@ -0,0 +1,5 @@
---
title: "Lumina leggings: Design Options"
---
<DesignOptions design='lumina' />

View file

@ -0,0 +1,5 @@
---
title: "Lumina leggings: Design Options"
---
<DesignOptions design='lumina' />

View file

@ -0,0 +1,5 @@
---
title: "Lumina leggings: Design Options"
---
<DesignOptions design='lumina' />

View file

@ -0,0 +1,19 @@
---
title: "Leg length"
---
***
Controls the length of the legs. This is a percentage of the inseam.
<note>
Since the inseam is measured to the floor, and these leggings max out at the ankle,
The maximum is beyond the ankle, and is ignored. The slider will not do anything
for the top 10% or so.
</note>

View file

@ -0,0 +1,19 @@
---
title: "Leg length"
---
***
Controls the length of the legs. This is a percentage of the inseam.
<note>
Since the inseam is measured to the floor, and these leggings max out at the ankle,
The maximum is beyond the ankle, and is ignored. The slider will not do anything
for the top 10% or so.
</note>

View file

@ -0,0 +1,19 @@
---
title: "Leg length"
---
***
Controls the length of the legs. This is a percentage of the inseam.
<note>
Since the inseam is measured to the floor, and these leggings max out at the ankle,
The maximum is beyond the ankle, and is ignored. The slider will not do anything
for the top 10% or so.
</note>

View file

@ -0,0 +1,19 @@
---
title: "Leg length"
---
***
Controls the length of the legs. This is a percentage of the inseam.
<note>
Since the inseam is measured to the floor, and these leggings max out at the ankle,
The maximum is beyond the ankle, and is ignored. The slider will not do anything
for the top 10% or so.
</note>

View file

@ -0,0 +1,19 @@
---
title: "Leg length"
---
***
Controls the length of the legs. This is a percentage of the inseam.
<note>
Since the inseam is measured to the floor, and these leggings max out at the ankle,
The maximum is beyond the ankle, and is ignored. The slider will not do anything
for the top 10% or so.
</note>

View file

@ -0,0 +1,19 @@
---
title: "Leg length"
---
***
Controls the length of the legs. This is a percentage of the inseam.
<note>
Since the inseam is measured to the floor, and these leggings max out at the ankle,
The maximum is beyond the ankle, and is ignored. The slider will not do anything
for the top 10% or so.
</note>

View file

@ -0,0 +1,5 @@
---
title: "Lumina leggings: Design Options"
---
<DesignOptions design='lumina' />

View file

@ -0,0 +1,10 @@
---
title: "Pocket"
---
***
The pattern allows for a pocket to be added in the side panel.

View file

@ -0,0 +1,10 @@
---
title: "Pocket"
---
***
The pattern allows for a pocket to be added in the side panel.

View file

@ -0,0 +1,10 @@
---
title: "Pocket"
---
***
The pattern allows for a pocket to be added in the side panel.

View file

@ -0,0 +1,10 @@
---
title: "Pocket"
---
***
The pattern allows for a pocket to be added in the side panel.

View file

@ -0,0 +1,10 @@
---
title: "Pocket"
---
***
The pattern allows for a pocket to be added in the side panel.

View file

@ -0,0 +1,10 @@
---
title: "Pocket"
---
***
The pattern allows for a pocket to be added in the side panel.

View file

@ -0,0 +1,11 @@
---
title: "Pocket depth"
---
***
Controls the depth of the pocket.

View file

@ -0,0 +1,10 @@
---
title: "Pocket depth"
---
***
Controls the depth of the pocket.

View file

@ -0,0 +1,11 @@
---
title: "Pocket depth"
---
***
Controls the depth of the pocket.

View file

@ -0,0 +1,11 @@
---
title: "Pocket depth"
---
***
Controls the depth of the pocket.

View file

@ -0,0 +1,11 @@
---
title: "Pocket depth"
---
***
Controls the depth of the pocket.

View file

@ -0,0 +1,11 @@
---
title: "Pocket depth"
---
***
Controls the depth of the pocket.

View file

@ -0,0 +1,15 @@
---
title: "Side panel"
---
***
Have either a fixed width side panel, or one that follows the contours of the legs.
<Note>
Even a fixed width side panel will taper towards the ankle
</Note>

View file

@ -0,0 +1,15 @@
---
title: "Side panel"
---
***
Have either a fixed width side panel, or one that follows the contours of the legs.
<Note>
Even a fixed width side panel will taper towards the ankle
</Note>

View file

@ -0,0 +1,15 @@
---
title: "Side panel"
---
***
Have either a fixed width side panel, or one that follows the contours of the legs.
<Note>
Even a fixed width side panel will taper towards the ankle
</Note>

View file

@ -0,0 +1,15 @@
---
title: "Side panel"
---
***
Have either a fixed width side panel, or one that follows the contours of the legs.
<Note>
Even a fixed width side panel will taper towards the ankle
</Note>

View file

@ -0,0 +1,15 @@
---
title: "Side panel"
---
***
Have either a fixed width side panel, or one that follows the contours of the legs.
<Note>
Even a fixed width side panel will taper towards the ankle
</Note>

View file

@ -0,0 +1,15 @@
---
title: "Side panel"
---
***
Have either a fixed width side panel, or one that follows the contours of the legs.
<Note>
Even a fixed width side panel will taper towards the ankle
</Note>

View file

@ -0,0 +1,11 @@
---
title: "Side panel side"
---
***
Controls the width of the side panel. This is a percentage of the waist.

View file

@ -0,0 +1,11 @@
---
title: "Side panel side"
---
***
Controls the width of the side panel. This is a percentage of the waist.

View file

@ -0,0 +1,11 @@
---
title: "Side panel side"
---
***
Controls the width of the side panel. This is a percentage of the waist.

View file

@ -0,0 +1,11 @@
---
title: "Side panel side"
---
***
Controls the width of the side panel. This is a percentage of the waist.

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