diff --git a/.github/workflows/tests.charlie.yml b/.github/workflows/tests.charlie.yml
index 7ab9496c1c3..877ebb46f6d 100644
--- a/.github/workflows/tests.charlie.yml
+++ b/.github/workflows/tests.charlie.yml
@@ -23,7 +23,7 @@ jobs:
env:
CI: true
- 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:
CI: true
- name: Build pattern
diff --git a/packages/charlie/CHANGELOG.md b/packages/charlie/CHANGELOG.md
index 4c276f600af..b0669d9ac51 100644
--- a/packages/charlie/CHANGELOG.md
+++ b/packages/charlie/CHANGELOG.md
@@ -1,6 +1,12 @@
# 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.
diff --git a/packages/charlie/README.md b/packages/charlie/README.md
index 106618d22ed..3a15cf6b71d 100644
--- a/packages/charlie/README.md
+++ b/packages/charlie/README.md
@@ -1,4 +1,4 @@
-
+
+
-## What am I looking at? 🤔
-
-This repository is our *monorepo* holding [all our NPM packages](https://www.npmjs.com/search?q=keywords:freesewing).
-This folder holds **@freesewing/charlie**
+# @freesewing/charlie
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 💀
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
-for parametric design of sewing patterns. It's a modular system (check our list
-of [plugins](https://freesewing.dev/reference/plugins/) and getting started is as simple as:
+for parametric design of sewing patterns. But we also provide 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
-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
-entrypoint to our documentation, but you'll find a lot more there, including
-our [API reference](https://freesewing.dev/reference/api/),
-as well as [our turorial](https://freesewing.dev/tutorials/pattern-design/),
-and [howtos](https://freesewing.dev/howtos/).
+Or, consult our getting started guides
+for [Linux](https://freesewing.dev/tutorials/getting-started-linux/),
+[MacOS](https://freesewing.dev/tutorials/getting-started-mac/),
+or [Windows](https://freesewing.dev/tutorials/getting-started-windows/).
-If you're a maker, checkout [freesewing.org](https://freesewing/) where you can generate
-our sewing patterns adapted to your measurements.
+We also have a [pattern design tutorial](https://freesewing.dev/tutorials/pattern-design/) that
+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 🥰
FreeSewing is an open source project run by a community,
and financially supported by our patrons.
-If you feel what we do is worthwhile, you too
-should [become a patron](https://freesewing.org/patrons/join).
+If you feel what we do is worthwhile, and you can spend a few coind without
+hardship, then you should [join us and become a patron](https://freesewing.org/community/join).
## Links 👩💻
- 💻 Makers website: [freesewing.org](https://freesewing.org)
- 💻 Developers website: [freesewing.dev](https://freesewing.dev)
- 💬 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)
- 📷 Instagram: [@freesewing_org](https://instagram.com/freesewing_org)
diff --git a/packages/charlie/config/index.js b/packages/charlie/config/index.js
index 453d9029bd8..9f553ceb461 100644
--- a/packages/charlie/config/index.js
+++ b/packages/charlie/config/index.js
@@ -11,7 +11,7 @@ export default {
tags: ['bottom', 'basics'],
optionGroups: {
fit: ['seatEase', 'kneeEase', 'waistEase'],
- style: ['waistHeight', 'lengthBonus', 'crotchDrop'],
+ style: ['waistHeight', 'waistbandWidth', 'lengthBonus', 'crotchDrop'],
pockets: [
{
backPockets: [
@@ -43,6 +43,7 @@ export default {
'grainlinePosition',
'legBalance',
'waistBalance',
+ 'beltLoops',
{
fly: ['flyCurve', 'flyLength', 'flyWidth']
}
@@ -69,17 +70,17 @@ export default {
frontPocket: 'front',
frontPocketFacing: 'frontPocket',
backPocketFacing: 'backPocket',
+ backPocketInterfacing: 'backPocket',
backPocketJet: 'backPocketFacing',
flyFacing: 'front',
- flyExtention: 'flyFacing'
+ flyExtension: 'flyFacing'
},
- parts: ['beltLoop'],
+ parts: ['beltLoops'],
dependencies: {
// The inheritance makes this a bit messy
+ titanFront: 'titanBack',
back: ['titanBack', 'titanFront', 'front'],
- waistband: ['titanBack', 'titanFront', 'front', 'back'],
- waistbandButtonSide: 'waistband',
- waistbandButtonholeSide: 'waistband'
+ waistband: ['titanBack', 'titanFront', 'front', 'back']
},
options: {
// Constants (from Titan)
@@ -87,12 +88,11 @@ export default {
fitCrossSeam: true,
fitCrossSeamFront: true,
fitCrossSeamBack: true,
-
// Lock titan options
fitKnee: true,
// Charlie constants
- waistbandReduction: 0.3, // See src/index.js
+ waistbandReduction: 0.25, // See src/index.js
waistbandFactor: 0.1,
// Fit (from Titan)
@@ -101,7 +101,8 @@ export default {
kneeEase: { pct: 15, min: 10, max: 30 },
// 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 },
crotchDrop: { pct: 2, min: 0, max: 15 },
@@ -133,9 +134,6 @@ export default {
frontPocketWidth: { pct: 55, min: 45, max: 65 },
frontPocketDepth: { pct: 100, min: 85, max: 110 },
- // Belt
- waistbandWidth: { mm: 25, min: 5, max: 45 },
-
// Fly
flyCurve: { pct: 72, min: 50, max: 100 },
flyLength: { pct: 45, min: 30, max: 60 },
@@ -143,6 +141,7 @@ export default {
// Waistband
splitWaistband: { bool: false },
- waistbandWidth: { pct: 40, min: 25, max: 65 }
+ waistbandWidth: { mm: 40, min: 20, max: 60 },
+ beltLoops: { count: 8, min: 6, max: 12 }
}
}
diff --git a/packages/charlie/example/package.json b/packages/charlie/example/package.json
index 56a47b3bc4f..0f82bb75aaf 100644
--- a/packages/charlie/example/package.json
+++ b/packages/charlie/example/package.json
@@ -15,21 +15,20 @@
"@freesewing/mui-theme": "latest",
"@freesewing/pattern-info": "latest",
"@freesewing/plugin-bundle": "latest",
- "@freesewing/plugin-buttons": "^2.14.0",
+ "@freesewing/plugin-theme": "latest",
"@freesewing/plugin-i18n": "latest",
"@freesewing/plugin-svgattr": "latest",
- "@freesewing/plugin-theme": "latest",
"@freesewing/utils": "latest",
"@material-ui/core": "^4.11.2",
"@material-ui/icons": "^4.11.2",
"@material-ui/lab": "^v4.0.0-alpha.57",
- "file-saver": "^2.0.5",
"pattern": "link:..",
"prismjs": "1.22.0",
"react": "^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": {
"start": "react-scripts start",
diff --git a/packages/charlie/example/src/index.js b/packages/charlie/example/src/index.js
index 9dd7ba788d4..24aefad45a1 100644
--- a/packages/charlie/example/src/index.js
+++ b/packages/charlie/example/src/index.js
@@ -2,6 +2,7 @@ import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
import * as serviceWorker from './serviceWorker'
+import './layout.css'
ReactDOM.render(, document.getElementById('root'))
diff --git a/packages/charlie/example/src/layout.css b/packages/charlie/example/src/layout.css
new file mode 100644
index 00000000000..94c9ddf0649
--- /dev/null
+++ b/packages/charlie/example/src/layout.css
@@ -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;
+ }
+}
diff --git a/packages/charlie/package.json b/packages/charlie/package.json
index 8e90f4be675..8564f7959b7 100644
--- a/packages/charlie/package.json
+++ b/packages/charlie/package.json
@@ -1,6 +1,6 @@
{
"name": "@freesewing/charlie",
- "version": "2.12.2",
+ "version": "2.14.0",
"description": "A FreeSewing pattern for chino trousers",
"author": "Joost De Cock (https://github.com/joostdecock)",
"homepage": "https://freesewing.org/",
@@ -34,8 +34,8 @@
"testci": "BABEL_ENV=production ./node_modules/.bin/_mocha tests/*.test.js --require @babel/register"
},
"peerDependencies": {
- "@freesewing/core": "^2.12.1",
- "@freesewing/plugin-bundle": "^2.12.1"
+ "@freesewing/core": "^2.14.0",
+ "@freesewing/plugin-bundle": "^2.14.0"
},
"dependencies": {},
"devDependencies": {
@@ -46,14 +46,14 @@
"eslint": "^7.6.0",
"babel-jest": "^26.2.2",
"jest": "26.2.2",
- "@freesewing/components": "^2.12.1",
- "@freesewing/css-theme": "^2.12.1",
- "@freesewing/i18n": "^2.12.1",
- "@freesewing/mui-theme": "^2.12.1",
- "@freesewing/plugin-bust": "^2.12.1",
- "@freesewing/plugin-buttons": "^2.12.1",
- "@freesewing/plugin-flip": "^2.12.1",
- "@freesewing/utils": "^2.12.1",
+ "@freesewing/components": "^2.14.0",
+ "@freesewing/css-theme": "^2.14.0",
+ "@freesewing/i18n": "^2.14.0",
+ "@freesewing/mui-theme": "^2.14.0",
+ "@freesewing/plugin-bust": "^2.14.0",
+ "@freesewing/plugin-buttons": "^2.14.0",
+ "@freesewing/plugin-flip": "^2.14.0",
+ "@freesewing/utils": "^2.14.0",
"@svgr/rollup": "^2.4.1",
"cross-env": "^7.0.2",
"react-scripts": "^3.4.1",
diff --git a/packages/charlie/src/back-pocket-facing.js b/packages/charlie/src/back-pocket-facing.js
index f2fd84b8695..e69266244e8 100644
--- a/packages/charlie/src/back-pocket-facing.js
+++ b/packages/charlie/src/back-pocket-facing.js
@@ -42,7 +42,7 @@ export default (part) => {
points.titleAnchor = points.rightNotch.shiftFractionTowards(points.leftNotch, 0.5)
macro('title', {
at: points.titleAnchor,
- nr: 5,
+ nr: 6,
title: 'backPocketBagFacing'
})
points.grainlineTop = points.waistbandLeft.shiftFractionTowards(points.waistbandRight, 0.15)
diff --git a/packages/charlie/src/back-pocket-interfacing.js b/packages/charlie/src/back-pocket-interfacing.js
new file mode 100644
index 00000000000..d053135104e
--- /dev/null
+++ b/packages/charlie/src/back-pocket-interfacing.js
@@ -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
+}
diff --git a/packages/charlie/src/back-pocket-jet.js b/packages/charlie/src/back-pocket-jet.js
index bcff6ddf4e1..a1729b47869 100644
--- a/packages/charlie/src/back-pocket-jet.js
+++ b/packages/charlie/src/back-pocket-jet.js
@@ -45,7 +45,7 @@ export default (part) => {
points.titleAnchor = points.rightNotch.shiftFractionTowards(points.leftNotch, 0.5)
macro('title', {
at: points.titleAnchor,
- nr: 3,
+ nr: 4,
title: 'backPocketJet',
scale: 0.5
})
diff --git a/packages/charlie/src/back-pocket.js b/packages/charlie/src/back-pocket.js
index 9ddd3e6a9d6..fd7d2b42245 100644
--- a/packages/charlie/src/back-pocket.js
+++ b/packages/charlie/src/back-pocket.js
@@ -56,7 +56,7 @@ export default (part) => {
points.titleAnchor = points.rightNotch.shiftFractionTowards(points.foldLeft, 0.5)
macro('title', {
at: points.titleAnchor,
- nr: 4,
+ nr: 5,
title: 'backPocketBag'
})
points.logoAnchor = points.foldLeft.shiftFractionTowards(points.bottomRight, 0.5)
diff --git a/packages/charlie/src/back.js b/packages/charlie/src/back.js
index fa71facae32..18e6da43eaa 100644
--- a/packages/charlie/src/back.js
+++ b/packages/charlie/src/back.js
@@ -2,22 +2,15 @@ export default (part) => {
// Helper method to draw the outseam path
const drawOutseam = () => {
let waistOut = points.styleWaistOut || points.waistOut
- if (points.waistOut.x > points.seatOut.x) {
- let outseam = new Path()
- .move(points.styleWaistOut)
- .curve(points.seatOut, points.kneeOutCp2, points.floorOut)
- return new Path()
- .move(points.slantOut)
- .line(points.slantCurveStart)
- .curve(points.slantCurveCp1, points.slantCurveCp2, points.slantCurveEnd)
- .join(outseam.split(points.slantCurveEnd).pop())
- .reverse()
- } else {
- return new Path()
- .move(points.floorOut)
- .curve(points.kneeOutCp2, points.seatOutCp1, points.seatOut)
- .curve_(points.seatOutCp2, waistOut)
- }
+ let outseam = new Path()
+ .move(points.styleWaistOut)
+ .curve(points.seatOut, points.kneeOutCp2, points.floorOut)
+ return new Path()
+ .move(points.slantOut)
+ .line(points.slantCurveStart)
+ .curve(points.slantCurveCp1, points.slantCurveCp2, points.slantCurveEnd)
+ .join(outseam.split(points.slantCurveEnd).pop())
+ .reverse()
}
/*
* Helper method to draw the outline path
@@ -88,10 +81,11 @@ export default (part) => {
.move(points.styleWaistOut)
.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
- 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'))
// Shape waist
@@ -165,6 +159,19 @@ export default (part) => {
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) {
paths.sa = paths.saBase
.offset(sa)
diff --git a/packages/charlie/src/beltloop.js b/packages/charlie/src/beltloop.js
deleted file mode 100644
index 63314aa89b2..00000000000
--- a/packages/charlie/src/beltloop.js
+++ /dev/null
@@ -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
-}
diff --git a/packages/charlie/src/beltloops.js b/packages/charlie/src/beltloops.js
new file mode 100644
index 00000000000..241a353a908
--- /dev/null
+++ b/packages/charlie/src/beltloops.js
@@ -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
+}
diff --git a/packages/charlie/src/fly-extention.js b/packages/charlie/src/fly-extension.js
similarity index 99%
rename from packages/charlie/src/fly-extention.js
rename to packages/charlie/src/fly-extension.js
index d26538d823b..430ba4218ed 100644
--- a/packages/charlie/src/fly-extention.js
+++ b/packages/charlie/src/fly-extension.js
@@ -56,7 +56,7 @@ export default (part) => {
points.titleAnchor = points.flyCurveStart
macro('title', {
at: points.titleAnchor,
- nr: 9,
+ nr: 10,
title: 'flyExtention'
})
if (sa)
diff --git a/packages/charlie/src/fly-facing.js b/packages/charlie/src/fly-facing.js
index e5137f62a99..dd744d30614 100644
--- a/packages/charlie/src/fly-facing.js
+++ b/packages/charlie/src/fly-facing.js
@@ -45,7 +45,7 @@ export default (part) => {
points.titleAnchor = points.grainlineTop.shiftFractionTowards(points.grainlineBottom, 0.5)
macro('title', {
at: points.titleAnchor,
- nr: 8,
+ nr: 9,
title: 'flyFacing'
})
if (sa)
diff --git a/packages/charlie/src/front-pocket-facing.js b/packages/charlie/src/front-pocket-facing.js
index 7eb53e3a79f..b70ed9f4037 100644
--- a/packages/charlie/src/front-pocket-facing.js
+++ b/packages/charlie/src/front-pocket-facing.js
@@ -41,7 +41,7 @@ export default (part) => {
points.titleAnchor = points.slantBottomNotch.shift(0, 10)
macro('title', {
at: points.titleAnchor,
- nr: 7,
+ nr: 8,
title: 'frontPocketBagFacing'
})
macro('grainline', {
diff --git a/packages/charlie/src/front-pocket.js b/packages/charlie/src/front-pocket.js
index 2398db5b60a..fa553699f93 100644
--- a/packages/charlie/src/front-pocket.js
+++ b/packages/charlie/src/front-pocket.js
@@ -28,9 +28,15 @@ export default (part) => {
'slantTop',
'slantBottom',
'slantTop',
+ 'pocketbagBottomCp1',
'pocketbagBottomCp2',
'pocketbagBottom',
- 'pocketbagBottomRight'
+ 'pocketbagBottomRight',
+ 'pocketFacingBottom',
+ 'slantCurveStart',
+ 'slantCurveCp1',
+ 'slantCurveCp2',
+ 'slantCurveEnd'
])
points[id] = points[id].rotate(-1 * (slant - 90), points.pocketbagTopRight)
@@ -61,7 +67,7 @@ export default (part) => {
)
macro('title', {
at: points.titleAnchor,
- nr: 6,
+ nr: 7,
title: 'frontPocketBag'
})
macro('cutonfold', {
diff --git a/packages/charlie/src/front.js b/packages/charlie/src/front.js
index 5f48877afa3..df1efc0bca3 100644
--- a/packages/charlie/src/front.js
+++ b/packages/charlie/src/front.js
@@ -67,11 +67,15 @@ export default (part) => {
points.styleWaistIn,
1 - options.flyWidth
)
+
points.flyCorner = points.flyTop.shift(
points.styleWaistIn.angle(points.crotchSeamCurveStart),
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.flyCurveCp2 = points.flyCurveStart.shiftFractionTowards(points.flyCorner, options.flyCurve)
@@ -185,15 +189,6 @@ export default (part) => {
.attr('class', 'dashed')
.attr('data-text', 'Left panel only')
.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()
.move(points.slantTop)
.line(points.slantCurveStart)
@@ -205,6 +200,25 @@ export default (part) => {
.line(points.pocketFacingBottom)
.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) {
paths.sa = drawPath()
.offset(sa)
diff --git a/packages/charlie/src/index.js b/packages/charlie/src/index.js
index aece940da28..02d02235c06 100644
--- a/packages/charlie/src/index.js
+++ b/packages/charlie/src/index.js
@@ -3,42 +3,24 @@ import Titan from '@freesewing/titan'
import plugins from '@freesewing/plugin-bundle'
import mirrorPlugin from '@freesewing/plugin-mirror'
import buttonsPlugin from '@freesewing/plugin-buttons'
+import bartackPlugin from '@freesewing/plugin-bartack'
import config from '../config'
// Parts
import draftBack from './back'
import draftFront from './front'
import draftWaistband from './waistband'
-import draftWaistbandButtonSide from './waistband-button-side'
-import draftWaistbandButtonholeSide from './waistband-buttonhole-side'
import draftFrontPocket from './front-pocket'
import draftFrontPocketFacing from './front-pocket-facing'
import draftBackPocket from './back-pocket'
import draftBackPocketFacing from './back-pocket-facing'
+import draftBackPocketInterfacing from './back-pocket-interfacing'
import draftBackPocketJet from './back-pocket-jet'
import draftFlyFacing from './fly-facing'
-import draftFlyExtention from './fly-extention'
-import draftBeltLoop from './beltloop'
-
-// 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
- }
- }
-}
+import draftFlyExtension from './fly-extension'
+import draftBeltLoops from './beltloops'
// Create design
-const Pattern = new freesewing.Design(config, [
- plugins,
- mirrorPlugin,
- buttonsPlugin,
- waistbandPlugin
-])
+const Pattern = new freesewing.Design(config, [plugins, mirrorPlugin, buttonsPlugin, bartackPlugin])
// Attach titan draft methods to prototype
for (let p of ['Front', 'Back']) {
@@ -51,15 +33,14 @@ for (let p of ['Front', 'Back']) {
Pattern.prototype.draftBack = (part) => draftBack(part)
Pattern.prototype.draftFront = (part) => draftFront(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.draftFrontPocketFacing = (part) => draftFrontPocketFacing(part)
Pattern.prototype.draftBackPocket = (part) => draftBackPocket(part)
Pattern.prototype.draftBackPocketFacing = (part) => draftBackPocketFacing(part)
+Pattern.prototype.draftBackPocketInterfacing = (part) => draftBackPocketInterfacing(part)
Pattern.prototype.draftBackPocketJet = (part) => draftBackPocketJet(part)
Pattern.prototype.draftFlyFacing = (part) => draftFlyFacing(part)
-Pattern.prototype.draftFlyExtention = (part) => draftFlyExtention(part)
-Pattern.prototype.draftBeltLoop = (part) => draftBeltLoop(part)
+Pattern.prototype.draftFlyExtension = (part) => draftFlyExtension(part)
+Pattern.prototype.draftBeltLoops = (part) => draftBeltLoops(part)
export default Pattern
diff --git a/packages/charlie/src/waistband-button-side.js b/packages/charlie/src/waistband-button-side.js
deleted file mode 100644
index 3899c5e1c79..00000000000
--- a/packages/charlie/src/waistband-button-side.js
+++ /dev/null
@@ -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
-}
diff --git a/packages/charlie/src/waistband-buttonhole-side.js b/packages/charlie/src/waistband-buttonhole-side.js
deleted file mode 100644
index 0c5dcb9d307..00000000000
--- a/packages/charlie/src/waistband-buttonhole-side.js
+++ /dev/null
@@ -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
-}
diff --git a/packages/charlie/src/waistband.js b/packages/charlie/src/waistband.js
index 8f6aa7c3aaa..e150168256a 100644
--- a/packages/charlie/src/waistband.js
+++ b/packages/charlie/src/waistband.js
@@ -17,10 +17,8 @@ export default (part) => {
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.top = new Point(options.waistbandWidth, 0)
points.topRight = new Point(points.top.x * 2, 0)
points.bottomLeft = new Point(
0,
@@ -55,7 +53,7 @@ export default (part) => {
points.logoAnchor = points.top.shiftFractionTowards(points.bottom, 0.6)
macro('title', {
at: points.titleAnchor,
- nr: 10,
+ nr: 11,
title: 'waistband',
rotation: 90
})