tada: Initial commit
This commit is contained in:
parent
909e95ab8c
commit
eb05e90620
16 changed files with 4579 additions and 2 deletions
13
packages/bent/.editorconfig
Normal file
13
packages/bent/.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
|
62
packages/bent/.gitignore
vendored
Normal file
62
packages/bent/.gitignore
vendored
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
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/bent/.npmignore
Normal file
2
packages/bent/.npmignore
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
src
|
||||||
|
.editorconfig
|
21
packages/bent/LICENSE
Normal file
21
packages/bent/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,22 @@
|
||||||
# bent
|
<p align="center">
|
||||||
Port of the Bent Body Block to JS for freesewing v2
|
<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>
|
||||||
|
|
||||||
|
# freesewing / patterns / bent
|
||||||
|
|
||||||
|
Bent is a [freesewing](https://github.com/freesewing/freesewing) pattern
|
||||||
|
for a body block or sloper with a two-part sleeve.
|
||||||
|
|
||||||
|
It's be basis for our coats and jacket patterns.
|
||||||
|
|
||||||
|
See [freesewing.org/patterns/bent](https://freesewing.org/patterns/bent)
|
||||||
|
for more info and examples.
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
```
|
||||||
|
npm i --save @freesewing/bent
|
||||||
|
```
|
||||||
|
|
74
packages/bent/config/index.js
Normal file
74
packages/bent/config/index.js
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
import { version } from "../package.json";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "bent",
|
||||||
|
version: version,
|
||||||
|
measurements: [
|
||||||
|
"bicepsCircumference",
|
||||||
|
"centerBackNeckToWaist",
|
||||||
|
"chestCircumference",
|
||||||
|
"naturalWaistToHip",
|
||||||
|
"neckCircumference",
|
||||||
|
"shoulderSlope",
|
||||||
|
"shoulderToElbow",
|
||||||
|
"shoulderToShoulder",
|
||||||
|
"shoulderToWrist",
|
||||||
|
"wristCircumference"
|
||||||
|
],
|
||||||
|
dependencies: {
|
||||||
|
back: "base",
|
||||||
|
front: "back",
|
||||||
|
topSleeve: "sleeve",
|
||||||
|
underSleeve: "sleeve",
|
||||||
|
},
|
||||||
|
inject: {
|
||||||
|
back: "base",
|
||||||
|
front: "back",
|
||||||
|
topSleeve: "sleeve",
|
||||||
|
underSleeve: "sleeve",
|
||||||
|
},
|
||||||
|
hide: ["base", "sleeve"],
|
||||||
|
options: {
|
||||||
|
// Constants
|
||||||
|
brianFitSleeve: true,
|
||||||
|
brianFitCollar: true,
|
||||||
|
collarFactor: 4.8,
|
||||||
|
|
||||||
|
// Percentages
|
||||||
|
acrossBackFactor: { pct: 97, min: 93, max: 100 },
|
||||||
|
armholeDepthFactor: { pct: 65, min: 50, max: 70 },
|
||||||
|
backNeckCutout: { pct: 5, min: 2, max: 8 },
|
||||||
|
bicepsEase: { pct: 20, min: 0, max: 50 },
|
||||||
|
chestEase: { pct: 8, min: -4, max: 20 },
|
||||||
|
collarEase: { pct: 3.5, min: 0, max: 10 },
|
||||||
|
cuffEase: { pct: 20, min: 0, max: 200 },
|
||||||
|
frontArmholeDeeper: { pct: 0.5, min: 0, max: 1.5 },
|
||||||
|
lengthBonus: { pct: 0, min: -4, max: 60 },
|
||||||
|
shoulderEase: { pct: 0, min: -2, max: 6 },
|
||||||
|
shoulderSlopeReduction: { pct: 0, min: 0, max: 8 },
|
||||||
|
|
||||||
|
sleeveBend: { deg: 10, min: 0, max: 20 },
|
||||||
|
sleevecapHeight: {pct: 45, min: 40, max: 60 },
|
||||||
|
sleevecapEase: { pct: 1, min: 0, max: 10 },
|
||||||
|
sleevecapTopFactorX: { pct: 63, min: 25, max: 75 },
|
||||||
|
sleevecapTopFactorY: { pct: 100, min: 35, max: 165 },
|
||||||
|
sleevecapBackFactorX: { pct: 30, min: 30, max: 75 },
|
||||||
|
sleevecapBackFactorY: { pct: 33, min: 35, max: 65 },
|
||||||
|
sleevecapFrontFactorX: { pct: 85, min: 35, max: 85 },
|
||||||
|
sleevecapFrontFactorY: { pct: 33, min: 35, max: 65 },
|
||||||
|
sleevecapQ1Offset: { pct: 2, min: 0, max: 7 },
|
||||||
|
sleevecapQ2Offset: { pct: 5, min: 0, max: 7 },
|
||||||
|
sleevecapQ3Offset: { pct: 2, min: -5, max: 7 },
|
||||||
|
sleevecapQ4Offset: { pct: 4, min: 0, max: 7 },
|
||||||
|
sleevecapQ1Spread1: { pct: 8, min: 4, max: 20 },
|
||||||
|
sleevecapQ1Spread2: { pct: 5, min: 4, max: 20 },
|
||||||
|
sleevecapQ2Spread1: { pct: 15, min: 4, max: 20 },
|
||||||
|
sleevecapQ2Spread2: { pct: 10, min: 4, max: 20 },
|
||||||
|
sleevecapQ3Spread1: { pct: 15, min: 4, max: 20 },
|
||||||
|
sleevecapQ3Spread2: { pct: 5, min: 4, max: 20 },
|
||||||
|
sleevecapQ4Spread1: { pct: 20, min: 4, max: 20 },
|
||||||
|
sleevecapQ4Spread2: { pct: 16, min: 4, max: 20 },
|
||||||
|
sleeveWidthGuarantee: { pct: 90, min: 25, max: 100 },
|
||||||
|
sleeveLengthBonus: { pct: 0, min:-40, max: 10 },
|
||||||
|
}
|
||||||
|
};
|
84
packages/bent/index.html
Normal file
84
packages/bent/index.html
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Bent</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="../brian/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": 10,
|
||||||
|
"paperless": true,
|
||||||
|
"measurements": {
|
||||||
|
"bicepsCircumference": 335,
|
||||||
|
"centerBackNeckToWaist": 520,
|
||||||
|
"chestCircumference": 1080,
|
||||||
|
"hipsCircumference": 990,
|
||||||
|
"naturalWaist": 925,
|
||||||
|
"naturalWaistToHip": 145,
|
||||||
|
"neckCircumference": 420,
|
||||||
|
"shoulderSlope": 55,
|
||||||
|
"shoulderToShoulder": 465,
|
||||||
|
"shoulderToWrist": 680,
|
||||||
|
"wristCircumference": 190,
|
||||||
|
"shoulderToElbow": 410
|
||||||
|
},
|
||||||
|
};
|
||||||
|
var pattern = new freesewing.patterns.bent(settings);
|
||||||
|
pattern.use(freesewing.plugins.theme);
|
||||||
|
pattern.use(freesewing.plugins.designer);
|
||||||
|
pattern.use(freesewing.plugins.validate);
|
||||||
|
pattern.draft();
|
||||||
|
//pattern.sampleOption("backScyeDart");
|
||||||
|
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>
|
3818
packages/bent/package-lock.json
generated
Normal file
3818
packages/bent/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
80
packages/bent/package.json
Normal file
80
packages/bent/package.json
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
{
|
||||||
|
"version": "0.1.0",
|
||||||
|
"name": "@freesewing/bent",
|
||||||
|
"description": "Freesewing pattern for a menswear body block with a two-part sleeve",
|
||||||
|
"author": "Joost De Cock <joost@decock.org> (https://github.com/joostdecock)",
|
||||||
|
"license": "MIT",
|
||||||
|
"homepage": "https://github.com/freesewing/bent#readme",
|
||||||
|
"repository": "github:freesewing/bent",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/freesewing/bent/issues"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"freesewing",
|
||||||
|
"block",
|
||||||
|
"sloper",
|
||||||
|
"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 --exec 'rollup -c rollup.js -o dist/browser.js -f iife -m true -n freesewing_patterns_bent --footer \"freesewing.patterns.bent = freesewing_patterns_bent;\"'",
|
||||||
|
"browserbuild": "rollup -c rollup.js -o dist/browser.js -f iife -m true -n freesewing_patterns_bent --footer 'freesewing.patterns.bent = freesewing_patterns_bent;'",
|
||||||
|
"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/brian": "latest",
|
||||||
|
"@freesewing/plugin-bundle": "latest",
|
||||||
|
"freesewing": "latest"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@babel/core": "latest",
|
||||||
|
"@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": "latest",
|
||||||
|
"eslint-config-prettier": "latest",
|
||||||
|
"eslint-plugin-prettier": "latest",
|
||||||
|
"husky": "latest",
|
||||||
|
"lint-staged": "latest",
|
||||||
|
"prettier": "latest",
|
||||||
|
"rimraf": "latest",
|
||||||
|
"rollup": "latest",
|
||||||
|
"rollup-plugin-babel": "latest",
|
||||||
|
"rollup-plugin-babel-minify": "latest",
|
||||||
|
"rollup-plugin-json": "latest",
|
||||||
|
"rollup-plugin-node-resolve": "latest"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"dist/*",
|
||||||
|
"README.md",
|
||||||
|
"package-lock.json",
|
||||||
|
"package.json"
|
||||||
|
]
|
||||||
|
}
|
26
packages/bent/rollup.js
Normal file
26
packages/bent/rollup.js
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
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/plugin-bundle"],
|
||||||
|
output: {
|
||||||
|
globals: {
|
||||||
|
freesewing: "freesewing",
|
||||||
|
"@freesewing/plugin-bundle": "freesewing.plugins.bundle"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
29
packages/bent/src/index.js
Normal file
29
packages/bent/src/index.js
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
import freesewing from "freesewing";
|
||||||
|
import plugins from "@freesewing/plugin-bundle";
|
||||||
|
import Brian from "@freesewing/brian";
|
||||||
|
import config from "../config";
|
||||||
|
// Parts
|
||||||
|
import draftSleeve from "./sleeve";
|
||||||
|
import draftTopSleeve from "./topsleeve";
|
||||||
|
import draftUnderSleeve from "./undersleeve";
|
||||||
|
|
||||||
|
// Create new design
|
||||||
|
const Bent = new freesewing.Design(config, plugins);
|
||||||
|
|
||||||
|
// Attach draft methods from Brian to prototype
|
||||||
|
Bent.prototype.draftBase = function(part) {
|
||||||
|
return new Brian(this.settings).draftBase(part);
|
||||||
|
};
|
||||||
|
Bent.prototype.draftFront = function(part) {
|
||||||
|
return new Brian(this.settings).draftFront(part);
|
||||||
|
};
|
||||||
|
Bent.prototype.draftBack = function(part) {
|
||||||
|
return new Brian(this.settings).draftBack(part);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Attach own draft methods to prototype
|
||||||
|
Bent.prototype.draftSleeve = draftSleeve;
|
||||||
|
Bent.prototype.draftTopSleeve = draftTopSleeve;
|
||||||
|
Bent.prototype.draftUnderSleeve = draftUnderSleeve;
|
||||||
|
|
||||||
|
export default Bent;
|
53
packages/bent/src/shared.js
Normal file
53
packages/bent/src/shared.js
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
export default function(part, s) {
|
||||||
|
let { macro, Point, Path, points, paths, complete, paperless, snippets, Snippet, sa } = part.shorthand();
|
||||||
|
|
||||||
|
macro("ld", {
|
||||||
|
from: points[s+"WristLeft"],
|
||||||
|
to: points[s+"WristRight"],
|
||||||
|
d: 15
|
||||||
|
});
|
||||||
|
macro("ld", {
|
||||||
|
from: points[s+"ElbowLeft"],
|
||||||
|
to: points.elbowRight
|
||||||
|
});
|
||||||
|
macro("ld", {
|
||||||
|
from: points[s+"LeftEdge"],
|
||||||
|
to: points[s+"RightEdge"]
|
||||||
|
});
|
||||||
|
macro("hd", {
|
||||||
|
from: points[s+"LeftEdge"],
|
||||||
|
to: points[s+"ElbowLeft"],
|
||||||
|
y: points[s+"WristRight"].y + 3 * sa + 15
|
||||||
|
});
|
||||||
|
macro("hd", {
|
||||||
|
from: points[s+"LeftEdge"],
|
||||||
|
to: points[s+"WristLeft"],
|
||||||
|
y: points[s+"WristRight"].y + 3 * sa + 30
|
||||||
|
});
|
||||||
|
macro("hd", {
|
||||||
|
from: points[s+"LeftEdge"],
|
||||||
|
to: points[s+"WristRight"],
|
||||||
|
y: points[s+"WristRight"].y + 3 * sa + 45
|
||||||
|
});
|
||||||
|
macro("hd", {
|
||||||
|
from: points[s+"LeftEdge"],
|
||||||
|
to: points.elbowRight,
|
||||||
|
y: points[s+"WristRight"].y + 3 * sa + 60
|
||||||
|
});
|
||||||
|
macro("vd", {
|
||||||
|
from: points[s+"ElbowLeft"],
|
||||||
|
to: points[s+"LeftEdge"],
|
||||||
|
x: points[s+"LeftEdge"].x - sa - 15
|
||||||
|
});
|
||||||
|
macro("vd", {
|
||||||
|
from: points[s+"WristLeft"],
|
||||||
|
to: points[s+"LeftEdge"],
|
||||||
|
x: points[s+"LeftEdge"].x - sa - 30
|
||||||
|
});
|
||||||
|
macro("vd", {
|
||||||
|
from: points[s+"WristRight"],
|
||||||
|
to: points[s+"LeftEdge"],
|
||||||
|
x: points[s+"LeftEdge"].x - sa - 45
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
156
packages/bent/src/sleeve.js
Normal file
156
packages/bent/src/sleeve.js
Normal file
|
@ -0,0 +1,156 @@
|
||||||
|
export default function(part) {
|
||||||
|
let { Point, Path, points, paths, store, options, measurements,utils } = part.shorthand();
|
||||||
|
// FIXME: simplify points names a bit, they're too long
|
||||||
|
|
||||||
|
function draftSleeve(part, tweak) {
|
||||||
|
let { Point, Path, points, paths, store, options, measurements,utils } = part.shorthand();
|
||||||
|
// Sleeve frame
|
||||||
|
points.top = new Point(0, 0);
|
||||||
|
points.boxTopRight = points.top.shift(0, store.get("sleevecapTarget") / 5.8 * tweak);
|
||||||
|
points.boxTopLeft = points.boxTopRight.flipX();
|
||||||
|
points.boxBottom = points.top.shift(-90, measurements.shoulderToWrist * (1 + options.sleeveLengthBonus));
|
||||||
|
points.boxBottomRight = points.boxBottom.shift(0, points.boxTopRight.x);
|
||||||
|
points.boxBottomLeft = points.boxBottomRight.flipX();
|
||||||
|
points.armCenter = points.top.shift(
|
||||||
|
-90,
|
||||||
|
measurements.bicepsCircumference *
|
||||||
|
(1+ options.bicepsEase) *
|
||||||
|
options.sleevecapHeight *
|
||||||
|
tweak
|
||||||
|
);
|
||||||
|
points.armRight = points.armCenter.shift(0, points.boxTopRight.x);
|
||||||
|
points.armLeft = points.armRight.flipX();
|
||||||
|
points.elbowCenter = points.top.shift(-90, measurements.shoulderToElbow);
|
||||||
|
points.elbowRight = points.elbowCenter.shift(0, points.boxTopRight.x);
|
||||||
|
points.elbowLeft = points.elbowRight.flipX();
|
||||||
|
|
||||||
|
// Using sleeve width to adapt other values
|
||||||
|
let factor = points.boxTopRight.x;
|
||||||
|
|
||||||
|
// Note: us = undersleeve, ts = topsleeve
|
||||||
|
points.backPitchPoint = new Point(factor, points.armCenter.y / 3);
|
||||||
|
points.usTip = points.backPitchPoint.shift(180, factor / 4);
|
||||||
|
points.tsLeftEdge = points.armLeft.shift(180, factor / 4);
|
||||||
|
points.usLeftEdge = points.armLeft.shift(0, factor / 4);
|
||||||
|
points.tsRightEdge = points.armRight.shift(0, factor / 9);
|
||||||
|
points.usRightEdge = points.armRight.shift(180, factor / 9);
|
||||||
|
points.frontPitchPoint = new Point(points.boxTopLeft.x, points.armCenter.y * 0.6);
|
||||||
|
points.tsElbowLeft = points.elbowLeft.shift(180, factor / 9);
|
||||||
|
points.usElbowLeft = points.elbowLeft.shift(0, factor / 2.4);
|
||||||
|
|
||||||
|
// Different approach to sleeve bend, wrist right first
|
||||||
|
points.tsWristRight = utils.beamsIntersect(
|
||||||
|
points.elbowRight,
|
||||||
|
points.boxBottomRight.rotate(options.sleeveBend * -1, points.elbowRight),
|
||||||
|
points.boxBottomLeft,
|
||||||
|
points.boxBottomRight
|
||||||
|
);
|
||||||
|
points.usWristRight = points.tsWristRight.clone();
|
||||||
|
|
||||||
|
// Shift wrist left to the exact wrist width
|
||||||
|
let wristWidth = measurements.wristCircumference * (1 + options.cuffEase);
|
||||||
|
let topWrist = wristWidth/2 + factor/5;
|
||||||
|
let underWrist = wristWidth/2 - factor/5;
|
||||||
|
points.tsWristLeftHelperBottom = points.tsWristRight.shift(180, topWrist/2);
|
||||||
|
points.usWristLeftHelperBottom = points.usWristRight.shift(180, underWrist/2);
|
||||||
|
points.tsWristLeftHelperTop = points.tsElbowLeft.shiftFractionTowards(points.elbowRight, 0.5)
|
||||||
|
points.usWristLeftHelperTop = points.usElbowLeft.shiftFractionTowards(points.elbowRight, 0.5)
|
||||||
|
let tsWristAngle = points.tsWristLeftHelperBottom.angle(points.tsWristLeftHelperTop);
|
||||||
|
let usWristAngle = points.usWristLeftHelperBottom.angle(points.usWristLeftHelperTop);
|
||||||
|
points.tsWristLeft = points.tsWristRight.shift(tsWristAngle - 90, topWrist * -1);
|
||||||
|
points.usWristLeft = points.usWristRight.shift(usWristAngle - 90, underWrist * -1);
|
||||||
|
|
||||||
|
// Control points ts
|
||||||
|
points.tsRightEdgeCpTop = points.tsRightEdge.shift(90, points.backPitchPoint.dy(points.tsRightEdge)/2);
|
||||||
|
points.tsRightEdgeCpBottom = points.tsRightEdgeCpTop.flipY(points.tsRightEdge);
|
||||||
|
points.elbowRightCpTop = points.tsWristRight.shiftFractionTowards(points.elbowRight, 1.15);
|
||||||
|
points.topCpRight = points.top.shift(0, factor/1.6);
|
||||||
|
points.topCpLeft = points.topCpRight.flipX();
|
||||||
|
points.tsLeftEdgeCpRight = points.tsLeftEdge.shift(0, points.tsLeftEdge.dist(points.armLeft)/2);
|
||||||
|
points.frontPitchPointCpBottom = points.frontPitchPoint.shiftFractionTowards(points.tsLeftEdgeCpRight, 0.666);
|
||||||
|
points.frontPitchPointCpTop = points.frontPitchPointCpBottom.rotate(180, points.frontPitchPoint);
|
||||||
|
points.tsElbowLeftCpTop = points.tsWristLeft.shiftFractionTowards(points.tsElbowLeft, 1.2);
|
||||||
|
|
||||||
|
// Control points us
|
||||||
|
points.usRightEdgeCpBottom = points.usRightEdge.shift(points.usTip.angle(points.elbowRight), points.usTip.dy(points.usRightEdge)/2);
|
||||||
|
points.usRightEdgeCpTop = points.usRightEdgeCpBottom.rotate(180, points.usRightEdge);
|
||||||
|
points._helper1 = new Path()
|
||||||
|
.move(points.backPitchPoint)
|
||||||
|
._curve(points.topCpRight, points.top)
|
||||||
|
.shiftAlong(5);
|
||||||
|
points._helper2 = new Path()
|
||||||
|
.move(points.backPitchPoint)
|
||||||
|
._curve(points.tsRightEdgeCpTop, points.tsRightEdge)
|
||||||
|
.shiftAlong(5);
|
||||||
|
points.usLeftEdgeRight = points.usLeftEdge.shift(0, points.usLeftEdge.dist(points.armCenter)/3);
|
||||||
|
points.usLeftEdgeCpRight = points.usLeftEdge.shift(0, points.usLeftEdge.dist(points.armCenter)/1.2);
|
||||||
|
|
||||||
|
// Angle of the usTip
|
||||||
|
let angle = points._helper1.angle(points.backPitchPoint) - points.backPitchPoint.angle(points._helper2);
|
||||||
|
points.usTipCpBottom = points.usRightEdgeCpTop.rotate(angle * -1, points.usTip)
|
||||||
|
points.usElbowLeftCpTop = points.usWristLeft.shiftFractionTowards(points.usElbowLeft, 1.2);
|
||||||
|
|
||||||
|
// Calculate length of the sleevecap seam
|
||||||
|
let lenTop = new Path()
|
||||||
|
.move(points.backPitchPoint)
|
||||||
|
.curve(points.backPitchPoint, points.topCpRight, points.top)
|
||||||
|
.curve(points.topCpLeft, points.frontPitchPointCpTop, points.frontPitchPoint)
|
||||||
|
.curve(points.frontPitchPointCpBottom, points.tsLeftEdgeCpRight, points.tsLeftEdge)
|
||||||
|
.length();
|
||||||
|
let lenUnder = new Path()
|
||||||
|
.move(points.usTip)
|
||||||
|
.curve(points.usTipCpBottom, points.usLeftEdgeCpRight, points.usLeftEdgeRight)
|
||||||
|
.line(points.usLeftEdge)
|
||||||
|
.length();
|
||||||
|
store.set("sleevecapLength", lenTop + lenUnder);
|
||||||
|
}
|
||||||
|
|
||||||
|
let armholeLength =
|
||||||
|
store.get("frontArmholeLength") + store.get("backArmholeLength");
|
||||||
|
let sleevecapEase = armholeLength * options.sleevecapEase;
|
||||||
|
store.set("sleevecapEase", sleevecapEase);
|
||||||
|
store.set("sleevecapTarget", armholeLength + sleevecapEase);
|
||||||
|
|
||||||
|
let delta = 0;
|
||||||
|
let runs = 0;
|
||||||
|
let tweak = 1;
|
||||||
|
let target = store.get("sleevecapTarget");
|
||||||
|
do {
|
||||||
|
draftSleeve(part, tweak);
|
||||||
|
runs++;
|
||||||
|
delta = store.get("sleevecapLength") - target;
|
||||||
|
if (delta > 0) tweak = tweak * 0.99;
|
||||||
|
else tweak = tweak * 1.02;
|
||||||
|
} while (Math.abs(delta) > 2 && runs < 25);
|
||||||
|
|
||||||
|
|
||||||
|
// Paths
|
||||||
|
paths.ts = new Path()
|
||||||
|
.move(points.tsWristRight)
|
||||||
|
.line(points.elbowRight)
|
||||||
|
.curve(points.elbowRightCpTop, points.tsRightEdgeCpBottom, points.tsRightEdge)
|
||||||
|
.curve_(points.tsRightEdgeCpTop, points.backPitchPoint)
|
||||||
|
.curve(points.backPitchPoint, points.topCpRight, points.top)
|
||||||
|
.curve(points.topCpLeft, points.frontPitchPointCpTop, points.frontPitchPoint)
|
||||||
|
.curve(points.frontPitchPointCpBottom, points.tsLeftEdgeCpRight, points.tsLeftEdge)
|
||||||
|
.curve(points.tsLeftEdge, points.tsElbowLeftCpTop, points.tsElbowLeft)
|
||||||
|
.line(points.tsWristLeft)
|
||||||
|
.line(points.tsWristRight)
|
||||||
|
.close()
|
||||||
|
.attr("class", "lining");
|
||||||
|
|
||||||
|
paths.us = new Path()
|
||||||
|
.move(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)
|
||||||
|
.curve(points.usLeftEdge, points.usElbowLeftCpTop, points.usElbowLeft)
|
||||||
|
.line(points.usWristLeft)
|
||||||
|
.line(points.usWristRight)
|
||||||
|
.close()
|
||||||
|
.attr("class", "stroke-xl interfacing");
|
||||||
|
|
||||||
|
return part;
|
||||||
|
}
|
70
packages/bent/src/topsleeve.js
Normal file
70
packages/bent/src/topsleeve.js
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
import dimensions from "./shared";
|
||||||
|
|
||||||
|
export default function(part) {
|
||||||
|
let { macro, Point, Path, points, paths, complete, paperless, snippets, Snippet, sa } = part.shorthand();
|
||||||
|
|
||||||
|
// Extract seamline from sleeve
|
||||||
|
delete paths.us;
|
||||||
|
paths.seam = paths.ts
|
||||||
|
.clone()
|
||||||
|
.attr("class", "fabric", true);
|
||||||
|
delete paths.ts;
|
||||||
|
|
||||||
|
// Complete?
|
||||||
|
if (complete) {
|
||||||
|
snippets.logo = new Snippet("logo", points.elbowCenter);
|
||||||
|
macro("title", {
|
||||||
|
at: points.armCenter,
|
||||||
|
nr: 3,
|
||||||
|
title: "topsleeve"
|
||||||
|
});
|
||||||
|
|
||||||
|
if (sa) {
|
||||||
|
paths.sa = paths.seam.clone();
|
||||||
|
// Remove hem
|
||||||
|
paths.sa.ops.splice(-2);
|
||||||
|
paths.sa = paths.sa
|
||||||
|
.offset(sa)
|
||||||
|
.join(new Path()
|
||||||
|
.move(points.tsWristLeft)
|
||||||
|
.line(points.tsWristRight)
|
||||||
|
.offset(sa * 3)
|
||||||
|
)
|
||||||
|
.close()
|
||||||
|
.attr("class", "fabric sa");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Paperless?
|
||||||
|
if (paperless) {
|
||||||
|
dimensions(part, "ts");
|
||||||
|
macro("vd", {
|
||||||
|
from: points.tsLeftEdge,
|
||||||
|
to: points.top,
|
||||||
|
x: points.tsLeftEdge.x - sa - 15
|
||||||
|
});
|
||||||
|
macro("hd", {
|
||||||
|
from: points.tsLeftEdge,
|
||||||
|
to: points.top,
|
||||||
|
y: points.top.x - sa - 15
|
||||||
|
});
|
||||||
|
macro("hd", {
|
||||||
|
from: points.tsLeftEdge,
|
||||||
|
to: points.backPitchPoint,
|
||||||
|
y: points.top.x - sa - 30
|
||||||
|
});
|
||||||
|
macro("hd", {
|
||||||
|
from: points.tsLeftEdge,
|
||||||
|
to: points.tsRightEdge,
|
||||||
|
y: points.top.x - sa - 45
|
||||||
|
});
|
||||||
|
macro("vd", {
|
||||||
|
from: points.tsRightEdge,
|
||||||
|
to: points.backPitchPoint,
|
||||||
|
x: points.tsRightEdge.x + sa + 15
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return part;
|
||||||
|
}
|
55
packages/bent/src/undersleeve.js
Normal file
55
packages/bent/src/undersleeve.js
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
import dimensions from "./shared";
|
||||||
|
|
||||||
|
export default function(part) {
|
||||||
|
let { macro, Point, Path, points, paths, complete, paperless, snippets, Snippet, sa } = part.shorthand();
|
||||||
|
|
||||||
|
// Extract seamline from sleeve
|
||||||
|
delete paths.ts;
|
||||||
|
paths.seam = paths.us
|
||||||
|
.clone()
|
||||||
|
.attr("class", "fabric", true);
|
||||||
|
delete paths.us;
|
||||||
|
|
||||||
|
// Complete?
|
||||||
|
if (complete) {
|
||||||
|
snippets.logo = new Snippet("logo", points.elbowCenter);
|
||||||
|
macro("title", {
|
||||||
|
at: points.armCenter,
|
||||||
|
nr: 4,
|
||||||
|
title: "undersleeve"
|
||||||
|
});
|
||||||
|
|
||||||
|
if (sa) {
|
||||||
|
paths.sa = paths.seam.clone();
|
||||||
|
// Remove hem
|
||||||
|
paths.sa.ops.splice(-2);
|
||||||
|
paths.sa = paths.sa
|
||||||
|
.offset(sa)
|
||||||
|
.join(new Path()
|
||||||
|
.move(points.usWristLeft)
|
||||||
|
.line(points.usWristRight)
|
||||||
|
.offset(sa * 3)
|
||||||
|
)
|
||||||
|
.close()
|
||||||
|
.attr("class", "fabric sa");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Paperless?
|
||||||
|
if (paperless) {
|
||||||
|
dimensions(part, "us");
|
||||||
|
macro("hd", {
|
||||||
|
from: points.usLeftEdge,
|
||||||
|
to: points.usTip,
|
||||||
|
y: points.usTip.y - sa - 15
|
||||||
|
});
|
||||||
|
macro("vd", {
|
||||||
|
from: points.tsRightEdge,
|
||||||
|
to: points.usTip,
|
||||||
|
x: points.tsRightEdge.x + sa + 15
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return part;
|
||||||
|
}
|
14
packages/bent/test.html
Normal file
14
packages/bent/test.html
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Brian</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="svg"></div>
|
||||||
|
<script type="text/javascript" src="freesewing.js"></script>
|
||||||
|
<script>
|
||||||
|
console.log(freesewing);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Add table
Add a link
Reference in a new issue