tada: Initial commit
This commit is contained in:
parent
2d5396c343
commit
c0ace10e2d
27 changed files with 5474 additions and 2 deletions
13
packages/carlton/.editorconfig
Normal file
13
packages/carlton/.editorconfig
Normal 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
64
packages/carlton/.gitignore
vendored
Normal 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
|
2
packages/carlton/.npmignore
Normal file
2
packages/carlton/.npmignore
Normal file
|
@ -0,0 +1,2 @@
|
|||
src
|
||||
.editorconfig
|
21
packages/carlton/LICENSE
Normal file
21
packages/carlton/LICENSE
Normal 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.
|
|
@ -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> <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
|
||||
```
|
||||
|
|
122
packages/carlton/config/index.js
Normal file
122
packages/carlton/config/index.js
Normal 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 },
|
||||
|
||||
}
|
||||
};
|
88
packages/carlton/index.html
Normal file
88
packages/carlton/index.html
Normal 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
3844
packages/carlton/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
81
packages/carlton/package.json
Normal file
81
packages/carlton/package.json
Normal 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"
|
||||
]
|
||||
}
|
27
packages/carlton/rollup.js
Normal file
27
packages/carlton/rollup.js
Normal 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"
|
||||
}
|
||||
}
|
||||
};
|
88
packages/carlton/src/back.js
Normal file
88
packages/carlton/src/back.js
Normal 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;
|
||||
}
|
46
packages/carlton/src/belt.js
Normal file
46
packages/carlton/src/belt.js
Normal 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;
|
||||
}
|
41
packages/carlton/src/chestpocketwelt.js
Normal file
41
packages/carlton/src/chestpocketwelt.js
Normal 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;
|
||||
}
|
184
packages/carlton/src/collar.js
Normal file
184
packages/carlton/src/collar.js
Normal 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;
|
||||
}
|
30
packages/carlton/src/collarstand.js
Normal file
30
packages/carlton/src/collarstand.js
Normal 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;
|
||||
}
|
44
packages/carlton/src/cufffacing.js
Normal file
44
packages/carlton/src/cufffacing.js
Normal 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;
|
||||
}
|
296
packages/carlton/src/front.js
Normal file
296
packages/carlton/src/front.js
Normal 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;
|
||||
}
|
66
packages/carlton/src/index.js
Normal file
66
packages/carlton/src/index.js
Normal 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;
|
41
packages/carlton/src/innerpocketbag.js
Normal file
41
packages/carlton/src/innerpocketbag.js
Normal 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;
|
||||
}
|
32
packages/carlton/src/innerpockettab.js
Normal file
32
packages/carlton/src/innerpockettab.js
Normal 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;
|
||||
}
|
60
packages/carlton/src/innerpocketwelt.js
Normal file
60
packages/carlton/src/innerpocketwelt.js
Normal 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;
|
||||
}
|
53
packages/carlton/src/pocket.js
Normal file
53
packages/carlton/src/pocket.js
Normal 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;
|
||||
}
|
53
packages/carlton/src/pocketflap.js
Normal file
53
packages/carlton/src/pocketflap.js
Normal 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;
|
||||
}
|
15
packages/carlton/src/shared.js
Normal file
15
packages/carlton/src/shared.js
Normal 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"));
|
||||
};
|
59
packages/carlton/src/tail.js
Normal file
59
packages/carlton/src/tail.js
Normal 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;
|
||||
}
|
||||
|
40
packages/carlton/src/topsleeve.js
Normal file
40
packages/carlton/src/topsleeve.js
Normal 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;
|
||||
}
|
37
packages/carlton/src/undersleeve.js
Normal file
37
packages/carlton/src/undersleeve.js
Normal 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;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue