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:
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

View file

@ -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.

View file

@ -1,4 +1,4 @@
![FreeSewing](https://freesewing.org/banner.jpg)
![FreeSewing](https://static.freesewing.org/banner.png)
<p align='center'><a
href="https://www.npmjs.com/package/@freesewing/charlie"
title="@freesewing/charlie on NPM"
@ -19,6 +19,11 @@
title="Open issues tagged pkg:charlie"
><img src="https://img.shields.io/github/issues/freesewing/freesewing/pkg:charlie.svg?label=Issues"
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
href="https://twitter.com/freesewing_org"
title="Follow @freesewing_org on Twitter"
@ -41,49 +46,62 @@
alt="Follow @freesewing_org on Twitter"/>
</a></p>
## 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)

View file

@ -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 }
}
}

View file

@ -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",

View file

@ -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(<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",
"version": "2.12.2",
"version": "2.14.0",
"description": "A FreeSewing pattern for chino trousers",
"author": "Joost De Cock <joost@decock.org> (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",

View file

@ -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)

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)
macro('title', {
at: points.titleAnchor,
nr: 3,
nr: 4,
title: 'backPocketJet',
scale: 0.5
})

View file

@ -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)

View file

@ -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)

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
macro('title', {
at: points.titleAnchor,
nr: 9,
nr: 10,
title: 'flyExtention'
})
if (sa)

View file

@ -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)

View file

@ -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', {

View file

@ -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', {

View file

@ -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)

View file

@ -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

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
} = 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
})