1
0
Fork 0

tada: Initial commit

This commit is contained in:
Joost De Cock 2019-03-25 18:20:15 +01:00
parent 2d5396c343
commit c0ace10e2d
27 changed files with 5474 additions and 2 deletions

View file

@ -0,0 +1,13 @@
# editorconfig.org
root = true
[*]
indent_size = 2
indent_style = space
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false

64
packages/carlton/.gitignore vendored Normal file
View file

@ -0,0 +1,64 @@
*.php
cnf.yml
dist
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
# next.js build output
.next

View file

@ -0,0 +1,2 @@
src
.editorconfig

21
packages/carlton/LICENSE Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018 Joost De Cock
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -1,2 +1,27 @@
# carlton
Port of the freesewing Carlton coat pattern to JS
<p align="center">
<a title="Go to freesewing.org" href="https://freesewing.org/"><img src="https://freesewing.org/img/logo/black.svg" align="center" width="150px" alt="Freesewing logo"/></a>
</p>
<h4 align="center"><em>&nbsp;<a title="Go to freesewing.org" href="https://freesewing.org/">freesewing</a></em>
<br><sup>a library for made-to-measure sewing patterns</sup>
</h4>
<p align="center">
<a href="https://www.npmjs.com/package/@freesewing/carlton"><img src="https://badgen.net/npm/v/@freesewing/carlton" alt="Version"></a>
<a href="https://www.npmjs.com/package/@freesewing/carlton"><img src="https://badgen.net/npm/license/@freesewing/carlton" alt="License"></a>
<a href="https://deepscan.io/dashboard#view=project&tid=2114&pid=4633&bid=37171"><img src="https://deepscan.io/api/teams/2114/projects/4633/branches/37171/badge/grade.svg" alt="DeepScan grade"></a>
<a href="https://gitter.im/freesewing/freesewing"><img src="https://badgen.net/badge/chat/on%20Gitter/cyan" alt="Chat on Gitter"></a>
<a href="https://freesewing.org/patrons/join"><img src="https://badgen.net/badge/become/a%20Patron/FF5B77" alt="Become a Patron"></a>
</p>
# freesewing / patterns / carlton
Carlton is a [freesewing](https://github.com/freesewing/freesewing) pattern
for Sherlock Holmes cosplay, or just a really nice coat.
See [freesewing.org/patterns/carlton](https://freesewing.org/patterns/carlton)
for more info and examples.
## Install
```
npm i --save @freesewing/carlton
```

View file

@ -0,0 +1,122 @@
import { version } from "../package.json";
export default {
name: "carlton",
version: version,
measurements: [
"bicepsCircumference",
"centerBackNeckToWaist",
"chestCircumference",
"hipsCircumference",
"naturalWaist",
"naturalWaistToHip",
"neckCircumference",
"shoulderSlope",
"shoulderToElbow",
"shoulderToShoulder",
"shoulderToWrist",
"wristCircumference",
"naturalWaistToFloor",
"naturalWaistToSeat",
"seatCircumference"
],
dependencies: {
bentBack: "bentBase",
bentFront: "bentBack",
bentTopSleeve: "bentSleeve",
bentUnderSleeve: "bentSleeve",
front: "bentFront",
back: "bentBack",
tail: ["front", "back"],
topSleeve: "bentTopSleeve",
underSleeve: "bentUnderSleeve",
belt: "back",
collarStand: ["front", "back"],
collar: "collarStand",
cuffFacing: ["topSleeve", "underSleeve"],
pocket: "front",
pocketFlap: "front",
chestPocketWelt: "front",
innerPocketWelt: "front",
innerPocketBag: "front",
innerPocketTab: "front",
},
inject: {
bentBack: "bentBase",
bentFront: "bentBack",
bentTopSleeve: "bentSleeve",
bentUnderSleeve: "bentSleeve",
front: "bentFront",
back: "bentBack",
topSleeve: "bentTopSleeve",
underSleeve: "bentUnderSleeve",
collar: "collarStand",
},
hide: [
"bentBase",
"bentBack",
"bentFront",
"bentSleeve",
"bentTopSleeve",
"bentUnderSleeve",
],
//parts: ["collar"],
options: {
// Constants
brianFitSleeve: true,
brianFitCollar: true,
collarFactor: 4.8,
chestShapingMax: 5,
backPleat: 0.048,
lengthBonus: 0,
collarEase: 0.145,
// Options inherited from Bent
acrossBackFactor: { pct: 97, min: 93, max: 100 },
armholeDepthFactor: { pct: 65, min: 50, max: 70 },
bicepsEase: { pct: 20, min: 0, max: 50 },
chestEase: { pct: 10, min: 5, max: 20 },
cuffEase: { pct: 60, min: 30, max: 100 },
shoulderEase: { pct: 0, min: -2, max: 6 },
sleeveBend: { deg: 10, min: 0, max: 20 },
sleevecapHeight: {pct: 45, min: 40, max: 60 },
sleevecapEase: { pct: 1, min: 0, max: 10 },
sleeveLengthBonus: { pct: 0, min:-40, max: 10 },
shoulderSlopeReduction: { pct: 2, min: 0, max: 5 },
// FIXME: Are these used?
backNeckCutout: { pct: 5, min: 2, max: 8 },
frontArmholeDeeper: { pct: 0.5, min: 0, max: 1.5 },
// Carlton options
waistEase: { pct: 14, min: 8, max: 25 },
seatEase: { pct: 14, min: 8, max: 25 },
/** Length as a factor from waist to floor */
length: { pct: 69, min: 35, max: 100 },
/** Horizontal button spacing as a percentage of the quarter waist */
buttonSpacingHorizontal: {pct: 43.5, min: 15, max: 60 },
frontOverlap: { pct: 1.5, min: 1, max: 2},
lapelReduction: { pct: 5, min: 0, max: 10 },
pocketPlacementHorizontal: {pct: 11, min: 5, max: 60 },
pocketPlacementVertical: {pct: 6, min: 5, max: 60 },
pocketWidth: {pct: 95, min: 40, max: 60},
pocketHeight: {pct: 15, min: 0, max: 80},
pocketRadius: {pct: 20, min: 0, max: 50},
pocketFlapRadius: {pct: 15, min: 0, max: 50},
chestPocketHeight: {pct: 60, min: 40, max: 80},
chestPocketWidth: {pct: 25, min: 10, max: 50},
chestPocketPlacement: {pct: 55, min: 30, max: 65},
chestPocketAngle: {deg: 4, min: 0, max: 6},
innerPocketPlacement: {pct: 53, min: 42, max: 62 },
innerPocketWidth: { pct: 50, min: 45, max: 65 },
innerPocketDepth: { pct: 110, min: 75, max: 140 },
innerPocketWeltHeight: { pct: 3.5, min: 2.5, max: 5 },
beltWidth: { pct: 15, min: 10, max: 20 },
cuffLength: { pct: 15, min: 10, max: 20 },
collarHeight: {pct: 9.6, min: 8, max: 11 },
collarSpread: {deg: 4, min: 2, max: 6 },
collarFlare: {pct: 20, min: 0, max: 40 },
}
};

View file

@ -0,0 +1,88 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Carlton</title>
<style>
.two {
display: inline-block;
max-width: 95%;
margin: auto;
}
</style>
</head>
<body>
<div id="svg"></div>
<div id="svg1" class="two"></div>
<div id="svg2" class="two"></div>
<script type="text/javascript" src="../../freesewing/dist/browser.js"></script>
<script type="text/javascript" src="../bent/dist/browser.js"></script>
<script type="text/javascript" src="node_modules/@freesewing/plugin-bundle/dist/browser.js"></script>
<script type="text/javascript" src="dist/browser.js"></script>
<script type="text/javascript" src="node_modules/@freesewing/plugin-theme/dist/browser.js"></script>
<script type="text/javascript" src="node_modules/@freesewing/plugin-designer/dist/browser.js"></script>
<script type="text/javascript" src="node_modules/@freesewing/plugin-debug/dist/browser.js"></script>
<script type="text/javascript" src="../../plugins/plugin-validate/dist/browser.js"></script>
<script type="text/javascript" src="node_modules/@freesewing/plugin-i18n/dist/browser.js"></script>
<script type="text/javascript" src="node_modules/@freesewing/models/dist/browser.js"></script>
<script>
let settings = {
"complete": true,
"idPrefix": "fs-",
"locale": "en",
"options": {
"frontStyle": "rounded",
//"hemStyle": "rounded",
},
//"embed": true,
"sa": 0,
//"paperless": true,
"measurements": {
"bicepsCircumference": 350,
"centerBackNeckToWaist": 560,
"chestCircumference": 1060,
"hipsCircumference": 990,
"naturalWaist": 930,
"naturalWaistToHip": 150,
"neckCircumference": 390,
"shoulderSlope": 55,
"shoulderToShoulder": 470,
"shoulderToWrist": 650,
"wristCircumference": 180,
"shoulderToElbow": 410,
"headCircumference": 590,
"naturalWaistToFloor": 1310,
"naturalWaistToSeat": 280,
"seatCircumference": 1130
},
};
var pattern = new freesewing.patterns.carlton(settings);
pattern.use(freesewing.plugins.theme);
pattern.use(freesewing.plugins.designer);
pattern.use(freesewing.plugins.validate);
pattern.draft();
//pattern.sampleOption("collarFlare");
document.getElementById("svg1").innerHTML = pattern.render();
function pointHover(evt) {
var point = evt.target;
var id = point.id;
var cx = point.getAttribute('x');
var cy = point.getAttribute('y');
var name = point.getAttribute('data-point');
var part = point.getAttribute('data-part');
console.log(name+' ('+cx+', '+cy+') @ '+part);
var scale = 2;
cx = cx-scale*cx;
cy = cy-scale*cy;
point.setAttribute("transform", 'matrix('+scale+', 0, 0, '+scale+', '+cx+', '+cy+')');
pointUnhover(id);
}
function pointUnhover(id) {
setTimeout(function(){
document.getElementById(id).removeAttribute("transform", '');
}, 500);
}
</script>
</body>
</html>

3844
packages/carlton/package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,81 @@
{
"version": "0.0.1",
"name": "@freesewing/carlton",
"description": "Freesewing pattern for Sherlock Holmes cosplay, or just a nice long coat",
"author": "Joost De Cock <joost@decock.org> (https://github.com/joostdecock)",
"license": "MIT",
"homepage": "https://github.com/freesewing/carlton#readme",
"repository": "github:freesewing/carlton",
"bugs": {
"url": "https://github.com/freesewing/carlton/issues"
},
"keywords": [
"freesewing",
"pattern",
"coat",
"sewing"
],
"main": "dist/index.js",
"module": "dist/index.mjs",
"unpkg": "dist/browser.js",
"scripts": {
"precommit": "npm run pretty && lint-staged",
"patch": "npm version patch -m ':bookmark: v%s' && npm run build",
"minor": "npm version minor -m ':bookmark: v%s' && npm run build",
"major": "npm version major -m ':bookmark: v%s' && npm run build",
"test": "echo \"Error: no test specified\" && exit 1",
"clean": "rimraf dist",
"pretty": "npx prettier --write 'src/*.js'",
"lint": "eslint --fix 'src/*.js'",
"watch": "nodemon -w src -w config --exec 'rollup -c rollup.js -o dist/browser.js -f iife -m true -n freesewing_patterns_carlton --footer \"freesewing.patterns.carlton = freesewing_patterns_carlton;\"'",
"browserbuild": "rollup -c rollup.js -o dist/browser.js -f iife -m true -n freesewing_patterns_carlton --footer 'freesewing.patterns.carlton = freesewing_patterns_carlton;'",
"nodebuild": "rollup -c rollup.js -o dist/index.js -f cjs -m true",
"modulebuild": "rollup -c rollup.js -o dist/index.mjs -f es -m true",
"build": "npm run clean && npm run browserbuild && npm run nodebuild && npm run modulebuild"
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"*.{js,json}": [
"prettier --write",
"git add"
]
},
"dependencies": {
"@freesewing/bent": "0.1.2",
"@freesewing/plugin-bundle": "0.8.0",
"@freesewing/plugin-buttons": "latest",
"freesewing": "latest"
},
"devDependencies": {
"@babel/core": "7.4.0",
"@freesewing/antman": "latest",
"@freesewing/models": "latest",
"@freesewing/plugin-debug": "latest",
"@freesewing/plugin-designer": "latest",
"@freesewing/plugin-i18n": "latest",
"@freesewing/plugin-theme": "latest",
"@freesewing/plugin-validate": "latest",
"eslint": "5.15.3",
"eslint-config-prettier": "latest",
"eslint-plugin-prettier": "latest",
"husky": "latest",
"lint-staged": "latest",
"prettier": "latest",
"rimraf": "latest",
"rollup": "1.7.2",
"rollup-plugin-babel": "latest",
"rollup-plugin-babel-minify": "8.0.0",
"rollup-plugin-json": "4.0.0",
"rollup-plugin-node-resolve": "latest"
},
"files": [
"dist/*",
"README.md",
"package-lock.json",
"package.json"
]
}

View file

@ -0,0 +1,27 @@
import babel from "rollup-plugin-babel";
import resolve from "rollup-plugin-node-resolve";
import json from "rollup-plugin-json";
import minify from "rollup-plugin-babel-minify";
import { name, version, description, author, license } from "./package.json";
export default {
input: "src/index.js",
plugins: [
resolve({ browser: true }),
json(),
babel({ exclude: "node_modules/**" }),
minify({
comments: false,
sourceMap: true,
banner: `/**\n * ${name} | v${version}\n * ${description}\n * (c) ${new Date().getFullYear()} ${author}\n * @license ${license}\n */`
})
],
external: ["freesewing", "@freesewing/bent", "@freesewing/plugin-bundle"],
output: {
globals: {
freesewing: "freesewing",
"@freesewing/bent": "freesewing.patterns.bent",
"@freesewing/plugin-bundle": "freesewing.plugins.bundle"
}
}
};

View file

@ -0,0 +1,88 @@
import { calculateRatios } from "./shared";
export default function(part) {
let { paperless, sa, snippets, Snippet, utils, store, complete, points, measurements, options, macro, Point, paths, Path } = part.shorthand();
calculateRatios(part);
// Belt width
let bw = measurements.centerBackNeckToWaist * options.beltWidth;
store.set("beltWidth", bw);
// Box pleat (bp)
points.bpStart = new Point(0, points.armholePitch.y);
points.bpTop = new Point(
measurements.chestCircumference * options.backPleat * -1,
points.armholePitch.y
);
points.bpBottom = new Point(
points.bpTop.x,
points.cbWaist.y - bw/2
);
points.bpTriangleEdge = points.bpStart.shift(0, points.bpTop.dx(points.bpStart)*0.6);
points.bpTriangleTip = points.bpStart.shift(90, points.bpStart.dx(points.bpTriangleEdge));
// Waist shaping
points.waist = new Point(
store.get("chest")/4 - store.get("waistReduction") / 8,
points.bpBottom.y
);
points.waistCp2 = points.waist.shift(90, points.armhole.dy(points.waist)/3);
points.cbWaist = new Point(0, points.bpBottom.y);
// Dart
points.dartCenter = points.cbWaist.shiftFractionTowards(points.waist, 0.4);
points.dartTip = points.dartCenter.shift(90, points.armhole.dy(points.dartCenter)*0.85);
points.dartRight = points.dartCenter.shift(0, store.get("waistReduction")/8);
points.dartLeft = points.dartRight.flipX(points.dartCenter);
points.dartLeftCp = points.dartLeft.shift(90, points.dartTip.dy(points.dartCenter)*0.6);
points.dartRightCp = points.dartLeftCp.flipX(points.dartCenter);
store.set("cbToDart", points.dartLeft.x);
store.set("dartToSide", points.dartRight.dx(points.waist));
// Back stay (bs)
points.bsCp1 = points.bpStart.shiftFractionTowards(points.armholePitch, 0.5);
points.bsCp2 = points.armhole.shiftFractionTowards(points.cbArmhole, 0.3);
// Store collar length
store.set(
"backCollarLength",
new Path()
.move(points.cbNeck)
._curve(points.neckCp2, points.neck)
.length()
);
// Clean up
for (let i in paths) delete paths[i]
for (let i in snippets) delete snippets[i]
// Paths
paths.seam = new Path()
.move(points.cbNeck)
.line(points.bpStart)
.line(points.bpTop)
.line(points.bpBottom)
.line(points.dartLeft)
.curve_(points.dartLeftCp, points.dartTip)
._curve(points.dartRightCp, points.dartRight)
.line(points.waist)
.curve_(points.waistCp2, points.armhole)
.curve(points.armholeCp2, points.armholeHollowCp1, points.armholeHollow)
.curve(points.armholeHollowCp2, points.armholePitchCp1, points.armholePitch)
.curve(points.armholePitchCp2, points.shoulderCp1, points.shoulder)
.line(points.neck)
.curve_(points.neckCp2, points.cbNeck)
.close()
.attr("class", "fabric");
paths.backStay = new Path()
.move(points.bpStart)
.curve(points.bsCp1, points.bsCp2, points.armhole)
.attr("class", "canvas lashed");
if (complete) {
}
return part;
}

View file

@ -0,0 +1,46 @@
export default function(part) {
let { paperless, sa, snippets, Snippet, utils, store, complete, points, measurements, options, macro, Point, paths, Path } = part.shorthand();
let length = 1.6 * (store.get("cbToDart") + store.get("dartToSide"));
let width = measurements.centerBackNeckToWaist * options.beltWidth;
points.topLeft = new Point(0, 0);
points.topRight = new Point(length, 0);
points.bottomLeft = new Point(0, width);
points.bottomRight = new Point(length, width);
points.button = new Point(width/2, width/2);
macro("round", {
from: points.topRight,
to: points.bottomLeft,
via: points.topLeft,
prefix: "roundTop",
radius: width/4,
render: true
});
macro("round", {
from: points.topLeft,
to: points.bottomRight,
via: points.bottomLeft,
prefix: "roundBottom",
radius: width/4,
render: true
});
// Paths
paths.seam = new Path()
.move(points.roundTopStart)
.curve(points.roundTopCp1, points.roundTopCp2, points.roundTopEnd)
.line(points.roundBottomStart)
.curve(points.roundBottomCp1, points.roundBottomCp2, points.roundBottomEnd)
.line(points.bottomRight)
.line(points.topRight)
.line(points.roundTopStart)
.close()
.attr("class", "fabric");
if (complete) {
snippets.button = new Snippet("button", points.button).attr("data-scale", 2);
}
return part;
}

View file

@ -0,0 +1,41 @@
export default function(part) {
let { paperless, sa, snippets, Snippet, utils, store, complete, points, measurements, options, macro, Point, paths, Path } = part.shorthand();
points.topLeft = new Point(0, 0);
points.bottomRight = new Point(
store.get("chestPocketWidth") * 2,
store.get("chestPocketHeight")
);
points.bottomLeft = new Point(
points.topLeft.x,
points.bottomRight.y
);
points.topRight = new Point(
points.bottomRight.x,
points.topLeft.y
);
points.topMid = new Point(
store.get("chestPocketWidth"),
points.topRight.y
);
points.bottomMid = new Point(
points.topMid.x,
points.bottomRight.y
);
paths.seam = new Path()
.move(points.topLeft)
.line(points.bottomLeft)
.line(points.bottomRight)
.line(points.topRight)
.line(points.topLeft)
.close()
.attr("class", "fabric");
paths.fold = new Path()
.move(points.topMid)
.line(points.bottomMid)
.attr("class", "dashed");
return part;
}

View file

@ -0,0 +1,184 @@
/**
* This collar is the most difficult part about this pattern
* That's because slash&spread is easy with paper and scissors
* but gets complicated when doing it in code.
*/
export default function(part) {
let { paperless, sa, snippets, Snippet, utils, store, complete, points, measurements, options, macro, Point, paths, Path } = part.shorthand();
// We're going to slash and spread this collar. Slashing first:
// Divide top in 5 parts
points.cutTop1 = points.topLeft.shiftFractionTowards(points.topRight, 0.2);
points.cutTop2 = points.topLeft.shiftFractionTowards(points.topRight, 0.4);
points.cutTop3 = points.topLeft.shiftFractionTowards(points.topRight, 0.6);
points.cutTop4 = points.topLeft.shiftFractionTowards(points.topRight, 0.8);
// Divide bottom in 4 parts
let bottom = new Path()
.move(points.standTop)
.curve_(points.standTopCp, points.standTip)
points.cutBottom1 = bottom.shiftFractionAlong(0.25);
points.cutBottom2 = bottom.shiftFractionAlong(0.5);
points.cutBottom3 = bottom.shiftFractionAlong(0.75);
// Split curve, extract control points from ops
let halves = bottom.split(points.cutBottom2);
let quarters = [];
quarters.push(...halves[0].split(points.cutBottom1));
quarters.push(...halves[1].split(points.cutBottom3));
points.q1Cp1 = quarters[0].ops[1].cp1;
points.q1Cp2 = quarters[0].ops[1].cp2;
points.q2Cp1 = quarters[1].ops[1].cp1;
points.q2Cp2 = quarters[1].ops[1].cp2;
points.q3Cp1 = quarters[2].ops[1].cp1;
points.q3Cp2 = quarters[2].ops[1].cp2;
points.q4Cp1 = quarters[3].ops[1].cp1;
points.q4Cp2 = quarters[3].ops[1].cp2;
// Collar slashed, not let's spread by rotating
let rotate = {
1: {
pivot: "cutBottom1",
points: ["cutBottom2", "cutTop1", "cutTop2", "q2Cp1", "q2Cp2"]
},
2: {
pivot: "cutBottom2",
points: ["cutBottom3", "cutTop2", "cutTop3", "q3Cp1", "q3Cp2"]
},
3: {
pivot: "cutBottom3",
points: ["standTip", "bottomRight", "cutTop4", "cutTop3", "q4Cp1"]
},
4: {
pivot: "standTip",
points: ["topRight", "bottomRight", "cutTop4"]
},
};
let angle = -1 * options.collarSpread;
let alsoRotate = [];
for (let nr of [4,3,2,1]) {
let step = rotate[nr];
let pivot = step.pivot;
let first = false;
for (let pnt of step.points) {
if(first === false) first = pnt;
let id = `rot${nr}${pnt}`;
points[id] = points[pnt].rotate(angle, points[pivot]);
alsoRotate.push(id);
}
if(nr <4) for (let pnt of alsoRotate) points[pnt] = points[pnt].rotate(angle, points[pivot]);
}
// Shift panel 2 in place
angle = points.cutBottom2.angle(points.rot1cutBottom2) + 180;
let distance = -1 * points.cutBottom2.dist(points.rot1cutBottom2);
for (let i of [
'cutBottom2',
'rot2cutTop2',
'rot2cutTop3',
'rot2cutBottom3',
'rot2q3Cp1',
'rot2q3Cp2'
]) points[i] = points[i].shift(angle, distance);
// Shift panel 3 in place
angle = points.cutBottom3.angle(points.rot2cutBottom3) + 180;
distance = -1 * points.cutBottom3.dist(points.rot2cutBottom3);
for (let i of [
'cutBottom3',
'rot3cutTop3',
'rot3cutTop4',
'rot3standTip',
'rot3q4Cp1',
]) points[i] = points[i].shift(angle, distance);
// Shift panel 4 in place
angle = points.standTip.angle(points.rot3standTip) + 180;
distance = -1 * points.standTip.dist(points.rot3standTip);
for (let i of [
'standTip',
'rot4cutTop4',
'rot4topRight',
'rot4bottomRight'
]) points[i] = points[i].shift(angle, distance);
// Top control point
points.topLeftCp = points.topLeft.shift(0, points.rot4topRight.x * 0.6);
// Paths
/* Uncomment these paths to gain insight into what's happening here
paths.collarStand = paths.seam.clone(); // Needed because it gets overwritten later
paths.panels = new Path()
.move(points.cutTop1).line(points.cutBottom1)
.move(points.cutTop2).line(points.cutBottom2)
.move(points.cutTop3).line(points.cutBottom3)
.move(points.cutTop4).line(points.standTip)
paths.outline = new Path()
.move(points.bottomLeft)
.curve(points.bottomLeftCp, points.standTipCp, points.standTip)
._curve(points.standTopCp, points.standTop)
.curve_(points.standTopCpLeft, points.standTipLeft)
.curve(points.standTipCpLeft, points.bottomLeftCpLeft, points.bottomLeft)
.close()
.move(points.topLeft)
.line(points.topRight)
.line(points.bottomRight);
paths.panel2 = new Path()
.move(points.cutBottom1)
.line(points.rot1cutBottom2)
.line(points.rot1cutTop2)
.line(points.rot1cutTop1)
.close()
.attr("class", "dashed");
paths.panel3 = new Path()
.move(points.cutBottom2)
.line(points.rot2cutBottom3)
.line(points.rot2cutTop3)
.line(points.rot2cutTop2)
.close()
.attr("class", "dashed");
paths.panel4 = new Path()
.move(points.cutBottom3)
.line(points.rot3standTip)
.line(points.rot3cutTop4)
.line(points.rot3cutTop3)
.close()
.attr("class", "dashed");
paths.panel5 = new Path()
.move(points.standTip)
.line(points.rot4bottomRight)
.line(points.rot4topRight)
.line(points.rot4cutTop4)
.close()
.attr("class", "dashed");
*/
paths.seam = new Path()
.move(points.standTop)
/** This is the non-slashed path. We use this instead of the slashed
* parts of the path, so that we get a smooth line
*/
.curve_(points.standTopCp, points.rot3standTip)
/** These are the slashed parts. We're not using these, but you can change that if you want
* Just uncomment this, and comment out the non-slashed curve operation above
*/
//.curve(points.q1Cp1, points.q1Cp2, points.cutBottom1)
//.curve(points.rot1q2Cp1, points.rot1q2Cp2, points.rot1cutBottom2)
//.curve(points.rot2q3Cp1, points.rot2q3Cp2, points.rot2cutBottom3)
//.curve_(points.rot3q4Cp1, points.rot3standTip)
.line(points.rot4bottomRight)
.line(points.rot4topRight)
._curve(points.topLeftCp, points.topLeft)
.line(points.standTop)
.close()
.attr("class", "fabric");
return part;
}

View file

@ -0,0 +1,30 @@
export default function(part) {
let { paperless, sa, snippets, Snippet, utils, store, complete, points, measurements, options, macro, Point, paths, Path } = part.shorthand();
let height = measurements.chestCircumference * options.collarHeight;
let length = store.get("frontCollarLength") + store.get("backCollarLength");
points.topLeft = new Point(0, 0);
points.bottomLeft = new Point(0, height);
points.topRight = new Point(length, height * -1 * options.collarFlare);
points.bottomRight = new Point(length, height)
points.bottomLeftCp = points.bottomLeft.shift(0, points.bottomRight.x * 0.4);
points.standTop = points.bottomLeft.shiftFractionTowards(points.topLeft, 0.25);
points.standTip = new Point(points.topRight.x * 0.75, points.bottomLeft.y + points.topRight.x/8.5);
points.standTipCp = points.standTip.shift(180, points.standTop.dy(points.bottomLeft));
points.standTopCp = points.standTop.shift(0, points.standTip.x * 0.9);
for (let i of ["standTopCp", "standTip", "standTipCp", "bottomLeftCp"]) {
points[i+"Left"] = points[i].flipX();
}
paths.seam = new Path()
.move(points.bottomLeft)
.curve(points.bottomLeftCp, points.standTipCp, points.standTip)
._curve(points.standTopCp, points.standTop)
.curve_(points.standTopCpLeft, points.standTipLeft)
.curve(points.standTipCpLeft, points.bottomLeftCpLeft, points.bottomLeft)
.close()
.attr("class", "fabric");
return part;
}

View file

@ -0,0 +1,44 @@
export default function(part) {
let { paperless, sa, snippets, Snippet, utils, store, complete, points, measurements, options, macro, Point, paths, Path } = part.shorthand();
points.topLeft = new Point(0, 0);
points.bottomRight = new Point(
store.get("topCuffWidth") + store.get("underCuffWidth"),
store.get("cuffLength") * 1.5
);
points.bottomLeft = new Point(
points.topLeft.x,
points.bottomRight.y
);
points.topRight = new Point(
points.bottomRight.x,
points.topLeft.y
);
macro("round", {
from: points.topLeft,
to: points.bottomRight,
via: points.bottomLeft,
radius: store.get("cuffRadius"),
prefix: "roundLeft"
});
macro("round", {
from: points.bottomLeft,
to: points.topRight,
via: points.bottomRight,
radius: store.get("cuffRadius"),
prefix: "roundRight"
});
paths.seam = new Path()
.move(points.topLeft)
.line(points.roundLeftStart)
.curve(points.roundLeftCp1, points.roundLeftCp2, points.roundLeftEnd)
.line(points.roundRightStart)
.curve(points.roundRightCp1, points.roundRightCp2, points.roundRightEnd)
.line(points.topRight)
.line(points.topLeft)
.close()
.attr("class", "fabric");
return part;
}

View file

@ -0,0 +1,296 @@
import { calculateRatios } from "./shared";
export default function(part) {
let { paperless, sa, snippets, Snippet, utils, store, complete, points, measurements, options, macro, Point, paths, Path } = part.shorthand();
calculateRatios(part);
// Waist shaping
points.waist = points.cfWaist.shift(0, store.get("chest")/4 - store.get("waistReduction")/8);
points.waistCp1 = points.waist.shift(-90, points.waist.dy(points.hips)/2);
points.waistCp2 = points.waist.shift(90, points.armhole.dy(points.waist)/2);
// Seat shaping
points.cfSeat = points.cfWaist.shift(-90, measurements.naturalWaistToSeat);
points.seat = points.cfSeat.shift(0, store.get("seat")/4);
points.seatCp2 = points.seat.shift(90, points.waist.dy(points.seat)/3);
// Hem length
points.cfHem = points.cfWaist.shift(-90, measurements.naturalWaistToFloor * options.length);
points.hem = new Point(
points.seat.x,
points.cfHem.y
);
store.set("waistToHem", points.cfHem.y - points.waist.y);
// Buttonline
let buttonW = points.waist.x * options.buttonSpacingHorizontal;
let buttonH = points.waist.dy(points.hips) / 1.5;
points.button1Left = points.cfHips.shift(180, buttonW / 2);
points.button1Right = points.cfHips.shift(0, buttonW / 2);
points.button2Left = points.button1Left.shift(90, buttonH);
points.button2Right = points.button2Left.shift(0, buttonW);
points.button3Left = points.button2Left.shift(90, buttonH);
points.button3Right = points.button3Left.shift(0, buttonW);
// Front closure edge
points.collarEdge = new Point(
points.button1Left.x - measurements.naturalWaist * options.frontOverlap,
points.cfNeck.y
);
points.hemEdge = new Point(
points.collarEdge.x,
points.hem.y
);
// Collar
points.collarTip = points.collarEdge.shiftFractionTowards(points.cfNeck, options.lapelReduction);
points.lapelStraightEnd = new Point(
points.collarEdge.x,
points.armhole.y
);
points.lapelStraightEndCp1 = points.lapelStraightEnd.shiftFractionTowards(points.collarEdge, 0.7);
// Pocket
points.pocketTopLeft = new Point(
points.button1Right.x + points.button1Right.dx(points.hips) * options.pocketPlacementHorizontal,
points.button1Right.y + points.button1Right.dy(points.button3Right) * options.pocketPlacementVertical
);
let pocketWidth = points.pocketTopLeft.dx(points.hips) * options.pocketWidth;
let pocketHeight = pocketWidth * (1 + options.pocketHeight);
points.pocketTopRight = points.pocketTopLeft.shift(0, pocketWidth);
points.pocketBottomLeft = points.pocketTopLeft.shift(-90, pocketHeight);
points.pocketBottomRight = points.pocketTopRight.shift(-90, pocketHeight);
if (options.pocketRadius > 0) {
let radius = pocketWidth * options.pocketRadius;
macro("round", {
from: points.pocketTopLeft,
to: points.pocketBottomRight,
via: points.pocketBottomLeft,
prefix: "pocketRoundLeft",
radius
});
macro("round", {
from: points.pocketBottomLeft,
to: points.pocketTopRight,
via: points.pocketBottomRight,
prefix: "pocketRoundRight",
radius
});
store.set("pocketRadius", radius);
}
store.set("pocketWidth", pocketWidth);
store.set("pocketHeight", pocketHeight);
// Pocket flap
points.pocketFlapMid = points.pocketTopLeft.shift(0, pocketWidth/2);
let pocketFlapHeight = pocketHeight * 0.3;
store.set("pocketFlapHeight", pocketFlapHeight);
points.pocketFlapTopLeft = new Point(
points.pocketTopLeft.x - pocketWidth * 0.005,
points.pocketTopLeft.y - pocketFlapHeight / 4
);
points.pocketFlapBottomLeft = new Point(
points.pocketFlapTopLeft.x,
points.pocketTopLeft.y + pocketFlapHeight * 0.75
);
points.pocketFlapTopRight = points.pocketFlapTopLeft.flipX(points.pocketFlapMid);
points.pocketFlapBottomRight = points.pocketFlapBottomLeft.flipX(points.pocketFlapMid);
if (options.pocketFlapRadius > 0) {
let radius = pocketWidth * options.pocketFlapRadius;
macro("round", {
from: points.pocketFlapTopLeft,
to: points.pocketFlapBottomRight,
via: points.pocketFlapBottomLeft,
prefix: "pocketFlapRoundLeft",
radius,
});
macro("round", {
from: points.pocketFlapBottomLeft,
to: points.pocketFlapTopRight,
via: points.pocketFlapBottomRight,
prefix: "pocketFlapRoundRight",
radius,
});
store.set("pocketFlapRadius", radius);
}
// Chest pocket
points.chestPocketAnchor = new Point(
points.waist.x * options.chestPocketPlacement,
points.button2Right.shiftFractionTowards(points.button3Right, 0.2).y
);
let chestPocketHeight = points.armhole.dy(points.chestPocketAnchor) * options.chestPocketHeight;
let chestPocketWidth = chestPocketHeight * options.chestPocketWidth;
store.set("chestPocketHeight", chestPocketHeight);
store.set("chestPocketWidth", chestPocketWidth);
points.chestPocketBottomLeft = points.chestPocketAnchor.shift(180, chestPocketWidth / 2);
points.chestPocketTopLeft = points.chestPocketBottomLeft.shift(90, chestPocketHeight);
points.chestPocketBottomRight = points.chestPocketBottomLeft.flipX(points.chestPocketAnchor);
points.chestPocketTopRight = points.chestPocketTopLeft.flipX(points.chestPocketAnchor);
for (let i of [
"chestPocketTopLeft",
"chestPocketBottomLeft",
"chestPocketTopRight",
"chestPocketBottomRight"]) points[i] = points[i].rotate(options.chestPocketAngle, points.chestPocketAnchor);
// Inner pocket
points.innerPocketAnchor = new Point(
points.waist.x * options.innerPocketPlacement,
points.button2Right.shiftFractionTowards(points.button3Right, 1.5).y
);
let innerPocketWidth = points.waist.x * options.innerPocketWidth;
let weltHeight = innerPocketWidth * options.innerPocketWeltHeight;
store.set("innerPocketWeltHeight", weltHeight);
store.set("innerPocketWidth", innerPocketWidth);
points.innerPocketTop = points.innerPocketAnchor.shift(90, weltHeight);
points.innerPocketBottom = points.innerPocketAnchor.shift(-90, weltHeight);
points.innerPocketLeft = points.innerPocketAnchor.shift(180, innerPocketWidth/2);
points.innerPocketRight = points.innerPocketLeft.flipX(points.innerPocketAnchor);
points.innerPocketTopLeft = points.innerPocketLeft.shift(90, weltHeight);
points.innerPocketTopRight = points.innerPocketTopLeft.flipX(points.innerPocketAnchor);
points.innerPocketBottomLeft = points.innerPocketLeft.shift(-90, weltHeight);
points.innerPocketBottomRight = points.innerPocketBottomLeft.flipX(points.innerPocketAnchor);
// Roll line
points.rollLineEdge = points.shoulder.shiftFractionTowards(points.neck, 1.15);
points.rollLineStart = new Point(
points.collarEdge.x,
points.button3Left.y
);
points.rollLineEnd = utils.lineIntersectsCurve(
points.rollLineStart,
points.rollLineEdge,
points.cfNeck,
points.cfNeckCp1,
points.neckCp2Front,
points.neck
);
// Facing/Lining border (flb)
points.flbX = points.button1Right.shift(0, points.button1Right.dx(points.pocketTopLeft)/2);
points.flbHem = new Point(points.flbX.x, points.hemEdge.y);
if (points.flbHem.x <= points.cfNeck.x)
points.flbTop = new Point(points.flbX.x, points.cfNeck.y);
else if (points.flbHem.x < points.neck.x)
points.flbTop = utils.lineIntersectsCurve(
points.flbHem,
points.flbX.shift(90,points.flbHem.y * 2),
points.cfNeck,
points.cfNeckCp1,
points.neckCp2Front,
points.neck
);
else if (points.flbHem.x < points.shoulder.x)
points.flbTop = utils.beamsIntersect(
points.flbHem,
points.flbX,
points.neck,
points.shoulder
);
else throw new Error("Could not find intersection of facing/lining boundary with neckline");
// Store collar length
store.set(
"frontCollarLength",
new Path()
.move(points.cfNeck)
.curve(points.cfNeckCp1, points.neckCp2Front, points.neck)
.length()
);
// Clean up
for (let i in paths) delete paths[i]
for (let i in snippets) delete snippets[i]
// Paths
paths.seam = new Path()
.move(points.collarTip)
._curve(points.lapelStraightEndCp1, points.lapelStraightEnd)
.line(points.hemEdge)
.line(points.hem)
.line(points.seat)
.curve(points.seatCp2, points.waistCp1, points.waist)
.curve_(points.waistCp2, points.armhole)
.curve(points.armholeCp2, points.armholeHollowCp1, points.armholeHollow)
.curve(points.armholeHollowCp2, points.armholePitchCp1, points.armholePitch)
.curve(points.armholePitchCp2, points.shoulderCp1, points.shoulder)
.line(points.neck)
.curve(points.neckCp2Front, points.cfNeckCp1, points.cfNeck)
.line(points.collarTip)
.close()
.attr("class", "fabric");
paths.rollLine = new Path()
.move(points.rollLineStart)
.line(points.rollLineEnd)
.attr("class", "lashed");
paths.chestPiece = new Path()
.move(points.rollLineStart)
.curve(points.button3Right, points.waistCp2, points.armhole)
.attr("class", "canvas lashed");
paths.flb = new Path()
.move(points.flbHem)
.line(points.flbTop)
.attr("class", "lining lashed");
paths.pocket = new Path().move(points.pocketTopLeft);
if (options.pocketRadius > 0) {
paths.pocket = paths.pocket
.line(points.pocketRoundLeftStart)
.curve(points.pocketRoundLeftCp1, points.pocketRoundLeftCp2, points.pocketRoundLeftEnd)
.line(points.pocketRoundRightStart)
.curve(points.pocketRoundRightCp1, points.pocketRoundRightCp2, points.pocketRoundRightEnd)
} else {
paths.pocket = paths.pocket
.line(points.pocketBottomLeft)
.line(points.pocketBottomRight)
}
paths.pocket = paths.pocket
.line(points.pocketTopRight)
.line(points.pocketTopLeft)
.close()
.attr("class", "fabric help");
paths.pocketFlap = new Path().move(points.pocketFlapTopLeft);
if (options.pocketFlapRadius > 0) {
paths.pocketFlap = paths.pocketFlap
.line(points.pocketFlapRoundLeftStart)
.curve(points.pocketFlapRoundLeftCp1, points.pocketFlapRoundLeftCp2, points.pocketFlapRoundLeftEnd)
.line(points.pocketFlapRoundRightStart)
.curve(points.pocketFlapRoundRightCp1, points.pocketFlapRoundRightCp2, points.pocketFlapRoundRightEnd)
} else {
paths.pocketFlap = paths.pocketFlap
.line(points.pocketFlapBottomLeft)
.line(points.pocketFlapBottomRight);
}
paths.pocketFlap = paths.pocketFlap
.line(points.pocketFlapTopRight)
.line(points.pocketFlapTopLeft)
.close()
.attr("class", "fabric help");
paths.chestPocket = new Path()
.move(points.chestPocketTopLeft)
.line(points.chestPocketBottomLeft)
.line(points.chestPocketBottomRight)
.line(points.chestPocketTopRight)
.line(points.chestPocketTopLeft)
.close()
.attr("class", "fabric help");
if (complete) {
snippets.button1Left = new Snippet("button", points.button1Left).attr("data-scale", 2);
snippets.button1Right = new Snippet("button", points.button1Right).attr("data-scale", 2);
snippets.button2Left = new Snippet("button", points.button2Left).attr("data-scale", 2);
snippets.button2Right = new Snippet("button", points.button2Right).attr("data-scale", 2);
snippets.button3Left = new Snippet("button", points.button3Left).attr("data-scale", 2);
snippets.button3Right = new Snippet("button", points.button3Right).attr("data-scale", 2);
}
return part;
}

View file

@ -0,0 +1,66 @@
import freesewing from "freesewing";
import plugins from "@freesewing/plugin-bundle";
import buttons from "@freesewing/plugin-buttons";
import Bent from "@freesewing/bent";
import config from "../config";
// Parts
import draftFront from "./front";
import draftBack from "./back";
import draftTail from "./tail";
import draftTopSleeve from "./topsleeve";
import draftUnderSleeve from "./undersleeve";
import draftBelt from "./belt";
import draftCollarStand from "./collarstand";
import draftCollar from "./collar";
import draftCuffFacing from "./cufffacing";
import draftPocket from "./pocket";
import draftPocketFlap from "./pocketflap";
import draftChestPocketWelt from "./chestpocketwelt";
import draftInnerPocketWelt from "./innerpocketwelt";
import draftInnerPocketBag from "./innerpocketbag";
import draftInnerPocketTab from "./innerpockettab";
// Create new design
const Carlton = new freesewing.Design(config, [
plugins,
buttons
]);
// Attach draft methods from Bent to prototype
Carlton.prototype.draftBentBase = function(part) {
return new Bent(this.settings).draftBase(part);
};
Carlton.prototype.draftBentFront = function(part) {
return new Bent(this.settings).draftFront(part);
}
Carlton.prototype.draftBentBack = function(part) {
return new Bent(this.settings).draftBack(part);
};
Carlton.prototype.draftBentSleeve = function(part) {
return new Bent(this.settings).draftSleeve(part);
};
Carlton.prototype.draftBentTopSleeve = function(part) {
return new Bent(this.settings).draftTopSleeve(part);
};
Carlton.prototype.draftBentUnderSleeve = function(part) {
return new Bent(this.settings).draftUnderSleeve(part);
};
// Attach own draft methods to prototype
Carlton.prototype.draftFront = draftFront;
Carlton.prototype.draftBack = draftBack;
Carlton.prototype.draftTail = draftTail;
Carlton.prototype.draftTopSleeve = draftTopSleeve;
Carlton.prototype.draftUnderSleeve = draftUnderSleeve;
Carlton.prototype.draftBelt = draftBelt;
Carlton.prototype.draftCollarStand = draftCollarStand;
Carlton.prototype.draftCollar = draftCollar;
Carlton.prototype.draftCuffFacing = draftCuffFacing;
Carlton.prototype.draftPocket = draftPocket;
Carlton.prototype.draftPocketFlap = draftPocketFlap;
Carlton.prototype.draftChestPocketWelt = draftChestPocketWelt;
Carlton.prototype.draftInnerPocketWelt = draftInnerPocketWelt;
Carlton.prototype.draftInnerPocketBag = draftInnerPocketBag;
Carlton.prototype.draftInnerPocketTab = draftInnerPocketTab;
export default Carlton;

View file

@ -0,0 +1,41 @@
export default function(part) {
let { paperless, sa, snippets, Snippet, utils, store, complete, points, measurements, options, macro, Point, paths, Path } = part.shorthand();
points.topLeft = new Point(0, 0);
points.bottomRight = new Point(
store.get("innerPocketWidth"),
store.get("innerPocketWidth") * options.innerPocketDepth / 2
);
points.bottomLeft = new Point(
points.topLeft.x,
points.bottomRight.y
);
points.topRight = new Point(
points.bottomRight.x,
points.topLeft.y
);
points.startLeft = points.topLeft.shiftFractionTowards(points.bottomLeft, 0.33);
points.endLeft = points.topLeft.shiftFractionTowards(points.bottomLeft, 0.66);
points.startRight = points.topRight.shiftFractionTowards(points.bottomRight, 0.33);
points.endRight = points.topRight.shiftFractionTowards(points.bottomRight, 0.66);
paths.seam = new Path()
.move(points.startRight)
.line(points.topRight)
.line(points.topLeft)
.line(points.startLeft)
.move(points.endLeft)
.line(points.bottomLeft)
.line(points.bottomRight)
.line(points.endRight)
.attr("class", "lining");
paths.hint = new Path()
.move(points.startLeft)
.line(points.endLeft)
.move(points.endRight)
.line(points.startRight)
.attr("class", "lining dashed");
return part;
}

View file

@ -0,0 +1,32 @@
export default function(part) {
let { paperless, sa, snippets, Snippet, utils, store, complete, points, measurements, options, macro, Point, paths, Path } = part.shorthand();
points.topLeft = new Point(0, 0);
points.topRight = new Point(
store.get("innerPocketWidth") * 1.2,
0
);
points.bottom = new Point(
store.get("innerPocketWidth") * 0.6,
store.get("innerPocketWidth") * 0.6,
);
points.top = new Point(
store.get("innerPocketWidth") * 0.6,
0
);
paths.seam = new Path()
.move(points.topLeft)
.line(points.bottom)
.line(points.topRight)
.line(points.topLeft)
.close()
.attr("class", "lining");
paths.hint = new Path()
.move(points.top)
.line(points.bottom)
.attr("class", "lining dashed");
return part;
}

View file

@ -0,0 +1,60 @@
export default function(part) {
let { paperless, sa, snippets, Snippet, utils, store, complete, points, measurements, options, macro, Point, paths, Path } = part.shorthand();
points.topLeft = new Point(0, 0);
points.bottomRight = new Point(
store.get("innerPocketWidth") * 1.4,
store.get("innerPocketWeltHeight") * 6
);
points.bottomLeft = new Point(
points.topLeft.x,
points.bottomRight.y
);
points.topRight = new Point(
points.bottomRight.x,
points.topLeft.y
);
points.leftMid = new Point(0, points.bottomRight.y / 2);
points.rightMid = new Point(points.bottomRight.x, points.bottomRight.y / 2);
points.realTopLeft = new Point(
store.get("innerPocketWidth") * 0.2,
store.get("innerPocketWeltHeight") * 2
);
points.realTopRight = new Point(
store.get("innerPocketWidth") * 1.2,
points.realTopLeft.y
);
points.realBottomLeft = new Point(
points.realTopLeft.x,
store.get("innerPocketWeltHeight") * 4
);
points.realBottomRight = new Point(
points.realTopRight.x,
points.realBottomLeft.y
);
paths.seam = new Path()
.move(points.topLeft)
.line(points.bottomLeft)
.line(points.bottomRight)
.line(points.topRight)
.line(points.topLeft)
.close()
.attr("class", "fabric");
paths.fold = new Path()
.move(points.leftMid)
.line(points.rightMid)
.attr("class", "dashed");
paths.welt = new Path()
.move(points.realTopLeft)
.line(points.realBottomLeft)
.line(points.realBottomRight)
.line(points.realTopRight)
.line(points.realTopLeft)
.close()
.attr("class", "lashed");
return part;
}

View file

@ -0,0 +1,53 @@
export default function(part) {
let { paperless, sa, snippets, Snippet, utils, store, complete, points, measurements, options, macro, Point, paths, Path } = part.shorthand();
points.topLeft = new Point(0, 0);
points.bottomRight = new Point(
store.get("pocketWidth"),
store.get("pocketHeight")
);
points.bottomLeft = new Point(
points.topLeft.x,
points.bottomRight.y
);
points.topRight = new Point(
points.bottomRight.x,
points.topLeft.y
);
if (options.pocketRadius > 0) {
macro("round", {
from: points.topLeft,
to: points.bottomRight,
via: points.bottomLeft,
radius: store.get("pocketRadius"),
prefix: "roundLeft"
});
macro("round", {
from: points.bottomLeft,
to: points.topRight,
via: points.bottomRight,
radius: store.get("pocketRadius"),
prefix: "roundRight"
});
paths.seam = new Path()
.move(points.topLeft)
.line(points.roundLeftStart)
.curve(points.roundLeftCp1, points.roundLeftCp2, points.roundLeftEnd)
.line(points.roundRightStart)
.curve(points.roundRightCp1, points.roundRightCp2, points.roundRightEnd)
} else {
paths.seam = new Path()
.move(points.topLeft)
.line(points.bottomLeft)
.line(points.bottomRight);
}
paths.seam = paths.seam
.line(points.topRight)
.line(points.topLeft)
.close()
.attr("class", "fabric");
return part;
}

View file

@ -0,0 +1,53 @@
export default function(part) {
let { paperless, sa, snippets, Snippet, utils, store, complete, points, measurements, options, macro, Point, paths, Path } = part.shorthand();
points.topLeft = new Point(0, 0);
points.bottomRight = new Point(
store.get("pocketWidth"),
store.get("pocketFlapHeight")
);
points.bottomLeft = new Point(
points.topLeft.x,
points.bottomRight.y
);
points.topRight = new Point(
points.bottomRight.x,
points.topLeft.y
);
if (options.pocketFlapRadius > 0) {
macro("round", {
from: points.topLeft,
to: points.bottomRight,
via: points.bottomLeft,
radius: store.get("pocketFlapRadius"),
prefix: "roundLeft"
});
macro("round", {
from: points.bottomLeft,
to: points.topRight,
via: points.bottomRight,
radius: store.get("pocketFlapRadius"),
prefix: "roundRight"
});
paths.seam = new Path()
.move(points.topLeft)
.line(points.roundLeftStart)
.curve(points.roundLeftCp1, points.roundLeftCp2, points.roundLeftEnd)
.line(points.roundRightStart)
.curve(points.roundRightCp1, points.roundRightCp2, points.roundRightEnd)
} else {
paths.seam = new Path()
.move(points.topLeft)
.line(points.bottomLeft)
.line(points.bottomRight);
}
paths.seam = paths.seam
.line(points.topRight)
.line(points.topLeft)
.close()
.attr("class", "fabric");
return part;
}

View file

@ -0,0 +1,15 @@
/**
* This calculates a bunch of helper variables and stores them
*/
export const calculateRatios = part => {
let { store, measurements, options } = part.shorthand();
// Calculate different values for reducing from chest to hips via waist
store.set("chest", measurements.chestCircumference * (1 + options.chestEase));
store.set("waist", measurements.naturalWaist * (1 + options.waistEase));
store.set("hips", measurements.hipsCircumference * (1 + options.hipsEase));
store.set("seat", measurements.seatCircumference * (1 + options.seatEase));
store.set("waistReduction", store.get("chest") - store.get("waist"));
store.set("hipsReduction", store.get("chest") - store.get("hips"));
};

View file

@ -0,0 +1,59 @@
export default function(part) {
let { paperless, sa, snippets, Snippet, utils, store, complete, points, measurements, options, macro, Point, paths, Path } = part.shorthand();
let beltWidth = measurements.centerBackNeckToWaist * options.beltWidth;
let waist = store.get("chest") / 4 - store.get("waistReduction") / 8;
let length = store.get("waistToHem") - store.get("beltWidth")/2;
points.cbTop = new Point(0,0);
points.fold1Top = points.cbTop.shift(0, store.get("cbToDart")/2);
points.fold2Top = points.cbTop.shift(0, store.get("cbToDart"));
points.fold3Top = points.cbTop.shift(0, store.get("cbToDart")*2);
points.fold4Top = points.fold3Top.shift(0, store.get("cbToDart")/2);
points.waistTop = points.fold4Top.shift(0, store.get("dartToSide"));
// 12cm will do as we're just drawing a rectangle.
// But check that lenght > 12cm because doll clothes.
let drawnLength = length < 120 ? length : 120;
for (let i of ["cb", "fold1", "fold2", "fold3", "fold4", "waist"]) {
points[i+"Bottom"] = points[i+"Top"].shift(-90, drawnLength);
if (i === "cb" || i === "waist") {
points[i+"MidTop"] = points[i+"Top"].shift(-90, drawnLength * 0.4);
points[i+"MidBottom"] = points[i+"Top"].shift(-90, drawnLength * 0.6);
}
}
paths.seam = new Path()
.move(points.cbTop)
.line(points.cbMidTop)
.move(points.cbMidBottom)
.line(points.cbBottom)
.line(points.waistBottom)
.line(points.waistMidBottom)
.move(points.waistMidTop)
.line(points.waistTop)
.line(points.cbTop)
.attr("class", "fabric");
paths.folds = new Path()
.move(points.fold1Top)
.line(points.fold1Bottom)
.move(points.fold2Top)
.line(points.fold2Bottom)
.move(points.fold3Top)
.line(points.fold3Bottom)
.move(points.fold4Top)
.line(points.fold4Bottom)
.attr("class", "lashed");
paths.hint = new Path()
.move(points.cbMidTop)
.line(points.cbMidBottom)
.move(points.waistMidBottom)
.line(points.waistMidTop)
.attr("class", "fabric dashed");
return part;
}

View file

@ -0,0 +1,40 @@
export default function(part) {
let { paperless, sa, snippets, Snippet, utils, store, complete, points, measurements, options, macro, Point, paths, Path } = part.shorthand();
// Add cuff
let length = measurements.shoulderToWrist * options.cuffLength;
let angle = points.tsWristRight.angle(points.tsWristLeft);
points.cuffBottomRight = points.tsWristRight.shift(angle+90, length);
points.cuffBottomLeft = points.tsWristLeft.shift(angle+90, length);
macro("round", {
to: points.tsWristRight,
from: points.cuffBottomLeft,
via: points.cuffBottomRight,
radius: length/3,
render: true,
prefix: "round"
});
store.set("topCuffWidth", points.tsWristLeft.dist(points.tsWristRight));
store.set("cuffLength", length);
store.set("cuffRadius", length/3);
// Paths
paths.seam = new Path()
.move(points.tsLeftEdge)
._curve(points.tsElbowLeftCpTop, points.tsElbowLeft)
.line(points.tsWristLeft)
.line(points.cuffBottomLeft)
.line(points.roundStart)
.curve(points.roundCp1, points.roundCp2, points.roundEnd)
.line(points.tsWristRight)
.line(points.elbowRight)
.curve(points.elbowRightCpTop, points.tsRightEdgeCpBottom, points.tsRightEdge)
.curve_(points.tsRightEdgeCpTop, points.backPitchPoint)
._curve(points.topCpRight, points.top)
.curve(points.topCpLeft, points.frontPitchPointCpTop, points.frontPitchPoint)
.curve(points.frontPitchPointCpBottom, points.tsLeftEdgeCpRight, points.tsLeftEdge)
.close()
.attr("class", "fabric");
return part;
}

View file

@ -0,0 +1,37 @@
export default function(part) {
let { paperless, sa, snippets, Snippet, utils, store, complete, points, measurements, options, macro, Point, paths, Path } = part.shorthand();
// Add cuff
let length = measurements.shoulderToWrist * options.cuffLength;
let angle = points.usWristRight.angle(points.usWristLeft);
points.cuffBottomRight = points.usWristRight.shift(angle+90, length);
points.cuffBottomLeft = points.usWristLeft.shift(angle+90, length);
macro("round", {
to: points.usWristRight,
from: points.cuffBottomLeft,
via: points.cuffBottomRight,
radius: length/3,
render: true,
prefix: "round"
});
store.set("underCuffWidth", points.usWristLeft.dist(points.usWristRight));
// Paths
paths.seam = new Path()
.move(points.usLeftEdge)
._curve(points.usElbowLeftCpTop, points.usElbowLeft)
.line(points.usWristLeft)
.line(points.cuffBottomLeft)
.line(points.roundStart)
.curve(points.roundCp1, points.roundCp2, points.roundEnd)
.line(points.usWristRight)
.line(points.elbowRight)
.curve(points.elbowRightCpTop, points.usRightEdgeCpBottom, points.usRightEdge)
.curve_(points.usRightEdgeCpTop, points.usTip)
.curve(points.usTipCpBottom, points.usLeftEdgeCpRight, points.usLeftEdgeRight)
.line(points.usLeftEdge)
.close()
.attr("class", "fabric");
return part;
}