1
0
Fork 0

wip: Progress on charlie

This commit is contained in:
Joost De Cock 2021-04-11 17:15:58 +02:00
parent ac3894eaa9
commit 856a6bc2e0
24 changed files with 585 additions and 343 deletions

View file

@ -23,7 +23,7 @@ jobs:
env: env:
CI: true CI: true
- name: Install peer & test dependencies - name: Install peer & test dependencies
run: "cd packages/charlie && npm install @freesewing/core@^2.12.1 @freesewing/plugin-bundle@^2.12.1 @freesewing/models@2.12.1 @freesewing/pattern-info@2.12.1 mocha chai" run: "cd packages/charlie && npm install @freesewing/core@^2.14.0 @freesewing/plugin-bundle@^2.14.0 @freesewing/models@2.14.0 @freesewing/pattern-info@2.14.0 mocha chai"
env: env:
CI: true CI: true
- name: Build pattern - name: Build pattern

View file

@ -1,6 +1,12 @@
# Change log for: @freesewing/charlie # Change log for: @freesewing/charlie
## 2.15.0 (NaN-NaN-NaN)
### Added
- Inital release of the Charlie Chinos pattern
This is the **initial release**, and the start of this change log. This is the **initial release**, and the start of this change log.

View file

@ -1,4 +1,4 @@
![FreeSewing](https://freesewing.org/banner.jpg) ![FreeSewing](https://static.freesewing.org/banner.png)
<p align='center'><a <p align='center'><a
href="https://www.npmjs.com/package/@freesewing/charlie" href="https://www.npmjs.com/package/@freesewing/charlie"
title="@freesewing/charlie on NPM" title="@freesewing/charlie on NPM"
@ -19,6 +19,11 @@
title="Open issues tagged pkg:charlie" title="Open issues tagged pkg:charlie"
><img src="https://img.shields.io/github/issues/freesewing/freesewing/pkg:charlie.svg?label=Issues" ><img src="https://img.shields.io/github/issues/freesewing/freesewing/pkg:charlie.svg?label=Issues"
alt="Open issues tagged pkg:charlie"/> alt="Open issues tagged pkg:charlie"/>
</a><a
href="https://todo.freesewing.org/"
title="Project board"
><img src="https://img.shields.io/badge/%F3%A0%80%A0-Project%20board-9775fa.svg?logo=github&logoColor=white&logoWidth=15"
alt="Project board"/>
</a></p><p align='center'><a </a></p><p align='center'><a
href="https://twitter.com/freesewing_org" href="https://twitter.com/freesewing_org"
title="Follow @freesewing_org on Twitter" title="Follow @freesewing_org on Twitter"
@ -41,49 +46,62 @@
alt="Follow @freesewing_org on Twitter"/> alt="Follow @freesewing_org on Twitter"/>
</a></p> </a></p>
## What am I looking at? 🤔 # @freesewing/charlie
This repository is our *monorepo* holding [all our NPM packages](https://www.npmjs.com/search?q=keywords:freesewing).
This folder holds **@freesewing/charlie**
A FreeSewing pattern for chino trousers A FreeSewing pattern for chino trousers
## What am I looking at? 🤔
This repository is our *monorepo*
holding [all our NPM packages](https://freesewing.dev/reference/packages/).
This folder holds: @freesewing/charlie
## About FreeSewing 💀 ## About FreeSewing 💀
Where the world of makers and developers collide, that's where you'll find 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
our sewing patterns adapted to your measurements.
If you're a developer, our documentation is on [freesewing.dev](https://freesewing.dev/).
Our [core library](https://freesewing.dev/reference/api/) is a *batteries-included* toolbox Our [core library](https://freesewing.dev/reference/api/) is a *batteries-included* toolbox
for parametric design of sewing patterns. It's a modular system (check our list for parametric design of sewing patterns. But we also provide a range
of [plugins](https://freesewing.dev/reference/plugins/) and getting started is as simple as: 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 ```bash
npm init freesewing-pattern npx create-freesewing-pattern
``` ```
The [getting started](https://freesewing.dev/guides/getting-started/) section on [freesewing.dev](https://freesewing.dev/) is a good Or, consult our getting started guides
entrypoint to our documentation, but you'll find a lot more there, including for [Linux](https://freesewing.dev/tutorials/getting-started-linux/),
our [API reference](https://freesewing.dev/reference/api/), [MacOS](https://freesewing.dev/tutorials/getting-started-mac/),
as well as [our turorial](https://freesewing.dev/tutorials/pattern-design/), or [Windows](https://freesewing.dev/tutorials/getting-started-windows/).
and [howtos](https://freesewing.dev/howtos/).
If you're a maker, checkout [freesewing.org](https://freesewing/) where you can generate We also have a [pattern design tutorial](https://freesewing.dev/tutorials/pattern-design/) that
our sewing patterns adapted to your measurements. walks you through your first parametric design,
and [a friendly community](https://freesewing.org/community/where/) with
people who can help you when you get stuck.
## Support FreeSewing: Become a patron 🥰 ## Support FreeSewing: Become a patron 🥰
FreeSewing is an open source project run by a community, FreeSewing is an open source project run by a community,
and financially supported by our patrons. and financially supported by our patrons.
If you feel what we do is worthwhile, you too If you feel what we do is worthwhile, and you can spend a few coind without
should [become a patron](https://freesewing.org/patrons/join). hardship, then you should [join us and become a patron](https://freesewing.org/community/join).
## Links 👩‍💻 ## Links 👩‍💻
- 💻 Makers website: [freesewing.org](https://freesewing.org) - 💻 Makers website: [freesewing.org](https://freesewing.org)
- 💻 Developers website: [freesewing.dev](https://freesewing.dev) - 💻 Developers website: [freesewing.dev](https://freesewing.dev)
- 💬 Chat: On Discord via [chat.freesewing.org](https://chat.freesewing.org/) - 💬 Chat: On Discord via [chat.freesewing.org](https://chat.freesewing.org/)
- ✅ Todo list/Kanban board: On Github via [todo.freesewing.org](https://todo.freesewing.org/)
- 🐦 Twitter: [@freesewing_org](https://twitter.com/freesewing_org) - 🐦 Twitter: [@freesewing_org](https://twitter.com/freesewing_org)
- 📷 Instagram: [@freesewing_org](https://instagram.com/freesewing_org) - 📷 Instagram: [@freesewing_org](https://instagram.com/freesewing_org)

View file

@ -11,7 +11,7 @@ export default {
tags: ['bottom', 'basics'], tags: ['bottom', 'basics'],
optionGroups: { optionGroups: {
fit: ['seatEase', 'kneeEase', 'waistEase'], fit: ['seatEase', 'kneeEase', 'waistEase'],
style: ['waistHeight', 'lengthBonus', 'crotchDrop'], style: ['waistHeight', 'waistbandWidth', 'lengthBonus', 'crotchDrop'],
pockets: [ pockets: [
{ {
backPockets: [ backPockets: [
@ -43,6 +43,7 @@ export default {
'grainlinePosition', 'grainlinePosition',
'legBalance', 'legBalance',
'waistBalance', 'waistBalance',
'beltLoops',
{ {
fly: ['flyCurve', 'flyLength', 'flyWidth'] fly: ['flyCurve', 'flyLength', 'flyWidth']
} }
@ -69,17 +70,17 @@ export default {
frontPocket: 'front', frontPocket: 'front',
frontPocketFacing: 'frontPocket', frontPocketFacing: 'frontPocket',
backPocketFacing: 'backPocket', backPocketFacing: 'backPocket',
backPocketInterfacing: 'backPocket',
backPocketJet: 'backPocketFacing', backPocketJet: 'backPocketFacing',
flyFacing: 'front', flyFacing: 'front',
flyExtention: 'flyFacing' flyExtension: 'flyFacing'
}, },
parts: ['beltLoop'], parts: ['beltLoops'],
dependencies: { dependencies: {
// The inheritance makes this a bit messy // The inheritance makes this a bit messy
titanFront: 'titanBack',
back: ['titanBack', 'titanFront', 'front'], back: ['titanBack', 'titanFront', 'front'],
waistband: ['titanBack', 'titanFront', 'front', 'back'], waistband: ['titanBack', 'titanFront', 'front', 'back']
waistbandButtonSide: 'waistband',
waistbandButtonholeSide: 'waistband'
}, },
options: { options: {
// Constants (from Titan) // Constants (from Titan)
@ -87,12 +88,11 @@ export default {
fitCrossSeam: true, fitCrossSeam: true,
fitCrossSeamFront: true, fitCrossSeamFront: true,
fitCrossSeamBack: true, fitCrossSeamBack: true,
// Lock titan options // Lock titan options
fitKnee: true, fitKnee: true,
// Charlie constants // Charlie constants
waistbandReduction: 0.3, // See src/index.js waistbandReduction: 0.25, // See src/index.js
waistbandFactor: 0.1, waistbandFactor: 0.1,
// Fit (from Titan) // Fit (from Titan)
@ -101,7 +101,8 @@ export default {
kneeEase: { pct: 15, min: 10, max: 30 }, kneeEase: { pct: 15, min: 10, max: 30 },
// Style (from Titan) // Style (from Titan)
waistHeight: { pct: 15, min: 0, max: 30 }, waistHeight: { pct: -4, min: -50, max: 30 },
waistbandWidth: { mm: 40, min: 20, max: 60 },
lengthBonus: { pct: 2, min: -20, max: 10 }, lengthBonus: { pct: 2, min: -20, max: 10 },
crotchDrop: { pct: 2, min: 0, max: 15 }, crotchDrop: { pct: 2, min: 0, max: 15 },
@ -133,9 +134,6 @@ export default {
frontPocketWidth: { pct: 55, min: 45, max: 65 }, frontPocketWidth: { pct: 55, min: 45, max: 65 },
frontPocketDepth: { pct: 100, min: 85, max: 110 }, frontPocketDepth: { pct: 100, min: 85, max: 110 },
// Belt
waistbandWidth: { mm: 25, min: 5, max: 45 },
// Fly // Fly
flyCurve: { pct: 72, min: 50, max: 100 }, flyCurve: { pct: 72, min: 50, max: 100 },
flyLength: { pct: 45, min: 30, max: 60 }, flyLength: { pct: 45, min: 30, max: 60 },
@ -143,6 +141,7 @@ export default {
// Waistband // Waistband
splitWaistband: { bool: false }, splitWaistband: { bool: false },
waistbandWidth: { pct: 40, min: 25, max: 65 } waistbandWidth: { mm: 40, min: 20, max: 60 },
beltLoops: { count: 8, min: 6, max: 12 }
} }
} }

View file

@ -15,21 +15,20 @@
"@freesewing/mui-theme": "latest", "@freesewing/mui-theme": "latest",
"@freesewing/pattern-info": "latest", "@freesewing/pattern-info": "latest",
"@freesewing/plugin-bundle": "latest", "@freesewing/plugin-bundle": "latest",
"@freesewing/plugin-buttons": "^2.14.0", "@freesewing/plugin-theme": "latest",
"@freesewing/plugin-i18n": "latest", "@freesewing/plugin-i18n": "latest",
"@freesewing/plugin-svgattr": "latest", "@freesewing/plugin-svgattr": "latest",
"@freesewing/plugin-theme": "latest",
"@freesewing/utils": "latest", "@freesewing/utils": "latest",
"@material-ui/core": "^4.11.2", "@material-ui/core": "^4.11.2",
"@material-ui/icons": "^4.11.2", "@material-ui/icons": "^4.11.2",
"@material-ui/lab": "^v4.0.0-alpha.57", "@material-ui/lab": "^v4.0.0-alpha.57",
"file-saver": "^2.0.5",
"pattern": "link:..", "pattern": "link:..",
"prismjs": "1.22.0", "prismjs": "1.22.0",
"react": "^17.0.1", "react": "^17.0.1",
"react-dom": "^17.0.1", "react-dom": "^17.0.1",
"react-markdown": "5.0.3", "react-scripts": "^3.4.4",
"react-scripts": "^3.4.4" "file-saver": "^2.0.5",
"react-markdown": "5.0.3"
}, },
"scripts": { "scripts": {
"start": "react-scripts start", "start": "react-scripts start",

View file

@ -2,6 +2,7 @@ import React from 'react'
import ReactDOM from 'react-dom' import ReactDOM from 'react-dom'
import App from './App' import App from './App'
import * as serviceWorker from './serviceWorker' import * as serviceWorker from './serviceWorker'
import './layout.css'
ReactDOM.render(<App />, document.getElementById('root')) ReactDOM.render(<App />, document.getElementById('root'))

View file

@ -0,0 +1,303 @@
div.layout-wrapper {
width: 100%;
margin: 0;
padding: 0;
background-color: red;
background: #f8f9fa;
background: linear-gradient(90deg, #f1f3f5 0%, #f1f3f5 25%, #f8f9fa 26%, #f8f9fa 100%);
}
div.layout-wrapper div.layout {
display: flex;
max-width: 1600px;
margin: auto;
padding: 0;
flex-direction: row;
flex-wrap: nowrap;
justify-content: space-between;
background-color: #f8f9fa;
min-height: calc(100vh - 64px);
}
div.layout-wrapper div.layout > aside {
width: 33%;
background: #f1f3f5;
border-right: 2px solid #dee2e6;
}
div.layout-wrapper div.layout > section {
margin: 0;
padding: 1rem;
}
div.layout-wrapper div.layout > section > div.content {
max-width: 66ch;
min-width: 340px;
}
div.layout-wrapper div.layout > section > div.content.wide {
max-width: 100%;
margin: auto;
}
.theme-wrapper.dark header {
background-color: #1a1d21;
}
.theme-wrapper.dark div.layout-wrapper {
background: #f8f9fa;
background: linear-gradient(90deg, #1a1d21 0%, #1a1d21 25%, #212529 26%, #212529 100%);
}
.theme-wrapper.dark div.layout-wrapper div.layout {
background-color: #212529;
}
.theme-wrapper.dark div.layout-wrapper div.layout > aside {
background-color: #1a1d21;
border-right: 2px solid #343a40;
}
header a svg {
color: #ced4da;
}
header a:first-of-type svg {
color: #f8f9fa;
}
header a:hover svg {
color: #b197fc;
}
header a span,
header button span {
color: #ced4da;
}
header a span svg,
header button span svg {
color: #dee2e6;
}
header a:hover span,
header button:hover span {
color: #f8f9fa;
}
header a:hover span svg,
header button:hover span svg {
color: #b197fc;
}
header a,
header button {
padding: 0 1vw !important;
}
/* monitor */
@media (min-width: 1200px) {
div.layout > section {
width: 63%;
}
}
/* slate */
@media (max-width: 1199px) and (min-width: 960px) {
div.layout > aside {
width: 298px;
}
div.layout > section {
width: calc(100% - 300px - 4rem);
max-width: none;
margin: 0 1rem 0 3rem;
}
}
/* tablet */
@media (max-width: 959px) {
div.layout > aside {
width: 218px;
}
div.layout > section {
width: calc(100% - 220px - 4rem);
max-width: none;
margin: 0;
padding: 0 2rem;
}
div.layout > section div.content {
min-width: inherit;
}
}
/* mobile */
@media (max-width: 599px) {
div.layout > aside {
display: none;
}
div.layout > section {
width: calc(100%);
margin: 0 auto;
padding: 0 1.5rem;
max-width: none;
}
}
div.gatsby-highlight {
margin-bottom: 1rem;
}
@media (max-width: 599px) {
#mobile-menu {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100vh;
padding: 0 0 1rem;
max-width: 600px;
z-index: -10;
transition: opacity 0.25s ease 0s;
opacity: 0;
overflow: scroll;
}
#mobile-menu > ul,
#mobile-menu > div {
transform: translate(0px, 10px);
transition: transform 0.25s ease 0s;
}
.theme-wrapper.show-menu #mobile-menu {
opacity: 1;
z-index: 10;
}
.theme-wrapper.show-menu #mobile-menu > div {
transform: translate(0px, 0px);
}
}
.theme-wrapper.light div.draft-ui-menu,
.theme-wrapper.light div.menu {
background: #f1f3f5;
}
.theme-wrapper.dark div.draft-ui-menu,
.theme-wrapper.dark div.menu {
background: #343a40;
}
.theme-wrapper.show-menu div.menu {
opacity: 1;
z-index: 10;
}
.theme-wrapper.show-menu div.menu > div {
transform: translate(0px, 0px);
}
div.spaced-buttons > button {
margin: 0 0.5rem 0.5rem 0;
}
div.spaced > * {
margin: 0 0.5rem 0.5rem 0;
}
ul#pre-main-menu {
margin: 0;
padding: 0;
}
.boldish {
font-weight: 500;
}
.freesewing.draft {
padding: 1rem;
}
li.action {
clear: both;
}
li.action span.MuiSwitch-root {
float: right;
}
.theme-wrapper.light ul#draft-config li.action.toggle.off,
.theme-wrapper.dark ul#draft-config li.action.toggle.off {
color: #868e96;
}
.theme-wrapper.light ul#draft-config li.action.toggle.off > span svg,
.theme-wrapper.dark ul#draft-config li.action.toggle.off > span svg {
color: #868e96;
}
footer {
background-color: #1a1d21;
color: #adb5bd;
padding: 3rem 0 6rem;
}
footer a {
color: #dee2e6 !important;
font-weight: 400;
}
footer a:hover {
color: #d0bfff !important;
}
footer div.cols {
display: flex;
flex-direction: row;
justify-content: space-between;
max-width: 1600px;
margin: auto;
padding: 0 1.5rem;
}
footer div.cols > div {
min-width: 150px;
max-width: calc(20% - 4rem);
padding: 0 2rem 0 0;
width: 100%;
}
footer ul {
text-align: left;
font-size: 1.1rem;
margin: 0;
padding: 0;
width: 100%;
}
footer ul li:first-of-type {
padding: 0.35rem 0.75rem;
}
footer ul li {
display: block;
}
footer ul li a:hover {
text-decoration: none !important;
}
footer ul li.heading {
font-weight: bold;
border-bottom: 3px solid #adb5bd;
margin-bottom: 0.5rem;
}
/* XL screens */
@media (min-width: 1200px) {
footer div.cols > div:last-of-type {
min-width: 350px;
}
}
/* SM screens */
@media (min-width: 600px) and (max-width: 959px) {
footer div.cols {
flex-wrap: wrap;
}
footer div.cols > div {
width: calc(30% - 4rem);
padding: 0 1rem;
}
}
/* XS screens */
@media (max-width: 599px) {
footer div.cols {
display: block;
}
footer div.cols > div {
margin: 2rem auto 0;
max-width: calc(100% - 4rem);
}
footer div.cols > div:first-of-type {
margin-top: 0;
}
}

View file

@ -1,6 +1,6 @@
{ {
"name": "@freesewing/charlie", "name": "@freesewing/charlie",
"version": "2.12.2", "version": "2.14.0",
"description": "A FreeSewing pattern for chino trousers", "description": "A FreeSewing pattern for chino trousers",
"author": "Joost De Cock <joost@decock.org> (https://github.com/joostdecock)", "author": "Joost De Cock <joost@decock.org> (https://github.com/joostdecock)",
"homepage": "https://freesewing.org/", "homepage": "https://freesewing.org/",
@ -34,8 +34,8 @@
"testci": "BABEL_ENV=production ./node_modules/.bin/_mocha tests/*.test.js --require @babel/register" "testci": "BABEL_ENV=production ./node_modules/.bin/_mocha tests/*.test.js --require @babel/register"
}, },
"peerDependencies": { "peerDependencies": {
"@freesewing/core": "^2.12.1", "@freesewing/core": "^2.14.0",
"@freesewing/plugin-bundle": "^2.12.1" "@freesewing/plugin-bundle": "^2.14.0"
}, },
"dependencies": {}, "dependencies": {},
"devDependencies": { "devDependencies": {
@ -46,14 +46,14 @@
"eslint": "^7.6.0", "eslint": "^7.6.0",
"babel-jest": "^26.2.2", "babel-jest": "^26.2.2",
"jest": "26.2.2", "jest": "26.2.2",
"@freesewing/components": "^2.12.1", "@freesewing/components": "^2.14.0",
"@freesewing/css-theme": "^2.12.1", "@freesewing/css-theme": "^2.14.0",
"@freesewing/i18n": "^2.12.1", "@freesewing/i18n": "^2.14.0",
"@freesewing/mui-theme": "^2.12.1", "@freesewing/mui-theme": "^2.14.0",
"@freesewing/plugin-bust": "^2.12.1", "@freesewing/plugin-bust": "^2.14.0",
"@freesewing/plugin-buttons": "^2.12.1", "@freesewing/plugin-buttons": "^2.14.0",
"@freesewing/plugin-flip": "^2.12.1", "@freesewing/plugin-flip": "^2.14.0",
"@freesewing/utils": "^2.12.1", "@freesewing/utils": "^2.14.0",
"@svgr/rollup": "^2.4.1", "@svgr/rollup": "^2.4.1",
"cross-env": "^7.0.2", "cross-env": "^7.0.2",
"react-scripts": "^3.4.1", "react-scripts": "^3.4.1",

View file

@ -42,7 +42,7 @@ export default (part) => {
points.titleAnchor = points.rightNotch.shiftFractionTowards(points.leftNotch, 0.5) points.titleAnchor = points.rightNotch.shiftFractionTowards(points.leftNotch, 0.5)
macro('title', { macro('title', {
at: points.titleAnchor, at: points.titleAnchor,
nr: 5, nr: 6,
title: 'backPocketBagFacing' title: 'backPocketBagFacing'
}) })
points.grainlineTop = points.waistbandLeft.shiftFractionTowards(points.waistbandRight, 0.15) points.grainlineTop = points.waistbandLeft.shiftFractionTowards(points.waistbandRight, 0.15)

View file

@ -0,0 +1,60 @@
export default (part) => {
// Shorthand
let {
points,
Point,
paths,
Path,
measurements,
options,
complete,
paperless,
store,
macro,
utils,
snippets,
Snippet,
sa
} = part.shorthand()
// Clean up
for (let id in paths) delete paths[id]
delete snippets.logo
const height = points.bottomRight.x / 3
points.bottomLeft = points.curveStartLeft.shift(-90, points.rightNotch.x / 1.75)
points.bottomRight = points.bottomLeft.flipX()
points.midLeft = points.bottomLeft.shift(90, height)
points.midRight = points.bottomRight.shift(90, height)
points.topLeft = points.bottomLeft.shift(90, height * 2)
points.topRight = points.bottomRight.shift(90, height * 2)
points.leftNotch = new Point(points.leftNotch.x, points.midRight.y)
points.rightNotch = points.leftNotch.flipX()
paths.seam = new Path()
.move(points.topLeft)
.line(points.bottomLeft)
.line(points.bottomRight)
.line(points.topRight)
.line(points.topLeft)
.close()
.attr('class', 'interfacing')
if (complete) {
paths.fold = new Path()
.move(points.leftNotch)
.line(points.rightNotch)
.attr('class', 'interfacing dashed')
points.titleAnchor = points.rightNotch.shiftFractionTowards(points.leftNotch, 0.5)
macro('title', {
at: points.titleAnchor,
nr: 3,
title: 'backPocketInterfacing'
})
if (paperless) {
}
}
return part
}

View file

@ -45,7 +45,7 @@ export default (part) => {
points.titleAnchor = points.rightNotch.shiftFractionTowards(points.leftNotch, 0.5) points.titleAnchor = points.rightNotch.shiftFractionTowards(points.leftNotch, 0.5)
macro('title', { macro('title', {
at: points.titleAnchor, at: points.titleAnchor,
nr: 3, nr: 4,
title: 'backPocketJet', title: 'backPocketJet',
scale: 0.5 scale: 0.5
}) })

View file

@ -56,7 +56,7 @@ export default (part) => {
points.titleAnchor = points.rightNotch.shiftFractionTowards(points.foldLeft, 0.5) points.titleAnchor = points.rightNotch.shiftFractionTowards(points.foldLeft, 0.5)
macro('title', { macro('title', {
at: points.titleAnchor, at: points.titleAnchor,
nr: 4, nr: 5,
title: 'backPocketBag' title: 'backPocketBag'
}) })
points.logoAnchor = points.foldLeft.shiftFractionTowards(points.bottomRight, 0.5) points.logoAnchor = points.foldLeft.shiftFractionTowards(points.bottomRight, 0.5)

View file

@ -2,22 +2,15 @@ export default (part) => {
// Helper method to draw the outseam path // Helper method to draw the outseam path
const drawOutseam = () => { const drawOutseam = () => {
let waistOut = points.styleWaistOut || points.waistOut let waistOut = points.styleWaistOut || points.waistOut
if (points.waistOut.x > points.seatOut.x) { let outseam = new Path()
let outseam = new Path() .move(points.styleWaistOut)
.move(points.styleWaistOut) .curve(points.seatOut, points.kneeOutCp2, points.floorOut)
.curve(points.seatOut, points.kneeOutCp2, points.floorOut) return new Path()
return new Path() .move(points.slantOut)
.move(points.slantOut) .line(points.slantCurveStart)
.line(points.slantCurveStart) .curve(points.slantCurveCp1, points.slantCurveCp2, points.slantCurveEnd)
.curve(points.slantCurveCp1, points.slantCurveCp2, points.slantCurveEnd) .join(outseam.split(points.slantCurveEnd).pop())
.join(outseam.split(points.slantCurveEnd).pop()) .reverse()
.reverse()
} else {
return new Path()
.move(points.floorOut)
.curve(points.kneeOutCp2, points.seatOutCp1, points.seatOut)
.curve_(points.seatOutCp2, waistOut)
}
} }
/* /*
* Helper method to draw the outline path * Helper method to draw the outline path
@ -88,10 +81,11 @@ export default (part) => {
.move(points.styleWaistOut) .move(points.styleWaistOut)
.curve(points.seatOut, points.kneeOutCp2, points.floorOut) .curve(points.seatOut, points.kneeOutCp2, points.floorOut)
// Keep the seat control point vertically between the (lowered) waist and seat line
points.seatOutCp2.y = points.styleWaistOut.y + points.styleWaistOut.dy(points.seatOut) / 2
// Construct pocket slant // Construct pocket slant
if (points.waistOut.x > points.seatOut.x) { points.slantBottom = titanOutseam.shiftAlong(store.get('slantLength'))
points.slantBottom = titanOutseam.shiftAlong(store.get('slantLength'))
}
points.slantOut = points.styleWaistIn.shiftOutwards(points.styleWaistOut, store.get('slantWidth')) points.slantOut = points.styleWaistIn.shiftOutwards(points.styleWaistOut, store.get('slantWidth'))
// Shape waist // Shape waist
@ -165,6 +159,19 @@ export default (part) => {
on: ['grainlineBottom', 'slantBottomNotch', 'slantTopNotch'] on: ['grainlineBottom', 'slantBottomNotch', 'slantTopNotch']
}) })
macro('bartack', {
anchor: points.slantTopNotch,
angle: points.slantTopNotch.angle(points.slantBottomNotch) - 90,
length: sa ? sa / 2 : 5,
suffix: 'slantTop'
})
macro('bartack', {
anchor: points.slantBottomNotch,
length: sa ? sa / 2 : 5,
angle: 180,
suffix: 'slantBottom'
})
if (sa) { if (sa) {
paths.sa = paths.saBase paths.sa = paths.saBase
.offset(sa) .offset(sa)

View file

@ -1,60 +0,0 @@
export default (part) => {
// Shorthand
let {
points,
Point,
paths,
Path,
measurements,
options,
complete,
paperless,
store,
macro,
utils,
snippets,
Snippet,
sa
} = part.shorthand()
let length = measurements.waist * options.waistbandWidth * options.waistbandFactor * 1.2
let width = length / 5
points.topLeft = new Point(0, 0)
points.topRight = new Point(width, 0)
points.bottomLeft = new Point(0, length)
points.bottomRight = new Point(width, length)
paths.seam = new Path()
.move(points.topLeft)
.line(points.bottomLeft)
.line(points.bottomRight)
.line(points.topRight)
.line(points.topLeft)
.close()
.attr('class', 'fabric')
if (complete) {
macro('title', {
at: new Point(width / 4, length / 4),
nr: 11,
title: 'beltLoop',
scale: 0.3,
rotation: 90
})
if (sa)
paths.sa = new Path()
.move(points.topLeft.shift(180, sa).shift(90, 2 * sa))
.line(points.bottomLeft.shift(180, sa).shift(-90, 2 * sa))
.line(points.bottomRight.shift(0, sa).shift(-90, 2 * sa))
.line(points.topRight.shift(0, sa).shift(90, 2 * sa))
.line(points.topLeft.shift(180, sa).shift(90, 2 * sa))
.close()
.attr('class', 'sa fabric')
if (paperless) {
}
}
return part
}

View file

@ -0,0 +1,78 @@
export default (part) => {
// Shorthand
let {
points,
Point,
paths,
Path,
measurements,
options,
complete,
paperless,
store,
macro,
utils,
snippets,
Snippet,
sa
} = part.shorthand()
let count = options.beltLoops
let length = options.waistbandWidth * 2.5 * count
let width = options.waistbandWidth / 4
points.topLeft = new Point(0, 0)
points.topRight = new Point(width * 2.8, 0)
points.bottomLeft = new Point(0, length)
points.bottomRight = new Point(width * 2.8, length)
points.topFold1 = new Point(width * 0.8, 0)
points.topFold2 = new Point(width * 1.8, 0)
points.bottomFold1 = new Point(width * 0.8, length)
points.bottomFold2 = new Point(width * 1.8, length)
for (let i = 1; i < count; i++) {
points[`cut${i}a`] = points.topLeft.shiftFractionTowards(points.bottomLeft, i / count)
points[`cut${i}b`] = points.topRight.shiftFractionTowards(points.bottomRight, i / count)
}
paths.seam = new Path()
.move(points.topLeft)
.line(points.bottomLeft)
.line(points.bottomRight)
.line(points.topRight)
.line(points.topLeft)
.close()
.attr('class', 'fabric')
if (complete) {
paths.fold = new Path()
.move(points.topFold1)
.line(points.bottomFold1)
.move(points.bottomFold2)
.line(points.topFold2)
.attr('class', 'fabric help')
macro('title', {
at: new Point(width / 2, length / 2),
nr: 12,
title: 'beltLoops',
rotation: 90,
scale: 0.7
})
points.grainlineTop = new Point(points.topRight.x / 2, 0)
points.grainlineBottom = new Point(points.topRight.x / 2, length)
macro('grainline', {
from: points.grainlineTop,
to: points.grainlineBottom
})
for (let i = 1; i < count; i++) {
paths[`cut${i}`] = new Path()
.move(points[`cut${i}a`])
.line(points[`cut${i}b`])
.attr('class', 'fabric dashed')
}
if (paperless) {
}
}
return part
}

View file

@ -56,7 +56,7 @@ export default (part) => {
points.titleAnchor = points.flyCurveStart points.titleAnchor = points.flyCurveStart
macro('title', { macro('title', {
at: points.titleAnchor, at: points.titleAnchor,
nr: 9, nr: 10,
title: 'flyExtention' title: 'flyExtention'
}) })
if (sa) if (sa)

View file

@ -45,7 +45,7 @@ export default (part) => {
points.titleAnchor = points.grainlineTop.shiftFractionTowards(points.grainlineBottom, 0.5) points.titleAnchor = points.grainlineTop.shiftFractionTowards(points.grainlineBottom, 0.5)
macro('title', { macro('title', {
at: points.titleAnchor, at: points.titleAnchor,
nr: 8, nr: 9,
title: 'flyFacing' title: 'flyFacing'
}) })
if (sa) if (sa)

View file

@ -41,7 +41,7 @@ export default (part) => {
points.titleAnchor = points.slantBottomNotch.shift(0, 10) points.titleAnchor = points.slantBottomNotch.shift(0, 10)
macro('title', { macro('title', {
at: points.titleAnchor, at: points.titleAnchor,
nr: 7, nr: 8,
title: 'frontPocketBagFacing' title: 'frontPocketBagFacing'
}) })
macro('grainline', { macro('grainline', {

View file

@ -28,9 +28,15 @@ export default (part) => {
'slantTop', 'slantTop',
'slantBottom', 'slantBottom',
'slantTop', 'slantTop',
'pocketbagBottomCp1',
'pocketbagBottomCp2', 'pocketbagBottomCp2',
'pocketbagBottom', 'pocketbagBottom',
'pocketbagBottomRight' 'pocketbagBottomRight',
'pocketFacingBottom',
'slantCurveStart',
'slantCurveCp1',
'slantCurveCp2',
'slantCurveEnd'
]) ])
points[id] = points[id].rotate(-1 * (slant - 90), points.pocketbagTopRight) points[id] = points[id].rotate(-1 * (slant - 90), points.pocketbagTopRight)
@ -61,7 +67,7 @@ export default (part) => {
) )
macro('title', { macro('title', {
at: points.titleAnchor, at: points.titleAnchor,
nr: 6, nr: 7,
title: 'frontPocketBag' title: 'frontPocketBag'
}) })
macro('cutonfold', { macro('cutonfold', {

View file

@ -67,11 +67,15 @@ export default (part) => {
points.styleWaistIn, points.styleWaistIn,
1 - options.flyWidth 1 - options.flyWidth
) )
points.flyCorner = points.flyTop.shift( points.flyCorner = points.flyTop.shift(
points.styleWaistIn.angle(points.crotchSeamCurveStart), points.styleWaistIn.angle(points.crotchSeamCurveStart),
points.styleWaistIn.dist(points.flyBottom) points.styleWaistIn.dist(points.flyBottom)
) )
points.flyCurveStart = points.flyBottom.rotate(90, points.flyCorner) points.flyCurveStart = points.flyCorner.shiftTowards(
points.flyTop,
points.flyBottom.dist(points.flyCorner)
)
points.flyCurveCp1 = points.flyBottom.shiftFractionTowards(points.flyCorner, options.flyCurve) points.flyCurveCp1 = points.flyBottom.shiftFractionTowards(points.flyCorner, options.flyCurve)
points.flyCurveCp2 = points.flyCurveStart.shiftFractionTowards(points.flyCorner, options.flyCurve) points.flyCurveCp2 = points.flyCurveStart.shiftFractionTowards(points.flyCorner, options.flyCurve)
@ -185,15 +189,6 @@ export default (part) => {
.attr('class', 'dashed') .attr('class', 'dashed')
.attr('data-text', 'Left panel only') .attr('data-text', 'Left panel only')
.attr('data-text-class', 'center') .attr('data-text-class', 'center')
points.barTack1 = Jseam.reverse().shiftFractionAlong(0.1)
points.barTack2a = Jseam.shiftFractionAlong(0.2)
points.barTack2b = Jseam.shiftFractionAlong(0.35)
paths.barTack1 = paths.Jseam.split(points.barTack1).pop().attr('class', 'bartack')
paths.barTack2 = paths.Jseam.split(points.barTack2a)
.pop()
.split(points.barTack2b)
.shift()
.attr('class', 'bartack')
paths.pocketBag = new Path() paths.pocketBag = new Path()
.move(points.slantTop) .move(points.slantTop)
.line(points.slantCurveStart) .line(points.slantCurveStart)
@ -205,6 +200,25 @@ export default (part) => {
.line(points.pocketFacingBottom) .line(points.pocketFacingBottom)
.attr('class', 'lining dashed') .attr('class', 'lining dashed')
// Bartack
macro('bartack', {
anchor: points.slantTopNotch,
angle: points.slantTopNotch.angle(points.slantCurveStart) + 90,
length: sa ? sa / 1.5 : 7.5,
suffix: 'slantTop'
})
macro('bartack', {
anchor: points.slantBottomNotch,
length: sa ? sa / 2 : 5,
suffix: 'slantBottom'
})
macro('bartackFractionAlong', {
path: Jseam.reverse(),
start: 0,
end: 0.1,
suffix: 'stom'
})
if (sa) { if (sa) {
paths.sa = drawPath() paths.sa = drawPath()
.offset(sa) .offset(sa)

View file

@ -3,42 +3,24 @@ import Titan from '@freesewing/titan'
import plugins from '@freesewing/plugin-bundle' import plugins from '@freesewing/plugin-bundle'
import mirrorPlugin from '@freesewing/plugin-mirror' import mirrorPlugin from '@freesewing/plugin-mirror'
import buttonsPlugin from '@freesewing/plugin-buttons' import buttonsPlugin from '@freesewing/plugin-buttons'
import bartackPlugin from '@freesewing/plugin-bartack'
import config from '../config' import config from '../config'
// Parts // Parts
import draftBack from './back' import draftBack from './back'
import draftFront from './front' import draftFront from './front'
import draftWaistband from './waistband' import draftWaistband from './waistband'
import draftWaistbandButtonSide from './waistband-button-side'
import draftWaistbandButtonholeSide from './waistband-buttonhole-side'
import draftFrontPocket from './front-pocket' import draftFrontPocket from './front-pocket'
import draftFrontPocketFacing from './front-pocket-facing' import draftFrontPocketFacing from './front-pocket-facing'
import draftBackPocket from './back-pocket' import draftBackPocket from './back-pocket'
import draftBackPocketFacing from './back-pocket-facing' import draftBackPocketFacing from './back-pocket-facing'
import draftBackPocketInterfacing from './back-pocket-interfacing'
import draftBackPocketJet from './back-pocket-jet' import draftBackPocketJet from './back-pocket-jet'
import draftFlyFacing from './fly-facing' import draftFlyFacing from './fly-facing'
import draftFlyExtention from './fly-extention' import draftFlyExtension from './fly-extension'
import draftBeltLoop from './beltloop' import draftBeltLoops from './beltloops'
// Hack the waistHeight option to make room for waistband
const waistbandPlugin = {
name: 'charlieWaistbandPlugin',
version: config.version,
hooks: {
preDraft: function ({ settings }) {
// Reduce the waistHeight option by 25% to make room for the waistband
// We could also just use negative numbers, but that might confuse the user
settings.options.waistHeight -= settings.options.waistbandReduction
}
}
}
// Create design // Create design
const Pattern = new freesewing.Design(config, [ const Pattern = new freesewing.Design(config, [plugins, mirrorPlugin, buttonsPlugin, bartackPlugin])
plugins,
mirrorPlugin,
buttonsPlugin,
waistbandPlugin
])
// Attach titan draft methods to prototype // Attach titan draft methods to prototype
for (let p of ['Front', 'Back']) { for (let p of ['Front', 'Back']) {
@ -51,15 +33,14 @@ for (let p of ['Front', 'Back']) {
Pattern.prototype.draftBack = (part) => draftBack(part) Pattern.prototype.draftBack = (part) => draftBack(part)
Pattern.prototype.draftFront = (part) => draftFront(part) Pattern.prototype.draftFront = (part) => draftFront(part)
Pattern.prototype.draftWaistband = (part) => draftWaistband(part) Pattern.prototype.draftWaistband = (part) => draftWaistband(part)
Pattern.prototype.draftWaistbandButtonSide = (part) => draftWaistbandButtonSide(part)
Pattern.prototype.draftWaistbandButtonholeSide = (part) => draftWaistbandButtonholeSide(part)
Pattern.prototype.draftFrontPocket = (part) => draftFrontPocket(part) Pattern.prototype.draftFrontPocket = (part) => draftFrontPocket(part)
Pattern.prototype.draftFrontPocketFacing = (part) => draftFrontPocketFacing(part) Pattern.prototype.draftFrontPocketFacing = (part) => draftFrontPocketFacing(part)
Pattern.prototype.draftBackPocket = (part) => draftBackPocket(part) Pattern.prototype.draftBackPocket = (part) => draftBackPocket(part)
Pattern.prototype.draftBackPocketFacing = (part) => draftBackPocketFacing(part) Pattern.prototype.draftBackPocketFacing = (part) => draftBackPocketFacing(part)
Pattern.prototype.draftBackPocketInterfacing = (part) => draftBackPocketInterfacing(part)
Pattern.prototype.draftBackPocketJet = (part) => draftBackPocketJet(part) Pattern.prototype.draftBackPocketJet = (part) => draftBackPocketJet(part)
Pattern.prototype.draftFlyFacing = (part) => draftFlyFacing(part) Pattern.prototype.draftFlyFacing = (part) => draftFlyFacing(part)
Pattern.prototype.draftFlyExtention = (part) => draftFlyExtention(part) Pattern.prototype.draftFlyExtension = (part) => draftFlyExtension(part)
Pattern.prototype.draftBeltLoop = (part) => draftBeltLoop(part) Pattern.prototype.draftBeltLoops = (part) => draftBeltLoops(part)
export default Pattern export default Pattern

View file

@ -1,87 +0,0 @@
export default (part) => {
// Shorthand
let {
points,
Point,
paths,
Path,
measurements,
options,
complete,
paperless,
store,
macro,
utils,
snippets,
Snippet,
sa
} = part.shorthand()
if (!options.splitWaistband) return part
points.topLeft = new Point(0, 0)
points.top = new Point(measurements.waist * options.waistbandWidth * options.waistbandFactor, 0)
points.topRight = new Point(points.top.x * 2, 0)
points.bottomLeft = new Point(
0,
store.get('waistbandBack') + store.get('waistbandFront') + store.get('waistbandFly')
)
points.bottom = new Point(points.top.x, points.bottomLeft.y)
points.bottomRight = new Point(points.topRight.x, points.bottomLeft.y)
paths.saBase = new Path()
.move(points.topLeft)
.line(points.topRight)
.line(points.bottomRight)
.setRender(false)
paths.seam = paths.saBase
.clone()
.line(points.bottomLeft)
.line(points.topLeft)
.close()
.attr('class', 'fabric')
.setRender(true)
if (complete) {
points.flyNotchRight = points.topRight.shift(-90, store.get('waistbandFly'))
points.flyNotchLeft = new Point(0, points.flyNotchRight.y)
points.firstSideNotchRight = points.flyNotchRight.shift(-90, store.get('waistbandFront'))
points.firstSideNotchLeft = new Point(0, points.firstSideNotchRight.y)
macro('sprinkle', {
snippet: 'notch',
on: ['flyNotchRight', 'flyNotchLeft', 'firstSideNotchRight', 'firstSideNotchLeft', 'bottom']
})
points.titleAnchor = points.top.shiftFractionTowards(points.bottom, 0.25)
points.logoAnchor = points.top.shiftFractionTowards(points.bottom, 0.75)
macro('title', {
at: points.titleAnchor,
nr: '3a',
title: 'waistbandButtonSide',
rotation: 90
})
macro('grainline', {
from: points.firstSideNotchLeft,
to: points.firstSideNotchRight
})
snippets.logo = new Snippet('logo', points.logoAnchor)
paths.fold = new Path().move(points.top).line(points.bottom).attr('class', 'fabric help')
if (sa) {
paths.sa = paths.saBase
.offset(sa * -1)
.join(
new Path()
.move(points.bottomRight)
.line(points.bottomLeft)
.line(points.topLeft)
.offset(sa * -2)
)
.close()
.attr('class', 'fabric sa')
}
if (paperless) {
}
}
return part
}

View file

@ -1,81 +0,0 @@
export default (part) => {
// Shorthand
let {
points,
Point,
paths,
Path,
measurements,
options,
complete,
paperless,
store,
macro,
utils,
snippets,
Snippet,
sa
} = part.shorthand()
if (!options.splitWaistband) return part
points.topLeft = new Point(0, 0)
points.top = new Point(measurements.waist * options.waistbandWidth * options.waistbandFactor, 0)
points.topRight = new Point(points.top.x * 2, 0)
points.bottomLeft = new Point(0, store.get('waistbandFront') + store.get('waistbandBack'))
points.bottom = new Point(points.top.x, points.bottomLeft.y)
points.bottomRight = new Point(points.topRight.x, points.bottomLeft.y)
paths.saBase = new Path()
.move(points.topRight)
.line(points.bottomRight)
.line(points.bottomLeft)
.setRender(false)
paths.seam = paths.saBase
.clone()
.line(points.topLeft)
.close()
.attr('class', 'fabric')
.setRender(true)
if (complete) {
points.firstSideNotchRight = points.topRight.shift(-90, store.get('waistbandBack'))
points.firstSideNotchLeft = new Point(0, points.firstSideNotchRight.y)
macro('sprinkle', {
snippet: 'notch',
on: ['firstSideNotchRight', 'firstSideNotchLeft', 'top']
})
points.titleAnchor = points.top.shiftFractionTowards(points.bottom, 0.25)
points.logoAnchor = points.top.shiftFractionTowards(points.bottom, 0.75)
macro('title', {
at: points.titleAnchor,
nr: '3b',
title: 'waistbandButtonholeSide',
rotation: 90
})
macro('grainline', {
from: points.firstSideNotchLeft,
to: points.firstSideNotchRight
})
snippets.logo = new Snippet('logo', points.logoAnchor)
paths.fold = new Path().move(points.top).line(points.bottom).attr('class', 'fabric help')
if (sa) {
paths.sa = paths.saBase
.offset(sa * -1)
.join(
new Path()
.move(points.bottomLeft)
.line(points.topLeft)
.line(points.topRight)
.offset(sa * -2)
)
.close()
.attr('class', 'fabric sa')
}
if (paperless) {
}
}
return part
}

View file

@ -17,10 +17,8 @@ export default (part) => {
sa sa
} = part.shorthand() } = part.shorthand()
if (options.splitWaistband) return part
points.topLeft = new Point(0, 0) points.topLeft = new Point(0, 0)
points.top = new Point(measurements.waist * options.waistbandWidth * options.waistbandFactor, 0) points.top = new Point(options.waistbandWidth, 0)
points.topRight = new Point(points.top.x * 2, 0) points.topRight = new Point(points.top.x * 2, 0)
points.bottomLeft = new Point( points.bottomLeft = new Point(
0, 0,
@ -55,7 +53,7 @@ export default (part) => {
points.logoAnchor = points.top.shiftFractionTowards(points.bottom, 0.6) points.logoAnchor = points.top.shiftFractionTowards(points.bottom, 0.6)
macro('title', { macro('title', {
at: points.titleAnchor, at: points.titleAnchor,
nr: 10, nr: 11,
title: 'waistband', title: 'waistband',
rotation: 90 rotation: 90
}) })