🎨 Updated prettier config
This commit is contained in:
parent
b8e632998b
commit
6710d76b08
401 changed files with 13193 additions and 15620 deletions
|
@ -1,22 +1,15 @@
|
|||
import React from "react";
|
||||
import freesewing from "@freesewing/core";
|
||||
import Workbench from "@freesewing/components/Workbench";
|
||||
import "typeface-roboto-condensed";
|
||||
import "@freesewing/css-theme";
|
||||
import React from 'react'
|
||||
import freesewing from '@freesewing/core'
|
||||
import Workbench from '@freesewing/components/Workbench'
|
||||
import 'typeface-roboto-condensed'
|
||||
import '@freesewing/css-theme'
|
||||
|
||||
import Pattern from "pattern";
|
||||
import Pattern from 'pattern'
|
||||
|
||||
const App = props => {
|
||||
let instance = new Pattern();
|
||||
let config = instance.config;
|
||||
return (
|
||||
<Workbench
|
||||
freesewing={freesewing}
|
||||
Pattern={Pattern}
|
||||
config={config}
|
||||
userLanguage="en"
|
||||
/>
|
||||
);
|
||||
};
|
||||
let instance = new Pattern()
|
||||
let config = instance.config
|
||||
return <Workbench freesewing={freesewing} Pattern={Pattern} config={config} userLanguage="en" />
|
||||
}
|
||||
|
||||
export default App;
|
||||
export default App
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import App from "./App";
|
||||
import * as serviceWorker from "./serviceWorker";
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import App from './App'
|
||||
import * as serviceWorker from './serviceWorker'
|
||||
|
||||
ReactDOM.render(<App />, document.getElementById("root"));
|
||||
ReactDOM.render(<App />, document.getElementById('root'))
|
||||
|
||||
// If you want your app to work offline and load faster, you can change
|
||||
// unregister() to register() below. Note this comes with some pitfalls.
|
||||
// Learn more about service workers: http://bit.ly/CRA-PWA
|
||||
serviceWorker.unregister();
|
||||
serviceWorker.unregister()
|
||||
|
|
|
@ -9,46 +9,44 @@
|
|||
// This link also includes instructions on opting out of this behavior.
|
||||
|
||||
const isLocalhost = Boolean(
|
||||
window.location.hostname === "localhost" ||
|
||||
window.location.hostname === 'localhost' ||
|
||||
// [::1] is the IPv6 localhost address.
|
||||
window.location.hostname === "[::1]" ||
|
||||
window.location.hostname === '[::1]' ||
|
||||
// 127.0.0.1/8 is considered localhost for IPv4.
|
||||
window.location.hostname.match(
|
||||
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
|
||||
)
|
||||
);
|
||||
window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/)
|
||||
)
|
||||
|
||||
export function register(config) {
|
||||
if (process.env.NODE_ENV === "production" && "serviceWorker" in navigator) {
|
||||
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
|
||||
// The URL constructor is available in all browsers that support SW.
|
||||
const publicUrl = new URL(process.env.PUBLIC_URL, window.location);
|
||||
const publicUrl = new URL(process.env.PUBLIC_URL, window.location)
|
||||
if (publicUrl.origin !== window.location.origin) {
|
||||
// Our service worker won't work if PUBLIC_URL is on a different origin
|
||||
// from what our page is served on. This might happen if a CDN is used to
|
||||
// serve assets; see https://github.com/facebook/create-react-app/issues/2374
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
window.addEventListener("load", () => {
|
||||
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
|
||||
window.addEventListener('load', () => {
|
||||
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`
|
||||
|
||||
if (isLocalhost) {
|
||||
// This is running on localhost. Let's check if a service worker still exists or not.
|
||||
checkValidServiceWorker(swUrl, config);
|
||||
checkValidServiceWorker(swUrl, config)
|
||||
|
||||
// Add some additional logging to localhost, pointing developers to the
|
||||
// service worker/PWA documentation.
|
||||
navigator.serviceWorker.ready.then(() => {
|
||||
console.log(
|
||||
"This web app is being served cache-first by a service " +
|
||||
"worker. To learn more, visit https://goo.gl/SC7cgQ"
|
||||
);
|
||||
});
|
||||
'This web app is being served cache-first by a service ' +
|
||||
'worker. To learn more, visit https://goo.gl/SC7cgQ'
|
||||
)
|
||||
})
|
||||
} else {
|
||||
// Is not local host. Just register service worker
|
||||
registerValidSW(swUrl, config);
|
||||
registerValidSW(swUrl, config)
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,38 +55,38 @@ function registerValidSW(swUrl, config) {
|
|||
.register(swUrl)
|
||||
.then(registration => {
|
||||
registration.onupdatefound = () => {
|
||||
const installingWorker = registration.installing;
|
||||
const installingWorker = registration.installing
|
||||
installingWorker.onstatechange = () => {
|
||||
if (installingWorker.state === "installed") {
|
||||
if (installingWorker.state === 'installed') {
|
||||
if (navigator.serviceWorker.controller) {
|
||||
// At this point, the old content will have been purged and
|
||||
// the fresh content will have been added to the cache.
|
||||
// It's the perfect time to display a "New content is
|
||||
// available; please refresh." message in your web app.
|
||||
console.log("New content is available; please refresh.");
|
||||
console.log('New content is available; please refresh.')
|
||||
|
||||
// Execute callback
|
||||
if (config.onUpdate) {
|
||||
config.onUpdate(registration);
|
||||
config.onUpdate(registration)
|
||||
}
|
||||
} else {
|
||||
// At this point, everything has been precached.
|
||||
// It's the perfect time to display a
|
||||
// "Content is cached for offline use." message.
|
||||
console.log("Content is cached for offline use.");
|
||||
console.log('Content is cached for offline use.')
|
||||
|
||||
// Execute callback
|
||||
if (config.onSuccess) {
|
||||
config.onSuccess(registration);
|
||||
config.onSuccess(registration)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
})
|
||||
.catch(error => {
|
||||
console.error("Error during service worker registration:", error);
|
||||
});
|
||||
console.error('Error during service worker registration:', error)
|
||||
})
|
||||
}
|
||||
|
||||
function checkValidServiceWorker(swUrl, config) {
|
||||
|
@ -98,30 +96,28 @@ function checkValidServiceWorker(swUrl, config) {
|
|||
// Ensure service worker exists, and that we really are getting a JS file.
|
||||
if (
|
||||
response.status === 404 ||
|
||||
response.headers.get("content-type").indexOf("javascript") === -1
|
||||
response.headers.get('content-type').indexOf('javascript') === -1
|
||||
) {
|
||||
// No service worker found. Probably a different app. Reload the page.
|
||||
navigator.serviceWorker.ready.then(registration => {
|
||||
registration.unregister().then(() => {
|
||||
window.location.reload();
|
||||
});
|
||||
});
|
||||
window.location.reload()
|
||||
})
|
||||
})
|
||||
} else {
|
||||
// Service worker found. Proceed as normal.
|
||||
registerValidSW(swUrl, config);
|
||||
registerValidSW(swUrl, config)
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
console.log(
|
||||
"No internet connection found. App is running in offline mode."
|
||||
);
|
||||
});
|
||||
console.log('No internet connection found. App is running in offline mode.')
|
||||
})
|
||||
}
|
||||
|
||||
export function unregister() {
|
||||
if ("serviceWorker" in navigator) {
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.ready.then(registration => {
|
||||
registration.unregister();
|
||||
});
|
||||
registration.unregister()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { dimensions } from "./shared";
|
||||
import { dimensions } from './shared'
|
||||
|
||||
export default function(part) {
|
||||
let {
|
||||
|
@ -14,23 +14,23 @@ export default function(part) {
|
|||
macro,
|
||||
utils,
|
||||
units
|
||||
} = part.shorthand();
|
||||
} = part.shorthand()
|
||||
|
||||
points.strapLeftCp2 = utils.beamsIntersect(
|
||||
points.strapLeft,
|
||||
points.strapCenter.rotate(90, points.strapLeft),
|
||||
points.cbNeck,
|
||||
points.cbNeck.shift(0, 10)
|
||||
);
|
||||
)
|
||||
|
||||
points.armholeCp2 = points.aaronArmhole.shiftFractionTowards(
|
||||
points.armholeCorner,
|
||||
options.backlineBend
|
||||
);
|
||||
)
|
||||
points.strapRightCp1 = points.strapRight.shiftFractionTowards(
|
||||
points.armholeCorner,
|
||||
options.backlineBend
|
||||
);
|
||||
)
|
||||
|
||||
// Seamline
|
||||
paths.seam = new Path()
|
||||
|
@ -43,7 +43,7 @@ export default function(part) {
|
|||
.line(points.strapLeft)
|
||||
.curve(points.strapLeftCp2, points.cbNeck, points.cbNeck)
|
||||
.close()
|
||||
.attr("class", "fabric");
|
||||
.attr('class', 'fabric')
|
||||
|
||||
// Complete pattern?
|
||||
if (complete) {
|
||||
|
@ -51,57 +51,54 @@ export default function(part) {
|
|||
new Path()
|
||||
.move(points.strapLeft)
|
||||
.curve(points.strapLeftCp2, points.cbNeck, points.cbNeck)
|
||||
.length() + store.get("frontNeckOpeningLength");
|
||||
.length() + store.get('frontNeckOpeningLength')
|
||||
let armholeLength =
|
||||
new Path()
|
||||
.move(points.aaronArmhole)
|
||||
.curve(points.armholeCp2, points.strapRightCp1, points.strapRight)
|
||||
.length() + store.get("frontArmholeLength");
|
||||
points.bindinAnchor = new Point(
|
||||
points.aaronArmhole.x / 4,
|
||||
points.aaronArmhole.y
|
||||
)
|
||||
.attr("data-text", "cutTwoStripsToFinishTheArmholes")
|
||||
.attr("data-text", ":\n")
|
||||
.attr("data-text", "width")
|
||||
.attr("data-text", ":")
|
||||
.attr("data-text", units(sa * 6))
|
||||
.attr("data-text", "\n")
|
||||
.attr("data-text", "length")
|
||||
.attr("data-text", ":")
|
||||
.attr("data-text", units(armholeLength * 0.95 + 2 * sa))
|
||||
.attr("data-text", "\n \n")
|
||||
.attr("data-text", "cutOneStripToFinishTheNeckOpening")
|
||||
.attr("data-text", ":\n")
|
||||
.attr("data-text", "width")
|
||||
.attr("data-text", ":")
|
||||
.attr("data-text", units(sa * 6))
|
||||
.attr("data-text", "\n")
|
||||
.attr("data-text", "length")
|
||||
.attr("data-text", ":")
|
||||
.attr("data-text", units(neckOpeningLength * 0.95 + 2 * sa))
|
||||
.attr("data-text-lineheight", 6);
|
||||
.length() + store.get('frontArmholeLength')
|
||||
points.bindinAnchor = new Point(points.aaronArmhole.x / 4, points.aaronArmhole.y)
|
||||
.attr('data-text', 'cutTwoStripsToFinishTheArmholes')
|
||||
.attr('data-text', ':\n')
|
||||
.attr('data-text', 'width')
|
||||
.attr('data-text', ':')
|
||||
.attr('data-text', units(sa * 6))
|
||||
.attr('data-text', '\n')
|
||||
.attr('data-text', 'length')
|
||||
.attr('data-text', ':')
|
||||
.attr('data-text', units(armholeLength * 0.95 + 2 * sa))
|
||||
.attr('data-text', '\n \n')
|
||||
.attr('data-text', 'cutOneStripToFinishTheNeckOpening')
|
||||
.attr('data-text', ':\n')
|
||||
.attr('data-text', 'width')
|
||||
.attr('data-text', ':')
|
||||
.attr('data-text', units(sa * 6))
|
||||
.attr('data-text', '\n')
|
||||
.attr('data-text', 'length')
|
||||
.attr('data-text', ':')
|
||||
.attr('data-text', units(neckOpeningLength * 0.95 + 2 * sa))
|
||||
.attr('data-text-lineheight', 6)
|
||||
|
||||
macro("cutonfold", {
|
||||
macro('cutonfold', {
|
||||
from: points.cfNeck,
|
||||
to: points.cfHem,
|
||||
grainline: true
|
||||
});
|
||||
})
|
||||
|
||||
macro("title", { at: points.title, nr: 2, title: "back" });
|
||||
points.scaleboxAnchor = points.scalebox = points.title.shift(90, 100);
|
||||
macro("scalebox", { at: points.scalebox });
|
||||
macro('title', { at: points.title, nr: 2, title: 'back' })
|
||||
points.scaleboxAnchor = points.scalebox = points.title.shift(90, 100)
|
||||
macro('scalebox', { at: points.scalebox })
|
||||
}
|
||||
|
||||
// Paperless?
|
||||
if (paperless) {
|
||||
dimensions(macro, points, sa);
|
||||
macro("vd", {
|
||||
dimensions(macro, points, sa)
|
||||
macro('vd', {
|
||||
from: points.cbHem,
|
||||
to: points.cbNeck,
|
||||
x: points.cbHem.x - sa - 15
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
return part;
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { dimensions } from "./shared";
|
||||
import { dimensions } from './shared'
|
||||
|
||||
export default function(part) {
|
||||
let {
|
||||
|
@ -16,75 +16,67 @@ export default function(part) {
|
|||
complete,
|
||||
paperless,
|
||||
macro
|
||||
} = part.shorthand();
|
||||
} = part.shorthand()
|
||||
|
||||
// Hide Brian paths
|
||||
for (let key of Object.keys(paths)) paths[key].render = false;
|
||||
for (let key of Object.keys(paths)) paths[key].render = false
|
||||
|
||||
// Handle stretch
|
||||
for (let i in points) points[i].x = points[i].x * (1 - options.stretchFactor);
|
||||
for (let i in points) points[i].x = points[i].x * (1 - options.stretchFactor)
|
||||
|
||||
// Rename cb (center back) to cf (center front)
|
||||
for (let key of ["Neck", "Shoulder", "Armhole", "Waist", "Hips", "Hem"]) {
|
||||
points[`cf${key}`] = new Point(points[`cb${key}`].x, points[`cb${key}`].y);
|
||||
for (let key of ['Neck', 'Shoulder', 'Armhole', 'Waist', 'Hips', 'Hem']) {
|
||||
points[`cf${key}`] = new Point(points[`cb${key}`].x, points[`cb${key}`].y)
|
||||
//delete points[`cb${key}`];
|
||||
}
|
||||
|
||||
// Neckline
|
||||
points.cfNeck = points.cfNeck.shift(
|
||||
-90,
|
||||
options.necklineDrop *
|
||||
(measurements.centerBackNeckToWaist + measurements.naturalWaistToHip)
|
||||
);
|
||||
options.necklineDrop * (measurements.centerBackNeckToWaist + measurements.naturalWaistToHip)
|
||||
)
|
||||
|
||||
// Strap
|
||||
points.strapCenter = points.neck.shiftFractionTowards(
|
||||
points.shoulder,
|
||||
options.shoulderStrapPlacement
|
||||
);
|
||||
)
|
||||
points.strapLeft = points.strapCenter.shiftTowards(
|
||||
points.neck,
|
||||
points.neck.dist(points.shoulder) * options.shoulderStrapWidth
|
||||
);
|
||||
points.strapRight = points.strapLeft.rotate(180, points.strapCenter);
|
||||
)
|
||||
points.strapRight = points.strapLeft.rotate(180, points.strapCenter)
|
||||
points.necklineCorner = utils.beamsIntersect(
|
||||
points.strapLeft,
|
||||
points.strapRight.rotate(-90, points.strapLeft),
|
||||
points.cfNeck.shift(0, points.armholePitch.x / 4),
|
||||
points.cfNeck
|
||||
);
|
||||
)
|
||||
points.strapLeftCp2 = points.strapLeft.shiftFractionTowards(
|
||||
points.necklineCorner,
|
||||
options.necklineBend
|
||||
);
|
||||
points.cfNeckCp1 = points.cfNeck.shiftFractionTowards(
|
||||
points.necklineCorner,
|
||||
options.necklineBend
|
||||
);
|
||||
)
|
||||
points.cfNeckCp1 = points.cfNeck.shiftFractionTowards(points.necklineCorner, options.necklineBend)
|
||||
|
||||
// Hips
|
||||
points.hips.x =
|
||||
((measurements.hipsCircumference +
|
||||
options.hipsEase * measurements.hipsCircumference) /
|
||||
4) *
|
||||
(1 - options.stretchFactor);
|
||||
points.waist.x = points.hips.x; // Because stretch
|
||||
points.waistCp2 = points.waist.shift(90, points.armhole.dy(points.waist) / 2);
|
||||
((measurements.hipsCircumference + options.hipsEase * measurements.hipsCircumference) / 4) *
|
||||
(1 - options.stretchFactor)
|
||||
points.waist.x = points.hips.x // Because stretch
|
||||
points.waistCp2 = points.waist.shift(90, points.armhole.dy(points.waist) / 2)
|
||||
|
||||
// Hem
|
||||
points.hem.x = points.hips.x;
|
||||
points.hem.x = points.hips.x
|
||||
|
||||
// Armhole drop
|
||||
let side = new Path()
|
||||
.move(points.hem)
|
||||
.line(points.waist)
|
||||
.curve(points.waistCp2, points.armhole, points.armhole);
|
||||
let split = side
|
||||
.intersectsY(points.armhole.y * (1 + options.armholeDrop))
|
||||
.pop();
|
||||
paths.side = side.split(split)[0];
|
||||
paths.side.render = false;
|
||||
points.aaronArmhole = split;
|
||||
.curve(points.waistCp2, points.armhole, points.armhole)
|
||||
let split = side.intersectsY(points.armhole.y * (1 + options.armholeDrop)).pop()
|
||||
paths.side = side.split(split)[0]
|
||||
paths.side.render = false
|
||||
points.aaronArmhole = split
|
||||
|
||||
// Armhole
|
||||
points.armholeCorner = utils.beamsIntersect(
|
||||
|
@ -92,15 +84,9 @@ export default function(part) {
|
|||
points.aaronArmhole.shift(180, 10),
|
||||
points.strapRight,
|
||||
points.strapLeft.rotate(90, points.strapRight)
|
||||
);
|
||||
points.armholeCp2 = points.aaronArmhole.shiftFractionTowards(
|
||||
points.armholeCorner,
|
||||
0.8
|
||||
);
|
||||
points.strapRightCp1 = points.strapRight.shiftFractionTowards(
|
||||
points.armholeCorner,
|
||||
0.6
|
||||
);
|
||||
)
|
||||
points.armholeCp2 = points.aaronArmhole.shiftFractionTowards(points.armholeCorner, 0.8)
|
||||
points.strapRightCp1 = points.strapRight.shiftFractionTowards(points.armholeCorner, 0.6)
|
||||
|
||||
// Seamline
|
||||
paths.seam = new Path()
|
||||
|
@ -113,35 +99,35 @@ export default function(part) {
|
|||
.line(points.strapLeft)
|
||||
.curve(points.strapLeftCp2, points.cfNeckCp1, points.cfNeck)
|
||||
.close()
|
||||
.attr("class", "fabric");
|
||||
.attr('class', 'fabric')
|
||||
|
||||
// Store length of armhole and neck opening
|
||||
store.set(
|
||||
"frontArmholeLength",
|
||||
'frontArmholeLength',
|
||||
new Path()
|
||||
.move(points.aaronArmhole)
|
||||
.curve(points.armholeCp2, points.strapRightCp1, points.strapRight)
|
||||
.length()
|
||||
);
|
||||
)
|
||||
store.set(
|
||||
"frontNeckOpeningLength",
|
||||
'frontNeckOpeningLength',
|
||||
new Path()
|
||||
.move(points.strapLeft)
|
||||
.curve(points.cfNeckCp1, points.cfNeckCp1, points.cfNeck)
|
||||
.length()
|
||||
);
|
||||
)
|
||||
|
||||
// Complete pattern?
|
||||
if (complete) {
|
||||
macro("cutonfold", {
|
||||
macro('cutonfold', {
|
||||
from: points.cfNeck,
|
||||
to: points.cfHem,
|
||||
grainline: true
|
||||
});
|
||||
points.title = new Point(points.waist.x / 2, points.waist.y);
|
||||
macro("title", { at: points.title, nr: 1, title: "front" });
|
||||
points.logo = points.title.shift(-90, 75);
|
||||
snippets.logo = new Snippet("logo", points.logo);
|
||||
})
|
||||
points.title = new Point(points.waist.x / 2, points.waist.y)
|
||||
macro('title', { at: points.title, nr: 1, title: 'front' })
|
||||
points.logo = points.title.shift(-90, 75)
|
||||
snippets.logo = new Snippet('logo', points.logo)
|
||||
|
||||
if (sa) {
|
||||
paths.saShoulder = new Path()
|
||||
|
@ -149,31 +135,31 @@ export default function(part) {
|
|||
.line(points.strapLeft)
|
||||
.offset(sa)
|
||||
.line(points.strapLeft)
|
||||
.attr("class", "fabric sa");
|
||||
paths.saShoulder.move(points.strapRight).line(paths.saShoulder.start());
|
||||
.attr('class', 'fabric sa')
|
||||
paths.saShoulder.move(points.strapRight).line(paths.saShoulder.start())
|
||||
paths.saSide = paths.side
|
||||
.offset(sa)
|
||||
.line(points.aaronArmhole)
|
||||
.attr("class", "fabric sa");
|
||||
.attr('class', 'fabric sa')
|
||||
paths.saHem = new Path()
|
||||
.move(points.cfHem)
|
||||
.line(points.hem)
|
||||
.offset(sa * 2.5)
|
||||
.attr("class", "fabric sa")
|
||||
.line(paths.saSide.start());
|
||||
paths.saHem.move(points.cfHem).line(paths.saHem.start());
|
||||
.attr('class', 'fabric sa')
|
||||
.line(paths.saSide.start())
|
||||
paths.saHem.move(points.cfHem).line(paths.saHem.start())
|
||||
}
|
||||
}
|
||||
|
||||
// Paperless?
|
||||
if (paperless) {
|
||||
dimensions(macro, points, sa);
|
||||
macro("vd", {
|
||||
dimensions(macro, points, sa)
|
||||
macro('vd', {
|
||||
from: points.cfHem,
|
||||
to: points.cfNeck,
|
||||
x: points.cfHem.x - sa - 15
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
return part;
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
import freesewing from "@freesewing/core";
|
||||
import Brian from "@freesewing/brian";
|
||||
import plugins from "@freesewing/plugin-bundle";
|
||||
import config from "../config";
|
||||
import freesewing from '@freesewing/core'
|
||||
import Brian from '@freesewing/brian'
|
||||
import plugins from '@freesewing/plugin-bundle'
|
||||
import config from '../config'
|
||||
// Parts
|
||||
import draftBack from "./back";
|
||||
import draftFront from "./front";
|
||||
import draftBack from './back'
|
||||
import draftFront from './front'
|
||||
|
||||
// Create design
|
||||
const Pattern = new freesewing.Design(config, plugins);
|
||||
const Pattern = new freesewing.Design(config, plugins)
|
||||
|
||||
// Attach draft methods to prototype
|
||||
Pattern.prototype.draftBase = function(part) {
|
||||
// Getting the base part from Brian
|
||||
return new Brian(this.settings).draftBase(part);
|
||||
};
|
||||
Pattern.prototype.draftFront = part => draftFront(part);
|
||||
Pattern.prototype.draftBack = part => draftBack(part);
|
||||
return new Brian(this.settings).draftBase(part)
|
||||
}
|
||||
Pattern.prototype.draftFront = part => draftFront(part)
|
||||
Pattern.prototype.draftBack = part => draftBack(part)
|
||||
|
||||
export default Pattern;
|
||||
export default Pattern
|
||||
|
|
|
@ -1,37 +1,37 @@
|
|||
export function dimensions(macro, points, sa) {
|
||||
macro("hd", {
|
||||
macro('hd', {
|
||||
from: points.cfHem,
|
||||
to: points.hem,
|
||||
y: points.hem.y + sa * 2.5 + 15
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.cfNeck,
|
||||
to: points.strapLeft,
|
||||
y: points.neck.y - sa - 15
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.cfNeck,
|
||||
to: points.strapRight,
|
||||
y: points.neck.y - sa - 30
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.hem,
|
||||
to: points.aaronArmhole,
|
||||
x: points.aaronArmhole.x + sa + 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.hem,
|
||||
to: points.strapRight,
|
||||
x: points.aaronArmhole.x + sa + 30
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.hem,
|
||||
to: points.strapLeft,
|
||||
x: points.aaronArmhole.x + sa + 45
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.cfNeck,
|
||||
to: points.aaronArmhole,
|
||||
y: points.neck.y - sa - 45
|
||||
});
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,22 +1,15 @@
|
|||
import React from "react";
|
||||
import freesewing from "@freesewing/core";
|
||||
import Workbench from "@freesewing/components/Workbench";
|
||||
import "typeface-roboto-condensed";
|
||||
import "@freesewing/css-theme";
|
||||
import React from 'react'
|
||||
import freesewing from '@freesewing/core'
|
||||
import Workbench from '@freesewing/components/Workbench'
|
||||
import 'typeface-roboto-condensed'
|
||||
import '@freesewing/css-theme'
|
||||
|
||||
import Pattern from "pattern";
|
||||
import Pattern from 'pattern'
|
||||
|
||||
const App = props => {
|
||||
let instance = new Pattern();
|
||||
let config = instance.config;
|
||||
return (
|
||||
<Workbench
|
||||
freesewing={freesewing}
|
||||
Pattern={Pattern}
|
||||
config={config}
|
||||
userLanguage="en"
|
||||
/>
|
||||
);
|
||||
};
|
||||
let instance = new Pattern()
|
||||
let config = instance.config
|
||||
return <Workbench freesewing={freesewing} Pattern={Pattern} config={config} userLanguage="en" />
|
||||
}
|
||||
|
||||
export default App;
|
||||
export default App
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import App from "./App";
|
||||
import * as serviceWorker from "./serviceWorker";
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import App from './App'
|
||||
import * as serviceWorker from './serviceWorker'
|
||||
|
||||
ReactDOM.render(<App />, document.getElementById("root"));
|
||||
ReactDOM.render(<App />, document.getElementById('root'))
|
||||
|
||||
// If you want your app to work offline and load faster, you can change
|
||||
// unregister() to register() below. Note this comes with some pitfalls.
|
||||
// Learn more about service workers: http://bit.ly/CRA-PWA
|
||||
serviceWorker.unregister();
|
||||
serviceWorker.unregister()
|
||||
|
|
|
@ -9,46 +9,44 @@
|
|||
// This link also includes instructions on opting out of this behavior.
|
||||
|
||||
const isLocalhost = Boolean(
|
||||
window.location.hostname === "localhost" ||
|
||||
window.location.hostname === 'localhost' ||
|
||||
// [::1] is the IPv6 localhost address.
|
||||
window.location.hostname === "[::1]" ||
|
||||
window.location.hostname === '[::1]' ||
|
||||
// 127.0.0.1/8 is considered localhost for IPv4.
|
||||
window.location.hostname.match(
|
||||
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
|
||||
)
|
||||
);
|
||||
window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/)
|
||||
)
|
||||
|
||||
export function register(config) {
|
||||
if (process.env.NODE_ENV === "production" && "serviceWorker" in navigator) {
|
||||
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
|
||||
// The URL constructor is available in all browsers that support SW.
|
||||
const publicUrl = new URL(process.env.PUBLIC_URL, window.location);
|
||||
const publicUrl = new URL(process.env.PUBLIC_URL, window.location)
|
||||
if (publicUrl.origin !== window.location.origin) {
|
||||
// Our service worker won't work if PUBLIC_URL is on a different origin
|
||||
// from what our page is served on. This might happen if a CDN is used to
|
||||
// serve assets; see https://github.com/facebook/create-react-app/issues/2374
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
window.addEventListener("load", () => {
|
||||
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
|
||||
window.addEventListener('load', () => {
|
||||
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`
|
||||
|
||||
if (isLocalhost) {
|
||||
// This is running on localhost. Let's check if a service worker still exists or not.
|
||||
checkValidServiceWorker(swUrl, config);
|
||||
checkValidServiceWorker(swUrl, config)
|
||||
|
||||
// Add some additional logging to localhost, pointing developers to the
|
||||
// service worker/PWA documentation.
|
||||
navigator.serviceWorker.ready.then(() => {
|
||||
console.log(
|
||||
"This web app is being served cache-first by a service " +
|
||||
"worker. To learn more, visit https://goo.gl/SC7cgQ"
|
||||
);
|
||||
});
|
||||
'This web app is being served cache-first by a service ' +
|
||||
'worker. To learn more, visit https://goo.gl/SC7cgQ'
|
||||
)
|
||||
})
|
||||
} else {
|
||||
// Is not local host. Just register service worker
|
||||
registerValidSW(swUrl, config);
|
||||
registerValidSW(swUrl, config)
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,38 +55,38 @@ function registerValidSW(swUrl, config) {
|
|||
.register(swUrl)
|
||||
.then(registration => {
|
||||
registration.onupdatefound = () => {
|
||||
const installingWorker = registration.installing;
|
||||
const installingWorker = registration.installing
|
||||
installingWorker.onstatechange = () => {
|
||||
if (installingWorker.state === "installed") {
|
||||
if (installingWorker.state === 'installed') {
|
||||
if (navigator.serviceWorker.controller) {
|
||||
// At this point, the old content will have been purged and
|
||||
// the fresh content will have been added to the cache.
|
||||
// It's the perfect time to display a "New content is
|
||||
// available; please refresh." message in your web app.
|
||||
console.log("New content is available; please refresh.");
|
||||
console.log('New content is available; please refresh.')
|
||||
|
||||
// Execute callback
|
||||
if (config.onUpdate) {
|
||||
config.onUpdate(registration);
|
||||
config.onUpdate(registration)
|
||||
}
|
||||
} else {
|
||||
// At this point, everything has been precached.
|
||||
// It's the perfect time to display a
|
||||
// "Content is cached for offline use." message.
|
||||
console.log("Content is cached for offline use.");
|
||||
console.log('Content is cached for offline use.')
|
||||
|
||||
// Execute callback
|
||||
if (config.onSuccess) {
|
||||
config.onSuccess(registration);
|
||||
config.onSuccess(registration)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
})
|
||||
.catch(error => {
|
||||
console.error("Error during service worker registration:", error);
|
||||
});
|
||||
console.error('Error during service worker registration:', error)
|
||||
})
|
||||
}
|
||||
|
||||
function checkValidServiceWorker(swUrl, config) {
|
||||
|
@ -98,30 +96,28 @@ function checkValidServiceWorker(swUrl, config) {
|
|||
// Ensure service worker exists, and that we really are getting a JS file.
|
||||
if (
|
||||
response.status === 404 ||
|
||||
response.headers.get("content-type").indexOf("javascript") === -1
|
||||
response.headers.get('content-type').indexOf('javascript') === -1
|
||||
) {
|
||||
// No service worker found. Probably a different app. Reload the page.
|
||||
navigator.serviceWorker.ready.then(registration => {
|
||||
registration.unregister().then(() => {
|
||||
window.location.reload();
|
||||
});
|
||||
});
|
||||
window.location.reload()
|
||||
})
|
||||
})
|
||||
} else {
|
||||
// Service worker found. Proceed as normal.
|
||||
registerValidSW(swUrl, config);
|
||||
registerValidSW(swUrl, config)
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
console.log(
|
||||
"No internet connection found. App is running in offline mode."
|
||||
);
|
||||
});
|
||||
console.log('No internet connection found. App is running in offline mode.')
|
||||
})
|
||||
}
|
||||
|
||||
export function unregister() {
|
||||
if ("serviceWorker" in navigator) {
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.ready.then(registration => {
|
||||
registration.unregister();
|
||||
});
|
||||
registration.unregister()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,122 +13,114 @@ export default function(part) {
|
|||
complete,
|
||||
paperless,
|
||||
macro
|
||||
} = part.shorthand();
|
||||
} = part.shorthand()
|
||||
|
||||
if (options.bowStyle === "square") options.tipWidth = options.knotWidth;
|
||||
if (options.bowStyle === 'square') options.tipWidth = options.knotWidth
|
||||
|
||||
for (let option of [
|
||||
"ribbonWidth",
|
||||
"bandLength",
|
||||
"tipWidth",
|
||||
"knotWidth",
|
||||
"bowLength",
|
||||
"collarEase"
|
||||
'ribbonWidth',
|
||||
'bandLength',
|
||||
'tipWidth',
|
||||
'knotWidth',
|
||||
'bowLength',
|
||||
'collarEase'
|
||||
])
|
||||
store.set(option, measurements.neckCircumference * options[option]);
|
||||
store.set(option, measurements.neckCircumference * options[option])
|
||||
|
||||
// For easy access
|
||||
const knot = store.get("knotWidth");
|
||||
const ribbon = store.get("ribbonWidth");
|
||||
const tip = store.get("tipWidth");
|
||||
const band = store.get("bandLength");
|
||||
const transition = band * options.transitionLength;
|
||||
const bow = store.get("bowLength");
|
||||
const knot = store.get('knotWidth')
|
||||
const ribbon = store.get('ribbonWidth')
|
||||
const tip = store.get('tipWidth')
|
||||
const band = store.get('bandLength')
|
||||
const transition = band * options.transitionLength
|
||||
const bow = store.get('bowLength')
|
||||
|
||||
// Points
|
||||
points.bandBottomLeft = new Point(0, ribbon / 2);
|
||||
points.bandTopLeft = points.bandBottomLeft.flipY();
|
||||
points.bandBottomRight = points.bandBottomLeft.shift(0, band);
|
||||
points.bandTopRight = points.bandBottomRight.flipY();
|
||||
points.bandBottomLeft = new Point(0, ribbon / 2)
|
||||
points.bandTopLeft = points.bandBottomLeft.flipY()
|
||||
points.bandBottomRight = points.bandBottomLeft.shift(0, band)
|
||||
points.bandTopRight = points.bandBottomRight.flipY()
|
||||
|
||||
points.transitionBottomRight = new Point(band + transition, knot / 2);
|
||||
points.transitionTopRight = points.transitionBottomRight.flipY();
|
||||
points.transitionBottomRight = new Point(band + transition, knot / 2)
|
||||
points.transitionTopRight = points.transitionBottomRight.flipY()
|
||||
|
||||
points.tip1Bottom = new Point(band + transition + 0.5 * bow, tip / 2);
|
||||
points.tip1Top = points.tip1Bottom.flipY();
|
||||
points.tip2Bottom = new Point(band + transition + 1.5 * bow, tip / 2);
|
||||
points.tip2Top = points.tip2Bottom.flipY();
|
||||
points.knotBottom = new Point(band + transition + bow, knot / 2);
|
||||
points.knotTop = points.knotBottom.flipY();
|
||||
points.tip1Bottom = new Point(band + transition + 0.5 * bow, tip / 2)
|
||||
points.tip1Top = points.tip1Bottom.flipY()
|
||||
points.tip2Bottom = new Point(band + transition + 1.5 * bow, tip / 2)
|
||||
points.tip2Top = points.tip2Bottom.flipY()
|
||||
points.knotBottom = new Point(band + transition + bow, knot / 2)
|
||||
points.knotTop = points.knotBottom.flipY()
|
||||
|
||||
if (options.endStyle === "pointed" || options.endStyle === "rounded") {
|
||||
points.tip = new Point(points.tip2Bottom.x + points.tip2Bottom.y, 0);
|
||||
} else points.tip = new Point(points.tip2Bottom.x, 0);
|
||||
if (options.endStyle === 'pointed' || options.endStyle === 'rounded') {
|
||||
points.tip = new Point(points.tip2Bottom.x + points.tip2Bottom.y, 0)
|
||||
} else points.tip = new Point(points.tip2Bottom.x, 0)
|
||||
|
||||
points.grainlineStart = new Point(0, 0);
|
||||
points.titleAnchor = new Point(points.tip1Top.x, 0);
|
||||
points.grainlineStart = new Point(0, 0)
|
||||
points.titleAnchor = new Point(points.tip1Top.x, 0)
|
||||
|
||||
// Paths
|
||||
paths.cap = new Path().move(points.tip2Bottom);
|
||||
if (options.endStyle === "straight") {
|
||||
paths.cap = new Path().move(points.tip2Bottom).line(points.tip2Top);
|
||||
} else if (options.endStyle === "pointed") {
|
||||
paths.cap = new Path().move(points.tip2Bottom)
|
||||
if (options.endStyle === 'straight') {
|
||||
paths.cap = new Path().move(points.tip2Bottom).line(points.tip2Top)
|
||||
} else if (options.endStyle === 'pointed') {
|
||||
paths.cap = new Path()
|
||||
.move(points.tip2Bottom)
|
||||
.line(points.tip)
|
||||
.line(points.tip2Top);
|
||||
.line(points.tip2Top)
|
||||
} else {
|
||||
points.roundBottom = new Point(points.tip.x, points.tip2Bottom.y);
|
||||
points.roundTop = points.roundBottom.flipY();
|
||||
macro("round", {
|
||||
points.roundBottom = new Point(points.tip.x, points.tip2Bottom.y)
|
||||
points.roundTop = points.roundBottom.flipY()
|
||||
macro('round', {
|
||||
from: points.tip2Bottom,
|
||||
to: points.tip,
|
||||
via: points.roundBottom,
|
||||
prefix: "bottom"
|
||||
});
|
||||
macro("round", {
|
||||
prefix: 'bottom'
|
||||
})
|
||||
macro('round', {
|
||||
from: points.tip,
|
||||
to: points.tip2Top,
|
||||
via: points.roundTop,
|
||||
prefix: "top"
|
||||
});
|
||||
paths.cap = paths.bottomRounded.join(paths.topRounded);
|
||||
prefix: 'top'
|
||||
})
|
||||
paths.cap = paths.bottomRounded.join(paths.topRounded)
|
||||
}
|
||||
paths.cap.render = false;
|
||||
paths.cap.render = false
|
||||
|
||||
if (options.bowStyle === "diamond" || options.bowStyle === "butterfly") {
|
||||
const cpl = options.bowStyle === "diamond" ? bow / 10 : bow / 4;
|
||||
if (options.bowStyle === 'diamond' || options.bowStyle === 'butterfly') {
|
||||
const cpl = options.bowStyle === 'diamond' ? bow / 10 : bow / 4
|
||||
|
||||
points.transitionBottomRightCp2 = points.bandBottomRight.shiftOutwards(
|
||||
points.transitionBottomRight,
|
||||
cpl
|
||||
);
|
||||
points.transitionTopRightCp1 = points.transitionBottomRightCp2.flipY();
|
||||
points.tip1TopCp2 = points.tip1Top.shift(180, cpl);
|
||||
points.tip1TopCp1 = points.tip1Top.shift(0, cpl);
|
||||
points.tip1BottomCp1 = points.tip1Bottom.shift(180, cpl);
|
||||
points.tip1BottomCp2 = points.tip1Bottom.shift(0, cpl);
|
||||
points.knotTopCp2 = points.knotTop.shift(180, cpl);
|
||||
points.knotTopCp1 = points.knotTop.shift(0, cpl);
|
||||
points.knotBottomCp2 = points.knotBottom.shift(0, cpl);
|
||||
points.knotBottomCp1 = points.knotBottom.shift(180, cpl);
|
||||
points.tip2TopCp2 = points.tip2Top.shift(180, cpl);
|
||||
points.tip2BottomCp1 = points.tip2Bottom.shift(180, cpl);
|
||||
)
|
||||
points.transitionTopRightCp1 = points.transitionBottomRightCp2.flipY()
|
||||
points.tip1TopCp2 = points.tip1Top.shift(180, cpl)
|
||||
points.tip1TopCp1 = points.tip1Top.shift(0, cpl)
|
||||
points.tip1BottomCp1 = points.tip1Bottom.shift(180, cpl)
|
||||
points.tip1BottomCp2 = points.tip1Bottom.shift(0, cpl)
|
||||
points.knotTopCp2 = points.knotTop.shift(180, cpl)
|
||||
points.knotTopCp1 = points.knotTop.shift(0, cpl)
|
||||
points.knotBottomCp2 = points.knotBottom.shift(0, cpl)
|
||||
points.knotBottomCp1 = points.knotBottom.shift(180, cpl)
|
||||
points.tip2TopCp2 = points.tip2Top.shift(180, cpl)
|
||||
points.tip2BottomCp1 = points.tip2Bottom.shift(180, cpl)
|
||||
|
||||
paths.seam = new Path()
|
||||
.move(points.bandTopLeft)
|
||||
.line(points.bandBottomLeft)
|
||||
.line(points.bandBottomRight)
|
||||
.line(points.transitionBottomRight)
|
||||
.curve(
|
||||
points.transitionBottomRightCp2,
|
||||
points.tip1BottomCp1,
|
||||
points.tip1Bottom
|
||||
)
|
||||
.curve(points.transitionBottomRightCp2, points.tip1BottomCp1, points.tip1Bottom)
|
||||
.curve(points.tip1BottomCp2, points.knotBottomCp1, points.knotBottom)
|
||||
.curve(points.knotBottomCp2, points.tip2BottomCp1, points.tip2Bottom)
|
||||
.join(paths.cap)
|
||||
.line(points.tip2Top)
|
||||
.curve(points.tip2TopCp2, points.knotTopCp1, points.knotTop)
|
||||
.curve(points.knotTopCp2, points.tip1TopCp1, points.tip1Top)
|
||||
.curve(
|
||||
points.tip1TopCp2,
|
||||
points.transitionTopRightCp1,
|
||||
points.transitionTopRight
|
||||
)
|
||||
.curve(points.tip1TopCp2, points.transitionTopRightCp1, points.transitionTopRight)
|
||||
.line(points.bandTopRight)
|
||||
.line(points.bandTopLeft)
|
||||
.close();
|
||||
.close()
|
||||
} else {
|
||||
paths.seam = new Path()
|
||||
.move(points.bandTopLeft)
|
||||
|
@ -141,85 +133,82 @@ export default function(part) {
|
|||
.line(points.transitionTopRight)
|
||||
.line(points.bandTopRight)
|
||||
.line(points.bandTopLeft)
|
||||
.close();
|
||||
.close()
|
||||
}
|
||||
|
||||
paths.seam.attr("class", "fabric");
|
||||
paths.seam.attr('class', 'fabric')
|
||||
|
||||
// Complete?
|
||||
if (complete) {
|
||||
if (sa) paths.sa = paths.seam.offset(sa).attr("class", "fabric sa");
|
||||
if (sa) paths.sa = paths.seam.offset(sa).attr('class', 'fabric sa')
|
||||
|
||||
macro("grainline", {
|
||||
macro('grainline', {
|
||||
from: points.grainlineStart,
|
||||
to: points.tip
|
||||
});
|
||||
points.logoAnchor = points.tip.shift(180, 20);
|
||||
snippets.logo = new Snippet("logo", points.logoAnchor).attr(
|
||||
"data-scale",
|
||||
0.5
|
||||
);
|
||||
})
|
||||
points.logoAnchor = points.tip.shift(180, 20)
|
||||
snippets.logo = new Snippet('logo', points.logoAnchor).attr('data-scale', 0.5)
|
||||
|
||||
// Paperless?
|
||||
if (paperless) {
|
||||
let baseY = points.tip2Bottom.y + 15 + sa;
|
||||
if (options.bowStyle === "butterfly" || options.bowStyle === "diamond") {
|
||||
macro("hd", {
|
||||
let baseY = points.tip2Bottom.y + 15 + sa
|
||||
if (options.bowStyle === 'butterfly' || options.bowStyle === 'diamond') {
|
||||
macro('hd', {
|
||||
from: points.knotBottom,
|
||||
to: points.tip2Bottom,
|
||||
y: baseY
|
||||
});
|
||||
baseY += 15;
|
||||
macro("hd", {
|
||||
})
|
||||
baseY += 15
|
||||
macro('hd', {
|
||||
from: points.tip1Bottom,
|
||||
to: points.tip2Bottom,
|
||||
y: baseY
|
||||
});
|
||||
baseY += 15;
|
||||
macro("vd", {
|
||||
})
|
||||
baseY += 15
|
||||
macro('vd', {
|
||||
from: points.tip1Bottom,
|
||||
to: points.tip1Top
|
||||
});
|
||||
})
|
||||
}
|
||||
macro("hd", {
|
||||
macro('hd', {
|
||||
from: points.transitionBottomRight,
|
||||
to: points.tip2Bottom,
|
||||
y: baseY
|
||||
});
|
||||
baseY += 15;
|
||||
macro("hd", {
|
||||
})
|
||||
baseY += 15
|
||||
macro('hd', {
|
||||
from: points.bandBottomRight,
|
||||
to: points.tip2Bottom,
|
||||
y: baseY
|
||||
});
|
||||
baseY += 15;
|
||||
macro("hd", {
|
||||
})
|
||||
baseY += 15
|
||||
macro('hd', {
|
||||
from: points.bandBottomLeft,
|
||||
to: points.tip2Bottom,
|
||||
y: baseY
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.bandBottomRight,
|
||||
to: points.bandTopRight
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.transitionBottomRight,
|
||||
to: points.transitionTopRight
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.tip2Bottom,
|
||||
to: points.tip2Top,
|
||||
x: points.tip.x + 15 + sa
|
||||
});
|
||||
if (options.endStyle !== "straight") {
|
||||
macro("hd", {
|
||||
})
|
||||
if (options.endStyle !== 'straight') {
|
||||
macro('hd', {
|
||||
from: points.tip2Bottom,
|
||||
to: points.tip,
|
||||
y: points.tip2Bottom.y + 15 + sa
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return part;
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
export default function(part) {
|
||||
let { complete, macro, points, paths, sa } = part.shorthand();
|
||||
let { complete, macro, points, paths, sa } = part.shorthand()
|
||||
|
||||
paths.seam.render = true;
|
||||
paths.seam.render = true
|
||||
|
||||
if (complete) {
|
||||
if (sa) paths.sa.render = true;
|
||||
macro("title", {
|
||||
if (sa) paths.sa.render = true
|
||||
macro('title', {
|
||||
at: points.titleAnchor,
|
||||
nr: 1,
|
||||
title: "bowTie",
|
||||
title: 'bowTie',
|
||||
scale: 0.8
|
||||
});
|
||||
points.scaleboxAnchor = points.bandTopLeft.shift(30, 80);
|
||||
macro("scalebox", { at: points.scaleboxAnchor });
|
||||
})
|
||||
points.scaleboxAnchor = points.bandTopLeft.shift(30, 80)
|
||||
macro('scalebox', { at: points.scaleboxAnchor })
|
||||
}
|
||||
|
||||
return part;
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
export default function(part) {
|
||||
let { options, points, paths, complete, macro, sa } = part.shorthand();
|
||||
let { options, points, paths, complete, macro, sa } = part.shorthand()
|
||||
|
||||
if (options.adjustmentRibbon) {
|
||||
part.render = false;
|
||||
return part;
|
||||
part.render = false
|
||||
return part
|
||||
}
|
||||
|
||||
paths.seam.render = true;
|
||||
paths.seam.render = true
|
||||
|
||||
if (complete) {
|
||||
if (sa) paths.sa.render = true;
|
||||
macro("title", {
|
||||
if (sa) paths.sa.render = true
|
||||
macro('title', {
|
||||
at: points.titleAnchor,
|
||||
nr: 2,
|
||||
title: "bowTie",
|
||||
title: 'bowTie',
|
||||
scale: 0.8
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
return part;
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
export default function(part) {
|
||||
let { options, points, paths, complete, macro, sa } = part.shorthand();
|
||||
let { options, points, paths, complete, macro, sa } = part.shorthand()
|
||||
|
||||
if (options.adjustmentRibbon) {
|
||||
part.render = false;
|
||||
return part;
|
||||
part.render = false
|
||||
return part
|
||||
}
|
||||
|
||||
if (complete) {
|
||||
if (sa) paths.sa.render = true;
|
||||
macro("title", {
|
||||
if (sa) paths.sa.render = true
|
||||
macro('title', {
|
||||
at: points.titleAnchor,
|
||||
nr: 3,
|
||||
title: "bowTie",
|
||||
title: 'bowTie',
|
||||
scale: 0.8
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
return part;
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
import freesewing from "@freesewing/core";
|
||||
import plugins from "@freesewing/plugin-bundle";
|
||||
import config from "../config";
|
||||
import freesewing from '@freesewing/core'
|
||||
import plugins from '@freesewing/plugin-bundle'
|
||||
import config from '../config'
|
||||
// Parts
|
||||
import draftBase from "./base";
|
||||
import draftBow1 from "./bow1";
|
||||
import draftBow2 from "./bow2";
|
||||
import draftBow3 from "./bow3";
|
||||
import draftRibbon from "./ribbon";
|
||||
import draftBase from './base'
|
||||
import draftBow1 from './bow1'
|
||||
import draftBow2 from './bow2'
|
||||
import draftBow3 from './bow3'
|
||||
import draftRibbon from './ribbon'
|
||||
|
||||
// Create new design
|
||||
const benjamin = new freesewing.Design(config, plugins);
|
||||
const benjamin = new freesewing.Design(config, plugins)
|
||||
|
||||
// Attach draft methods to prototype
|
||||
benjamin.prototype.draftBase = draftBase;
|
||||
benjamin.prototype.draftBow1 = draftBow1;
|
||||
benjamin.prototype.draftBow2 = draftBow2;
|
||||
benjamin.prototype.draftBow3 = draftBow3;
|
||||
benjamin.prototype.draftRibbon = draftRibbon;
|
||||
benjamin.prototype.draftBase = draftBase
|
||||
benjamin.prototype.draftBow1 = draftBow1
|
||||
benjamin.prototype.draftBow2 = draftBow2
|
||||
benjamin.prototype.draftBow3 = draftBow3
|
||||
benjamin.prototype.draftRibbon = draftRibbon
|
||||
|
||||
export default benjamin;
|
||||
export default benjamin
|
||||
|
|
|
@ -11,26 +11,20 @@ export default function(part) {
|
|||
paths,
|
||||
sa,
|
||||
paperless
|
||||
} = part.shorthand();
|
||||
} = part.shorthand()
|
||||
|
||||
if (!options.adjustmentRibbon) {
|
||||
part.render = false;
|
||||
return part;
|
||||
part.render = false
|
||||
return part
|
||||
}
|
||||
|
||||
// Points
|
||||
points.bottomLeft = new Point(0, 0.5 * store.get("ribbonWidth"));
|
||||
points.topLeft = points.bottomLeft.flipY();
|
||||
points.bottomLeft = new Point(0, 0.5 * store.get('ribbonWidth'))
|
||||
points.topLeft = points.bottomLeft.flipY()
|
||||
// FIXME: How long should this adjustment ribbon be?
|
||||
points.bottomRight = points.bottomLeft.shift(
|
||||
0,
|
||||
measurements.neckCircumference
|
||||
);
|
||||
points.topRight = points.bottomRight.flipY();
|
||||
points.titleAnchor = points.topLeft.shiftFractionTowards(
|
||||
points.bottomRight,
|
||||
0.5
|
||||
);
|
||||
points.bottomRight = points.bottomLeft.shift(0, measurements.neckCircumference)
|
||||
points.topRight = points.bottomRight.flipY()
|
||||
points.titleAnchor = points.topLeft.shiftFractionTowards(points.bottomRight, 0.5)
|
||||
|
||||
// Paths
|
||||
paths.seam = new Path()
|
||||
|
@ -40,30 +34,30 @@ export default function(part) {
|
|||
.line(points.topRight)
|
||||
.line(points.topLeft)
|
||||
.close()
|
||||
.attr("class", "fabric");
|
||||
.attr('class', 'fabric')
|
||||
|
||||
if (complete) {
|
||||
if (sa) paths.sa = paths.seam.offset(sa).attr("class", "fabric sa");
|
||||
macro("title", {
|
||||
if (sa) paths.sa = paths.seam.offset(sa).attr('class', 'fabric sa')
|
||||
macro('title', {
|
||||
at: points.titleAnchor,
|
||||
nr: 4,
|
||||
title: "ribbon",
|
||||
title: 'ribbon',
|
||||
scale: 0.5
|
||||
});
|
||||
})
|
||||
|
||||
if (paperless) {
|
||||
macro("hd", {
|
||||
macro('hd', {
|
||||
from: points.bottomLeft,
|
||||
to: points.bottomRight,
|
||||
y: points.bottomLeft.y + 15 + sa
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.bottomRight,
|
||||
to: points.topRight,
|
||||
x: points.topRight.x + 15 + sa
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return part;
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -1,22 +1,15 @@
|
|||
import React from "react";
|
||||
import freesewing from "@freesewing/core";
|
||||
import Workbench from "@freesewing/components/Workbench";
|
||||
import "typeface-roboto-condensed";
|
||||
import "@freesewing/css-theme";
|
||||
import React from 'react'
|
||||
import freesewing from '@freesewing/core'
|
||||
import Workbench from '@freesewing/components/Workbench'
|
||||
import 'typeface-roboto-condensed'
|
||||
import '@freesewing/css-theme'
|
||||
|
||||
import Pattern from "pattern";
|
||||
import Pattern from 'pattern'
|
||||
|
||||
const App = props => {
|
||||
let instance = new Pattern();
|
||||
let config = instance.config;
|
||||
return (
|
||||
<Workbench
|
||||
freesewing={freesewing}
|
||||
Pattern={Pattern}
|
||||
config={config}
|
||||
userLanguage="en"
|
||||
/>
|
||||
);
|
||||
};
|
||||
let instance = new Pattern()
|
||||
let config = instance.config
|
||||
return <Workbench freesewing={freesewing} Pattern={Pattern} config={config} userLanguage="en" />
|
||||
}
|
||||
|
||||
export default App;
|
||||
export default App
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import App from "./App";
|
||||
import * as serviceWorker from "./serviceWorker";
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import App from './App'
|
||||
import * as serviceWorker from './serviceWorker'
|
||||
|
||||
ReactDOM.render(<App />, document.getElementById("root"));
|
||||
ReactDOM.render(<App />, document.getElementById('root'))
|
||||
|
||||
// If you want your app to work offline and load faster, you can change
|
||||
// unregister() to register() below. Note this comes with some pitfalls.
|
||||
// Learn more about service workers: http://bit.ly/CRA-PWA
|
||||
serviceWorker.unregister();
|
||||
serviceWorker.unregister()
|
||||
|
|
|
@ -9,46 +9,44 @@
|
|||
// This link also includes instructions on opting out of this behavior.
|
||||
|
||||
const isLocalhost = Boolean(
|
||||
window.location.hostname === "localhost" ||
|
||||
window.location.hostname === 'localhost' ||
|
||||
// [::1] is the IPv6 localhost address.
|
||||
window.location.hostname === "[::1]" ||
|
||||
window.location.hostname === '[::1]' ||
|
||||
// 127.0.0.1/8 is considered localhost for IPv4.
|
||||
window.location.hostname.match(
|
||||
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
|
||||
)
|
||||
);
|
||||
window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/)
|
||||
)
|
||||
|
||||
export function register(config) {
|
||||
if (process.env.NODE_ENV === "production" && "serviceWorker" in navigator) {
|
||||
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
|
||||
// The URL constructor is available in all browsers that support SW.
|
||||
const publicUrl = new URL(process.env.PUBLIC_URL, window.location);
|
||||
const publicUrl = new URL(process.env.PUBLIC_URL, window.location)
|
||||
if (publicUrl.origin !== window.location.origin) {
|
||||
// Our service worker won't work if PUBLIC_URL is on a different origin
|
||||
// from what our page is served on. This might happen if a CDN is used to
|
||||
// serve assets; see https://github.com/facebook/create-react-app/issues/2374
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
window.addEventListener("load", () => {
|
||||
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
|
||||
window.addEventListener('load', () => {
|
||||
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`
|
||||
|
||||
if (isLocalhost) {
|
||||
// This is running on localhost. Let's check if a service worker still exists or not.
|
||||
checkValidServiceWorker(swUrl, config);
|
||||
checkValidServiceWorker(swUrl, config)
|
||||
|
||||
// Add some additional logging to localhost, pointing developers to the
|
||||
// service worker/PWA documentation.
|
||||
navigator.serviceWorker.ready.then(() => {
|
||||
console.log(
|
||||
"This web app is being served cache-first by a service " +
|
||||
"worker. To learn more, visit https://goo.gl/SC7cgQ"
|
||||
);
|
||||
});
|
||||
'This web app is being served cache-first by a service ' +
|
||||
'worker. To learn more, visit https://goo.gl/SC7cgQ'
|
||||
)
|
||||
})
|
||||
} else {
|
||||
// Is not local host. Just register service worker
|
||||
registerValidSW(swUrl, config);
|
||||
registerValidSW(swUrl, config)
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,38 +55,38 @@ function registerValidSW(swUrl, config) {
|
|||
.register(swUrl)
|
||||
.then(registration => {
|
||||
registration.onupdatefound = () => {
|
||||
const installingWorker = registration.installing;
|
||||
const installingWorker = registration.installing
|
||||
installingWorker.onstatechange = () => {
|
||||
if (installingWorker.state === "installed") {
|
||||
if (installingWorker.state === 'installed') {
|
||||
if (navigator.serviceWorker.controller) {
|
||||
// At this point, the old content will have been purged and
|
||||
// the fresh content will have been added to the cache.
|
||||
// It's the perfect time to display a "New content is
|
||||
// available; please refresh." message in your web app.
|
||||
console.log("New content is available; please refresh.");
|
||||
console.log('New content is available; please refresh.')
|
||||
|
||||
// Execute callback
|
||||
if (config.onUpdate) {
|
||||
config.onUpdate(registration);
|
||||
config.onUpdate(registration)
|
||||
}
|
||||
} else {
|
||||
// At this point, everything has been precached.
|
||||
// It's the perfect time to display a
|
||||
// "Content is cached for offline use." message.
|
||||
console.log("Content is cached for offline use.");
|
||||
console.log('Content is cached for offline use.')
|
||||
|
||||
// Execute callback
|
||||
if (config.onSuccess) {
|
||||
config.onSuccess(registration);
|
||||
config.onSuccess(registration)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
})
|
||||
.catch(error => {
|
||||
console.error("Error during service worker registration:", error);
|
||||
});
|
||||
console.error('Error during service worker registration:', error)
|
||||
})
|
||||
}
|
||||
|
||||
function checkValidServiceWorker(swUrl, config) {
|
||||
|
@ -98,30 +96,28 @@ function checkValidServiceWorker(swUrl, config) {
|
|||
// Ensure service worker exists, and that we really are getting a JS file.
|
||||
if (
|
||||
response.status === 404 ||
|
||||
response.headers.get("content-type").indexOf("javascript") === -1
|
||||
response.headers.get('content-type').indexOf('javascript') === -1
|
||||
) {
|
||||
// No service worker found. Probably a different app. Reload the page.
|
||||
navigator.serviceWorker.ready.then(registration => {
|
||||
registration.unregister().then(() => {
|
||||
window.location.reload();
|
||||
});
|
||||
});
|
||||
window.location.reload()
|
||||
})
|
||||
})
|
||||
} else {
|
||||
// Service worker found. Proceed as normal.
|
||||
registerValidSW(swUrl, config);
|
||||
registerValidSW(swUrl, config)
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
console.log(
|
||||
"No internet connection found. App is running in offline mode."
|
||||
);
|
||||
});
|
||||
console.log('No internet connection found. App is running in offline mode.')
|
||||
})
|
||||
}
|
||||
|
||||
export function unregister() {
|
||||
if ("serviceWorker" in navigator) {
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.ready.then(registration => {
|
||||
registration.unregister();
|
||||
});
|
||||
registration.unregister()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,29 +1,29 @@
|
|||
import freesewing from "@freesewing/core";
|
||||
import plugins from "@freesewing/plugin-bundle";
|
||||
import Brian from "@freesewing/brian";
|
||||
import config from "../config";
|
||||
import freesewing from '@freesewing/core'
|
||||
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";
|
||||
import draftSleeve from './sleeve'
|
||||
import draftTopSleeve from './topsleeve'
|
||||
import draftUnderSleeve from './undersleeve'
|
||||
|
||||
// Create new design
|
||||
const Pattern = new freesewing.Design(config, plugins);
|
||||
const Pattern = new freesewing.Design(config, plugins)
|
||||
|
||||
// Attach draft methods from Brian to prototype
|
||||
Pattern.prototype.draftBase = function(part) {
|
||||
return new Brian(this.settings).draftBase(part);
|
||||
};
|
||||
return new Brian(this.settings).draftBase(part)
|
||||
}
|
||||
Pattern.prototype.draftFront = function(part) {
|
||||
return new Brian(this.settings).draftFront(part);
|
||||
};
|
||||
return new Brian(this.settings).draftFront(part)
|
||||
}
|
||||
Pattern.prototype.draftBack = function(part) {
|
||||
return new Brian(this.settings).draftBack(part);
|
||||
};
|
||||
return new Brian(this.settings).draftBack(part)
|
||||
}
|
||||
|
||||
// Attach own draft methods to prototype
|
||||
Pattern.prototype.draftSleeve = draftSleeve;
|
||||
Pattern.prototype.draftTopSleeve = draftTopSleeve;
|
||||
Pattern.prototype.draftUnderSleeve = draftUnderSleeve;
|
||||
Pattern.prototype.draftSleeve = draftSleeve
|
||||
Pattern.prototype.draftTopSleeve = draftTopSleeve
|
||||
Pattern.prototype.draftUnderSleeve = draftUnderSleeve
|
||||
|
||||
export default Pattern;
|
||||
export default Pattern
|
||||
|
|
|
@ -1,52 +1,52 @@
|
|||
export default function(part, s) {
|
||||
let { macro, points, sa } = part.shorthand();
|
||||
let { macro, points, sa } = part.shorthand()
|
||||
|
||||
macro("ld", {
|
||||
from: points[s + "WristLeft"],
|
||||
to: points[s + "WristRight"],
|
||||
macro('ld', {
|
||||
from: points[s + 'WristLeft'],
|
||||
to: points[s + 'WristRight'],
|
||||
d: 15
|
||||
});
|
||||
macro("ld", {
|
||||
from: points[s + "ElbowLeft"],
|
||||
})
|
||||
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"],
|
||||
})
|
||||
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
|
||||
});
|
||||
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
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,59 +1,41 @@
|
|||
export default function(part) {
|
||||
let { Path, paths, points, store, options } = part.shorthand();
|
||||
let { Path, paths, points, store, options } = part.shorthand()
|
||||
|
||||
function draftSleeve(part, tweak) {
|
||||
let {
|
||||
Point,
|
||||
Path,
|
||||
points,
|
||||
paths,
|
||||
store,
|
||||
options,
|
||||
measurements,
|
||||
utils
|
||||
} = part.shorthand();
|
||||
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.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.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();
|
||||
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;
|
||||
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);
|
||||
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(
|
||||
|
@ -61,206 +43,130 @@ export default function(part) {
|
|||
points.boxBottomRight.rotate(options.sleeveBend * -1, points.elbowRight),
|
||||
points.boxBottomLeft,
|
||||
points.boxBottomRight
|
||||
);
|
||||
points.usWristRight = points.tsWristRight.clone();
|
||||
)
|
||||
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
|
||||
);
|
||||
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.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
|
||||
);
|
||||
)
|
||||
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.usRightEdgeCpTop = points.usRightEdgeCpBottom.rotate(180, points.usRightEdge)
|
||||
points._helper1 = new Path()
|
||||
.move(points.backPitchPoint)
|
||||
._curve(points.topCpRight, points.top)
|
||||
.shiftAlong(5);
|
||||
.shiftAlong(5)
|
||||
points._helper2 = new Path()
|
||||
.move(points.backPitchPoint)
|
||||
._curve(points.tsRightEdgeCpTop, points.tsRightEdge)
|
||||
.shiftAlong(5);
|
||||
.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
|
||||
);
|
||||
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();
|
||||
.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
|
||||
)
|
||||
.curve(points.usTipCpBottom, points.usLeftEdgeCpRight, points.usLeftEdgeRight)
|
||||
.line(points.usLeftEdge)
|
||||
.length();
|
||||
store.set("sleevecapLength", lenTop + lenUnder);
|
||||
.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 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");
|
||||
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);
|
||||
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.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.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");
|
||||
.attr('class', 'lining')
|
||||
|
||||
paths.us = new Path()
|
||||
.move(points.usWristRight)
|
||||
.line(points.elbowRight)
|
||||
.curve(
|
||||
points.elbowRightCpTop,
|
||||
points.usRightEdgeCpBottom,
|
||||
points.usRightEdge
|
||||
)
|
||||
.curve(points.elbowRightCpTop, points.usRightEdgeCpBottom, points.usRightEdge)
|
||||
.curve_(points.usRightEdgeCpTop, points.usTip)
|
||||
.curve(
|
||||
points.usTipCpBottom,
|
||||
points.usLeftEdgeCpRight,
|
||||
points.usLeftEdgeRight
|
||||
)
|
||||
.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");
|
||||
.attr('class', 'stroke-xl interfacing')
|
||||
|
||||
return part;
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -1,36 +1,26 @@
|
|||
import dimensions from "./shared";
|
||||
import dimensions from './shared'
|
||||
|
||||
export default function(part) {
|
||||
let {
|
||||
macro,
|
||||
Path,
|
||||
points,
|
||||
paths,
|
||||
complete,
|
||||
paperless,
|
||||
snippets,
|
||||
Snippet,
|
||||
sa
|
||||
} = part.shorthand();
|
||||
let { macro, 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;
|
||||
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", {
|
||||
snippets.logo = new Snippet('logo', points.elbowCenter)
|
||||
macro('title', {
|
||||
at: points.armCenter,
|
||||
nr: 3,
|
||||
title: "topsleeve"
|
||||
});
|
||||
title: 'topsleeve'
|
||||
})
|
||||
|
||||
if (sa) {
|
||||
paths.sa = paths.seam.clone();
|
||||
paths.sa = paths.seam.clone()
|
||||
// Remove hem
|
||||
paths.sa.ops.splice(-2);
|
||||
paths.sa.ops.splice(-2)
|
||||
paths.sa = paths.sa
|
||||
.offset(sa)
|
||||
.join(
|
||||
|
@ -40,39 +30,39 @@ export default function(part) {
|
|||
.offset(sa * 3)
|
||||
)
|
||||
.close()
|
||||
.attr("class", "fabric sa");
|
||||
.attr('class', 'fabric sa')
|
||||
}
|
||||
}
|
||||
|
||||
// Paperless?
|
||||
if (paperless) {
|
||||
dimensions(part, "ts");
|
||||
macro("vd", {
|
||||
dimensions(part, 'ts')
|
||||
macro('vd', {
|
||||
from: points.tsLeftEdge,
|
||||
to: points.top,
|
||||
x: points.tsLeftEdge.x - sa - 15
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.tsLeftEdge,
|
||||
to: points.top,
|
||||
y: points.top.x - sa - 15
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.tsLeftEdge,
|
||||
to: points.backPitchPoint,
|
||||
y: points.top.x - sa - 30
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.tsLeftEdge,
|
||||
to: points.tsRightEdge,
|
||||
y: points.top.x - sa - 45
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.tsRightEdge,
|
||||
to: points.backPitchPoint,
|
||||
x: points.tsRightEdge.x + sa + 15
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
return part;
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -1,36 +1,26 @@
|
|||
import dimensions from "./shared";
|
||||
import dimensions from './shared'
|
||||
|
||||
export default function(part) {
|
||||
let {
|
||||
macro,
|
||||
Path,
|
||||
points,
|
||||
paths,
|
||||
complete,
|
||||
paperless,
|
||||
snippets,
|
||||
Snippet,
|
||||
sa
|
||||
} = part.shorthand();
|
||||
let { macro, 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;
|
||||
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", {
|
||||
snippets.logo = new Snippet('logo', points.elbowCenter)
|
||||
macro('title', {
|
||||
at: points.armCenter,
|
||||
nr: 4,
|
||||
title: "undersleeve"
|
||||
});
|
||||
title: 'undersleeve'
|
||||
})
|
||||
|
||||
if (sa) {
|
||||
paths.sa = paths.seam.clone();
|
||||
paths.sa = paths.seam.clone()
|
||||
// Remove hem
|
||||
paths.sa.ops.splice(-2);
|
||||
paths.sa.ops.splice(-2)
|
||||
paths.sa = paths.sa
|
||||
.offset(sa)
|
||||
.join(
|
||||
|
@ -40,24 +30,24 @@ export default function(part) {
|
|||
.offset(sa * 3)
|
||||
)
|
||||
.close()
|
||||
.attr("class", "fabric sa");
|
||||
.attr('class', 'fabric sa')
|
||||
}
|
||||
}
|
||||
|
||||
// Paperless?
|
||||
if (paperless) {
|
||||
dimensions(part, "us");
|
||||
macro("hd", {
|
||||
dimensions(part, 'us')
|
||||
macro('hd', {
|
||||
from: points.usLeftEdge,
|
||||
to: points.usTip,
|
||||
y: points.usTip.y - sa - 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.tsRightEdge,
|
||||
to: points.usTip,
|
||||
x: points.tsRightEdge.x + sa + 15
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
return part;
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -1,22 +1,15 @@
|
|||
import React from "react";
|
||||
import freesewing from "@freesewing/core";
|
||||
import Workbench from "@freesewing/components/Workbench";
|
||||
import "typeface-roboto-condensed";
|
||||
import "@freesewing/css-theme";
|
||||
import React from 'react'
|
||||
import freesewing from '@freesewing/core'
|
||||
import Workbench from '@freesewing/components/Workbench'
|
||||
import 'typeface-roboto-condensed'
|
||||
import '@freesewing/css-theme'
|
||||
|
||||
import Pattern from "pattern";
|
||||
import Pattern from 'pattern'
|
||||
|
||||
const App = props => {
|
||||
let instance = new Pattern();
|
||||
let config = instance.config;
|
||||
return (
|
||||
<Workbench
|
||||
freesewing={freesewing}
|
||||
Pattern={Pattern}
|
||||
config={config}
|
||||
userLanguage="en"
|
||||
/>
|
||||
);
|
||||
};
|
||||
let instance = new Pattern()
|
||||
let config = instance.config
|
||||
return <Workbench freesewing={freesewing} Pattern={Pattern} config={config} userLanguage="en" />
|
||||
}
|
||||
|
||||
export default App;
|
||||
export default App
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import App from "./App";
|
||||
import * as serviceWorker from "./serviceWorker";
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import App from './App'
|
||||
import * as serviceWorker from './serviceWorker'
|
||||
|
||||
ReactDOM.render(<App />, document.getElementById("root"));
|
||||
ReactDOM.render(<App />, document.getElementById('root'))
|
||||
|
||||
// If you want your app to work offline and load faster, you can change
|
||||
// unregister() to register() below. Note this comes with some pitfalls.
|
||||
// Learn more about service workers: http://bit.ly/CRA-PWA
|
||||
serviceWorker.unregister();
|
||||
serviceWorker.unregister()
|
||||
|
|
|
@ -9,46 +9,44 @@
|
|||
// This link also includes instructions on opting out of this behavior.
|
||||
|
||||
const isLocalhost = Boolean(
|
||||
window.location.hostname === "localhost" ||
|
||||
window.location.hostname === 'localhost' ||
|
||||
// [::1] is the IPv6 localhost address.
|
||||
window.location.hostname === "[::1]" ||
|
||||
window.location.hostname === '[::1]' ||
|
||||
// 127.0.0.1/8 is considered localhost for IPv4.
|
||||
window.location.hostname.match(
|
||||
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
|
||||
)
|
||||
);
|
||||
window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/)
|
||||
)
|
||||
|
||||
export function register(config) {
|
||||
if (process.env.NODE_ENV === "production" && "serviceWorker" in navigator) {
|
||||
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
|
||||
// The URL constructor is available in all browsers that support SW.
|
||||
const publicUrl = new URL(process.env.PUBLIC_URL, window.location);
|
||||
const publicUrl = new URL(process.env.PUBLIC_URL, window.location)
|
||||
if (publicUrl.origin !== window.location.origin) {
|
||||
// Our service worker won't work if PUBLIC_URL is on a different origin
|
||||
// from what our page is served on. This might happen if a CDN is used to
|
||||
// serve assets; see https://github.com/facebook/create-react-app/issues/2374
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
window.addEventListener("load", () => {
|
||||
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
|
||||
window.addEventListener('load', () => {
|
||||
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`
|
||||
|
||||
if (isLocalhost) {
|
||||
// This is running on localhost. Let's check if a service worker still exists or not.
|
||||
checkValidServiceWorker(swUrl, config);
|
||||
checkValidServiceWorker(swUrl, config)
|
||||
|
||||
// Add some additional logging to localhost, pointing developers to the
|
||||
// service worker/PWA documentation.
|
||||
navigator.serviceWorker.ready.then(() => {
|
||||
console.log(
|
||||
"This web app is being served cache-first by a service " +
|
||||
"worker. To learn more, visit https://goo.gl/SC7cgQ"
|
||||
);
|
||||
});
|
||||
'This web app is being served cache-first by a service ' +
|
||||
'worker. To learn more, visit https://goo.gl/SC7cgQ'
|
||||
)
|
||||
})
|
||||
} else {
|
||||
// Is not local host. Just register service worker
|
||||
registerValidSW(swUrl, config);
|
||||
registerValidSW(swUrl, config)
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,38 +55,38 @@ function registerValidSW(swUrl, config) {
|
|||
.register(swUrl)
|
||||
.then(registration => {
|
||||
registration.onupdatefound = () => {
|
||||
const installingWorker = registration.installing;
|
||||
const installingWorker = registration.installing
|
||||
installingWorker.onstatechange = () => {
|
||||
if (installingWorker.state === "installed") {
|
||||
if (installingWorker.state === 'installed') {
|
||||
if (navigator.serviceWorker.controller) {
|
||||
// At this point, the old content will have been purged and
|
||||
// the fresh content will have been added to the cache.
|
||||
// It's the perfect time to display a "New content is
|
||||
// available; please refresh." message in your web app.
|
||||
console.log("New content is available; please refresh.");
|
||||
console.log('New content is available; please refresh.')
|
||||
|
||||
// Execute callback
|
||||
if (config.onUpdate) {
|
||||
config.onUpdate(registration);
|
||||
config.onUpdate(registration)
|
||||
}
|
||||
} else {
|
||||
// At this point, everything has been precached.
|
||||
// It's the perfect time to display a
|
||||
// "Content is cached for offline use." message.
|
||||
console.log("Content is cached for offline use.");
|
||||
console.log('Content is cached for offline use.')
|
||||
|
||||
// Execute callback
|
||||
if (config.onSuccess) {
|
||||
config.onSuccess(registration);
|
||||
config.onSuccess(registration)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
})
|
||||
.catch(error => {
|
||||
console.error("Error during service worker registration:", error);
|
||||
});
|
||||
console.error('Error during service worker registration:', error)
|
||||
})
|
||||
}
|
||||
|
||||
function checkValidServiceWorker(swUrl, config) {
|
||||
|
@ -98,30 +96,28 @@ function checkValidServiceWorker(swUrl, config) {
|
|||
// Ensure service worker exists, and that we really are getting a JS file.
|
||||
if (
|
||||
response.status === 404 ||
|
||||
response.headers.get("content-type").indexOf("javascript") === -1
|
||||
response.headers.get('content-type').indexOf('javascript') === -1
|
||||
) {
|
||||
// No service worker found. Probably a different app. Reload the page.
|
||||
navigator.serviceWorker.ready.then(registration => {
|
||||
registration.unregister().then(() => {
|
||||
window.location.reload();
|
||||
});
|
||||
});
|
||||
window.location.reload()
|
||||
})
|
||||
})
|
||||
} else {
|
||||
// Service worker found. Proceed as normal.
|
||||
registerValidSW(swUrl, config);
|
||||
registerValidSW(swUrl, config)
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
console.log(
|
||||
"No internet connection found. App is running in offline mode."
|
||||
);
|
||||
});
|
||||
console.log('No internet connection found. App is running in offline mode.')
|
||||
})
|
||||
}
|
||||
|
||||
export function unregister() {
|
||||
if ("serviceWorker" in navigator) {
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.ready.then(registration => {
|
||||
registration.unregister();
|
||||
});
|
||||
registration.unregister()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import * as shared from "./shared";
|
||||
import * as shared from './shared'
|
||||
|
||||
export default part => {
|
||||
let {
|
||||
|
@ -12,67 +12,64 @@ export default part => {
|
|||
complete,
|
||||
paperless,
|
||||
macro
|
||||
} = part.shorthand();
|
||||
} = part.shorthand()
|
||||
|
||||
// Seamline
|
||||
paths.saBase = shared.saBase("back", points, Path);
|
||||
paths.saBase = shared.saBase('back', points, Path)
|
||||
paths.seam = new Path()
|
||||
.move(points.cbNeck)
|
||||
.line(points.cbHips)
|
||||
.join(paths.saBase)
|
||||
.attr("class", "fabric");
|
||||
.attr('class', 'fabric')
|
||||
|
||||
// Store lengths to fit sleeve
|
||||
store.set("backArmholeLength", shared.armholeLength(points, Path));
|
||||
store.set(
|
||||
"backShoulderToArmholePitch",
|
||||
shared.shoulderToArmholePitch(points, Path)
|
||||
);
|
||||
store.set('backArmholeLength', shared.armholeLength(points, Path))
|
||||
store.set('backShoulderToArmholePitch', shared.shoulderToArmholePitch(points, Path))
|
||||
|
||||
// Complete pattern?
|
||||
if (complete) {
|
||||
macro("cutonfold", {
|
||||
macro('cutonfold', {
|
||||
from: points.cbNeck,
|
||||
to: points.cbHips,
|
||||
grainline: true
|
||||
});
|
||||
})
|
||||
|
||||
macro("title", { at: points.title, nr: 2, title: "back" });
|
||||
snippets.armholePitchNotch = new Snippet("bnotch", points.armholePitch);
|
||||
macro('title', { at: points.title, nr: 2, title: 'back' })
|
||||
snippets.armholePitchNotch = new Snippet('bnotch', points.armholePitch)
|
||||
if (sa) {
|
||||
paths.sa = paths.saBase
|
||||
.offset(sa)
|
||||
.attr("class", "fabric sa")
|
||||
.attr('class', 'fabric sa')
|
||||
.line(points.cbNeck)
|
||||
.move(points.cbHips);
|
||||
paths.sa.line(paths.sa.start());
|
||||
.move(points.cbHips)
|
||||
paths.sa.line(paths.sa.start())
|
||||
}
|
||||
}
|
||||
|
||||
// Paperless?
|
||||
if (paperless) {
|
||||
shared.dimensions(macro, points, Path, sa);
|
||||
macro("hd", {
|
||||
shared.dimensions(macro, points, Path, sa)
|
||||
macro('hd', {
|
||||
from: points.cbHips,
|
||||
to: points.hips,
|
||||
y: points.hips.y + sa + 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.cbHips,
|
||||
to: points.cbNeck,
|
||||
x: points.cbHips.x - sa - 15
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.cbNeck,
|
||||
to: points.neck,
|
||||
y: points.neck.y - sa - 15
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.cbNeck,
|
||||
to: points.shoulder,
|
||||
y: points.neck.y - sa - 30
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
return part;
|
||||
};
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import * as shared from "./shared";
|
||||
import * as shared from './shared'
|
||||
|
||||
export default part => {
|
||||
let {
|
||||
|
@ -15,179 +15,146 @@ export default part => {
|
|||
paths,
|
||||
utils,
|
||||
complete
|
||||
} = part.shorthand();
|
||||
} = part.shorthand()
|
||||
|
||||
store.set(
|
||||
"shoulderEase",
|
||||
(measurements.shoulderToShoulder * options.shoulderEase) / 2
|
||||
);
|
||||
store.set('shoulderEase', (measurements.shoulderToShoulder * options.shoulderEase) / 2)
|
||||
|
||||
// Center back (cb) vertical axis
|
||||
points.cbNeck = new Point(
|
||||
0,
|
||||
options.backNeckCutout * measurements.neckCircumference
|
||||
);
|
||||
points.cbNeck = new Point(0, options.backNeckCutout * measurements.neckCircumference)
|
||||
points.cbShoulder = new Point(
|
||||
0,
|
||||
(measurements.shoulderSlope -
|
||||
measurements.shoulderToShoulder * options.shoulderSlopeReduction) /
|
||||
2
|
||||
);
|
||||
)
|
||||
points.cbArmhole = new Point(
|
||||
0,
|
||||
points.cbShoulder.y +
|
||||
(measurements.shoulderToShoulder * options.shoulderSlopeReduction) / 2 +
|
||||
measurements.bicepsCircumference *
|
||||
(1 + options.bicepsEase) *
|
||||
options.armholeDepthFactor
|
||||
);
|
||||
points.cbWaist = new Point(
|
||||
0,
|
||||
points.cbNeck.y + measurements.centerBackNeckToWaist
|
||||
);
|
||||
points.cbHips = new Point(
|
||||
0,
|
||||
points.cbWaist.y + measurements.naturalWaistToHip
|
||||
);
|
||||
measurements.bicepsCircumference * (1 + options.bicepsEase) * options.armholeDepthFactor
|
||||
)
|
||||
points.cbWaist = new Point(0, points.cbNeck.y + measurements.centerBackNeckToWaist)
|
||||
points.cbHips = new Point(0, points.cbWaist.y + measurements.naturalWaistToHip)
|
||||
points.cbHem = new Point(
|
||||
0,
|
||||
points.cbWaist.y +
|
||||
measurements.naturalWaistToHip +
|
||||
(measurements.centerBackNeckToWaist + measurements.naturalWaistToHip) *
|
||||
options.lengthBonus
|
||||
);
|
||||
(measurements.centerBackNeckToWaist + measurements.naturalWaistToHip) * options.lengthBonus
|
||||
)
|
||||
|
||||
// Side back (cb) vertical axis
|
||||
points.armhole = new Point(
|
||||
(measurements.chestCircumference * (1 + options.chestEase)) / 4,
|
||||
points.cbArmhole.y
|
||||
);
|
||||
points.waist = new Point(points.armhole.x, points.cbWaist.y);
|
||||
points.hips = new Point(points.armhole.x, points.cbHips.y);
|
||||
points.hem = new Point(points.armhole.x, points.cbHem.y);
|
||||
)
|
||||
points.waist = new Point(points.armhole.x, points.cbWaist.y)
|
||||
points.hips = new Point(points.armhole.x, points.cbHips.y)
|
||||
points.hem = new Point(points.armhole.x, points.cbHem.y)
|
||||
|
||||
// Shoulder line
|
||||
points.neck = new Point(
|
||||
(measurements.neckCircumference * (1 + options.collarEase)) /
|
||||
options.collarFactor,
|
||||
(measurements.neckCircumference * (1 + options.collarEase)) / options.collarFactor,
|
||||
0
|
||||
);
|
||||
)
|
||||
points.shoulder = new Point(
|
||||
measurements.shoulderToShoulder / 2 + store.get("shoulderEase"),
|
||||
measurements.shoulderToShoulder / 2 + store.get('shoulderEase'),
|
||||
points.cbShoulder.y
|
||||
);
|
||||
)
|
||||
|
||||
// Armhhole
|
||||
points.armholePitch = new Point(
|
||||
(measurements.shoulderToShoulder * options.acrossBackFactor) / 2 +
|
||||
store.get("shoulderEase") / 2,
|
||||
store.get('shoulderEase') / 2,
|
||||
points.shoulder.y + points.shoulder.dy(points.armhole) / 2
|
||||
);
|
||||
points._tmp1 = new Point(points.armholePitch.x, points.armhole.y);
|
||||
points._tmp2 = points._tmp1.shift(45, 10);
|
||||
)
|
||||
points._tmp1 = new Point(points.armholePitch.x, points.armhole.y)
|
||||
points._tmp2 = points._tmp1.shift(45, 10)
|
||||
points._tmp3 = utils.beamsIntersect(
|
||||
points._tmp1,
|
||||
points._tmp2,
|
||||
points.armhole,
|
||||
points.armholePitch
|
||||
);
|
||||
points.armholeHollow = points._tmp1.shiftFractionTowards(points._tmp3, 0.5);
|
||||
points.armholeCp2 = points.armhole.shift(
|
||||
180,
|
||||
points._tmp1.dx(points.armhole) / 4
|
||||
);
|
||||
)
|
||||
points.armholeHollow = points._tmp1.shiftFractionTowards(points._tmp3, 0.5)
|
||||
points.armholeCp2 = points.armhole.shift(180, points._tmp1.dx(points.armhole) / 4)
|
||||
points.armholeHollowCp1 = points.armholeHollow.shift(
|
||||
-45,
|
||||
points.armholeHollow.dy(points.armhole) / 2
|
||||
);
|
||||
)
|
||||
points.armholeHollowCp2 = points.armholeHollow.shift(
|
||||
135,
|
||||
points.armholePitch.dx(points.armholeHollow)
|
||||
);
|
||||
)
|
||||
points.armholePitchCp1 = points.armholePitch.shift(
|
||||
-90,
|
||||
points.armholePitch.dy(points.armholeHollow) / 2
|
||||
);
|
||||
)
|
||||
points.armholePitchCp2 = points.armholePitch.shift(
|
||||
90,
|
||||
points.shoulder.dy(points.armholePitch) / 2
|
||||
);
|
||||
)
|
||||
points.shoulderCp1 = points.shoulder
|
||||
.shiftTowards(points.neck, points.shoulder.dy(points.armholePitch) / 5)
|
||||
.rotate(90, points.shoulder);
|
||||
.rotate(90, points.shoulder)
|
||||
|
||||
// Neck opening (back)
|
||||
points._tmp4 = points.neck
|
||||
.shiftTowards(points.shoulder, 10)
|
||||
.rotate(-90, points.neck);
|
||||
points.neckCp2 = utils.beamIntersectsY(
|
||||
points.neck,
|
||||
points._tmp4,
|
||||
points.cbNeck.y
|
||||
);
|
||||
points._tmp4 = points.neck.shiftTowards(points.shoulder, 10).rotate(-90, points.neck)
|
||||
points.neckCp2 = utils.beamIntersectsY(points.neck, points._tmp4, points.cbNeck.y)
|
||||
|
||||
// Fit collar
|
||||
points.cfNeck = points.neck.rotate(-90, new Point(0, 0));
|
||||
let target = measurements.neckCircumference * (1 + options.collarEase);
|
||||
let delta = 0;
|
||||
let run = 0;
|
||||
points.cfNeck = points.neck.rotate(-90, new Point(0, 0))
|
||||
let target = measurements.neckCircumference * (1 + options.collarEase)
|
||||
let delta = 0
|
||||
let run = 0
|
||||
do {
|
||||
run++;
|
||||
points.cfNeck = points.cfNeck.shift(90, delta / 3);
|
||||
run++
|
||||
points.cfNeck = points.cfNeck.shift(90, delta / 3)
|
||||
points.frontNeckCpEdge = utils.beamsIntersect(
|
||||
points.neck,
|
||||
points.neckCp2,
|
||||
points.cfNeck,
|
||||
new Point(20, points.cfNeck.y)
|
||||
);
|
||||
points.cfNeckCp1 = points.cfNeck.shiftFractionTowards(
|
||||
points.frontNeckCpEdge,
|
||||
0.55
|
||||
);
|
||||
points.neckCp2Front = points.neck.shiftFractionTowards(
|
||||
points.frontNeckCpEdge,
|
||||
0.65
|
||||
);
|
||||
)
|
||||
points.cfNeckCp1 = points.cfNeck.shiftFractionTowards(points.frontNeckCpEdge, 0.55)
|
||||
points.neckCp2Front = points.neck.shiftFractionTowards(points.frontNeckCpEdge, 0.65)
|
||||
paths.neckOpening = new Path()
|
||||
.move(points.cfNeck)
|
||||
.curve(points.cfNeckCp1, points.neckCp2Front, points.neck)
|
||||
.curve(points.neckCp2, points.cbNeck, points.cbNeck)
|
||||
.attr("class", "dashed stroke-xl various");
|
||||
delta = paths.neckOpening.length() * 2 - target;
|
||||
} while (Math.abs(delta) > 1 && options.brianFitCollar && run < 10);
|
||||
delete paths.neckOpening;
|
||||
.attr('class', 'dashed stroke-xl various')
|
||||
delta = paths.neckOpening.length() * 2 - target
|
||||
} while (Math.abs(delta) > 1 && options.brianFitCollar && run < 10)
|
||||
delete paths.neckOpening
|
||||
if (options.brianFitCollar) {
|
||||
debug({
|
||||
style: "success",
|
||||
label: "🏁 Collar fitted",
|
||||
msg: `Target was ${units(target)}, delta of ${units(
|
||||
delta
|
||||
)} reached in ${run} attempts.`
|
||||
});
|
||||
style: 'success',
|
||||
label: '🏁 Collar fitted',
|
||||
msg: `Target was ${units(target)}, delta of ${units(delta)} reached in ${run} attempts.`
|
||||
})
|
||||
} else
|
||||
debug({
|
||||
style: "warning",
|
||||
label: "🚫 Not fittingcollar",
|
||||
msg: "(in Brian)"
|
||||
});
|
||||
style: 'warning',
|
||||
label: '🚫 Not fittingcollar',
|
||||
msg: '(in Brian)'
|
||||
})
|
||||
|
||||
// Anchor point for sampling
|
||||
points.gridAnchor = points.cbHem;
|
||||
points.gridAnchor = points.cbHem
|
||||
|
||||
// Seamline
|
||||
paths.saBase = shared.saBase("back", points, Path);
|
||||
paths.saBase = shared.saBase('back', points, Path)
|
||||
paths.seam = new Path()
|
||||
.move(points.cbNeck)
|
||||
.line(points.cbHem)
|
||||
.join(paths.saBase)
|
||||
.attr("class", "fabric");
|
||||
.attr('class', 'fabric')
|
||||
|
||||
// Complete pattern?
|
||||
if (complete) {
|
||||
points.title = new Point(points.armholePitch.x / 2, points.armholePitch.y);
|
||||
points.logo = points.title.shift(-90, 100);
|
||||
snippets.logo = new Snippet("logo", points.logo);
|
||||
points.title = new Point(points.armholePitch.x / 2, points.armholePitch.y)
|
||||
points.logo = points.title.shift(-90, 100)
|
||||
snippets.logo = new Snippet('logo', points.logo)
|
||||
}
|
||||
|
||||
return part;
|
||||
};
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import * as shared from "./shared";
|
||||
import * as shared from './shared'
|
||||
|
||||
export default part => {
|
||||
let {
|
||||
|
@ -15,80 +15,77 @@ export default part => {
|
|||
complete,
|
||||
paperless,
|
||||
macro
|
||||
} = part.shorthand();
|
||||
} = part.shorthand()
|
||||
|
||||
// Cut arm a bit deeper at the front
|
||||
let deeper = measurements.chestCircumference * options.frontArmholeDeeper;
|
||||
points.armholePitchCp1.x -= deeper;
|
||||
points.armholePitch.x -= deeper;
|
||||
points.armholePitchCp2.x -= deeper;
|
||||
let deeper = measurements.chestCircumference * options.frontArmholeDeeper
|
||||
points.armholePitchCp1.x -= deeper
|
||||
points.armholePitch.x -= deeper
|
||||
points.armholePitchCp2.x -= deeper
|
||||
|
||||
// Rename cb (center back) to cf (center front)
|
||||
for (let key of ["Shoulder", "Armhole", "Waist", "Hips", "Hem"]) {
|
||||
points[`cf${key}`] = new Point(points[`cb${key}`].x, points[`cb${key}`].y);
|
||||
delete points[`cb${key}`];
|
||||
for (let key of ['Shoulder', 'Armhole', 'Waist', 'Hips', 'Hem']) {
|
||||
points[`cf${key}`] = new Point(points[`cb${key}`].x, points[`cb${key}`].y)
|
||||
delete points[`cb${key}`]
|
||||
}
|
||||
// Front neckline points
|
||||
points.neckCp2 = new Point(points.neckCp2Front.x, points.neckCp2Front.y);
|
||||
points.neckCp2 = new Point(points.neckCp2Front.x, points.neckCp2Front.y)
|
||||
|
||||
// Seamline
|
||||
paths.saBase = shared.saBase("front", points, Path);
|
||||
paths.saBase = shared.saBase('front', points, Path)
|
||||
paths.seam = new Path()
|
||||
.move(points.cfNeck)
|
||||
.line(points.cfHem)
|
||||
.join(paths.saBase)
|
||||
.attr("class", "fabric");
|
||||
.attr('class', 'fabric')
|
||||
|
||||
// Store lengths to fit sleeve
|
||||
store.set("frontArmholeLength", shared.armholeLength(points, Path));
|
||||
store.set(
|
||||
"frontShoulderToArmholePitch",
|
||||
shared.shoulderToArmholePitch(points, Path)
|
||||
);
|
||||
store.set('frontArmholeLength', shared.armholeLength(points, Path))
|
||||
store.set('frontShoulderToArmholePitch', shared.shoulderToArmholePitch(points, Path))
|
||||
|
||||
// Complete pattern?
|
||||
if (complete) {
|
||||
macro("cutonfold", {
|
||||
macro('cutonfold', {
|
||||
from: points.cfNeck,
|
||||
to: points.cfHips,
|
||||
grainline: true
|
||||
});
|
||||
macro("title", { at: points.title, nr: 1, title: "front" });
|
||||
snippets.armholePitchNotch = new Snippet("notch", points.armholePitch);
|
||||
})
|
||||
macro('title', { at: points.title, nr: 1, title: 'front' })
|
||||
snippets.armholePitchNotch = new Snippet('notch', points.armholePitch)
|
||||
if (sa) {
|
||||
paths.sa = paths.saBase
|
||||
.offset(sa)
|
||||
.attr("class", "fabric sa")
|
||||
.attr('class', 'fabric sa')
|
||||
.line(points.cfNeck)
|
||||
.move(points.cfHips);
|
||||
paths.sa.line(paths.sa.start());
|
||||
.move(points.cfHips)
|
||||
paths.sa.line(paths.sa.start())
|
||||
}
|
||||
}
|
||||
|
||||
// Paperless?
|
||||
if (paperless) {
|
||||
shared.dimensions(macro, points, Path, sa);
|
||||
macro("hd", {
|
||||
shared.dimensions(macro, points, Path, sa)
|
||||
macro('hd', {
|
||||
from: points.cfHips,
|
||||
to: points.hips,
|
||||
y: points.hips.y + sa + 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.cfHips,
|
||||
to: points.cfNeck,
|
||||
x: points.cfHips.x - sa - 15
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.cfNeck,
|
||||
to: points.neck,
|
||||
y: points.neck.y - sa - 15
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.cfNeck,
|
||||
to: points.shoulder,
|
||||
y: points.neck.y - sa - 30
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
return part;
|
||||
};
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
import freesewing from "@freesewing/core";
|
||||
import plugins from "@freesewing/plugin-bundle";
|
||||
import config from "../config";
|
||||
import freesewing from '@freesewing/core'
|
||||
import plugins from '@freesewing/plugin-bundle'
|
||||
import config from '../config'
|
||||
// Parts
|
||||
import draftBase from "./base";
|
||||
import draftBack from "./back";
|
||||
import draftFront from "./front";
|
||||
import draftSleevecap from "./sleevecap";
|
||||
import draftSleeve from "./sleeve";
|
||||
import draftBase from './base'
|
||||
import draftBack from './back'
|
||||
import draftFront from './front'
|
||||
import draftSleevecap from './sleevecap'
|
||||
import draftSleeve from './sleeve'
|
||||
|
||||
// Create design
|
||||
const Pattern = new freesewing.Design(config, plugins);
|
||||
const Pattern = new freesewing.Design(config, plugins)
|
||||
|
||||
// Attach draft methods to prototype
|
||||
Pattern.prototype.draftBase = draftBase;
|
||||
Pattern.prototype.draftBack = draftBack;
|
||||
Pattern.prototype.draftFront = draftFront;
|
||||
Pattern.prototype.draftSleevecap = draftSleevecap;
|
||||
Pattern.prototype.draftSleeve = draftSleeve;
|
||||
Pattern.prototype.draftBase = draftBase
|
||||
Pattern.prototype.draftBack = draftBack
|
||||
Pattern.prototype.draftFront = draftFront
|
||||
Pattern.prototype.draftSleevecap = draftSleevecap
|
||||
Pattern.prototype.draftSleeve = draftSleeve
|
||||
|
||||
export default Pattern;
|
||||
export default Pattern
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
export function saBase(side, points, Path) {
|
||||
let path = new Path();
|
||||
if (side === "back") path.move(points.cbHem);
|
||||
else path.move(points.cfHem);
|
||||
let path = new Path()
|
||||
if (side === 'back') path.move(points.cbHem)
|
||||
else path.move(points.cfHem)
|
||||
path
|
||||
.line(points.hem)
|
||||
.line(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);
|
||||
if (side === "back") {
|
||||
path.curve(points.neckCp2, points.cbNeck, points.cbNeck);
|
||||
.line(points.neck)
|
||||
if (side === 'back') {
|
||||
path.curve(points.neckCp2, points.cbNeck, points.cbNeck)
|
||||
} else {
|
||||
path.curve(points.neckCp2, points.cfNeckCp1, points.cfNeck);
|
||||
path.curve(points.neckCp2, points.cfNeckCp1, points.cfNeck)
|
||||
}
|
||||
|
||||
return path;
|
||||
return path
|
||||
}
|
||||
|
||||
export function armholeLength(points, Path) {
|
||||
|
@ -24,54 +24,50 @@ export function armholeLength(points, Path) {
|
|||
.curve(points.armholeCp2, points.armholeHollowCp1, points.armholeHollow)
|
||||
.curve(points.armholeHollowCp2, points.armholePitchCp1, points.armholePitch)
|
||||
.curve(points.armholePitchCp2, points.shoulderCp1, points.shoulder)
|
||||
.length();
|
||||
.length()
|
||||
}
|
||||
|
||||
export function shoulderToArmholePitch(points, Path) {
|
||||
return new Path()
|
||||
.move(points.armholePitch)
|
||||
.curve(points.armholePitchCp2, points.shoulderCp1, points.shoulder)
|
||||
.length();
|
||||
.length()
|
||||
}
|
||||
|
||||
export function dimensions(macro, points, Path, sa) {
|
||||
macro("pd", {
|
||||
macro('pd', {
|
||||
path: new Path()
|
||||
.move(points.armhole)
|
||||
.curve(points.armholeCp2, points.armholeHollowCp1, points.armholeHollow)
|
||||
.curve(
|
||||
points.armholeHollowCp2,
|
||||
points.armholePitchCp1,
|
||||
points.armholePitch
|
||||
)
|
||||
.curve(points.armholeHollowCp2, points.armholePitchCp1, points.armholePitch)
|
||||
.curve(points.armholePitchCp2, points.shoulderCp1, points.shoulder),
|
||||
d: sa + 15
|
||||
});
|
||||
macro("pd", {
|
||||
})
|
||||
macro('pd', {
|
||||
path: new Path()
|
||||
.move(points.armholePitch)
|
||||
.curve(points.armholePitchCp2, points.shoulderCp1, points.shoulder),
|
||||
d: -15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.hips,
|
||||
to: points.armhole,
|
||||
x: points.hips.x + sa + 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.hips,
|
||||
to: points.armholePitch,
|
||||
x: points.hips.x + sa + 30
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.hips,
|
||||
to: points.shoulder,
|
||||
x: points.hips.x + sa + 45
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.hips,
|
||||
to: points.neck,
|
||||
x: points.hips.x + sa + 60
|
||||
});
|
||||
macro("ld", { from: points.neck, to: points.shoulder, d: sa + 15 });
|
||||
})
|
||||
macro('ld', { from: points.neck, to: points.shoulder, d: sa + 15 })
|
||||
}
|
||||
|
|
|
@ -15,33 +15,33 @@ export default part => {
|
|||
complete,
|
||||
paperless,
|
||||
macro
|
||||
} = part.shorthand();
|
||||
} = part.shorthand()
|
||||
|
||||
// Wrist
|
||||
let top = paths.sleevecap.bbox().topLeft.y;
|
||||
let top = paths.sleevecap.bbox().topLeft.y
|
||||
debug({
|
||||
style: "info",
|
||||
label: "🗸 Sleevecap height",
|
||||
style: 'info',
|
||||
label: '🗸 Sleevecap height',
|
||||
msg: units(Math.abs(top))
|
||||
});
|
||||
})
|
||||
debug({
|
||||
style: "info",
|
||||
label: "🗸 Sleevecap width",
|
||||
style: 'info',
|
||||
label: '🗸 Sleevecap width',
|
||||
msg: units(points.bicepsRight.x * 2)
|
||||
});
|
||||
})
|
||||
points.centerWrist = new Point(
|
||||
0,
|
||||
top + measurements.shoulderToWrist * (1 + options.sleeveLengthBonus)
|
||||
);
|
||||
)
|
||||
points.wristRight = points.centerWrist.shift(
|
||||
0,
|
||||
(measurements.wristCircumference * (1 + options.cuffEase)) / 2
|
||||
);
|
||||
points.wristLeft = points.wristRight.rotate(180, points.centerWrist);
|
||||
points.sleeveTip = paths.sleevecap.shiftFractionAlong(0.5);
|
||||
)
|
||||
points.wristLeft = points.wristRight.rotate(180, points.centerWrist)
|
||||
points.sleeveTip = paths.sleevecap.shiftFractionAlong(0.5)
|
||||
|
||||
// Paths
|
||||
paths.sleevecap.render = false;
|
||||
paths.sleevecap.render = false
|
||||
paths.seam = new Path()
|
||||
.move(points.bicepsLeft)
|
||||
.move(points.wristLeft)
|
||||
|
@ -49,67 +49,64 @@ export default part => {
|
|||
.line(points.bicepsRight)
|
||||
.join(paths.sleevecap)
|
||||
.close()
|
||||
.attr("class", "fabric");
|
||||
.attr('class', 'fabric')
|
||||
|
||||
// Anchor point for sampling
|
||||
points.gridAnchor = new Point(0, 0);
|
||||
points.gridAnchor = new Point(0, 0)
|
||||
|
||||
// Complete pattern?
|
||||
if (complete) {
|
||||
points.logo = points.centerBiceps.shiftFractionTowards(
|
||||
points.centerWrist,
|
||||
0.3
|
||||
);
|
||||
snippets.logo = new Snippet("logo", points.logo);
|
||||
macro("title", { at: points.centerBiceps, nr: 3, title: "sleeve" });
|
||||
macro("grainline", { from: points.centerWrist, to: points.centerBiceps });
|
||||
points.logo = points.centerBiceps.shiftFractionTowards(points.centerWrist, 0.3)
|
||||
snippets.logo = new Snippet('logo', points.logo)
|
||||
macro('title', { at: points.centerBiceps, nr: 3, title: 'sleeve' })
|
||||
macro('grainline', { from: points.centerWrist, to: points.centerBiceps })
|
||||
points.scaleboxAnchor = points.scalebox = points.centerBiceps.shiftFractionTowards(
|
||||
points.centerWrist,
|
||||
0.5
|
||||
);
|
||||
macro("scalebox", { at: points.scalebox });
|
||||
)
|
||||
macro('scalebox', { at: points.scalebox })
|
||||
|
||||
points.frontNotch = paths.sleevecap.shiftAlong(
|
||||
paths.sleevecap.length() / 2 -
|
||||
store.get("frontShoulderToArmholePitch") -
|
||||
store.get("sleevecapEase") / 2
|
||||
);
|
||||
store.get('frontShoulderToArmholePitch') -
|
||||
store.get('sleevecapEase') / 2
|
||||
)
|
||||
points.backNotch = paths.sleevecap.shiftAlong(
|
||||
paths.sleevecap.length() / 2 +
|
||||
store.get("backShoulderToArmholePitch") +
|
||||
store.get("sleevecapEase") / 2
|
||||
);
|
||||
snippets.frontNotch = new Snippet("notch", points.frontNotch);
|
||||
snippets.backNotch = new Snippet("bnotch", points.backNotch);
|
||||
if (sa) paths.sa = paths.seam.offset(sa).attr("class", "fabric sa");
|
||||
store.get('backShoulderToArmholePitch') +
|
||||
store.get('sleevecapEase') / 2
|
||||
)
|
||||
snippets.frontNotch = new Snippet('notch', points.frontNotch)
|
||||
snippets.backNotch = new Snippet('bnotch', points.backNotch)
|
||||
if (sa) paths.sa = paths.seam.offset(sa).attr('class', 'fabric sa')
|
||||
}
|
||||
|
||||
// Paperless?
|
||||
if (paperless) {
|
||||
macro("vd", {
|
||||
macro('vd', {
|
||||
from: points.wristLeft,
|
||||
to: points.bicepsLeft,
|
||||
x: points.bicepsLeft.x - sa - 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.wristLeft,
|
||||
to: points.sleeveTip,
|
||||
x: points.bicepsLeft.x - sa - 30
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.bicepsLeft,
|
||||
to: points.bicepsRight,
|
||||
y: points.sleeveTip.y - sa - 30
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.wristLeft,
|
||||
to: points.wristRight,
|
||||
y: points.wristLeft.y + sa + 30
|
||||
});
|
||||
macro("pd", {
|
||||
})
|
||||
macro('pd', {
|
||||
path: paths.sleevecap.reverse(),
|
||||
d: -1 * sa - 15
|
||||
});
|
||||
})
|
||||
}
|
||||
return part;
|
||||
};
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -2,139 +2,116 @@
|
|||
* Positive values mean sleevecap is longer than armhole
|
||||
*/
|
||||
function sleevecapDelta(store) {
|
||||
return store.get("sleevecapLength") - store.get("sleevecapTarget");
|
||||
return store.get('sleevecapLength') - store.get('sleevecapTarget')
|
||||
}
|
||||
|
||||
function sleevecapAdjust(store) {
|
||||
let delta = sleevecapDelta(store);
|
||||
let factor = store.get("sleeveFactor");
|
||||
if (delta > 0) factor = factor * 0.98;
|
||||
else factor = factor * 1.02;
|
||||
store.set("sleeveFactor", factor);
|
||||
let delta = sleevecapDelta(store)
|
||||
let factor = store.get('sleeveFactor')
|
||||
if (delta > 0) factor = factor * 0.98
|
||||
else factor = factor * 1.02
|
||||
store.set('sleeveFactor', factor)
|
||||
}
|
||||
|
||||
function draftSleevecap(part, run) {
|
||||
let {
|
||||
debug,
|
||||
units,
|
||||
store,
|
||||
measurements,
|
||||
options,
|
||||
Point,
|
||||
points,
|
||||
Path,
|
||||
paths
|
||||
} = part.shorthand();
|
||||
let { debug, units, store, measurements, options, Point, points, Path, paths } = part.shorthand()
|
||||
// Sleeve center axis
|
||||
points.centerBiceps = new Point(0, 0);
|
||||
points.centerBiceps = new Point(0, 0)
|
||||
points.centerCap = points.centerBiceps.shift(
|
||||
90,
|
||||
options.sleevecapTopFactorY *
|
||||
(measurements.bicepsCircumference *
|
||||
(1 + options.bicepsEase) *
|
||||
options.armholeDepthFactor *
|
||||
store.get("sleeveFactor"))
|
||||
);
|
||||
store.get('sleeveFactor'))
|
||||
)
|
||||
|
||||
// Left and right biceps points, limit impact of sleeveFactor to 25%
|
||||
let halfWidth =
|
||||
(measurements.bicepsCircumference * (1 + options.bicepsEase)) / 2;
|
||||
let halfWidth = (measurements.bicepsCircumference * (1 + options.bicepsEase)) / 2
|
||||
points.bicepsLeft = points.centerBiceps.shift(
|
||||
180,
|
||||
halfWidth * options.sleeveWidthGuarantee +
|
||||
halfWidth * (1 - options.sleeveWidthGuarantee) * store.get("sleeveFactor")
|
||||
);
|
||||
points.bicepsRight = points.bicepsLeft.flipX(points.centerBiceps);
|
||||
halfWidth * (1 - options.sleeveWidthGuarantee) * store.get('sleeveFactor')
|
||||
)
|
||||
points.bicepsRight = points.bicepsLeft.flipX(points.centerBiceps)
|
||||
|
||||
// Adapt sleeve center axis
|
||||
points.capLeft = new Point(points.bicepsLeft.x, points.centerCap.y);
|
||||
points.capRight = points.capLeft.flipX();
|
||||
points.capLeft = new Point(points.bicepsLeft.x, points.centerCap.y)
|
||||
points.capRight = points.capLeft.flipX()
|
||||
points.centerCap = points.capLeft.shiftFractionTowards(
|
||||
points.capRight,
|
||||
options.sleevecapTopFactorX
|
||||
);
|
||||
)
|
||||
|
||||
// Pitch points
|
||||
let width = points.bicepsRight.x;
|
||||
let height = points.centerCap.y;
|
||||
let width = points.bicepsRight.x
|
||||
let height = points.centerCap.y
|
||||
points.backPitch = new Point(
|
||||
-1 * width * options.sleevecapBackFactorX,
|
||||
height * options.sleevecapBackFactorY
|
||||
);
|
||||
)
|
||||
points.frontPitch = new Point(
|
||||
width * options.sleevecapFrontFactorX,
|
||||
height * options.sleevecapFrontFactorY
|
||||
);
|
||||
)
|
||||
|
||||
// 4 sleevecap quadrants
|
||||
// Base points
|
||||
points.capQ1Base = points.frontPitch.shiftFractionTowards(
|
||||
points.bicepsRight,
|
||||
0.5
|
||||
);
|
||||
points.capQ2Base = points.frontPitch.shiftFractionTowards(
|
||||
points.centerCap,
|
||||
0.5
|
||||
);
|
||||
points.capQ3Base = points.backPitch.shiftFractionTowards(
|
||||
points.centerCap,
|
||||
0.5
|
||||
);
|
||||
points.capQ4Base = points.backPitch.shiftFractionTowards(
|
||||
points.bicepsLeft,
|
||||
0.5
|
||||
);
|
||||
points.capQ1Base = points.frontPitch.shiftFractionTowards(points.bicepsRight, 0.5)
|
||||
points.capQ2Base = points.frontPitch.shiftFractionTowards(points.centerCap, 0.5)
|
||||
points.capQ3Base = points.backPitch.shiftFractionTowards(points.centerCap, 0.5)
|
||||
points.capQ4Base = points.backPitch.shiftFractionTowards(points.bicepsLeft, 0.5)
|
||||
// Offset points
|
||||
let baseOffset = measurements.bicepsCircumference * (1 + options.bicepsEase);
|
||||
let baseOffset = measurements.bicepsCircumference * (1 + options.bicepsEase)
|
||||
points.capQ1 = points.capQ1Base.shift(
|
||||
points.bicepsRight.angle(points.frontPitch) + 90,
|
||||
baseOffset * options.sleevecapQ1Offset
|
||||
);
|
||||
)
|
||||
points.capQ2 = points.capQ2Base.shift(
|
||||
points.centerCap.angle(points.frontPitch) + 90,
|
||||
baseOffset * options.sleevecapQ2Offset
|
||||
);
|
||||
)
|
||||
points.capQ3 = points.capQ3Base.shift(
|
||||
points.centerCap.angle(points.backPitch) - 90,
|
||||
baseOffset * options.sleevecapQ3Offset
|
||||
);
|
||||
)
|
||||
points.capQ4 = points.capQ4Base.shift(
|
||||
points.bicepsLeft.angle(points.backPitch) - 90,
|
||||
baseOffset * options.sleevecapQ4Offset
|
||||
);
|
||||
)
|
||||
// Control points
|
||||
points.capQ1Cp1 = points.capQ1.shift(
|
||||
points.frontPitch.angle(points.bicepsRight),
|
||||
baseOffset * options.sleevecapQ1Spread1
|
||||
);
|
||||
)
|
||||
points.capQ1Cp2 = points.capQ1.shift(
|
||||
points.frontPitch.angle(points.bicepsRight),
|
||||
baseOffset * options.sleevecapQ1Spread2 * -1
|
||||
);
|
||||
)
|
||||
points.capQ2Cp1 = points.capQ2.shift(
|
||||
points.centerCap.angle(points.frontPitch),
|
||||
baseOffset * options.sleevecapQ2Spread1
|
||||
);
|
||||
)
|
||||
points.capQ2Cp2 = points.capQ2.shift(
|
||||
points.centerCap.angle(points.frontPitch),
|
||||
baseOffset * options.sleevecapQ2Spread2 * -1
|
||||
);
|
||||
)
|
||||
points.capQ3Cp1 = points.capQ3.shift(
|
||||
points.backPitch.angle(points.centerCap),
|
||||
baseOffset * options.sleevecapQ3Spread1
|
||||
);
|
||||
)
|
||||
points.capQ3Cp2 = points.capQ3.shift(
|
||||
points.backPitch.angle(points.centerCap),
|
||||
baseOffset * options.sleevecapQ3Spread2 * -1
|
||||
);
|
||||
)
|
||||
points.capQ4Cp1 = points.capQ4.shift(
|
||||
points.bicepsLeft.angle(points.backPitch),
|
||||
baseOffset * options.sleevecapQ4Spread1
|
||||
);
|
||||
)
|
||||
points.capQ4Cp2 = points.capQ4.shift(
|
||||
points.bicepsLeft.angle(points.backPitch),
|
||||
baseOffset * options.sleevecapQ4Spread2 * -1
|
||||
);
|
||||
)
|
||||
|
||||
// Sleevecap seamline
|
||||
paths.sleevecap = new Path()
|
||||
|
@ -143,21 +120,20 @@ function draftSleevecap(part, run) {
|
|||
.curve(points.capQ1Cp2, points.capQ2Cp1, points.capQ2)
|
||||
.curve(points.capQ2Cp2, points.capQ3Cp1, points.capQ3)
|
||||
.curve(points.capQ3Cp2, points.capQ4Cp1, points.capQ4)
|
||||
.curve(points.capQ4Cp2, points.bicepsLeft, points.bicepsLeft);
|
||||
.curve(points.capQ4Cp2, points.bicepsLeft, points.bicepsLeft)
|
||||
|
||||
// Store sleevecap length
|
||||
store.set("sleevecapLength", paths.sleevecap.length());
|
||||
store.set('sleevecapLength', paths.sleevecap.length())
|
||||
if (run === 0) {
|
||||
let armholeLength =
|
||||
store.get("frontArmholeLength") + store.get("backArmholeLength");
|
||||
let sleevecapEase = armholeLength * options.sleevecapEase;
|
||||
store.set("sleevecapEase", sleevecapEase);
|
||||
store.set("sleevecapTarget", armholeLength + sleevecapEase);
|
||||
let armholeLength = store.get('frontArmholeLength') + store.get('backArmholeLength')
|
||||
let sleevecapEase = armholeLength * options.sleevecapEase
|
||||
store.set('sleevecapEase', sleevecapEase)
|
||||
store.set('sleevecapTarget', armholeLength + sleevecapEase)
|
||||
debug({
|
||||
style: "info",
|
||||
label: "🗸 Sleevecap ease",
|
||||
style: 'info',
|
||||
label: '🗸 Sleevecap ease',
|
||||
msg: units(sleevecapEase)
|
||||
});
|
||||
})
|
||||
|
||||
// Uncomment this line to see all sleevecap iterations
|
||||
//paths[run] = paths.sleevecap;
|
||||
|
@ -165,41 +141,37 @@ function draftSleevecap(part, run) {
|
|||
}
|
||||
|
||||
export default part => {
|
||||
let { debug, store, units, options, Point, points, paths } = part.shorthand();
|
||||
let { debug, store, units, options, Point, points, paths } = part.shorthand()
|
||||
|
||||
store.set("sleeveFactor", 1);
|
||||
let run = 0;
|
||||
let delta = 0;
|
||||
store.set('sleeveFactor', 1)
|
||||
let run = 0
|
||||
let delta = 0
|
||||
do {
|
||||
draftSleevecap(part, run);
|
||||
delta = sleevecapDelta(store);
|
||||
sleevecapAdjust(store);
|
||||
run++;
|
||||
} while (
|
||||
options.brianFitSleeve === true &&
|
||||
run < 30 &&
|
||||
Math.abs(sleevecapDelta(store)) > 2
|
||||
);
|
||||
draftSleevecap(part, run)
|
||||
delta = sleevecapDelta(store)
|
||||
sleevecapAdjust(store)
|
||||
run++
|
||||
} while (options.brianFitSleeve === true && run < 30 && Math.abs(sleevecapDelta(store)) > 2)
|
||||
if (options.brianFitSleeve) {
|
||||
debug({
|
||||
style: "success",
|
||||
label: "🏁 Sleevecap fitted",
|
||||
msg: `Target was ${units(store.get("sleevecapTarget"))}, delta of ${units(
|
||||
style: 'success',
|
||||
label: '🏁 Sleevecap fitted',
|
||||
msg: `Target was ${units(store.get('sleevecapTarget'))}, delta of ${units(
|
||||
delta
|
||||
)} reached in ${run} attempts.`
|
||||
});
|
||||
})
|
||||
} else
|
||||
debug({
|
||||
style: "warning",
|
||||
label: "🚫 Not fittingsleevecap",
|
||||
msg: "(in Brian)"
|
||||
});
|
||||
style: 'warning',
|
||||
label: '🚫 Not fittingsleevecap',
|
||||
msg: '(in Brian)'
|
||||
})
|
||||
|
||||
// Paths
|
||||
paths.sleevecap.attr("class", "fabric");
|
||||
paths.sleevecap.attr('class', 'fabric')
|
||||
|
||||
// Anchor point for sampling
|
||||
points.gridAnchor = new Point(0, 0);
|
||||
points.gridAnchor = new Point(0, 0)
|
||||
|
||||
return part;
|
||||
};
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -1,22 +1,15 @@
|
|||
import React from "react";
|
||||
import freesewing from "@freesewing/core";
|
||||
import Workbench from "@freesewing/components/Workbench";
|
||||
import "typeface-roboto-condensed";
|
||||
import "@freesewing/css-theme";
|
||||
import React from 'react'
|
||||
import freesewing from '@freesewing/core'
|
||||
import Workbench from '@freesewing/components/Workbench'
|
||||
import 'typeface-roboto-condensed'
|
||||
import '@freesewing/css-theme'
|
||||
|
||||
import Pattern from "pattern";
|
||||
import Pattern from 'pattern'
|
||||
|
||||
const App = props => {
|
||||
let instance = new Pattern();
|
||||
let config = instance.config;
|
||||
return (
|
||||
<Workbench
|
||||
freesewing={freesewing}
|
||||
Pattern={Pattern}
|
||||
config={config}
|
||||
userLanguage="en"
|
||||
/>
|
||||
);
|
||||
};
|
||||
let instance = new Pattern()
|
||||
let config = instance.config
|
||||
return <Workbench freesewing={freesewing} Pattern={Pattern} config={config} userLanguage="en" />
|
||||
}
|
||||
|
||||
export default App;
|
||||
export default App
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import App from "./App";
|
||||
import * as serviceWorker from "./serviceWorker";
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import App from './App'
|
||||
import * as serviceWorker from './serviceWorker'
|
||||
|
||||
ReactDOM.render(<App />, document.getElementById("root"));
|
||||
ReactDOM.render(<App />, document.getElementById('root'))
|
||||
|
||||
// If you want your app to work offline and load faster, you can change
|
||||
// unregister() to register() below. Note this comes with some pitfalls.
|
||||
// Learn more about service workers: http://bit.ly/CRA-PWA
|
||||
serviceWorker.unregister();
|
||||
serviceWorker.unregister()
|
||||
|
|
|
@ -9,46 +9,44 @@
|
|||
// This link also includes instructions on opting out of this behavior.
|
||||
|
||||
const isLocalhost = Boolean(
|
||||
window.location.hostname === "localhost" ||
|
||||
window.location.hostname === 'localhost' ||
|
||||
// [::1] is the IPv6 localhost address.
|
||||
window.location.hostname === "[::1]" ||
|
||||
window.location.hostname === '[::1]' ||
|
||||
// 127.0.0.1/8 is considered localhost for IPv4.
|
||||
window.location.hostname.match(
|
||||
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
|
||||
)
|
||||
);
|
||||
window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/)
|
||||
)
|
||||
|
||||
export function register(config) {
|
||||
if (process.env.NODE_ENV === "production" && "serviceWorker" in navigator) {
|
||||
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
|
||||
// The URL constructor is available in all browsers that support SW.
|
||||
const publicUrl = new URL(process.env.PUBLIC_URL, window.location);
|
||||
const publicUrl = new URL(process.env.PUBLIC_URL, window.location)
|
||||
if (publicUrl.origin !== window.location.origin) {
|
||||
// Our service worker won't work if PUBLIC_URL is on a different origin
|
||||
// from what our page is served on. This might happen if a CDN is used to
|
||||
// serve assets; see https://github.com/facebook/create-react-app/issues/2374
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
window.addEventListener("load", () => {
|
||||
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
|
||||
window.addEventListener('load', () => {
|
||||
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`
|
||||
|
||||
if (isLocalhost) {
|
||||
// This is running on localhost. Let's check if a service worker still exists or not.
|
||||
checkValidServiceWorker(swUrl, config);
|
||||
checkValidServiceWorker(swUrl, config)
|
||||
|
||||
// Add some additional logging to localhost, pointing developers to the
|
||||
// service worker/PWA documentation.
|
||||
navigator.serviceWorker.ready.then(() => {
|
||||
console.log(
|
||||
"This web app is being served cache-first by a service " +
|
||||
"worker. To learn more, visit https://goo.gl/SC7cgQ"
|
||||
);
|
||||
});
|
||||
'This web app is being served cache-first by a service ' +
|
||||
'worker. To learn more, visit https://goo.gl/SC7cgQ'
|
||||
)
|
||||
})
|
||||
} else {
|
||||
// Is not local host. Just register service worker
|
||||
registerValidSW(swUrl, config);
|
||||
registerValidSW(swUrl, config)
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,38 +55,38 @@ function registerValidSW(swUrl, config) {
|
|||
.register(swUrl)
|
||||
.then(registration => {
|
||||
registration.onupdatefound = () => {
|
||||
const installingWorker = registration.installing;
|
||||
const installingWorker = registration.installing
|
||||
installingWorker.onstatechange = () => {
|
||||
if (installingWorker.state === "installed") {
|
||||
if (installingWorker.state === 'installed') {
|
||||
if (navigator.serviceWorker.controller) {
|
||||
// At this point, the old content will have been purged and
|
||||
// the fresh content will have been added to the cache.
|
||||
// It's the perfect time to display a "New content is
|
||||
// available; please refresh." message in your web app.
|
||||
console.log("New content is available; please refresh.");
|
||||
console.log('New content is available; please refresh.')
|
||||
|
||||
// Execute callback
|
||||
if (config.onUpdate) {
|
||||
config.onUpdate(registration);
|
||||
config.onUpdate(registration)
|
||||
}
|
||||
} else {
|
||||
// At this point, everything has been precached.
|
||||
// It's the perfect time to display a
|
||||
// "Content is cached for offline use." message.
|
||||
console.log("Content is cached for offline use.");
|
||||
console.log('Content is cached for offline use.')
|
||||
|
||||
// Execute callback
|
||||
if (config.onSuccess) {
|
||||
config.onSuccess(registration);
|
||||
config.onSuccess(registration)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
})
|
||||
.catch(error => {
|
||||
console.error("Error during service worker registration:", error);
|
||||
});
|
||||
console.error('Error during service worker registration:', error)
|
||||
})
|
||||
}
|
||||
|
||||
function checkValidServiceWorker(swUrl, config) {
|
||||
|
@ -98,30 +96,28 @@ function checkValidServiceWorker(swUrl, config) {
|
|||
// Ensure service worker exists, and that we really are getting a JS file.
|
||||
if (
|
||||
response.status === 404 ||
|
||||
response.headers.get("content-type").indexOf("javascript") === -1
|
||||
response.headers.get('content-type').indexOf('javascript') === -1
|
||||
) {
|
||||
// No service worker found. Probably a different app. Reload the page.
|
||||
navigator.serviceWorker.ready.then(registration => {
|
||||
registration.unregister().then(() => {
|
||||
window.location.reload();
|
||||
});
|
||||
});
|
||||
window.location.reload()
|
||||
})
|
||||
})
|
||||
} else {
|
||||
// Service worker found. Proceed as normal.
|
||||
registerValidSW(swUrl, config);
|
||||
registerValidSW(swUrl, config)
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
console.log(
|
||||
"No internet connection found. App is running in offline mode."
|
||||
);
|
||||
});
|
||||
console.log('No internet connection found. App is running in offline mode.')
|
||||
})
|
||||
}
|
||||
|
||||
export function unregister() {
|
||||
if ("serviceWorker" in navigator) {
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.ready.then(registration => {
|
||||
registration.unregister();
|
||||
});
|
||||
registration.unregister()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import init from "./init";
|
||||
import init from './init'
|
||||
|
||||
export default function(part) {
|
||||
let {
|
||||
|
@ -14,55 +14,49 @@ export default function(part) {
|
|||
paperless,
|
||||
macro,
|
||||
utils
|
||||
} = part.shorthand();
|
||||
} = part.shorthand()
|
||||
|
||||
// Initialize
|
||||
init(part);
|
||||
init(part)
|
||||
|
||||
// Center back
|
||||
points.zero = new Point(0, 0);
|
||||
points.center = points.zero.shift(90, store.get("rise"));
|
||||
points.zero = new Point(0, 0)
|
||||
points.center = points.zero.shift(90, store.get('rise'))
|
||||
|
||||
// Side top
|
||||
points.sideRight = new Point(store.get("hipsBack") / 2, points.center.y);
|
||||
points.sideRight = new Point(store.get('hipsBack') / 2, points.center.y)
|
||||
|
||||
// Gusset
|
||||
points.gussetTop = points.center.shift(-90, store.get("riseLength"));
|
||||
points.gussetBottom = points.gussetTop.shift(
|
||||
-90,
|
||||
store.get("gusset") + store.get("legBonus")
|
||||
);
|
||||
points.gussetRight = points.gussetBottom.shift(
|
||||
0,
|
||||
(store.get("gusset") * store.get("xScale")) / 2
|
||||
);
|
||||
points.gussetCpRight = new Point(points.gussetRight.x, points.gussetTop.y);
|
||||
points.gussetTop = points.center.shift(-90, store.get('riseLength'))
|
||||
points.gussetBottom = points.gussetTop.shift(-90, store.get('gusset') + store.get('legBonus'))
|
||||
points.gussetRight = points.gussetBottom.shift(0, (store.get('gusset') * store.get('xScale')) / 2)
|
||||
points.gussetCpRight = new Point(points.gussetRight.x, points.gussetTop.y)
|
||||
|
||||
// Find leg edge
|
||||
let isect = utils.circlesIntersect(
|
||||
points.gussetRight,
|
||||
store.get("legBack"),
|
||||
store.get('legBack'),
|
||||
points.sideRight,
|
||||
store.get("fullLength")
|
||||
);
|
||||
points.legRight = isect[1];
|
||||
points.legLeft = points.legRight.flipX(points.center);
|
||||
store.get('fullLength')
|
||||
)
|
||||
points.legRight = isect[1]
|
||||
points.legLeft = points.legRight.flipX(points.center)
|
||||
|
||||
// Store back seam length and (half of the) crotch seam length
|
||||
store.set("backSeamLength", points.sideRight.dist(points.legRight));
|
||||
store.set('backSeamLength', points.sideRight.dist(points.legRight))
|
||||
store.set(
|
||||
"crotchSeamLength",
|
||||
'crotchSeamLength',
|
||||
new Path()
|
||||
.move(points.gussetTop)
|
||||
.curve(points.gussetCpRight, points.gussetRight, points.gussetRight)
|
||||
.length()
|
||||
);
|
||||
)
|
||||
|
||||
// Handle back rise
|
||||
points.center = points.center.shift(90, store.get("backRise"));
|
||||
points.sideRight = points.sideRight.shift(90, store.get("sideRise"));
|
||||
points.centerCpRight = new Point(points.sideRight.x / 2, points.center.y);
|
||||
points.centerCpLeft = points.centerCpRight.flipX();
|
||||
points.center = points.center.shift(90, store.get('backRise'))
|
||||
points.sideRight = points.sideRight.shift(90, store.get('sideRise'))
|
||||
points.centerCpRight = new Point(points.sideRight.x / 2, points.center.y)
|
||||
points.centerCpLeft = points.centerCpRight.flipX()
|
||||
|
||||
paths.seam = new Path()
|
||||
.move(points.gussetTop)
|
||||
|
@ -72,7 +66,7 @@ export default function(part) {
|
|||
.curve(points.sideRight, points.centerCpRight, points.center)
|
||||
.line(points.gussetTop)
|
||||
.close()
|
||||
.attr("class", "fabric");
|
||||
.attr('class', 'fabric')
|
||||
|
||||
// Complete pattern?
|
||||
if (complete) {
|
||||
|
@ -81,15 +75,15 @@ export default function(part) {
|
|||
.move(points.legRight)
|
||||
.line(points.sideRight)
|
||||
.curve(points.sideRight, points.centerCpRight, points.center)
|
||||
.offset(sa);
|
||||
.offset(sa)
|
||||
let sa2 = new Path()
|
||||
.move(points.gussetTop)
|
||||
.curve(points.gussetCpRight, points.gussetRight, points.gussetRight)
|
||||
.offset(sa);
|
||||
.offset(sa)
|
||||
let hemSa = new Path()
|
||||
.move(points.gussetRight)
|
||||
.line(points.legRight)
|
||||
.offset(sa * 2);
|
||||
.offset(sa * 2)
|
||||
paths.sa = new Path()
|
||||
.move(points.gussetTop)
|
||||
.line(sa2.start())
|
||||
|
@ -97,68 +91,65 @@ export default function(part) {
|
|||
.join(hemSa)
|
||||
.join(sa1)
|
||||
.line(points.center)
|
||||
.attr("class", "fabric sa");
|
||||
.attr('class', 'fabric sa')
|
||||
}
|
||||
points.title = new Point(
|
||||
points.sideRight.x * 0.6,
|
||||
points.gussetTop.y * 0.6
|
||||
);
|
||||
macro("title", {
|
||||
points.title = new Point(points.sideRight.x * 0.6, points.gussetTop.y * 0.6)
|
||||
macro('title', {
|
||||
at: points.title,
|
||||
nr: 1,
|
||||
title: "back"
|
||||
});
|
||||
macro("cutonfold", {
|
||||
title: 'back'
|
||||
})
|
||||
macro('cutonfold', {
|
||||
from: points.center,
|
||||
to: points.gussetTop,
|
||||
grainline: true
|
||||
});
|
||||
snippets.logo = new Snippet("logo", points.title.shift(90, 50));
|
||||
})
|
||||
snippets.logo = new Snippet('logo', points.title.shift(90, 50))
|
||||
}
|
||||
|
||||
// Paperless?
|
||||
if (paperless) {
|
||||
macro("vd", {
|
||||
macro('vd', {
|
||||
from: points.gussetTop,
|
||||
to: points.center,
|
||||
x: points.center.x - 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.gussetRight,
|
||||
to: points.center,
|
||||
x: points.center.x - 30
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.legRight,
|
||||
to: points.sideRight,
|
||||
x: points.legRight.x + 15 + sa
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.legRight,
|
||||
to: points.center,
|
||||
x: points.legRight.x + 30 + sa
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.center,
|
||||
to: points.sideRight,
|
||||
y: points.center.y - 15 - sa
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.gussetTop,
|
||||
to: points.gussetRight,
|
||||
y: points.gussetRight.y + 15 + sa * 2
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.gussetTop,
|
||||
to: points.legRight,
|
||||
y: points.gussetRight.y + 30 + sa * 2
|
||||
});
|
||||
macro("ld", {
|
||||
})
|
||||
macro('ld', {
|
||||
from: points.gussetRight,
|
||||
to: points.legRight,
|
||||
d: -15 - sa * 2
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
return part;
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -1,32 +1,25 @@
|
|||
import init from "./init";
|
||||
import init from './init'
|
||||
|
||||
function tuskDelta(part) {
|
||||
let { Path, points, store } = part.shorthand();
|
||||
let { Path, points, store } = part.shorthand()
|
||||
let len = new Path()
|
||||
.move(points.midRight)
|
||||
.curve(
|
||||
points.curveRightCpTop,
|
||||
points.curveRightCpBottom,
|
||||
points.rightTuskRight
|
||||
)
|
||||
.length();
|
||||
.curve(points.curveRightCpTop, points.curveRightCpBottom, points.rightTuskRight)
|
||||
.length()
|
||||
|
||||
return len - store.get("curve");
|
||||
return len - store.get('curve')
|
||||
}
|
||||
|
||||
function tweakTusk(delta, part) {
|
||||
let { points } = part.shorthand();
|
||||
let { points } = part.shorthand()
|
||||
|
||||
let factor;
|
||||
if (Math.abs(delta) > 2) factor = 3;
|
||||
else factor = 5;
|
||||
let factor
|
||||
if (Math.abs(delta) > 2) factor = 3
|
||||
else factor = 5
|
||||
|
||||
points.rightTuskRight = points.rightTuskRight.shift(90, delta / factor);
|
||||
points.rightTuskLeft = points.rightTuskLeft.shift(90, delta / factor);
|
||||
points.curveRightCpBottom = points.curveRightCpBottom.shift(
|
||||
90,
|
||||
delta / factor
|
||||
);
|
||||
points.rightTuskRight = points.rightTuskRight.shift(90, delta / factor)
|
||||
points.rightTuskLeft = points.rightTuskLeft.shift(90, delta / factor)
|
||||
points.curveRightCpBottom = points.curveRightCpBottom.shift(90, delta / factor)
|
||||
}
|
||||
|
||||
export default function(part) {
|
||||
|
@ -43,133 +36,108 @@ export default function(part) {
|
|||
macro,
|
||||
utils,
|
||||
debug
|
||||
} = part.shorthand();
|
||||
} = part.shorthand()
|
||||
|
||||
// Initialize
|
||||
init(part);
|
||||
init(part)
|
||||
|
||||
points.topRight = new Point(store.get("hipsFront") / 2, 0);
|
||||
points.topLeft = points.topRight.flipX();
|
||||
points.midMid = new Point(0, store.get("heightFront"));
|
||||
points.midRight = new Point(
|
||||
points.topRight.x + store.get("heightFront") * 0.05,
|
||||
points.midMid.y
|
||||
);
|
||||
points.midLeft = points.midRight.flipX();
|
||||
points.topRight = new Point(store.get('hipsFront') / 2, 0)
|
||||
points.topLeft = points.topRight.flipX()
|
||||
points.midMid = new Point(0, store.get('heightFront'))
|
||||
points.midRight = new Point(points.topRight.x + store.get('heightFront') * 0.05, points.midMid.y)
|
||||
points.midLeft = points.midRight.flipX()
|
||||
|
||||
// Store this length for a notch on the side part
|
||||
store.set("frontNotch", points.topRight.dist(points.midRight));
|
||||
store.set('frontNotch', points.topRight.dist(points.midRight))
|
||||
|
||||
points.bottomMid = new Point(0, store.get("riseLength"));
|
||||
points.bottomMid = new Point(0, store.get('riseLength'))
|
||||
points.rightTuskRight = new Point(
|
||||
store.get("gusset") *
|
||||
store.get("xScale") *
|
||||
(1 - store.get("gussetInsetRatio")),
|
||||
store.get('gusset') * store.get('xScale') * (1 - store.get('gussetInsetRatio')),
|
||||
points.bottomMid.y
|
||||
);
|
||||
points.rightTuskLeft = points.bottomMid.clone();
|
||||
)
|
||||
points.rightTuskLeft = points.bottomMid.clone()
|
||||
points.curveRightCpTop = new Point(
|
||||
points.midRight.x - store.get("gusset") * 1.3,
|
||||
points.midRight.x - store.get('gusset') * 1.3,
|
||||
points.midRight.y
|
||||
);
|
||||
)
|
||||
points.curveRightCpBottom = new Point(
|
||||
points.rightTuskRight.x,
|
||||
points.rightTuskRight.y - store.get("gusset") * 1.3
|
||||
);
|
||||
points.rightTuskRight.y - store.get('gusset') * 1.3
|
||||
)
|
||||
|
||||
// Adjust tusk length to fit inset curve
|
||||
let delta = tuskDelta(part);
|
||||
let count = 0;
|
||||
let delta = tuskDelta(part)
|
||||
let count = 0
|
||||
while (Math.abs(delta) > 1) {
|
||||
// Below 1mm is good enough
|
||||
tweakTusk(delta, part);
|
||||
delta = tuskDelta(part);
|
||||
count++;
|
||||
tweakTusk(delta, part)
|
||||
delta = tuskDelta(part)
|
||||
count++
|
||||
if (count > 150)
|
||||
throw "We got stuck trying to calculate an optimal tusk length. Please report this.";
|
||||
throw 'We got stuck trying to calculate an optimal tusk length. Please report this.'
|
||||
}
|
||||
debug(
|
||||
`After ${count} iterations, tusk curve length is ${utils.round(
|
||||
delta
|
||||
)}mm off.`
|
||||
);
|
||||
debug(`After ${count} iterations, tusk curve length is ${utils.round(delta)}mm off.`)
|
||||
|
||||
// Adjust midMid to new length
|
||||
points.bottomMid = new Point(0, points.rightTuskLeft.y);
|
||||
points.bottomMid = new Point(0, points.rightTuskLeft.y)
|
||||
|
||||
// Front dart only if bulge > 0
|
||||
if (options.bulge > 0) {
|
||||
// Rotate tusk according to bulge option
|
||||
for (let pid of [
|
||||
"curveRightCpTop",
|
||||
"curveRightCpBottom",
|
||||
"rightTuskRight",
|
||||
"rightTuskLeft"
|
||||
]) {
|
||||
points[pid] = points[pid].rotate(options.bulge, points.midRight);
|
||||
for (let pid of ['curveRightCpTop', 'curveRightCpBottom', 'rightTuskRight', 'rightTuskLeft']) {
|
||||
points[pid] = points[pid].rotate(options.bulge, points.midRight)
|
||||
}
|
||||
|
||||
// Dart join point
|
||||
points.dartJoin = new Point(
|
||||
0,
|
||||
points.midMid.y + 0.65 * points.midMid.dist(points.bottomMid)
|
||||
);
|
||||
points.dartJoin = new Point(0, points.midMid.y + 0.65 * points.midMid.dist(points.bottomMid))
|
||||
|
||||
// Dart control point
|
||||
points.dartCpRight = new Point(
|
||||
0,
|
||||
points.dartJoin.y +
|
||||
points.dartJoin.dist(points.bottomMid) * (options.bulge / 30)
|
||||
);
|
||||
points.dartCpRight = points.dartCpRight.rotate(
|
||||
options.bulge,
|
||||
points.dartJoin
|
||||
);
|
||||
points.dartJoin.y + points.dartJoin.dist(points.bottomMid) * (options.bulge / 30)
|
||||
)
|
||||
points.dartCpRight = points.dartCpRight.rotate(options.bulge, points.dartJoin)
|
||||
|
||||
// Flip control point to left side
|
||||
points.dartCpLeft = points.dartCpRight.flipX();
|
||||
points.dartCpLeft = points.dartCpRight.flipX()
|
||||
} else {
|
||||
points.dartJoin = points.rightTuskLeft;
|
||||
points.dartJoin = points.rightTuskLeft
|
||||
}
|
||||
|
||||
// Flip points to left side
|
||||
points.leftTuskRight = points.rightTuskLeft.flipX();
|
||||
points.leftTuskLeft = points.rightTuskRight.flipX();
|
||||
points.curveLeftCpBottom = points.curveRightCpBottom.flipX();
|
||||
points.curveLeftCpTop = points.curveRightCpTop.flipX();
|
||||
points.leftTuskRight = points.rightTuskLeft.flipX()
|
||||
points.leftTuskLeft = points.rightTuskRight.flipX()
|
||||
points.curveLeftCpBottom = points.curveRightCpBottom.flipX()
|
||||
points.curveLeftCpTop = points.curveRightCpTop.flipX()
|
||||
|
||||
// Handle back rise
|
||||
points.topMid = new Point(0, points.topLeft.y);
|
||||
points.topLeft = points.topLeft.shift(90, store.get("frontRise"));
|
||||
points.topRight = points.topRight.shift(90, store.get("frontRise"));
|
||||
points.topMidCpRight = new Point(points.topRight.x / 2, points.topMid.y);
|
||||
points.topMidCpLeft = points.topMidCpRight.flipX();
|
||||
points.topMid = new Point(0, points.topLeft.y)
|
||||
points.topLeft = points.topLeft.shift(90, store.get('frontRise'))
|
||||
points.topRight = points.topRight.shift(90, store.get('frontRise'))
|
||||
points.topMidCpRight = new Point(points.topRight.x / 2, points.topMid.y)
|
||||
points.topMidCpLeft = points.topMidCpRight.flipX()
|
||||
|
||||
if (options.bulge > 0) {
|
||||
paths.trimBase = new Path()
|
||||
.move(points.rightTuskLeft)
|
||||
.curve(points.rightTuskLeft, points.dartCpRight, points.dartJoin)
|
||||
.curve(points.dartCpLeft, points.leftTuskRight, points.leftTuskRight);
|
||||
.curve(points.dartCpLeft, points.leftTuskRight, points.leftTuskRight)
|
||||
paths.seamStart = new Path()
|
||||
.move(points.midLeft)
|
||||
.line(points.topLeft)
|
||||
.curve(points.topLeft, points.topMidCpLeft, points.topMid)
|
||||
.curve(points.topMidCpRight, points.topRight, points.topRight)
|
||||
.line(points.midRight)
|
||||
.curve(
|
||||
points.curveRightCpTop,
|
||||
points.curveRightCpBottom,
|
||||
points.rightTuskRight
|
||||
)
|
||||
.line(points.rightTuskLeft);
|
||||
.curve(points.curveRightCpTop, points.curveRightCpBottom, points.rightTuskRight)
|
||||
.line(points.rightTuskLeft)
|
||||
paths.seamEnd = new Path()
|
||||
.move(points.leftTuskRight)
|
||||
.line(points.leftTuskLeft)
|
||||
.curve(points.curveLeftCpBottom, points.curveLeftCpTop, points.midLeft);
|
||||
paths.seamStart.render = false;
|
||||
paths.trimBase.render = false;
|
||||
paths.seamEnd.render = false;
|
||||
paths.seam = paths.seamStart.join(paths.trimBase).join(paths.seamEnd);
|
||||
.curve(points.curveLeftCpBottom, points.curveLeftCpTop, points.midLeft)
|
||||
paths.seamStart.render = false
|
||||
paths.trimBase.render = false
|
||||
paths.seamEnd.render = false
|
||||
paths.seam = paths.seamStart.join(paths.trimBase).join(paths.seamEnd)
|
||||
} else {
|
||||
paths.seam = new Path()
|
||||
.move(points.midLeft)
|
||||
|
@ -177,140 +145,128 @@ export default function(part) {
|
|||
.curve(points.topLeft, points.topMidCpLeft, points.topMid)
|
||||
.curve(points.topMidCpRight, points.topRight, points.topRight)
|
||||
.line(points.midRight)
|
||||
.curve(
|
||||
points.curveRightCpTop,
|
||||
points.curveRightCpBottom,
|
||||
points.rightTuskRight
|
||||
)
|
||||
.curve(points.curveRightCpTop, points.curveRightCpBottom, points.rightTuskRight)
|
||||
.line(points.leftTuskLeft)
|
||||
.curve(points.curveLeftCpBottom, points.curveLeftCpTop, points.midLeft);
|
||||
.curve(points.curveLeftCpBottom, points.curveLeftCpTop, points.midLeft)
|
||||
}
|
||||
paths.seam.close().attr("class", "fabric");
|
||||
paths.seam.close().attr('class', 'fabric')
|
||||
|
||||
// Complete pattern?
|
||||
if (complete) {
|
||||
if (sa) {
|
||||
if (options.bulge > 0) {
|
||||
let saStart = paths.seamStart.offset(sa * -1);
|
||||
let saTrim = paths.trimBase.offset(sa * -1).trim();
|
||||
let saEnd = paths.seamEnd.offset(sa * -1);
|
||||
let saStart = paths.seamStart.offset(sa * -1)
|
||||
let saTrim = paths.trimBase.offset(sa * -1).trim()
|
||||
let saEnd = paths.seamEnd.offset(sa * -1)
|
||||
paths.sa = saStart
|
||||
.join(saTrim)
|
||||
.join(saEnd)
|
||||
.close()
|
||||
.attr("class", "fabric sa");
|
||||
.attr('class', 'fabric sa')
|
||||
} else {
|
||||
paths.sa = paths.seam
|
||||
.offset(sa * -1)
|
||||
.trim()
|
||||
.close()
|
||||
.attr("class", "fabric sa");
|
||||
.attr('class', 'fabric sa')
|
||||
}
|
||||
}
|
||||
macro("title", {
|
||||
macro('title', {
|
||||
at: points.midMid,
|
||||
nr: 2,
|
||||
title: "front"
|
||||
});
|
||||
macro("grainline", {
|
||||
title: 'front'
|
||||
})
|
||||
macro('grainline', {
|
||||
from: points.dartJoin,
|
||||
to: points.topMid
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
// Paperless?
|
||||
if (paperless) {
|
||||
macro("hd", {
|
||||
macro('hd', {
|
||||
from: points.topLeft,
|
||||
to: points.topRight,
|
||||
y: points.topLeft.y - 15 - sa
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.midLeft,
|
||||
to: points.midRight,
|
||||
y: points.topLeft.y - 30 - sa
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.midLeft,
|
||||
to: points.topMid,
|
||||
x: points.midLeft.x - 15 - sa
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.midLeft,
|
||||
to: points.topLeft,
|
||||
x: points.midLeft.x - 30 - sa
|
||||
});
|
||||
})
|
||||
if (options.bulge === 0) {
|
||||
macro("hd", {
|
||||
macro('hd', {
|
||||
from: points.leftTuskLeft,
|
||||
to: points.rightTuskRight,
|
||||
y: points.leftTuskLeft.y + 15 + sa
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.leftTuskLeft,
|
||||
to: points.topLeft,
|
||||
x: points.midLeft.x - 45 - sa
|
||||
});
|
||||
})
|
||||
} else {
|
||||
macro("vd", {
|
||||
macro('vd', {
|
||||
from: points.leftTuskLeft,
|
||||
to: points.topLeft,
|
||||
x: points.midLeft.x - 45 - sa
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.leftTuskRight,
|
||||
to: points.topLeft,
|
||||
x: points.midLeft.x - 60 - sa
|
||||
});
|
||||
})
|
||||
points.narrowRight = new Path()
|
||||
.move(points.midRight)
|
||||
.curve(
|
||||
points.curveRightCpTop,
|
||||
points.curveRightCpBottom,
|
||||
points.rightTuskRight
|
||||
)
|
||||
.edge("left");
|
||||
.curve(points.curveRightCpTop, points.curveRightCpBottom, points.rightTuskRight)
|
||||
.edge('left')
|
||||
points.narrowLeft = new Path()
|
||||
.move(points.midLeft)
|
||||
.curve(
|
||||
points.curveLeftCpTop,
|
||||
points.curveLeftCpBottom,
|
||||
points.leftTuskLeft
|
||||
)
|
||||
.attr("class", "various stroke-xl lashed")
|
||||
.edge("right");
|
||||
macro("hd", {
|
||||
.curve(points.curveLeftCpTop, points.curveLeftCpBottom, points.leftTuskLeft)
|
||||
.attr('class', 'various stroke-xl lashed')
|
||||
.edge('right')
|
||||
macro('hd', {
|
||||
from: points.narrowLeft,
|
||||
to: points.narrowRight,
|
||||
y: points.narrowLeft.y
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.leftTuskRight,
|
||||
to: points.rightTuskLeft,
|
||||
y: points.rightTuskLeft.y + 15 + sa
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.leftTuskLeft,
|
||||
to: points.rightTuskRight,
|
||||
y: points.rightTuskLeft.y + 30 + sa
|
||||
});
|
||||
macro("ld", {
|
||||
})
|
||||
macro('ld', {
|
||||
from: points.rightTuskLeft,
|
||||
to: points.rightTuskRight,
|
||||
d: -15 - sa
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.narrowRight,
|
||||
to: points.topRight,
|
||||
x: points.topRight.x + 15 + sa
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.dartJoin,
|
||||
to: points.topRight,
|
||||
x: points.topRight.x + 30 + sa
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return part;
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
import freesewing from "@freesewing/core";
|
||||
import plugins from "@freesewing/plugin-bundle";
|
||||
import config from "../config";
|
||||
import freesewing from '@freesewing/core'
|
||||
import plugins from '@freesewing/plugin-bundle'
|
||||
import config from '../config'
|
||||
// Parts
|
||||
import draftBack from "./back";
|
||||
import draftSide from "./side";
|
||||
import draftFront from "./front";
|
||||
import draftInset from "./inset";
|
||||
import draftBack from './back'
|
||||
import draftSide from './side'
|
||||
import draftFront from './front'
|
||||
import draftInset from './inset'
|
||||
|
||||
// Create design
|
||||
const Pattern = new freesewing.Design(config, plugins);
|
||||
const Pattern = new freesewing.Design(config, plugins)
|
||||
|
||||
// Attach draft methods to prototype
|
||||
Pattern.prototype.draftBack = part => draftBack(part);
|
||||
Pattern.prototype.draftSide = part => draftSide(part);
|
||||
Pattern.prototype.draftInset = part => draftInset(part);
|
||||
Pattern.prototype.draftFront = part => draftFront(part);
|
||||
Pattern.prototype.draftBack = part => draftBack(part)
|
||||
Pattern.prototype.draftSide = part => draftSide(part)
|
||||
Pattern.prototype.draftInset = part => draftInset(part)
|
||||
Pattern.prototype.draftFront = part => draftFront(part)
|
||||
|
||||
export default Pattern;
|
||||
export default Pattern
|
||||
|
|
|
@ -1,50 +1,54 @@
|
|||
export default function init(part) {
|
||||
let {store, options, measurements, utils} = part.shorthand();
|
||||
let { store, options, measurements, utils } = part.shorthand()
|
||||
|
||||
if(store.get('init') !== true) {
|
||||
if (store.get('init') !== true) {
|
||||
/* Set vertical scale to 1 (no stretch) */
|
||||
store.set('yScale', 1);
|
||||
store.set('yScale', 1)
|
||||
|
||||
/* Store rise, backRise and legBonus as absolute values */
|
||||
store.set('rise', measurements.hipsToUpperLeg * options.rise * store.get('yScale'));
|
||||
store.set('backRise', measurements.hipsToUpperLeg * options.backRise * store.get('yScale'));
|
||||
store.set('sideRise', store.get('backRise') * 0.75);
|
||||
store.set('frontRise', store.get('backRise') * 0.25);
|
||||
store.set('legBonus', measurements.hipsToUpperLeg * options.legBonus * store.get('yScale'));
|
||||
store.set('rise', measurements.hipsToUpperLeg * options.rise * store.get('yScale'))
|
||||
store.set('backRise', measurements.hipsToUpperLeg * options.backRise * store.get('yScale'))
|
||||
store.set('sideRise', store.get('backRise') * 0.75)
|
||||
store.set('frontRise', store.get('backRise') * 0.25)
|
||||
store.set('legBonus', measurements.hipsToUpperLeg * options.legBonus * store.get('yScale'))
|
||||
|
||||
/* Set horizontal scale based on stretch */
|
||||
store.set('xScale', utils.stretchToScale(options.stretch));
|
||||
store.set('xScaleLegs', utils.stretchToScale(options.legStretch));
|
||||
store.set('xScale', utils.stretchToScale(options.stretch))
|
||||
store.set('xScaleLegs', utils.stretchToScale(options.legStretch))
|
||||
|
||||
/* Ratio of parts at the hips*/
|
||||
store.set('hips', measurements.hipsCircumference * store.get('xScale'));
|
||||
store.set('hipsFront', store.get('hips') * options.hipRatioFront);
|
||||
let hipRatioSide = (1 - (options.hipRatioFront + options.hipRatioBack)) / 2;
|
||||
store.set('hipsSide', store.get('hips') * hipRatioSide);
|
||||
store.set('hipsBack', store.get('hips') * options.hipRatioBack);
|
||||
store.set('hips', measurements.hipsCircumference * store.get('xScale'))
|
||||
store.set('hipsFront', store.get('hips') * options.hipRatioFront)
|
||||
let hipRatioSide = (1 - (options.hipRatioFront + options.hipRatioBack)) / 2
|
||||
store.set('hipsSide', store.get('hips') * hipRatioSide)
|
||||
store.set('hipsBack', store.get('hips') * options.hipRatioBack)
|
||||
|
||||
/* Ratio of parts at the legs*/
|
||||
store.set('leg', measurements.upperLegCircumference * store.get('xScaleLegs'));
|
||||
store.set('legInset', store.get('leg') * options.legRatioInset);
|
||||
let legRatioSide = 1 - options.legRatioInset - options.legRatioBack;
|
||||
store.set('legSide', store.get('leg') * legRatioSide);
|
||||
store.set('legBack', store.get('leg') * options.legRatioBack);
|
||||
store.set('leg', measurements.upperLegCircumference * store.get('xScaleLegs'))
|
||||
store.set('legInset', store.get('leg') * options.legRatioInset)
|
||||
let legRatioSide = 1 - options.legRatioInset - options.legRatioBack
|
||||
store.set('legSide', store.get('leg') * legRatioSide)
|
||||
store.set('legBack', store.get('leg') * options.legRatioBack)
|
||||
|
||||
/* Gusset */
|
||||
store.set('gusset', measurements.hipsCircumference * options.gussetRatio);
|
||||
store.set('gussetInsetRatio', options.gussetInsetRatio);
|
||||
store.set('gusset', measurements.hipsCircumference * options.gussetRatio)
|
||||
store.set('gussetInsetRatio', options.gussetInsetRatio)
|
||||
|
||||
/* Length helper */
|
||||
store.set('length', measurements.hipsToUpperLeg * store.get('yScale'));
|
||||
store.set('riseLength', measurements.hipsToUpperLeg + store.get('rise'));
|
||||
store.set('fullLength', store.get('riseLength') + store.get('legBonus') * store.get('yScale'));
|
||||
store.set('length', measurements.hipsToUpperLeg * store.get('yScale'))
|
||||
store.set('riseLength', measurements.hipsToUpperLeg + store.get('rise'))
|
||||
store.set('fullLength', store.get('riseLength') + store.get('legBonus') * store.get('yScale'))
|
||||
|
||||
/* Height ratio front/inset */
|
||||
store.set('heightInset', store.get('riseLength') * options.heightRatioInset + store.get('legBonus') * store.get('yScale'));
|
||||
store.set('heightFront', store.get('riseLength') * (1 - options.heightRatioInset));
|
||||
store.set(
|
||||
'heightInset',
|
||||
store.get('riseLength') * options.heightRatioInset +
|
||||
store.get('legBonus') * store.get('yScale')
|
||||
)
|
||||
store.set('heightFront', store.get('riseLength') * (1 - options.heightRatioInset))
|
||||
|
||||
/* Absolute amount to raise the back */
|
||||
|
||||
store.set('init', true);
|
||||
store.set('init', true)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,48 +1,34 @@
|
|||
import init from "./init";
|
||||
import init from './init'
|
||||
|
||||
export default function(part) {
|
||||
let {
|
||||
store,
|
||||
sa,
|
||||
Point,
|
||||
points,
|
||||
Path,
|
||||
paths,
|
||||
complete,
|
||||
paperless,
|
||||
macro
|
||||
} = part.shorthand();
|
||||
let { store, sa, Point, points, Path, paths, complete, paperless, macro } = part.shorthand()
|
||||
|
||||
// Initialize
|
||||
init(part);
|
||||
init(part)
|
||||
|
||||
// height is 73.5%
|
||||
points.topLeft = new Point(0, 0);
|
||||
points.bottomLeft = points.topLeft.shift(-90, store.get("heightInset"));
|
||||
points.bottomRight = new Point(store.get("legInset"), points.bottomLeft.y);
|
||||
points.tip = new Point(
|
||||
points.bottomRight.x * 1.111,
|
||||
points.bottomRight.y - store.get("gusset")
|
||||
);
|
||||
points.topLeft = new Point(0, 0)
|
||||
points.bottomLeft = points.topLeft.shift(-90, store.get('heightInset'))
|
||||
points.bottomRight = new Point(store.get('legInset'), points.bottomLeft.y)
|
||||
points.tip = new Point(points.bottomRight.x * 1.111, points.bottomRight.y - store.get('gusset'))
|
||||
points.tip = points.bottomRight.shiftTowards(
|
||||
points.tip,
|
||||
store.get("crotchSeamLength") -
|
||||
store.get("gusset") * (1 - store.get("gussetInsetRatio"))
|
||||
);
|
||||
points.tipCpTop = new Point(store.get("gusset") * 1.2, 0);
|
||||
store.get('crotchSeamLength') - store.get('gusset') * (1 - store.get('gussetInsetRatio'))
|
||||
)
|
||||
points.tipCpTop = new Point(store.get('gusset') * 1.2, 0)
|
||||
points.tipCpBottom = points.tip.shift(
|
||||
points.bottomRight.angle(points.tip) + 90,
|
||||
store.get("gusset") * 1.5
|
||||
);
|
||||
store.get('gusset') * 1.5
|
||||
)
|
||||
|
||||
// Store cuve length
|
||||
store.set(
|
||||
"curve",
|
||||
'curve',
|
||||
new Path()
|
||||
.move(points.tip)
|
||||
.curve(points.tipCpBottom, points.tipCpTop, points.topLeft)
|
||||
.length()
|
||||
);
|
||||
)
|
||||
|
||||
// Path
|
||||
paths.seam = new Path()
|
||||
|
@ -52,46 +38,46 @@ export default function(part) {
|
|||
.line(points.tip)
|
||||
.curve(points.tipCpBottom, points.tipCpTop, points.topLeft)
|
||||
.close()
|
||||
.attr("class", "fabric");
|
||||
.attr('class', 'fabric')
|
||||
|
||||
// Complete pattern?
|
||||
if (complete) {
|
||||
if (sa) paths.sa = paths.seam.offset(sa).attr("class", "fabric sa");
|
||||
points.title = points.topLeft.shiftFractionTowards(points.bottomRight, 0.5);
|
||||
macro("title", {
|
||||
if (sa) paths.sa = paths.seam.offset(sa).attr('class', 'fabric sa')
|
||||
points.title = points.topLeft.shiftFractionTowards(points.bottomRight, 0.5)
|
||||
macro('title', {
|
||||
at: points.title.shift(-90, 15),
|
||||
nr: 4,
|
||||
title: "inset"
|
||||
});
|
||||
macro("grainline", {
|
||||
title: 'inset'
|
||||
})
|
||||
macro('grainline', {
|
||||
from: points.bottomLeft.shift(0, 15),
|
||||
to: points.topLeft.shift(0, 15)
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
// Paperless?
|
||||
if (paperless) {
|
||||
macro("vd", {
|
||||
macro('vd', {
|
||||
from: points.bottomLeft,
|
||||
to: points.topLeft,
|
||||
x: points.topLeft.x - 15 - sa
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.bottomRight,
|
||||
to: points.tip,
|
||||
x: points.tip.x + 15 + sa
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.bottomLeft,
|
||||
to: points.bottomRight,
|
||||
y: points.bottomRight.y + 15 + sa
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.bottomLeft,
|
||||
to: points.tip,
|
||||
y: points.bottomRight.y + 30 + sa
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
return part;
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import init from "./init";
|
||||
import init from './init'
|
||||
|
||||
export default function(part) {
|
||||
let {
|
||||
|
@ -12,36 +12,36 @@ export default function(part) {
|
|||
paperless,
|
||||
macro,
|
||||
utils
|
||||
} = part.shorthand();
|
||||
} = part.shorthand()
|
||||
|
||||
// Initialize
|
||||
init(part);
|
||||
init(part)
|
||||
|
||||
// Top left
|
||||
points.zero = new Point(0, 0);
|
||||
points.topLeft = points.zero.shift(90, store.get("rise"));
|
||||
points.zero = new Point(0, 0)
|
||||
points.topLeft = points.zero.shift(90, store.get('rise'))
|
||||
|
||||
// Top right
|
||||
points.topRight = new Point(store.get("hipsSide"), points.topLeft.y);
|
||||
points.topRight = new Point(store.get('hipsSide'), points.topLeft.y)
|
||||
|
||||
// Bottom right
|
||||
points.bottomRight = points.topRight.shift(-90, store.get("fullLength"));
|
||||
points.bottomRight = points.topRight.shift(-90, store.get('fullLength'))
|
||||
|
||||
// Find bottom left
|
||||
let isect = utils.circlesIntersect(
|
||||
points.bottomRight,
|
||||
store.get("legSide"),
|
||||
store.get('legSide'),
|
||||
points.topLeft,
|
||||
store.get("backSeamLength")
|
||||
);
|
||||
points.bottomLeft = isect[0];
|
||||
store.get('backSeamLength')
|
||||
)
|
||||
points.bottomLeft = isect[0]
|
||||
|
||||
// Store side seam length
|
||||
store.set("sideSeamLength", points.topRight.dist(points.bottomRight));
|
||||
store.set('sideSeamLength', points.topRight.dist(points.bottomRight))
|
||||
|
||||
// Handle back rise
|
||||
points.topLeft = points.topLeft.shift(90, store.get("sideRise"));
|
||||
points.topRight = points.topRight.shift(90, store.get("frontRise"));
|
||||
points.topLeft = points.topLeft.shift(90, store.get('sideRise'))
|
||||
points.topRight = points.topRight.shift(90, store.get('frontRise'))
|
||||
|
||||
// Path
|
||||
paths.seam = new Path()
|
||||
|
@ -51,51 +51,51 @@ export default function(part) {
|
|||
.line(points.bottomLeft)
|
||||
.line(points.topLeft)
|
||||
.close()
|
||||
.attr("class", "fabric");
|
||||
.attr('class', 'fabric')
|
||||
|
||||
// Anchor point for sampling
|
||||
points.anchor = points.topLeft;
|
||||
points.anchor = points.topLeft
|
||||
|
||||
// Complete pattern?
|
||||
if (complete) {
|
||||
points.title = points.topLeft.shiftFractionTowards(points.bottomRight, 0.5);
|
||||
macro("title", {
|
||||
points.title = points.topLeft.shiftFractionTowards(points.bottomRight, 0.5)
|
||||
macro('title', {
|
||||
at: points.title.shift(90, 30),
|
||||
nr: 3,
|
||||
title: "side"
|
||||
});
|
||||
title: 'side'
|
||||
})
|
||||
if (sa) {
|
||||
paths.sa = paths.seam.offset(sa * -1).attr("class", "fabric sa");
|
||||
paths.sa = paths.seam.offset(sa * -1).attr('class', 'fabric sa')
|
||||
}
|
||||
macro("grainline", {
|
||||
macro('grainline', {
|
||||
from: new Point(points.bottomRight.x / 2, points.bottomRight.y),
|
||||
to: new Point(points.bottomRight.x / 2, points.topRight.y)
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
// Paperless?
|
||||
if (paperless) {
|
||||
macro("vd", {
|
||||
macro('vd', {
|
||||
from: points.bottomLeft,
|
||||
to: points.topLeft,
|
||||
x: points.topLeft.x - 15 - sa
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.bottomRight,
|
||||
to: points.topRight,
|
||||
x: points.topRight.x + 15 + sa
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.topLeft,
|
||||
to: points.topRight,
|
||||
y: points.topLeft.y - 15 - sa
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.bottomLeft,
|
||||
to: points.bottomRight,
|
||||
y: points.bottomLeft.y + 15 + sa
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
return part;
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -1,22 +1,15 @@
|
|||
import React from "react";
|
||||
import freesewing from "@freesewing/core";
|
||||
import Workbench from "@freesewing/components/Workbench";
|
||||
import "typeface-roboto-condensed";
|
||||
import "@freesewing/css-theme";
|
||||
import React from 'react'
|
||||
import freesewing from '@freesewing/core'
|
||||
import Workbench from '@freesewing/components/Workbench'
|
||||
import 'typeface-roboto-condensed'
|
||||
import '@freesewing/css-theme'
|
||||
|
||||
import Pattern from "pattern";
|
||||
import Pattern from 'pattern'
|
||||
|
||||
const App = props => {
|
||||
let instance = new Pattern();
|
||||
let config = instance.config;
|
||||
return (
|
||||
<Workbench
|
||||
freesewing={freesewing}
|
||||
Pattern={Pattern}
|
||||
config={config}
|
||||
userLanguage="en"
|
||||
/>
|
||||
);
|
||||
};
|
||||
let instance = new Pattern()
|
||||
let config = instance.config
|
||||
return <Workbench freesewing={freesewing} Pattern={Pattern} config={config} userLanguage="en" />
|
||||
}
|
||||
|
||||
export default App;
|
||||
export default App
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import App from "./App";
|
||||
import * as serviceWorker from "./serviceWorker";
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import App from './App'
|
||||
import * as serviceWorker from './serviceWorker'
|
||||
|
||||
ReactDOM.render(<App />, document.getElementById("root"));
|
||||
ReactDOM.render(<App />, document.getElementById('root'))
|
||||
|
||||
// If you want your app to work offline and load faster, you can change
|
||||
// unregister() to register() below. Note this comes with some pitfalls.
|
||||
// Learn more about service workers: http://bit.ly/CRA-PWA
|
||||
serviceWorker.unregister();
|
||||
serviceWorker.unregister()
|
||||
|
|
|
@ -9,46 +9,44 @@
|
|||
// This link also includes instructions on opting out of this behavior.
|
||||
|
||||
const isLocalhost = Boolean(
|
||||
window.location.hostname === "localhost" ||
|
||||
window.location.hostname === 'localhost' ||
|
||||
// [::1] is the IPv6 localhost address.
|
||||
window.location.hostname === "[::1]" ||
|
||||
window.location.hostname === '[::1]' ||
|
||||
// 127.0.0.1/8 is considered localhost for IPv4.
|
||||
window.location.hostname.match(
|
||||
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
|
||||
)
|
||||
);
|
||||
window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/)
|
||||
)
|
||||
|
||||
export function register(config) {
|
||||
if (process.env.NODE_ENV === "production" && "serviceWorker" in navigator) {
|
||||
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
|
||||
// The URL constructor is available in all browsers that support SW.
|
||||
const publicUrl = new URL(process.env.PUBLIC_URL, window.location);
|
||||
const publicUrl = new URL(process.env.PUBLIC_URL, window.location)
|
||||
if (publicUrl.origin !== window.location.origin) {
|
||||
// Our service worker won't work if PUBLIC_URL is on a different origin
|
||||
// from what our page is served on. This might happen if a CDN is used to
|
||||
// serve assets; see https://github.com/facebook/create-react-app/issues/2374
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
window.addEventListener("load", () => {
|
||||
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
|
||||
window.addEventListener('load', () => {
|
||||
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`
|
||||
|
||||
if (isLocalhost) {
|
||||
// This is running on localhost. Let's check if a service worker still exists or not.
|
||||
checkValidServiceWorker(swUrl, config);
|
||||
checkValidServiceWorker(swUrl, config)
|
||||
|
||||
// Add some additional logging to localhost, pointing developers to the
|
||||
// service worker/PWA documentation.
|
||||
navigator.serviceWorker.ready.then(() => {
|
||||
console.log(
|
||||
"This web app is being served cache-first by a service " +
|
||||
"worker. To learn more, visit https://goo.gl/SC7cgQ"
|
||||
);
|
||||
});
|
||||
'This web app is being served cache-first by a service ' +
|
||||
'worker. To learn more, visit https://goo.gl/SC7cgQ'
|
||||
)
|
||||
})
|
||||
} else {
|
||||
// Is not local host. Just register service worker
|
||||
registerValidSW(swUrl, config);
|
||||
registerValidSW(swUrl, config)
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,38 +55,38 @@ function registerValidSW(swUrl, config) {
|
|||
.register(swUrl)
|
||||
.then(registration => {
|
||||
registration.onupdatefound = () => {
|
||||
const installingWorker = registration.installing;
|
||||
const installingWorker = registration.installing
|
||||
installingWorker.onstatechange = () => {
|
||||
if (installingWorker.state === "installed") {
|
||||
if (installingWorker.state === 'installed') {
|
||||
if (navigator.serviceWorker.controller) {
|
||||
// At this point, the old content will have been purged and
|
||||
// the fresh content will have been added to the cache.
|
||||
// It's the perfect time to display a "New content is
|
||||
// available; please refresh." message in your web app.
|
||||
console.log("New content is available; please refresh.");
|
||||
console.log('New content is available; please refresh.')
|
||||
|
||||
// Execute callback
|
||||
if (config.onUpdate) {
|
||||
config.onUpdate(registration);
|
||||
config.onUpdate(registration)
|
||||
}
|
||||
} else {
|
||||
// At this point, everything has been precached.
|
||||
// It's the perfect time to display a
|
||||
// "Content is cached for offline use." message.
|
||||
console.log("Content is cached for offline use.");
|
||||
console.log('Content is cached for offline use.')
|
||||
|
||||
// Execute callback
|
||||
if (config.onSuccess) {
|
||||
config.onSuccess(registration);
|
||||
config.onSuccess(registration)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
})
|
||||
.catch(error => {
|
||||
console.error("Error during service worker registration:", error);
|
||||
});
|
||||
console.error('Error during service worker registration:', error)
|
||||
})
|
||||
}
|
||||
|
||||
function checkValidServiceWorker(swUrl, config) {
|
||||
|
@ -98,30 +96,28 @@ function checkValidServiceWorker(swUrl, config) {
|
|||
// Ensure service worker exists, and that we really are getting a JS file.
|
||||
if (
|
||||
response.status === 404 ||
|
||||
response.headers.get("content-type").indexOf("javascript") === -1
|
||||
response.headers.get('content-type').indexOf('javascript') === -1
|
||||
) {
|
||||
// No service worker found. Probably a different app. Reload the page.
|
||||
navigator.serviceWorker.ready.then(registration => {
|
||||
registration.unregister().then(() => {
|
||||
window.location.reload();
|
||||
});
|
||||
});
|
||||
window.location.reload()
|
||||
})
|
||||
})
|
||||
} else {
|
||||
// Service worker found. Proceed as normal.
|
||||
registerValidSW(swUrl, config);
|
||||
registerValidSW(swUrl, config)
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
console.log(
|
||||
"No internet connection found. App is running in offline mode."
|
||||
);
|
||||
});
|
||||
console.log('No internet connection found. App is running in offline mode.')
|
||||
})
|
||||
}
|
||||
|
||||
export function unregister() {
|
||||
if ("serviceWorker" in navigator) {
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.ready.then(registration => {
|
||||
registration.unregister();
|
||||
});
|
||||
registration.unregister()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ export default function(part) {
|
|||
Point,
|
||||
paths,
|
||||
Path
|
||||
} = part.shorthand();
|
||||
} = part.shorthand()
|
||||
|
||||
/**
|
||||
* we're adding half of the proportionate amount of chest east for the bust span
|
||||
|
@ -24,14 +24,11 @@ export default function(part) {
|
|||
measurements.bustSpan / 2 +
|
||||
((measurements.bustSpan / measurements.bust) * options.chestEase) / 4,
|
||||
points.neck.y + measurements.highPointShoulderToBust
|
||||
);
|
||||
)
|
||||
|
||||
// Draw the princess seam (ps)
|
||||
points.psHem = new Point(points.bustPoint.x, points.hem.y);
|
||||
points.bustPointCp1 = points.bustPoint.shift(
|
||||
90,
|
||||
points.armholePitch.dy(points.bustPoint) / 2
|
||||
);
|
||||
points.psHem = new Point(points.bustPoint.x, points.hem.y)
|
||||
points.bustPointCp1 = points.bustPoint.shift(90, points.armholePitch.dy(points.bustPoint) / 2)
|
||||
|
||||
// Paths
|
||||
paths.seam = new Path()
|
||||
|
@ -46,15 +43,11 @@ export default function(part) {
|
|||
.line(points.hemEdge)
|
||||
.line(points.psHem)
|
||||
.close()
|
||||
.attr("class", "fabric");
|
||||
.attr('class', 'fabric')
|
||||
|
||||
paths.chestPiece = paths.chestPiece
|
||||
.curve(points.armholeCp2, points.armholeHollowCp1, points.armholeHollow)
|
||||
.curve(
|
||||
points.armholeHollowCp2,
|
||||
points.armholePitchCp1,
|
||||
points.armholePitch
|
||||
);
|
||||
.curve(points.armholeHollowCp2, points.armholePitchCp1, points.armholePitch)
|
||||
|
||||
paths.chestPocket = new Path()
|
||||
.move(points.chestPocketTopLeft)
|
||||
|
@ -63,7 +56,7 @@ export default function(part) {
|
|||
.line(points.chestPocketTopRight)
|
||||
.line(points.chestPocketTopLeft)
|
||||
.close()
|
||||
.attr("class", "fabric help");
|
||||
.attr('class', 'fabric help')
|
||||
|
||||
/////////////////////////////////////////
|
||||
|
||||
|
@ -74,146 +67,135 @@ export default function(part) {
|
|||
*/
|
||||
|
||||
let side = [
|
||||
"bustPoint",
|
||||
"bustPointCp1",
|
||||
"psHem",
|
||||
"hem",
|
||||
"seat",
|
||||
"seatCp2",
|
||||
"waistCp1",
|
||||
"waist",
|
||||
"waistCp2",
|
||||
"armhole",
|
||||
"armholeCp2",
|
||||
"armholeHollowCp1",
|
||||
"armholeHollow",
|
||||
"armholeHollowCp2",
|
||||
"armholePitchCp1",
|
||||
"armholePitch"
|
||||
];
|
||||
'bustPoint',
|
||||
'bustPointCp1',
|
||||
'psHem',
|
||||
'hem',
|
||||
'seat',
|
||||
'seatCp2',
|
||||
'waistCp1',
|
||||
'waist',
|
||||
'waistCp2',
|
||||
'armhole',
|
||||
'armholeCp2',
|
||||
'armholeHollowCp1',
|
||||
'armholeHollow',
|
||||
'armholeHollowCp2',
|
||||
'armholePitchCp1',
|
||||
'armholePitch'
|
||||
]
|
||||
// Store these, we'll use them in the side part
|
||||
store.set("side", side);
|
||||
store.set('side', side)
|
||||
|
||||
// How much (horizontal) room do we need to create?
|
||||
let extra = measurements.bust - measurements.highBust;
|
||||
let extra = measurements.bust - measurements.highBust
|
||||
|
||||
/* Cut from armholePitch point to bustPoint and rotate
|
||||
* entire side panel until we have created enough room */
|
||||
let added = 0;
|
||||
let delta = 10;
|
||||
let count = 1;
|
||||
let added = 0
|
||||
let delta = 10
|
||||
let count = 1
|
||||
while (Math.abs(delta) > 0.5 && count < 50) {
|
||||
for (let i of side)
|
||||
points[i + "Rot1"] = points[i].rotate(delta / 5, points.armholePitch);
|
||||
added = points.bustPoint.dx(points.bustPointRot1);
|
||||
delta = extra - added;
|
||||
count++;
|
||||
for (let i of side) points[i + 'Rot1'] = points[i].rotate(delta / 5, points.armholePitch)
|
||||
added = points.bustPoint.dx(points.bustPointRot1)
|
||||
delta = extra - added
|
||||
count++
|
||||
}
|
||||
|
||||
/* Now cut from armhole to rotated bustpoint and rotate
|
||||
* the lower part of the site until it's aligned vertically again
|
||||
* We'll also rotate the top point, thus closing the bust dart */
|
||||
let angle = -1 * (points.bustPointRot1.angle(points.psHemRot1) - 270);
|
||||
for (let i of side)
|
||||
points[i + "Rot2"] = points[i + "Rot1"].rotate(angle, points.bustPointRot1);
|
||||
let angle = -1 * (points.bustPointRot1.angle(points.psHemRot1) - 270)
|
||||
for (let i of side) points[i + 'Rot2'] = points[i + 'Rot1'].rotate(angle, points.bustPointRot1)
|
||||
// Also rotate original bustPoint and bustPointCp1
|
||||
points.bustPointRot2 = points.bustPoint.rotate(angle, points.bustPointRot1);
|
||||
points.bustPointCp1Rot2 = points.bustPointCp1.rotate(
|
||||
angle,
|
||||
points.bustPointRot1
|
||||
);
|
||||
points.bustPointRot2 = points.bustPoint.rotate(angle, points.bustPointRot1)
|
||||
points.bustPointCp1Rot2 = points.bustPointCp1.rotate(angle, points.bustPointRot1)
|
||||
|
||||
// Now construct the new curve
|
||||
points.bustPointCp2 = points.bustPointCp1Rot2
|
||||
.rotate(180, points.bustPointRot2)
|
||||
.shiftFractionTowards(points.bustPointRot2, 0.5);
|
||||
points.psWaist = new Point(points.psHemRot2.x, points.waistRot2.y);
|
||||
.shiftFractionTowards(points.bustPointRot2, 0.5)
|
||||
points.psWaist = new Point(points.psHemRot2.x, points.waistRot2.y)
|
||||
points.psWaistCp1 = points.psWaist.shift(
|
||||
90,
|
||||
points.bustPointRot2.dy(points.psWaist) * options.contour
|
||||
);
|
||||
)
|
||||
|
||||
// Adapt lenght of the front part
|
||||
let frontCurve = new Path()
|
||||
.move(points.armholePitch)
|
||||
._curve(points.bustPointCp1, points.bustPoint)
|
||||
.line(new Point(points.psHem.x, points.waist.y))
|
||||
.length();
|
||||
.length()
|
||||
let sideCurve = new Path()
|
||||
.move(points.armholePitchRot2)
|
||||
._curve(points.bustPointCp1Rot2, points.bustPointRot2)
|
||||
.curve(points.bustPointCp2, points.psWaistCp1, points.psWaist)
|
||||
.length();
|
||||
let longer = sideCurve - frontCurve;
|
||||
.length()
|
||||
let longer = sideCurve - frontCurve
|
||||
|
||||
let belowBust = [
|
||||
"button1Left",
|
||||
"button2Left",
|
||||
"button3Left",
|
||||
"button1Right",
|
||||
"button2Right",
|
||||
"button3Right",
|
||||
"rollLineStart",
|
||||
"hemEdge",
|
||||
"flbHem",
|
||||
"psHem",
|
||||
"pocketTopLeft",
|
||||
"pocketTopRight",
|
||||
"pocketBottomLeft",
|
||||
"pocketBottomRight",
|
||||
"pocketRoundLeftStart",
|
||||
"pocketRoundLeftCp1",
|
||||
"pocketRoundLeftCp2",
|
||||
"pocketRoundLeftEnd",
|
||||
"pocketRoundRightStart",
|
||||
"pocketRoundRightCp1",
|
||||
"pocketRoundRightCp2",
|
||||
"pocketRoundRightEnd",
|
||||
"pocketFlapTopLeft",
|
||||
"pocketFlapTopRight",
|
||||
"pocketFlapBottomLeft",
|
||||
"pocketFlapBottomRight",
|
||||
"pocketFlapRoundLeftStart",
|
||||
"pocketFlapRoundLeftCp1",
|
||||
"pocketFlapRoundLeftCp2",
|
||||
"pocketFlapRoundLeftEnd",
|
||||
"pocketFlapRoundRightStart",
|
||||
"pocketFlapRoundRightCp1",
|
||||
"pocketFlapRoundRightCp2",
|
||||
"pocketFlapRoundRightEnd",
|
||||
"innerPocketTopLeft",
|
||||
"innerPocketTopRight",
|
||||
"innerPocketBottomLeft",
|
||||
"innerPocketBottomRight",
|
||||
"chestPocketTopLeft",
|
||||
"chestPocketTopRight",
|
||||
"chestPocketBottomLeft",
|
||||
"chestPocketBottomRight"
|
||||
];
|
||||
'button1Left',
|
||||
'button2Left',
|
||||
'button3Left',
|
||||
'button1Right',
|
||||
'button2Right',
|
||||
'button3Right',
|
||||
'rollLineStart',
|
||||
'hemEdge',
|
||||
'flbHem',
|
||||
'psHem',
|
||||
'pocketTopLeft',
|
||||
'pocketTopRight',
|
||||
'pocketBottomLeft',
|
||||
'pocketBottomRight',
|
||||
'pocketRoundLeftStart',
|
||||
'pocketRoundLeftCp1',
|
||||
'pocketRoundLeftCp2',
|
||||
'pocketRoundLeftEnd',
|
||||
'pocketRoundRightStart',
|
||||
'pocketRoundRightCp1',
|
||||
'pocketRoundRightCp2',
|
||||
'pocketRoundRightEnd',
|
||||
'pocketFlapTopLeft',
|
||||
'pocketFlapTopRight',
|
||||
'pocketFlapBottomLeft',
|
||||
'pocketFlapBottomRight',
|
||||
'pocketFlapRoundLeftStart',
|
||||
'pocketFlapRoundLeftCp1',
|
||||
'pocketFlapRoundLeftCp2',
|
||||
'pocketFlapRoundLeftEnd',
|
||||
'pocketFlapRoundRightStart',
|
||||
'pocketFlapRoundRightCp1',
|
||||
'pocketFlapRoundRightCp2',
|
||||
'pocketFlapRoundRightEnd',
|
||||
'innerPocketTopLeft',
|
||||
'innerPocketTopRight',
|
||||
'innerPocketBottomLeft',
|
||||
'innerPocketBottomRight',
|
||||
'chestPocketTopLeft',
|
||||
'chestPocketTopRight',
|
||||
'chestPocketBottomLeft',
|
||||
'chestPocketBottomRight'
|
||||
]
|
||||
for (let i of belowBust) {
|
||||
// Round points depend on options, so add a check
|
||||
if (typeof points[i] !== "undefined") {
|
||||
points[i] = points[i].shift(-90, longer);
|
||||
} else console.log(i);
|
||||
if (typeof points[i] !== 'undefined') {
|
||||
points[i] = points[i].shift(-90, longer)
|
||||
} else console.log(i)
|
||||
}
|
||||
|
||||
// Move the map/chest pocket into the princess seam
|
||||
points.chestPocketBottomLeft = new Point(
|
||||
points.bustPoint.x,
|
||||
points.button2Right.y - points.button3Right.dy(points.button2Right) / 10
|
||||
);
|
||||
points.chestPocketTopLeft = points.chestPocketBottomLeft.shift(
|
||||
90,
|
||||
store.get("chestPocketHeight")
|
||||
);
|
||||
points.chestPocketTopRight = points.chestPocketTopLeft.shift(
|
||||
0,
|
||||
store.get("chestPocketWidth")
|
||||
);
|
||||
)
|
||||
points.chestPocketTopLeft = points.chestPocketBottomLeft.shift(90, store.get('chestPocketHeight'))
|
||||
points.chestPocketTopRight = points.chestPocketTopLeft.shift(0, store.get('chestPocketWidth'))
|
||||
points.chestPocketBottomRight = points.chestPocketBottomLeft.shift(
|
||||
0,
|
||||
store.get("chestPocketWidth")
|
||||
);
|
||||
store.get('chestPocketWidth')
|
||||
)
|
||||
|
||||
// Uncomment these to better understand the FBA
|
||||
/*
|
||||
|
@ -256,8 +238,8 @@ export default function(part) {
|
|||
*/
|
||||
|
||||
// Clean up
|
||||
for (let i in paths) delete paths[i];
|
||||
for (let i in snippets) delete snippets[i];
|
||||
for (let i in paths) delete paths[i]
|
||||
for (let i in snippets) delete snippets[i]
|
||||
|
||||
// Paths
|
||||
paths.saBase = new Path()
|
||||
|
@ -270,22 +252,22 @@ export default function(part) {
|
|||
.line(points.collarTip)
|
||||
._curve(points.lapelStraightEndCp1, points.lapelStraightEnd)
|
||||
.line(points.hemEdge)
|
||||
.line(points.flbHem);
|
||||
.line(points.flbHem)
|
||||
paths.seam = paths.saBase
|
||||
.clone()
|
||||
.line(points.psHem)
|
||||
.close()
|
||||
.attr("class", "fabric");
|
||||
.attr('class', 'fabric')
|
||||
|
||||
paths.rollLine = new Path()
|
||||
.move(points.rollLineStart)
|
||||
.line(points.rollLineEnd)
|
||||
.attr("class", "lashed");
|
||||
.attr('class', 'lashed')
|
||||
|
||||
paths.flb = new Path()
|
||||
.move(points.flbHem)
|
||||
.line(points.flbTop)
|
||||
.attr("class", "lining lashed");
|
||||
.attr('class', 'lining lashed')
|
||||
|
||||
paths.pocket = new Path()
|
||||
.move(
|
||||
|
@ -297,15 +279,11 @@ export default function(part) {
|
|||
)
|
||||
)
|
||||
.line(points.pocketTopLeft)
|
||||
.attr("class", "fabric help");
|
||||
.attr('class', 'fabric help')
|
||||
if (options.pocketRadius > 0) {
|
||||
paths.pocket = paths.pocket
|
||||
.line(points.pocketRoundLeftStart)
|
||||
.curve(
|
||||
points.pocketRoundLeftCp1,
|
||||
points.pocketRoundLeftCp2,
|
||||
points.pocketRoundLeftEnd
|
||||
);
|
||||
.curve(points.pocketRoundLeftCp1, points.pocketRoundLeftCp2, points.pocketRoundLeftEnd)
|
||||
} else {
|
||||
paths.pocket = paths.pocket
|
||||
.line(points.pocketBottomLeft)
|
||||
|
@ -316,7 +294,7 @@ export default function(part) {
|
|||
points.bustPoint,
|
||||
points.psHem
|
||||
)
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
paths.pocketFlap = new Path()
|
||||
|
@ -329,7 +307,7 @@ export default function(part) {
|
|||
)
|
||||
)
|
||||
.line(points.pocketFlapTopLeft)
|
||||
.attr("class", "fabric help");
|
||||
.attr('class', 'fabric help')
|
||||
if (options.pocketFlapRadius > 0) {
|
||||
paths.pocketFlap = paths.pocketFlap
|
||||
.line(points.pocketFlapRoundLeftStart)
|
||||
|
@ -337,7 +315,7 @@ export default function(part) {
|
|||
points.pocketFlapRoundLeftCp1,
|
||||
points.pocketFlapRoundLeftCp2,
|
||||
points.pocketFlapRoundLeftEnd
|
||||
);
|
||||
)
|
||||
} else {
|
||||
paths.pocketFlap = paths.pocketFlap
|
||||
.line(points.pocketFlapBottomLeft)
|
||||
|
@ -348,7 +326,7 @@ export default function(part) {
|
|||
points.bustPoint,
|
||||
points.psHem
|
||||
)
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
paths.chestPocket = new Path()
|
||||
|
@ -358,7 +336,7 @@ export default function(part) {
|
|||
.line(points.chestPocketTopRight)
|
||||
.line(points.chestPocketTopLeft)
|
||||
.close()
|
||||
.attr("class", "fabric help");
|
||||
.attr('class', 'fabric help')
|
||||
|
||||
paths.innerPocket = new Path()
|
||||
.move(points.innerPocketTopLeft)
|
||||
|
@ -367,180 +345,156 @@ export default function(part) {
|
|||
.line(points.innerPocketTopRight)
|
||||
.line(points.innerPocketTopLeft)
|
||||
.close()
|
||||
.attr("class", "fabric help");
|
||||
.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
|
||||
);
|
||||
macro("sprinkle", {
|
||||
snippet: "notch",
|
||||
on: [
|
||||
"cfNeck",
|
||||
"rollLineStart",
|
||||
"bustPoint",
|
||||
"chestPocketTopLeft",
|
||||
"chestPocketBottomLeft"
|
||||
]
|
||||
});
|
||||
points.logo = points.cfSeat.shiftFractionTowards(points.cfHem, 0.5);
|
||||
snippets.logo = new Snippet("logo", points.logo);
|
||||
macro("title", { at: points.title, nr: "1a", title: "front" });
|
||||
macro("grainline", { from: points.cfHem, to: points.cfNeck });
|
||||
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)
|
||||
macro('sprinkle', {
|
||||
snippet: 'notch',
|
||||
on: ['cfNeck', 'rollLineStart', 'bustPoint', 'chestPocketTopLeft', 'chestPocketBottomLeft']
|
||||
})
|
||||
points.logo = points.cfSeat.shiftFractionTowards(points.cfHem, 0.5)
|
||||
snippets.logo = new Snippet('logo', points.logo)
|
||||
macro('title', { at: points.title, nr: '1a', title: 'front' })
|
||||
macro('grainline', { from: points.cfHem, to: points.cfNeck })
|
||||
|
||||
if (sa) {
|
||||
let hemBase = new Path().move(points.flbHem).line(points.psHem);
|
||||
let hemBase = new Path().move(points.flbHem).line(points.psHem)
|
||||
paths.sa = paths.saBase
|
||||
.offset(sa)
|
||||
.join(hemBase.offset(3 * sa))
|
||||
.line(points.psHem.shift(-90, 3 * sa).shift(0, sa))
|
||||
.close()
|
||||
.attr("class", "fabric sa");
|
||||
.attr('class', 'fabric sa')
|
||||
}
|
||||
if (paperless) {
|
||||
macro("ld", {
|
||||
macro('ld', {
|
||||
from: points.hemEdge,
|
||||
to: points.flbHem,
|
||||
d: 15
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.hemEdge,
|
||||
to: points.psHem,
|
||||
y: points.psHem.y + 15 + 3 * sa
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.rollLineStart,
|
||||
to: points.pocketTopLeft,
|
||||
y: points.pocketFlapBottomLeft.y
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.pocketFlapTopLeft,
|
||||
to: points.button3Right,
|
||||
x: points.bustPoint.x + sa + 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.pocketTopLeft,
|
||||
to: points.button3Right,
|
||||
x: points.bustPoint.x + sa + 30
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.chestPocketBottomLeft,
|
||||
to: points.button3Right,
|
||||
x: points.bustPoint.x - 15
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.rollLineStart,
|
||||
to: points.chestPocketBottomLeft,
|
||||
y: points.chestPocketBottomLeft.y + 15
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.rollLineStart,
|
||||
to: points.button3Left,
|
||||
y: points.button3Left.y + 15
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.button3Left,
|
||||
to: points.button3Right,
|
||||
y: points.button3Left.y + 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.psHem,
|
||||
to: points.bustPoint,
|
||||
x: points.bustPoint.x + sa + 45
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.psHem,
|
||||
to: points.armholePitch,
|
||||
x: points.armholePitch.x + sa + 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.armholePitch,
|
||||
to: points.shoulder,
|
||||
x: points.shoulder.x + sa + 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.armholePitch,
|
||||
to: points.neck,
|
||||
x: points.shoulder.x + sa + 30
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.rollLineStart,
|
||||
to: points.collarTip,
|
||||
x: points.rollLineStart.x - sa - 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.button2Left,
|
||||
to: points.rollLineStart,
|
||||
x: points.rollLineStart.x - sa - 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.button1Left,
|
||||
to: points.button2Left,
|
||||
x: points.rollLineStart.x - sa - 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.hemEdge,
|
||||
to: points.collarTip,
|
||||
x: points.rollLineStart.x - sa - 30
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.lapelStraightEnd,
|
||||
to: points.collarTip,
|
||||
y: points.collarTip.y - sa - 15
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.lapelStraightEnd,
|
||||
to: points.cfNeck,
|
||||
y: points.collarTip.y - sa - 30
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.lapelStraightEnd,
|
||||
to: points.rollLineEnd,
|
||||
y: points.collarTip.y - sa - 45
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.lapelStraightEnd,
|
||||
to: points.neck,
|
||||
y: points.neck.y - sa - 15
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.lapelStraightEnd,
|
||||
to: points.armholePitch,
|
||||
y: points.neck.y - sa - 30
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.lapelStraightEnd,
|
||||
to: points.shoulder,
|
||||
y: points.neck.y - sa - 45
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.lapelStraightEnd,
|
||||
to: points.armhole,
|
||||
y: points.neck.y - sa - 60
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return part;
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -1,56 +1,56 @@
|
|||
import freesewing from "@freesewing/core";
|
||||
import plugins from "@freesewing/plugin-bundle";
|
||||
import buttons from "@freesewing/plugin-buttons";
|
||||
import bust from "@freesewing/plugin-bust";
|
||||
import Bent from "@freesewing/bent";
|
||||
import Carlton from "@freesewing/carlton";
|
||||
import config from "../config";
|
||||
import freesewing from '@freesewing/core'
|
||||
import plugins from '@freesewing/plugin-bundle'
|
||||
import buttons from '@freesewing/plugin-buttons'
|
||||
import bust from '@freesewing/plugin-bust'
|
||||
import Bent from '@freesewing/bent'
|
||||
import Carlton from '@freesewing/carlton'
|
||||
import config from '../config'
|
||||
// Parts
|
||||
import draftFront from "./front";
|
||||
import draftSide from "./side";
|
||||
import draftFront from './front'
|
||||
import draftSide from './side'
|
||||
|
||||
// Create new design
|
||||
const Pattern = new freesewing.Design(config, [plugins, buttons, bust]);
|
||||
const Pattern = new freesewing.Design(config, [plugins, buttons, bust])
|
||||
|
||||
let fromBent = ["Base", "Front", "Back", "Sleeve", "TopSleeve", "UnderSleeve"];
|
||||
let fromBent = ['Base', 'Front', 'Back', 'Sleeve', 'TopSleeve', 'UnderSleeve']
|
||||
|
||||
// Attach draft methods from Bent to prototype
|
||||
for (let m of fromBent) {
|
||||
Pattern.prototype["draftBent" + m] = function(part) {
|
||||
return new Bent(this.settings)["draft" + m](part);
|
||||
};
|
||||
Pattern.prototype['draftBent' + m] = function(part) {
|
||||
return new Bent(this.settings)['draft' + m](part)
|
||||
}
|
||||
}
|
||||
|
||||
// Attach draft methods from Carlton to prototype
|
||||
for (let m of [
|
||||
"draftBack",
|
||||
"draftTail",
|
||||
"draftTopSleeve",
|
||||
"draftUnderSleeve",
|
||||
"draftBelt",
|
||||
"draftCollarStand",
|
||||
"draftCollar",
|
||||
"draftCuffFacing",
|
||||
"draftPocket",
|
||||
"draftPocketFlap",
|
||||
"draftPocketLining",
|
||||
"draftChestPocketWelt",
|
||||
"draftChestPocketBag",
|
||||
"draftInnerPocketWelt",
|
||||
"draftInnerPocketBag",
|
||||
"draftInnerPocketTab"
|
||||
'draftBack',
|
||||
'draftTail',
|
||||
'draftTopSleeve',
|
||||
'draftUnderSleeve',
|
||||
'draftBelt',
|
||||
'draftCollarStand',
|
||||
'draftCollar',
|
||||
'draftCuffFacing',
|
||||
'draftPocket',
|
||||
'draftPocketFlap',
|
||||
'draftPocketLining',
|
||||
'draftChestPocketWelt',
|
||||
'draftChestPocketBag',
|
||||
'draftInnerPocketWelt',
|
||||
'draftInnerPocketBag',
|
||||
'draftInnerPocketTab'
|
||||
]) {
|
||||
Pattern.prototype[m] = function(part) {
|
||||
return new Carlton(this.settings)[m](part);
|
||||
};
|
||||
return new Carlton(this.settings)[m](part)
|
||||
}
|
||||
}
|
||||
|
||||
Pattern.prototype.draftCarltonFront = function(part) {
|
||||
return new Carlton(this.settings).draftFront(part);
|
||||
};
|
||||
return new Carlton(this.settings).draftFront(part)
|
||||
}
|
||||
|
||||
// Attach own draft methods to prototype
|
||||
Pattern.prototype.draftFront = draftFront;
|
||||
Pattern.prototype.draftSide = draftSide;
|
||||
Pattern.prototype.draftFront = draftFront
|
||||
Pattern.prototype.draftSide = draftSide
|
||||
|
||||
export default Pattern;
|
||||
export default Pattern
|
||||
|
|
|
@ -11,14 +11,14 @@ export default function(part) {
|
|||
Point,
|
||||
paths,
|
||||
Path
|
||||
} = part.shorthand();
|
||||
} = part.shorthand()
|
||||
|
||||
// Give points their original names
|
||||
for (let i of store.get("side")) points[i] = points[i + "Rot2"].clone();
|
||||
for (let i of store.get('side')) points[i] = points[i + 'Rot2'].clone()
|
||||
|
||||
// Clean up
|
||||
for (let i in paths) delete paths[i];
|
||||
for (let i in snippets) delete snippets[i];
|
||||
for (let i in paths) delete paths[i]
|
||||
for (let i in snippets) delete snippets[i]
|
||||
|
||||
paths.saBase = new Path()
|
||||
.move(points.hem)
|
||||
|
@ -29,34 +29,31 @@ export default function(part) {
|
|||
.curve(points.armholeHollowCp2, points.armholePitchCp1, points.armholePitch)
|
||||
._curve(points.bustPointCp1, points.bustPoint)
|
||||
.curve(points.bustPointCp2, points.psWaistCp1, points.psWaist)
|
||||
.line(points.psHem);
|
||||
.line(points.psHem)
|
||||
paths.seam = paths.saBase
|
||||
.clone()
|
||||
.line(points.hem)
|
||||
.close()
|
||||
.attr("class", "fabric");
|
||||
.attr('class', 'fabric')
|
||||
|
||||
if (complete) {
|
||||
points.title = points.bustPoint.shiftFractionTowards(points.waist, 0.5);
|
||||
macro("title", {
|
||||
points.title = points.bustPoint.shiftFractionTowards(points.waist, 0.5)
|
||||
macro('title', {
|
||||
at: points.title,
|
||||
nr: "1b",
|
||||
title: "side"
|
||||
});
|
||||
nr: '1b',
|
||||
title: 'side'
|
||||
})
|
||||
|
||||
points.logo = points.psHem.shiftFractionTowards(points.seat, 0.5);
|
||||
snippets.logo = new Snippet("logo", points.logo);
|
||||
points.logo = points.psHem.shiftFractionTowards(points.seat, 0.5)
|
||||
snippets.logo = new Snippet('logo', points.logo)
|
||||
|
||||
points.grainlineFrom = points.psHem.shiftFractionTowards(points.hem, 0.5);
|
||||
points.grainlineTo = new Point(
|
||||
points.grainlineFrom.x,
|
||||
points.armholePitchCp1.y
|
||||
);
|
||||
macro("grainline", {
|
||||
points.grainlineFrom = points.psHem.shiftFractionTowards(points.hem, 0.5)
|
||||
points.grainlineTo = new Point(points.grainlineFrom.x, points.armholePitchCp1.y)
|
||||
macro('grainline', {
|
||||
from: points.grainlineFrom,
|
||||
to: points.grainlineTo
|
||||
});
|
||||
snippets.bust = new Snippet("notch", points.bustPoint);
|
||||
})
|
||||
snippets.bust = new Snippet('notch', points.bustPoint)
|
||||
|
||||
if (sa) {
|
||||
paths.sa = paths.saBase
|
||||
|
@ -64,66 +61,66 @@ export default function(part) {
|
|||
.line(points.psHem.shift(-90, 3 * sa).shift(180, sa))
|
||||
.line(points.hem.shift(-90, 3 * sa).shift(0, sa))
|
||||
.close()
|
||||
.attr("class", "fabric sa");
|
||||
.attr('class', 'fabric sa')
|
||||
}
|
||||
|
||||
if (paperless) {
|
||||
macro("vd", {
|
||||
macro('vd', {
|
||||
from: points.psHem,
|
||||
to: points.psWaist,
|
||||
x: points.psWaist.x - sa - 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.psHem,
|
||||
to: points.bustPoint,
|
||||
x: points.bustPoint.x - sa - 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.hem,
|
||||
to: points.seat,
|
||||
x: points.hem.x + sa + 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.hem,
|
||||
to: points.waist,
|
||||
x: points.hem.x + sa + 30
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.hem,
|
||||
to: points.armhole,
|
||||
x: points.hem.x + sa + 45
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.hem,
|
||||
to: points.armholePitch,
|
||||
x: points.hem.x + sa + 60
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.psWaist,
|
||||
to: points.waist
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.bustPoint,
|
||||
to: points.waist,
|
||||
y: points.bustPoint.y
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.bustPoint,
|
||||
to: points.armholePitch,
|
||||
y: points.armholePitch.y - sa - 15
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.bustPoint,
|
||||
to: points.armhole,
|
||||
y: points.armholePitch.y - sa - 30
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.psHem,
|
||||
to: points.hem,
|
||||
y: points.hem.y + 3 * sa + 15
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return part;
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -1,22 +1,15 @@
|
|||
import React from "react";
|
||||
import freesewing from "@freesewing/core";
|
||||
import Workbench from "@freesewing/components/Workbench";
|
||||
import "typeface-roboto-condensed";
|
||||
import "@freesewing/css-theme";
|
||||
import React from 'react'
|
||||
import freesewing from '@freesewing/core'
|
||||
import Workbench from '@freesewing/components/Workbench'
|
||||
import 'typeface-roboto-condensed'
|
||||
import '@freesewing/css-theme'
|
||||
|
||||
import Pattern from "pattern";
|
||||
import Pattern from 'pattern'
|
||||
|
||||
const App = props => {
|
||||
let instance = new Pattern();
|
||||
let config = instance.config;
|
||||
return (
|
||||
<Workbench
|
||||
freesewing={freesewing}
|
||||
Pattern={Pattern}
|
||||
config={config}
|
||||
userLanguage="en"
|
||||
/>
|
||||
);
|
||||
};
|
||||
let instance = new Pattern()
|
||||
let config = instance.config
|
||||
return <Workbench freesewing={freesewing} Pattern={Pattern} config={config} userLanguage="en" />
|
||||
}
|
||||
|
||||
export default App;
|
||||
export default App
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import App from "./App";
|
||||
import * as serviceWorker from "./serviceWorker";
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import App from './App'
|
||||
import * as serviceWorker from './serviceWorker'
|
||||
|
||||
ReactDOM.render(<App />, document.getElementById("root"));
|
||||
ReactDOM.render(<App />, document.getElementById('root'))
|
||||
|
||||
// If you want your app to work offline and load faster, you can change
|
||||
// unregister() to register() below. Note this comes with some pitfalls.
|
||||
// Learn more about service workers: http://bit.ly/CRA-PWA
|
||||
serviceWorker.unregister();
|
||||
serviceWorker.unregister()
|
||||
|
|
|
@ -9,46 +9,44 @@
|
|||
// This link also includes instructions on opting out of this behavior.
|
||||
|
||||
const isLocalhost = Boolean(
|
||||
window.location.hostname === "localhost" ||
|
||||
window.location.hostname === 'localhost' ||
|
||||
// [::1] is the IPv6 localhost address.
|
||||
window.location.hostname === "[::1]" ||
|
||||
window.location.hostname === '[::1]' ||
|
||||
// 127.0.0.1/8 is considered localhost for IPv4.
|
||||
window.location.hostname.match(
|
||||
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
|
||||
)
|
||||
);
|
||||
window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/)
|
||||
)
|
||||
|
||||
export function register(config) {
|
||||
if (process.env.NODE_ENV === "production" && "serviceWorker" in navigator) {
|
||||
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
|
||||
// The URL constructor is available in all browsers that support SW.
|
||||
const publicUrl = new URL(process.env.PUBLIC_URL, window.location);
|
||||
const publicUrl = new URL(process.env.PUBLIC_URL, window.location)
|
||||
if (publicUrl.origin !== window.location.origin) {
|
||||
// Our service worker won't work if PUBLIC_URL is on a different origin
|
||||
// from what our page is served on. This might happen if a CDN is used to
|
||||
// serve assets; see https://github.com/facebook/create-react-app/issues/2374
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
window.addEventListener("load", () => {
|
||||
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
|
||||
window.addEventListener('load', () => {
|
||||
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`
|
||||
|
||||
if (isLocalhost) {
|
||||
// This is running on localhost. Let's check if a service worker still exists or not.
|
||||
checkValidServiceWorker(swUrl, config);
|
||||
checkValidServiceWorker(swUrl, config)
|
||||
|
||||
// Add some additional logging to localhost, pointing developers to the
|
||||
// service worker/PWA documentation.
|
||||
navigator.serviceWorker.ready.then(() => {
|
||||
console.log(
|
||||
"This web app is being served cache-first by a service " +
|
||||
"worker. To learn more, visit https://goo.gl/SC7cgQ"
|
||||
);
|
||||
});
|
||||
'This web app is being served cache-first by a service ' +
|
||||
'worker. To learn more, visit https://goo.gl/SC7cgQ'
|
||||
)
|
||||
})
|
||||
} else {
|
||||
// Is not local host. Just register service worker
|
||||
registerValidSW(swUrl, config);
|
||||
registerValidSW(swUrl, config)
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,38 +55,38 @@ function registerValidSW(swUrl, config) {
|
|||
.register(swUrl)
|
||||
.then(registration => {
|
||||
registration.onupdatefound = () => {
|
||||
const installingWorker = registration.installing;
|
||||
const installingWorker = registration.installing
|
||||
installingWorker.onstatechange = () => {
|
||||
if (installingWorker.state === "installed") {
|
||||
if (installingWorker.state === 'installed') {
|
||||
if (navigator.serviceWorker.controller) {
|
||||
// At this point, the old content will have been purged and
|
||||
// the fresh content will have been added to the cache.
|
||||
// It's the perfect time to display a "New content is
|
||||
// available; please refresh." message in your web app.
|
||||
console.log("New content is available; please refresh.");
|
||||
console.log('New content is available; please refresh.')
|
||||
|
||||
// Execute callback
|
||||
if (config.onUpdate) {
|
||||
config.onUpdate(registration);
|
||||
config.onUpdate(registration)
|
||||
}
|
||||
} else {
|
||||
// At this point, everything has been precached.
|
||||
// It's the perfect time to display a
|
||||
// "Content is cached for offline use." message.
|
||||
console.log("Content is cached for offline use.");
|
||||
console.log('Content is cached for offline use.')
|
||||
|
||||
// Execute callback
|
||||
if (config.onSuccess) {
|
||||
config.onSuccess(registration);
|
||||
config.onSuccess(registration)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
})
|
||||
.catch(error => {
|
||||
console.error("Error during service worker registration:", error);
|
||||
});
|
||||
console.error('Error during service worker registration:', error)
|
||||
})
|
||||
}
|
||||
|
||||
function checkValidServiceWorker(swUrl, config) {
|
||||
|
@ -98,30 +96,28 @@ function checkValidServiceWorker(swUrl, config) {
|
|||
// Ensure service worker exists, and that we really are getting a JS file.
|
||||
if (
|
||||
response.status === 404 ||
|
||||
response.headers.get("content-type").indexOf("javascript") === -1
|
||||
response.headers.get('content-type').indexOf('javascript') === -1
|
||||
) {
|
||||
// No service worker found. Probably a different app. Reload the page.
|
||||
navigator.serviceWorker.ready.then(registration => {
|
||||
registration.unregister().then(() => {
|
||||
window.location.reload();
|
||||
});
|
||||
});
|
||||
window.location.reload()
|
||||
})
|
||||
})
|
||||
} else {
|
||||
// Service worker found. Proceed as normal.
|
||||
registerValidSW(swUrl, config);
|
||||
registerValidSW(swUrl, config)
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
console.log(
|
||||
"No internet connection found. App is running in offline mode."
|
||||
);
|
||||
});
|
||||
console.log('No internet connection found. App is running in offline mode.')
|
||||
})
|
||||
}
|
||||
|
||||
export function unregister() {
|
||||
if ("serviceWorker" in navigator) {
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.ready.then(registration => {
|
||||
registration.unregister();
|
||||
});
|
||||
registration.unregister()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,57 +1,68 @@
|
|||
import { calculateRatios } from "./shared";
|
||||
import { calculateRatios } from './shared'
|
||||
|
||||
export default function(part) {
|
||||
let { paperless, sa, snippets, Snippet, store, complete, points, measurements, options, macro, Point, paths, Path } = part.shorthand();
|
||||
let {
|
||||
paperless,
|
||||
sa,
|
||||
snippets,
|
||||
Snippet,
|
||||
store,
|
||||
complete,
|
||||
points,
|
||||
measurements,
|
||||
options,
|
||||
macro,
|
||||
Point,
|
||||
paths,
|
||||
Path
|
||||
} = part.shorthand()
|
||||
|
||||
calculateRatios(part);
|
||||
calculateRatios(part)
|
||||
// Belt width
|
||||
let bw = measurements.centerBackNeckToWaist * options.beltWidth;
|
||||
store.set("beltWidth", bw);
|
||||
let bw = measurements.centerBackNeckToWaist * options.beltWidth
|
||||
store.set('beltWidth', bw)
|
||||
|
||||
// Box pleat (bp)
|
||||
points.bpStart = new Point(0, points.armholePitch.y);
|
||||
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));
|
||||
)
|
||||
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,
|
||||
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);
|
||||
)
|
||||
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);
|
||||
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));
|
||||
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);
|
||||
points.bsCp1 = points.bpStart.shiftFractionTowards(points.armholePitch, 0.5)
|
||||
points.bsCp2 = points.armhole.shiftFractionTowards(points.cbArmhole, 0.3)
|
||||
|
||||
// Store collar length
|
||||
store.set(
|
||||
"backCollarLength",
|
||||
'backCollarLength',
|
||||
new Path()
|
||||
.move(points.cbNeck)
|
||||
._curve(points.neckCp2, points.neck)
|
||||
.length()
|
||||
);
|
||||
)
|
||||
|
||||
// Clean up
|
||||
for (let i in paths) delete paths[i]
|
||||
|
@ -79,154 +90,147 @@ export default function(part) {
|
|||
.join(paths.dart)
|
||||
.join(paths.seam2)
|
||||
.close()
|
||||
.attr("class", "fabric");
|
||||
.attr('class', 'fabric')
|
||||
|
||||
paths.backStay = new Path()
|
||||
.move(points.bpStart)
|
||||
.curve(points.bsCp1, points.bsCp2, points.armhole)
|
||||
.attr("class", "canvas lashed");
|
||||
.attr('class', 'canvas lashed')
|
||||
|
||||
paths.triangle = new Path()
|
||||
.move(points.bpTriangleTip)
|
||||
.line(points.bpTriangleEdge)
|
||||
.line(points.bpStart)
|
||||
.attr("class", "dashed");
|
||||
.attr('class', 'dashed')
|
||||
|
||||
if (complete) {
|
||||
macro("sprinkle", {
|
||||
snippet: "notch",
|
||||
on: [
|
||||
"armholePitch",
|
||||
"bpTriangleTip"
|
||||
]
|
||||
});
|
||||
macro('sprinkle', {
|
||||
snippet: 'notch',
|
||||
on: ['armholePitch', 'bpTriangleTip']
|
||||
})
|
||||
|
||||
macro("grainline", {
|
||||
macro('grainline', {
|
||||
from: points.cbWaist,
|
||||
to: points.bpStart
|
||||
});
|
||||
})
|
||||
|
||||
points.logo = new Point(
|
||||
points.armhole.x * 0.7,
|
||||
points.dartTip.y
|
||||
);
|
||||
snippets.logo = new Snippet("logo", points.logo);
|
||||
points.logo = new Point(points.armhole.x * 0.7, points.dartTip.y)
|
||||
snippets.logo = new Snippet('logo', points.logo)
|
||||
|
||||
if (sa) {
|
||||
paths.sa =
|
||||
paths.seam1
|
||||
paths.sa = paths.seam1
|
||||
.line(points.waist)
|
||||
.offset(sa)
|
||||
.join(paths.seam2.offset(sa))
|
||||
.close()
|
||||
.trim()
|
||||
.close()
|
||||
.attr("class", "fabric sa");
|
||||
.attr('class', 'fabric sa')
|
||||
}
|
||||
|
||||
if (paperless) {
|
||||
macro("hd", {
|
||||
macro('hd', {
|
||||
from: points.bpBottom,
|
||||
to: points.cbWaist,
|
||||
y: points.cbWaist.y + 15 + sa
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.cbWaist,
|
||||
to: points.dartLeft,
|
||||
y: points.cbWaist.y + 15 + sa
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.dartLeft,
|
||||
to: points.dartRight,
|
||||
y: points.cbWaist.y + 15 + sa
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.dartRight,
|
||||
to: points.waist,
|
||||
y: points.cbWaist.y + 15 + sa
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.cbWaist,
|
||||
to: points.waist,
|
||||
y: points.cbWaist.y + 30 + sa
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.bpBottom,
|
||||
to: points.waist,
|
||||
y: points.cbWaist.y + 45 + sa
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.waist,
|
||||
to: points.armhole,
|
||||
x: points.armhole.x + 15 + sa
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.armhole,
|
||||
to: points.armholePitch,
|
||||
x: points.armhole.x + 15 + sa
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.armhole,
|
||||
to: points.shoulder,
|
||||
x: points.armhole.x + 30 + sa
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.waist,
|
||||
to: points.shoulder,
|
||||
x: points.armhole.x + 45 + sa
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.dartRight,
|
||||
to: points.dartTip,
|
||||
x: points.dartRight.x + 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.bpBottom,
|
||||
to: points.bpTop,
|
||||
x: points.bpTop.x - 15 - sa
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.bpTop,
|
||||
to: points.cbNeck,
|
||||
x: points.bpTop.x - 15 - sa
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.bpBottom,
|
||||
to: points.neck,
|
||||
x: points.bpTop.x - 30 - sa
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.bpStart,
|
||||
to: points.bpTriangleTip,
|
||||
x: points.bpTriangleEdge.x + 15
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.bpStart,
|
||||
to: points.bpTriangleEdge,
|
||||
y: points.bpTriangleEdge.y + 15
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.cbNeck,
|
||||
to: points.neck,
|
||||
y: points.neck.y - 15 - sa
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.cbNeck,
|
||||
to: points.armholePitch,
|
||||
y: points.neck.y - 30 - sa
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.cbNeck,
|
||||
to: points.shoulder,
|
||||
y: points.neck.y - 45 - sa
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.cbNeck,
|
||||
to: points.armhole,
|
||||
y: points.neck.y - 60 - sa
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return part;
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -1,30 +1,44 @@
|
|||
export default function(part) {
|
||||
let { paperless, sa, snippets, Snippet, store, complete, points, measurements, options, macro, Point, paths, Path } = part.shorthand();
|
||||
let {
|
||||
paperless,
|
||||
sa,
|
||||
snippets,
|
||||
Snippet,
|
||||
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;
|
||||
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", {
|
||||
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,
|
||||
prefix: 'roundTop',
|
||||
radius: width / 4,
|
||||
render: true
|
||||
});
|
||||
macro("round", {
|
||||
})
|
||||
macro('round', {
|
||||
from: points.topLeft,
|
||||
to: points.bottomRight,
|
||||
via: points.bottomLeft,
|
||||
prefix: "roundBottom",
|
||||
radius: width/4,
|
||||
prefix: 'roundBottom',
|
||||
radius: width / 4,
|
||||
render: true
|
||||
});
|
||||
})
|
||||
|
||||
// Paths
|
||||
paths.seam = new Path()
|
||||
|
@ -36,50 +50,44 @@ export default function(part) {
|
|||
.line(points.topRight)
|
||||
.line(points.roundTopStart)
|
||||
.close()
|
||||
.attr("class", "fabric");
|
||||
.attr('class', 'fabric')
|
||||
|
||||
if (complete) {
|
||||
snippets.button = new Snippet("button", points.button).attr("data-scale", 2);
|
||||
points.title = new Point(
|
||||
points.bottomRight.x/2,
|
||||
points.bottomRight.y/2
|
||||
);
|
||||
macro("title", {
|
||||
snippets.button = new Snippet('button', points.button).attr('data-scale', 2)
|
||||
points.title = new Point(points.bottomRight.x / 2, points.bottomRight.y / 2)
|
||||
macro('title', {
|
||||
at: points.title,
|
||||
nr: 6,
|
||||
title: "belt"
|
||||
});
|
||||
points.logo = new Point(
|
||||
points.bottomRight.x * 0.75,
|
||||
points.bottomRight.y * 0.65
|
||||
);
|
||||
snippets.logo = new Snippet("logo", points.logo);
|
||||
title: 'belt'
|
||||
})
|
||||
points.logo = new Point(points.bottomRight.x * 0.75, points.bottomRight.y * 0.65)
|
||||
snippets.logo = new Snippet('logo', points.logo)
|
||||
|
||||
if (sa) paths.sa = paths.seam.offset(sa).attr("class", "fabric sa");
|
||||
if (sa) paths.sa = paths.seam.offset(sa).attr('class', 'fabric sa')
|
||||
|
||||
if (paperless) {
|
||||
macro("hd", {
|
||||
macro('hd', {
|
||||
from: points.roundBottomStart,
|
||||
to: points.roundBottomEnd,
|
||||
y: points.roundBottomEnd.y + sa + 15
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.roundBottomStart,
|
||||
to: points.button,
|
||||
y: points.roundBottomEnd.y + sa + 30
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.roundBottomStart,
|
||||
to: points.bottomRight,
|
||||
y: points.roundBottomEnd.y + sa + 45
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.bottomRight,
|
||||
to: points.topRight,
|
||||
x: points.topRight.x + sa + 15
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return part;
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -10,28 +10,19 @@ export default function(part) {
|
|||
Point,
|
||||
paths,
|
||||
Path
|
||||
} = part.shorthand();
|
||||
} = part.shorthand()
|
||||
|
||||
points.topLeft = new Point(0, 0);
|
||||
points.topLeft = new Point(0, 0)
|
||||
points.bottomRight = new Point(
|
||||
store.get("chestPocketHeight"),
|
||||
store.get("chestPocketBagDepth") / 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
|
||||
);
|
||||
store.get('chestPocketHeight'),
|
||||
store.get('chestPocketBagDepth') / 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)
|
||||
|
@ -42,45 +33,45 @@ export default function(part) {
|
|||
.line(points.bottomLeft)
|
||||
.line(points.bottomRight)
|
||||
.line(points.endRight)
|
||||
.attr("class", "lining");
|
||||
.attr('class', 'lining')
|
||||
|
||||
paths.hint = new Path()
|
||||
.move(points.startLeft)
|
||||
.line(points.endLeft)
|
||||
.move(points.endRight)
|
||||
.line(points.startRight)
|
||||
.attr("class", "lining dashed");
|
||||
.attr('class', 'lining dashed')
|
||||
|
||||
if (complete) {
|
||||
points.title = points.topLeft.shiftFractionTowards(points.bottomRight, 0.5);
|
||||
macro("title", {
|
||||
points.title = points.topLeft.shiftFractionTowards(points.bottomRight, 0.5)
|
||||
macro('title', {
|
||||
at: points.title,
|
||||
nr: 17,
|
||||
title: "chestPocketBag"
|
||||
});
|
||||
title: 'chestPocketBag'
|
||||
})
|
||||
|
||||
macro("grainline", {
|
||||
macro('grainline', {
|
||||
from: points.bottomLeft.shift(0, 10),
|
||||
to: points.topLeft.shift(0, 10)
|
||||
});
|
||||
})
|
||||
|
||||
if (sa) {
|
||||
paths.sa = paths.seam.offset(sa).attr("class", "lining sa");
|
||||
paths.sa = paths.seam.offset(sa).attr('class', 'lining sa')
|
||||
}
|
||||
macro("ld", {
|
||||
macro('ld', {
|
||||
from: points.bottomRight.shift(180, 15),
|
||||
to: points.topRight.shift(180, 15),
|
||||
text: units(store.get("chestPocketBagDepth") * 2)
|
||||
});
|
||||
text: units(store.get('chestPocketBagDepth') * 2)
|
||||
})
|
||||
|
||||
if (paperless) {
|
||||
macro("hd", {
|
||||
macro('hd', {
|
||||
from: points.bottomLeft,
|
||||
to: points.bottomRight,
|
||||
y: points.bottomLeft.y + sa + 15
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return part;
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -1,27 +1,12 @@
|
|||
export default function(part) {
|
||||
let { paperless, sa, store, complete, points, macro, Point, paths, Path } = part.shorthand();
|
||||
let { paperless, sa, store, complete, points, 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
|
||||
);
|
||||
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)
|
||||
|
@ -30,39 +15,36 @@ export default function(part) {
|
|||
.line(points.topRight)
|
||||
.line(points.topLeft)
|
||||
.close()
|
||||
.attr("class", "fabric");
|
||||
.attr('class', 'fabric')
|
||||
|
||||
paths.fold = new Path()
|
||||
.move(points.topMid)
|
||||
.line(points.bottomMid)
|
||||
.attr("class", "dashed");
|
||||
.attr('class', 'dashed')
|
||||
|
||||
if (complete) {
|
||||
points.title = new Point(
|
||||
points.bottomRight.x/4,
|
||||
points.bottomRight.y/2,
|
||||
);
|
||||
macro("title", {
|
||||
points.title = new Point(points.bottomRight.x / 4, points.bottomRight.y / 2)
|
||||
macro('title', {
|
||||
at: points.title,
|
||||
nr: 12,
|
||||
title: "chestPocketWelt"
|
||||
});
|
||||
title: 'chestPocketWelt'
|
||||
})
|
||||
|
||||
if (sa) paths.sa = paths.seam.offset(sa).attr("class", "fabric sa");
|
||||
if (sa) paths.sa = paths.seam.offset(sa).attr('class', 'fabric sa')
|
||||
|
||||
if (paperless) {
|
||||
macro("hd", {
|
||||
macro('hd', {
|
||||
from: points.bottomLeft,
|
||||
to: points.bottomRight,
|
||||
y: points.bottomLeft.y + sa + 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.bottomRight,
|
||||
to: points.topRight,
|
||||
x: points.topRight.x + sa + 15
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return part;
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -5,74 +5,72 @@
|
|||
*/
|
||||
|
||||
export default function(part) {
|
||||
let { paperless, sa, complete, points, options, macro, paths, Path } = part.shorthand();
|
||||
let { paperless, sa, complete, points, options, macro, 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);
|
||||
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);
|
||||
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;
|
||||
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"]
|
||||
pivot: 'cutBottom1',
|
||||
points: ['cutBottom2', 'cutTop1', 'cutTop2', 'q2Cp1', 'q2Cp2']
|
||||
},
|
||||
2: {
|
||||
pivot: "cutBottom2",
|
||||
points: ["cutBottom3", "cutTop2", "cutTop3", "q3Cp1", "q3Cp2"]
|
||||
pivot: 'cutBottom2',
|
||||
points: ['cutBottom3', 'cutTop2', 'cutTop3', 'q3Cp1', 'q3Cp2']
|
||||
},
|
||||
3: {
|
||||
pivot: "cutBottom3",
|
||||
points: ["standTip", "bottomRight", "cutTop4", "cutTop3", "q4Cp1"]
|
||||
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);
|
||||
pivot: 'standTip',
|
||||
points: ['topRight', 'bottomRight', 'cutTop4']
|
||||
}
|
||||
if(nr <4) for (let pnt of alsoRotate) points[pnt] = points[pnt].rotate(angle, points[pivot]);
|
||||
}
|
||||
|
||||
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);
|
||||
angle = points.cutBottom2.angle(points.rot1cutBottom2) + 180
|
||||
let distance = -1 * points.cutBottom2.dist(points.rot1cutBottom2)
|
||||
for (let i of [
|
||||
'cutBottom2',
|
||||
'rot2cutTop2',
|
||||
|
@ -80,31 +78,23 @@ export default function(part) {
|
|||
'rot2cutBottom3',
|
||||
'rot2q3Cp1',
|
||||
'rot2q3Cp2'
|
||||
]) points[i] = points[i].shift(angle, distance);
|
||||
])
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
points.topLeftCp = points.topLeft.shift(0, points.rot4topRight.x * 0.6)
|
||||
|
||||
// Paths
|
||||
/* Uncomment these paths to gain insight into what's happening here
|
||||
|
@ -159,7 +149,6 @@ export default function(part) {
|
|||
.attr("class", "dashed");
|
||||
*/
|
||||
|
||||
|
||||
paths.saBase = new Path()
|
||||
.move(points.standTop)
|
||||
/** This is the non-slashed path. We use this instead of the slashed
|
||||
|
@ -175,82 +164,83 @@ export default function(part) {
|
|||
//.curve_(points.rot3q4Cp1, points.rot3standTip)
|
||||
.line(points.rot4bottomRight)
|
||||
.line(points.rot4topRight)
|
||||
._curve(points.topLeftCp, points.topLeft);
|
||||
paths.seam = paths.saBase.clone()
|
||||
._curve(points.topLeftCp, points.topLeft)
|
||||
paths.seam = paths.saBase
|
||||
.clone()
|
||||
.line(points.standTop)
|
||||
.close()
|
||||
.attr("class", "fabric");
|
||||
.attr('class', 'fabric')
|
||||
|
||||
if (complete) {
|
||||
points.title = points.standTopCp.clone();
|
||||
macro("title", {
|
||||
points.title = points.standTopCp.clone()
|
||||
macro('title', {
|
||||
at: points.title,
|
||||
nr: 8,
|
||||
title: "collar"
|
||||
});
|
||||
title: 'collar'
|
||||
})
|
||||
|
||||
macro("grainline", {
|
||||
macro('grainline', {
|
||||
from: points.standTop.shift(0, 10),
|
||||
to: points.topLeft.shift(0, 10)
|
||||
});
|
||||
})
|
||||
|
||||
if (sa) {
|
||||
paths.sa = paths.saBase.offset(sa);
|
||||
paths.sa = paths.saBase.offset(sa)
|
||||
paths.sa = paths.sa
|
||||
.line(points.topLeft)
|
||||
.move(points.standTop)
|
||||
.line(paths.sa.start())
|
||||
.attr("class", "fabric sa");
|
||||
.attr('class', 'fabric sa')
|
||||
}
|
||||
|
||||
if (paperless) {
|
||||
macro("hd", {
|
||||
macro('hd', {
|
||||
from: points.standTop,
|
||||
to: points.rot3standTip,
|
||||
y: points.rot4bottomRight.y + sa + 15
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.standTop,
|
||||
to: points.rot4bottomRight,
|
||||
y: points.rot4bottomRight.y + sa + 30
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.standTop,
|
||||
to: points.rot4topRight,
|
||||
y: points.rot4bottomRight.y + sa + 45
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.standTop,
|
||||
to: points.topLeft,
|
||||
x: points.topLeft.x - 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.rot3standTip,
|
||||
to: points.topLeft,
|
||||
x: points.topLeft.x - 30
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.rot4topRight,
|
||||
to: points.topLeft,
|
||||
x: points.rot4topRight.x + sa + 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.rot4bottomRight,
|
||||
to: points.topLeft,
|
||||
x: points.rot4topRight.x + sa + 30
|
||||
});
|
||||
macro("ld", {
|
||||
})
|
||||
macro('ld', {
|
||||
from: points.rot4bottomRight,
|
||||
to: points.rot4topRight,
|
||||
d: -1*sa - 15
|
||||
});
|
||||
macro("ld", {
|
||||
d: -1 * sa - 15
|
||||
})
|
||||
macro('ld', {
|
||||
from: points.rot3standTip,
|
||||
to: points.rot4bottomRight,
|
||||
d: -1*sa - 15
|
||||
});
|
||||
d: -1 * sa - 15
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return part;
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -1,20 +1,35 @@
|
|||
export default function(part) {
|
||||
let { paperless, sa, store, complete, points, measurements, options, macro, Point, paths, Path } = part.shorthand();
|
||||
let {
|
||||
paperless,
|
||||
sa,
|
||||
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);
|
||||
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);
|
||||
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();
|
||||
for (let i of ['standTopCp', 'standTip', 'standTipCp', 'bottomLeftCp']) {
|
||||
points[i + 'Left'] = points[i].flipX()
|
||||
}
|
||||
|
||||
paths.seam = new Path()
|
||||
|
@ -24,41 +39,41 @@ export default function(part) {
|
|||
.curve_(points.standTopCpLeft, points.standTipLeft)
|
||||
.curve(points.standTipCpLeft, points.bottomLeftCpLeft, points.bottomLeft)
|
||||
.close()
|
||||
.attr("class", "fabric");
|
||||
.attr('class', 'fabric')
|
||||
|
||||
if (complete) {
|
||||
points.title = points.bottomLeftCp.clone();
|
||||
macro("title", {
|
||||
points.title = points.bottomLeftCp.clone()
|
||||
macro('title', {
|
||||
at: points.title,
|
||||
nr: 7,
|
||||
title: "collarStand"
|
||||
});
|
||||
title: 'collarStand'
|
||||
})
|
||||
|
||||
macro("grainline", {
|
||||
macro('grainline', {
|
||||
from: points.bottomLeft,
|
||||
to: points.standTop
|
||||
});
|
||||
})
|
||||
|
||||
if (sa) paths.sa = paths.seam.offset(sa).attr("class", "fabric sa");
|
||||
if (sa) paths.sa = paths.seam.offset(sa).attr('class', 'fabric sa')
|
||||
|
||||
if (paperless) {
|
||||
macro("hd", {
|
||||
macro('hd', {
|
||||
from: points.standTipLeft,
|
||||
to: points.standTip,
|
||||
y: points.standTip.y + sa + 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.bottomLeft,
|
||||
to: points.standTop,
|
||||
x: points.standTip.x + sa + 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.standTip,
|
||||
to: points.standTop,
|
||||
x: points.standTip.x + sa + 30
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return part;
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -1,33 +1,27 @@
|
|||
export default function(part) {
|
||||
let { paperless, sa, store, complete, points, macro, Point, paths, Path } = part.shorthand();
|
||||
let { paperless, sa, store, complete, points, macro, Point, paths, Path } = part.shorthand()
|
||||
|
||||
points.topLeft = new Point(0, 0);
|
||||
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", {
|
||||
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", {
|
||||
radius: store.get('cuffRadius'),
|
||||
prefix: 'roundLeft'
|
||||
})
|
||||
macro('round', {
|
||||
from: points.bottomLeft,
|
||||
to: points.topRight,
|
||||
via: points.bottomRight,
|
||||
radius: store.get("cuffRadius"),
|
||||
prefix: "roundRight"
|
||||
});
|
||||
radius: store.get('cuffRadius'),
|
||||
prefix: 'roundRight'
|
||||
})
|
||||
|
||||
paths.seam = new Path()
|
||||
.move(points.topLeft)
|
||||
|
@ -38,47 +32,46 @@ export default function(part) {
|
|||
.line(points.topRight)
|
||||
.line(points.topLeft)
|
||||
.close()
|
||||
.attr("class", "fabric");
|
||||
.attr('class', 'fabric')
|
||||
|
||||
if (complete) {
|
||||
points.title = points.topLeft.shiftFractionTowards(points.bottomRight, 0.5);
|
||||
macro("title", {
|
||||
points.title = points.topLeft.shiftFractionTowards(points.bottomRight, 0.5)
|
||||
macro('title', {
|
||||
at: points.title,
|
||||
nr: 9,
|
||||
title: "cuffFacing"
|
||||
});
|
||||
title: 'cuffFacing'
|
||||
})
|
||||
|
||||
macro("grainline", {
|
||||
from: points.bottomLeft.shift(0, 10+store.get("cuffRadius")),
|
||||
to: points.topLeft.shift(0, 10+store.get("cuffRadius")),
|
||||
});
|
||||
macro('grainline', {
|
||||
from: points.bottomLeft.shift(0, 10 + store.get('cuffRadius')),
|
||||
to: points.topLeft.shift(0, 10 + store.get('cuffRadius'))
|
||||
})
|
||||
|
||||
if (sa) paths.sa = paths.seam.offset(sa).attr("class", "fabric sa");
|
||||
if (sa) paths.sa = paths.seam.offset(sa).attr('class', 'fabric sa')
|
||||
|
||||
if (paperless) {
|
||||
macro("vd", {
|
||||
macro('vd', {
|
||||
from: points.roundRightStart,
|
||||
to: points.roundRightEnd,
|
||||
x: points.topRight.x + sa + 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.roundRightStart,
|
||||
to: points.topRight,
|
||||
x: points.topRight.x + sa + 30
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.roundRightStart,
|
||||
to: points.roundRightEnd,
|
||||
y: points.bottomRight.y + sa + 15
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.roundLeftStart,
|
||||
to: points.roundRightEnd,
|
||||
y: points.bottomRight.y + sa + 30
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return part;
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -1,164 +1,170 @@
|
|||
import { calculateRatios } from "./shared";
|
||||
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();
|
||||
let {
|
||||
paperless,
|
||||
sa,
|
||||
snippets,
|
||||
Snippet,
|
||||
utils,
|
||||
store,
|
||||
complete,
|
||||
points,
|
||||
measurements,
|
||||
options,
|
||||
macro,
|
||||
Point,
|
||||
paths,
|
||||
Path
|
||||
} = part.shorthand()
|
||||
|
||||
calculateRatios(part);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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
|
||||
);
|
||||
)
|
||||
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);
|
||||
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.button1Right.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);
|
||||
points.button1Right.y +
|
||||
points.button1Right.dy(points.button3Right) * options.pocketPlacementVertical
|
||||
)
|
||||
let pocketWidth = points.button1Right.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", {
|
||||
let radius = pocketWidth * options.pocketRadius
|
||||
macro('round', {
|
||||
from: points.pocketTopLeft,
|
||||
to: points.pocketBottomRight,
|
||||
via: points.pocketBottomLeft,
|
||||
prefix: "pocketRoundLeft",
|
||||
prefix: 'pocketRoundLeft',
|
||||
radius
|
||||
});
|
||||
macro("round", {
|
||||
})
|
||||
macro('round', {
|
||||
from: points.pocketBottomLeft,
|
||||
to: points.pocketTopRight,
|
||||
via: points.pocketBottomRight,
|
||||
prefix: "pocketRoundRight",
|
||||
prefix: 'pocketRoundRight',
|
||||
radius
|
||||
});
|
||||
store.set("pocketRadius", radius);
|
||||
})
|
||||
store.set('pocketRadius', radius)
|
||||
}
|
||||
store.set("pocketWidth", pocketWidth);
|
||||
store.set("pocketHeight", pocketHeight);
|
||||
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.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);
|
||||
)
|
||||
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", {
|
||||
let radius = pocketWidth * options.pocketFlapRadius
|
||||
macro('round', {
|
||||
from: points.pocketFlapTopLeft,
|
||||
to: points.pocketFlapBottomRight,
|
||||
via: points.pocketFlapBottomLeft,
|
||||
prefix: "pocketFlapRoundLeft",
|
||||
radius,
|
||||
});
|
||||
macro("round", {
|
||||
prefix: 'pocketFlapRoundLeft',
|
||||
radius
|
||||
})
|
||||
macro('round', {
|
||||
from: points.pocketFlapBottomLeft,
|
||||
to: points.pocketFlapTopRight,
|
||||
via: points.pocketFlapBottomRight,
|
||||
prefix: "pocketFlapRoundRight",
|
||||
radius,
|
||||
});
|
||||
store.set("pocketFlapRadius", radius);
|
||||
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);
|
||||
)
|
||||
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);
|
||||
store.set("chestPocketBagDepth", points.button3Left.dx(points.chestPocketBottomLeft));
|
||||
'chestPocketTopLeft',
|
||||
'chestPocketBottomLeft',
|
||||
'chestPocketTopRight',
|
||||
'chestPocketBottomRight'
|
||||
])
|
||||
points[i] = points[i].rotate(options.chestPocketAngle, points.chestPocketAnchor)
|
||||
store.set('chestPocketBagDepth', points.button3Left.dx(points.chestPocketBottomLeft))
|
||||
|
||||
// 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);
|
||||
)
|
||||
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.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,
|
||||
|
@ -166,39 +172,33 @@ export default function(part) {
|
|||
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);
|
||||
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.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");
|
||||
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",
|
||||
'frontCollarLength',
|
||||
new Path()
|
||||
.move(points.cfNeck)
|
||||
.curve(points.cfNeckCp1, points.neckCp2Front, points.neck)
|
||||
.length()
|
||||
);
|
||||
)
|
||||
|
||||
// Clean up
|
||||
for (let i in paths) delete paths[i]
|
||||
|
@ -218,33 +218,31 @@ export default function(part) {
|
|||
.line(points.collarTip)
|
||||
._curve(points.lapelStraightEndCp1, points.lapelStraightEnd)
|
||||
.line(points.hemEdge)
|
||||
.line(points.flbHem);
|
||||
paths.hemBase = new Path()
|
||||
.move(points.flbHem)
|
||||
.line(points.hem);
|
||||
paths.saBase.render = false;
|
||||
paths.hemBase.render = false;
|
||||
.line(points.flbHem)
|
||||
paths.hemBase = new Path().move(points.flbHem).line(points.hem)
|
||||
paths.saBase.render = false
|
||||
paths.hemBase.render = false
|
||||
paths.seam = paths.saBase
|
||||
.join(paths.hemBase)
|
||||
.close()
|
||||
.attr("class", "fabric");
|
||||
.attr('class', 'fabric')
|
||||
|
||||
paths.rollLine = new Path()
|
||||
.move(points.rollLineStart)
|
||||
.line(points.rollLineEnd)
|
||||
.attr("class", "lashed");
|
||||
.attr('class', 'lashed')
|
||||
|
||||
paths.chestPiece = new Path()
|
||||
.move(points.rollLineStart)
|
||||
.curve(points.button3Right, points.waistCp2, points.armhole)
|
||||
.attr("class", "canvas lashed");
|
||||
.attr('class', 'canvas lashed')
|
||||
|
||||
paths.flb = new Path()
|
||||
.move(points.flbHem)
|
||||
.line(points.flbTop)
|
||||
.attr("class", "lining lashed");
|
||||
.attr('class', 'lining lashed')
|
||||
|
||||
paths.pocket = new Path().move(points.pocketTopLeft);
|
||||
paths.pocket = new Path().move(points.pocketTopLeft)
|
||||
if (options.pocketRadius > 0) {
|
||||
paths.pocket = paths.pocket
|
||||
.line(points.pocketRoundLeftStart)
|
||||
|
@ -252,33 +250,39 @@ export default function(part) {
|
|||
.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.pocketBottomLeft).line(points.pocketBottomRight)
|
||||
}
|
||||
paths.pocket = paths.pocket
|
||||
.line(points.pocketTopRight)
|
||||
.line(points.pocketTopLeft)
|
||||
.close()
|
||||
.attr("class", "fabric help");
|
||||
.attr('class', 'fabric help')
|
||||
|
||||
paths.pocketFlap = new Path().move(points.pocketFlapTopLeft);
|
||||
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)
|
||||
.curve(
|
||||
points.pocketFlapRoundLeftCp1,
|
||||
points.pocketFlapRoundLeftCp2,
|
||||
points.pocketFlapRoundLeftEnd
|
||||
)
|
||||
.line(points.pocketFlapRoundRightStart)
|
||||
.curve(points.pocketFlapRoundRightCp1, points.pocketFlapRoundRightCp2, points.pocketFlapRoundRightEnd)
|
||||
.curve(
|
||||
points.pocketFlapRoundRightCp1,
|
||||
points.pocketFlapRoundRightCp2,
|
||||
points.pocketFlapRoundRightEnd
|
||||
)
|
||||
} else {
|
||||
paths.pocketFlap = paths.pocketFlap
|
||||
.line(points.pocketFlapBottomLeft)
|
||||
.line(points.pocketFlapBottomRight);
|
||||
.line(points.pocketFlapBottomRight)
|
||||
}
|
||||
paths.pocketFlap = paths.pocketFlap
|
||||
.line(points.pocketFlapTopRight)
|
||||
.line(points.pocketFlapTopLeft)
|
||||
.close()
|
||||
.attr("class", "fabric help");
|
||||
.attr('class', 'fabric help')
|
||||
|
||||
paths.chestPocket = new Path()
|
||||
.move(points.chestPocketTopLeft)
|
||||
|
@ -287,7 +291,7 @@ export default function(part) {
|
|||
.line(points.chestPocketTopRight)
|
||||
.line(points.chestPocketTopLeft)
|
||||
.close()
|
||||
.attr("class", "fabric help");
|
||||
.attr('class', 'fabric help')
|
||||
|
||||
paths.innerPocket = new Path()
|
||||
.move(points.innerPocketTopLeft)
|
||||
|
@ -296,190 +300,180 @@ export default function(part) {
|
|||
.line(points.innerPocketTopRight)
|
||||
.line(points.innerPocketTopLeft)
|
||||
.close()
|
||||
.attr("class", "fabric help");
|
||||
.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);
|
||||
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)
|
||||
|
||||
macro("sprinkle", {
|
||||
snippet: "notch",
|
||||
on: [
|
||||
"armholePitch",
|
||||
"cfNeck",
|
||||
"rollLineStart",
|
||||
"waist",
|
||||
"seat"
|
||||
]
|
||||
});
|
||||
macro('sprinkle', {
|
||||
snippet: 'notch',
|
||||
on: ['armholePitch', 'cfNeck', 'rollLineStart', 'waist', 'seat']
|
||||
})
|
||||
|
||||
points.logo = new Point(
|
||||
points.chestPocketTopRight.x,
|
||||
points.armhole.y
|
||||
);
|
||||
snippets.logo = new Snippet("logo", points.logo);
|
||||
points.logo = new Point(points.chestPocketTopRight.x, points.armhole.y)
|
||||
snippets.logo = new Snippet('logo', points.logo)
|
||||
|
||||
macro("grainline", {
|
||||
macro('grainline', {
|
||||
from: points.cfHem,
|
||||
to: points.cfNeck
|
||||
});
|
||||
})
|
||||
|
||||
if (sa) {
|
||||
paths.sa = paths.saBase
|
||||
.offset(sa)
|
||||
.join(paths.hemBase.offset(sa*3))
|
||||
.join(paths.hemBase.offset(sa * 3))
|
||||
.close()
|
||||
.attr("class", "fabric sa");
|
||||
.attr('class', 'fabric sa')
|
||||
}
|
||||
|
||||
if (paperless) {
|
||||
macro("ld", {
|
||||
macro('ld', {
|
||||
from: points.hemEdge,
|
||||
to: points.flbHem,
|
||||
d: 15
|
||||
});
|
||||
macro("ld", {
|
||||
})
|
||||
macro('ld', {
|
||||
from: points.flbHem,
|
||||
to: points.hem,
|
||||
d: 15
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.hemEdge,
|
||||
to: points.hem,
|
||||
y: points.hem.y + 15 + 3*sa
|
||||
});
|
||||
macro("hd", {
|
||||
y: points.hem.y + 15 + 3 * sa
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.rollLineStart,
|
||||
to: points.pocketTopLeft,
|
||||
y: points.pocketFlapBottomLeft.y
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.pocketFlapTopRight,
|
||||
to: points.waist,
|
||||
x: points.pocketTopRight.x - 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.pocketTopRight,
|
||||
to: points.waist,
|
||||
x: points.pocketTopRight.x - 30
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.chestPocketBottomLeft,
|
||||
to: points.waist,
|
||||
x: points.chestPocketBottomLeft.x - 15
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.rollLineStart,
|
||||
to: points.chestPocketBottomLeft,
|
||||
y: points.chestPocketBottomLeft.y + 15
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.rollLineStart,
|
||||
to: points.button3Left,
|
||||
y: points.button3Left.y + 15
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.button3Left,
|
||||
to: points.button3Right,
|
||||
y: points.button3Left.y + 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.hem,
|
||||
to: points.seat,
|
||||
x: points.hem.x + sa + 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.hem,
|
||||
to: points.waist,
|
||||
x: points.hem.x + sa + 30
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.hem,
|
||||
to: points.armhole,
|
||||
x: points.hem.x + sa + 45
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.armhole,
|
||||
to: points.armholePitch,
|
||||
x: points.armhole.x + sa + 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.armhole,
|
||||
to: points.shoulder,
|
||||
x: points.armhole.x + sa + 30
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.armhole,
|
||||
to: points.neck,
|
||||
x: points.armhole.x + sa + 45
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.rollLineStart,
|
||||
to: points.collarTip,
|
||||
x: points.rollLineStart.x - sa - 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.button2Left,
|
||||
to: points.rollLineStart,
|
||||
x: points.rollLineStart.x - sa - 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.button1Left,
|
||||
to: points.button2Left,
|
||||
x: points.rollLineStart.x - sa - 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.hemEdge,
|
||||
to: points.collarTip,
|
||||
x: points.rollLineStart.x - sa - 30
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.hemEdge,
|
||||
to: points.neck,
|
||||
x: points.rollLineStart.x - sa - 45
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.lapelStraightEnd,
|
||||
to: points.collarTip,
|
||||
y: points.collarTip.y - sa - 15
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.lapelStraightEnd,
|
||||
to: points.cfNeck,
|
||||
y: points.collarTip.y - sa - 30
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.lapelStraightEnd,
|
||||
to: points.rollLineEnd,
|
||||
y: points.collarTip.y - sa - 45
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.lapelStraightEnd,
|
||||
to: points.neck,
|
||||
y: points.neck.y - sa - 15
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.lapelStraightEnd,
|
||||
to: points.armholePitch,
|
||||
y: points.neck.y - sa - 30
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.lapelStraightEnd,
|
||||
to: points.shoulder,
|
||||
y: points.neck.y - sa - 45
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.lapelStraightEnd,
|
||||
to: points.armhole,
|
||||
y: points.neck.y - sa - 60
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return part;
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -1,67 +1,67 @@
|
|||
import freesewing from "@freesewing/core";
|
||||
import plugins from "@freesewing/plugin-bundle";
|
||||
import buttons from "@freesewing/plugin-buttons";
|
||||
import Bent from "@freesewing/bent";
|
||||
import config from "../config";
|
||||
import freesewing from '@freesewing/core'
|
||||
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 draftPocketLining from "./pocketlining";
|
||||
import draftChestPocketWelt from "./chestpocketwelt";
|
||||
import draftChestPocketBag from "./chestpocketbag";
|
||||
import draftInnerPocketWelt from "./innerpocketwelt";
|
||||
import draftInnerPocketBag from "./innerpocketbag";
|
||||
import draftInnerPocketTab from "./innerpockettab";
|
||||
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 draftPocketLining from './pocketlining'
|
||||
import draftChestPocketWelt from './chestpocketwelt'
|
||||
import draftChestPocketBag from './chestpocketbag'
|
||||
import draftInnerPocketWelt from './innerpocketwelt'
|
||||
import draftInnerPocketBag from './innerpocketbag'
|
||||
import draftInnerPocketTab from './innerpockettab'
|
||||
|
||||
// Create new design
|
||||
const Pattern = new freesewing.Design(config, [plugins, buttons]);
|
||||
const Pattern = new freesewing.Design(config, [plugins, buttons])
|
||||
|
||||
// Attach draft methods from Bent to prototype
|
||||
Pattern.prototype.draftBentBase = function(part) {
|
||||
return new Bent(this.settings).draftBase(part);
|
||||
};
|
||||
return new Bent(this.settings).draftBase(part)
|
||||
}
|
||||
Pattern.prototype.draftBentFront = function(part) {
|
||||
return new Bent(this.settings).draftFront(part);
|
||||
};
|
||||
return new Bent(this.settings).draftFront(part)
|
||||
}
|
||||
Pattern.prototype.draftBentBack = function(part) {
|
||||
return new Bent(this.settings).draftBack(part);
|
||||
};
|
||||
return new Bent(this.settings).draftBack(part)
|
||||
}
|
||||
Pattern.prototype.draftBentSleeve = function(part) {
|
||||
return new Bent(this.settings).draftSleeve(part);
|
||||
};
|
||||
return new Bent(this.settings).draftSleeve(part)
|
||||
}
|
||||
Pattern.prototype.draftBentTopSleeve = function(part) {
|
||||
return new Bent(this.settings).draftTopSleeve(part);
|
||||
};
|
||||
return new Bent(this.settings).draftTopSleeve(part)
|
||||
}
|
||||
Pattern.prototype.draftBentUnderSleeve = function(part) {
|
||||
return new Bent(this.settings).draftUnderSleeve(part);
|
||||
};
|
||||
return new Bent(this.settings).draftUnderSleeve(part)
|
||||
}
|
||||
|
||||
// Attach own draft methods to prototype
|
||||
Pattern.prototype.draftFront = draftFront;
|
||||
Pattern.prototype.draftBack = draftBack;
|
||||
Pattern.prototype.draftTail = draftTail;
|
||||
Pattern.prototype.draftTopSleeve = draftTopSleeve;
|
||||
Pattern.prototype.draftUnderSleeve = draftUnderSleeve;
|
||||
Pattern.prototype.draftBelt = draftBelt;
|
||||
Pattern.prototype.draftCollarStand = draftCollarStand;
|
||||
Pattern.prototype.draftCollar = draftCollar;
|
||||
Pattern.prototype.draftCuffFacing = draftCuffFacing;
|
||||
Pattern.prototype.draftPocket = draftPocket;
|
||||
Pattern.prototype.draftPocketFlap = draftPocketFlap;
|
||||
Pattern.prototype.draftPocketLining = draftPocketLining;
|
||||
Pattern.prototype.draftChestPocketWelt = draftChestPocketWelt;
|
||||
Pattern.prototype.draftChestPocketBag = draftChestPocketBag;
|
||||
Pattern.prototype.draftInnerPocketWelt = draftInnerPocketWelt;
|
||||
Pattern.prototype.draftInnerPocketBag = draftInnerPocketBag;
|
||||
Pattern.prototype.draftInnerPocketTab = draftInnerPocketTab;
|
||||
Pattern.prototype.draftFront = draftFront
|
||||
Pattern.prototype.draftBack = draftBack
|
||||
Pattern.prototype.draftTail = draftTail
|
||||
Pattern.prototype.draftTopSleeve = draftTopSleeve
|
||||
Pattern.prototype.draftUnderSleeve = draftUnderSleeve
|
||||
Pattern.prototype.draftBelt = draftBelt
|
||||
Pattern.prototype.draftCollarStand = draftCollarStand
|
||||
Pattern.prototype.draftCollar = draftCollar
|
||||
Pattern.prototype.draftCuffFacing = draftCuffFacing
|
||||
Pattern.prototype.draftPocket = draftPocket
|
||||
Pattern.prototype.draftPocketFlap = draftPocketFlap
|
||||
Pattern.prototype.draftPocketLining = draftPocketLining
|
||||
Pattern.prototype.draftChestPocketWelt = draftChestPocketWelt
|
||||
Pattern.prototype.draftChestPocketBag = draftChestPocketBag
|
||||
Pattern.prototype.draftInnerPocketWelt = draftInnerPocketWelt
|
||||
Pattern.prototype.draftInnerPocketBag = draftInnerPocketBag
|
||||
Pattern.prototype.draftInnerPocketTab = draftInnerPocketTab
|
||||
|
||||
export default Pattern;
|
||||
export default Pattern
|
||||
|
|
|
@ -1,23 +1,29 @@
|
|||
export default function(part) {
|
||||
let { units, paperless, sa, store, complete, points, options, macro, Point, paths, Path } = part.shorthand();
|
||||
let {
|
||||
units,
|
||||
paperless,
|
||||
sa,
|
||||
store,
|
||||
complete,
|
||||
points,
|
||||
options,
|
||||
macro,
|
||||
Point,
|
||||
paths,
|
||||
Path
|
||||
} = part.shorthand()
|
||||
|
||||
points.topLeft = new Point(0, 0);
|
||||
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);
|
||||
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)
|
||||
|
@ -28,46 +34,45 @@ export default function(part) {
|
|||
.line(points.bottomLeft)
|
||||
.line(points.bottomRight)
|
||||
.line(points.endRight)
|
||||
.attr("class", "lining");
|
||||
.attr('class', 'lining')
|
||||
|
||||
paths.hint = new Path()
|
||||
.move(points.startLeft)
|
||||
.line(points.endLeft)
|
||||
.move(points.endRight)
|
||||
.line(points.startRight)
|
||||
.attr("class", "lining dashed");
|
||||
.attr('class', 'lining dashed')
|
||||
|
||||
if (complete) {
|
||||
points.title = points.topLeft.shiftFractionTowards(points.bottomRight, 0.5);
|
||||
macro("title", {
|
||||
points.title = points.topLeft.shiftFractionTowards(points.bottomRight, 0.5)
|
||||
macro('title', {
|
||||
at: points.title,
|
||||
nr: 14,
|
||||
title: "innerPocketBag"
|
||||
});
|
||||
title: 'innerPocketBag'
|
||||
})
|
||||
|
||||
macro("grainline", {
|
||||
macro('grainline', {
|
||||
from: points.bottomLeft.shift(0, 10),
|
||||
to: points.topLeft.shift(0, 10)
|
||||
});
|
||||
})
|
||||
|
||||
if (sa) {
|
||||
paths.sa = paths.seam.offset(sa).attr("class", "lining sa");
|
||||
paths.sa = paths.seam.offset(sa).attr('class', 'lining sa')
|
||||
}
|
||||
macro("ld", {
|
||||
macro('ld', {
|
||||
from: points.bottomRight.shift(180, 15),
|
||||
to: points.topRight.shift(180, 15),
|
||||
text: units(store.get("innerPocketWidth") * options.innerPocketDepth * 2)
|
||||
|
||||
});
|
||||
text: units(store.get('innerPocketWidth') * options.innerPocketDepth * 2)
|
||||
})
|
||||
|
||||
if (paperless) {
|
||||
macro("hd", {
|
||||
macro('hd', {
|
||||
from: points.bottomLeft,
|
||||
to: points.bottomRight,
|
||||
y: points.bottomLeft.y + sa + 15
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return part;
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -1,19 +1,13 @@
|
|||
export default function(part) {
|
||||
let { paperless, sa, store, complete, points, macro, Point, paths, Path } = part.shorthand();
|
||||
let { paperless, sa, store, complete, points, macro, Point, paths, Path } = part.shorthand()
|
||||
|
||||
points.topLeft = new Point(0, 0);
|
||||
points.topRight = new Point(
|
||||
store.get("innerPocketWidth") * 1.2,
|
||||
0
|
||||
);
|
||||
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
|
||||
);
|
||||
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)
|
||||
|
@ -21,46 +15,46 @@ export default function(part) {
|
|||
.line(points.topRight)
|
||||
.line(points.topLeft)
|
||||
.close()
|
||||
.attr("class", "lining");
|
||||
.attr('class', 'lining')
|
||||
|
||||
paths.hint = new Path()
|
||||
.move(points.top)
|
||||
.line(points.bottom)
|
||||
.attr("class", "lining dashed");
|
||||
.attr('class', 'lining dashed')
|
||||
|
||||
if (complete) {
|
||||
points.title = points.top.shiftFractionTowards(points.bottom, 0.5);
|
||||
macro("title", {
|
||||
points.title = points.top.shiftFractionTowards(points.bottom, 0.5)
|
||||
macro('title', {
|
||||
at: points.title,
|
||||
nr: 15,
|
||||
title: "innerPocketTab"
|
||||
});
|
||||
title: 'innerPocketTab'
|
||||
})
|
||||
|
||||
macro("grainline", {
|
||||
macro('grainline', {
|
||||
from: points.top,
|
||||
to: points.top.shift(-45, points.top.x*0.7)
|
||||
});
|
||||
to: points.top.shift(-45, points.top.x * 0.7)
|
||||
})
|
||||
|
||||
if (sa) paths.sa = paths.seam.offset(sa).attr("class", "lining sa");
|
||||
if (sa) paths.sa = paths.seam.offset(sa).attr('class', 'lining sa')
|
||||
|
||||
if (paperless) {
|
||||
macro("hd", {
|
||||
macro('hd', {
|
||||
from: points.topLeft,
|
||||
to: points.top,
|
||||
y: points.topLeft.y - sa - 15
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.topLeft,
|
||||
to: points.topRight,
|
||||
y: points.topLeft.y - sa - 30
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.bottom,
|
||||
to: points.topRight,
|
||||
x: points.topRight.x + sa + 15
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return part;
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -1,37 +1,22 @@
|
|||
export default function(part) {
|
||||
let { paperless, sa, store, complete, points, macro, Point, paths, Path } = part.shorthand();
|
||||
let { paperless, sa, store, complete, points, macro, Point, paths, Path } = part.shorthand()
|
||||
|
||||
points.topLeft = new Point(0, 0);
|
||||
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);
|
||||
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
|
||||
);
|
||||
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)
|
||||
|
@ -40,12 +25,12 @@ export default function(part) {
|
|||
.line(points.topRight)
|
||||
.line(points.topLeft)
|
||||
.close()
|
||||
.attr("class", "fabric");
|
||||
.attr('class', 'fabric')
|
||||
|
||||
paths.fold = new Path()
|
||||
.move(points.leftMid)
|
||||
.line(points.rightMid)
|
||||
.attr("class", "dashed");
|
||||
.attr('class', 'dashed')
|
||||
|
||||
paths.welt = new Path()
|
||||
.move(points.realTopLeft)
|
||||
|
@ -54,45 +39,45 @@ export default function(part) {
|
|||
.line(points.realTopRight)
|
||||
.line(points.realTopLeft)
|
||||
.close()
|
||||
.attr("class", "lashed");
|
||||
.attr('class', 'lashed')
|
||||
|
||||
if (complete) {
|
||||
points.title = points.topLeft.shiftFractionTowards(points.bottomRight, 0.5);
|
||||
macro("title", {
|
||||
points.title = points.topLeft.shiftFractionTowards(points.bottomRight, 0.5)
|
||||
macro('title', {
|
||||
at: points.title,
|
||||
nr: 13,
|
||||
title: "innerPocketWelt"
|
||||
});
|
||||
title: 'innerPocketWelt'
|
||||
})
|
||||
|
||||
macro("grainline", {
|
||||
macro('grainline', {
|
||||
from: points.bottomLeft.shift(0, 10),
|
||||
to: points.topLeft.shift(0, 10)
|
||||
});
|
||||
})
|
||||
|
||||
if (sa) paths.sa = paths.seam.offset(sa).attr("class", "fabric sa");
|
||||
if (sa) paths.sa = paths.seam.offset(sa).attr('class', 'fabric sa')
|
||||
|
||||
if (paperless) {
|
||||
macro("vd", {
|
||||
macro('vd', {
|
||||
from: points.realBottomRight,
|
||||
to: points.realTopRight,
|
||||
x: points.topRight.x + sa + 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.bottomRight,
|
||||
to: points.topRight,
|
||||
x: points.topRight.x + sa + 30
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.realBottomLeft,
|
||||
to: points.realBottomRight,
|
||||
y: points.bottomLeft.y + sa + 15
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.bottomLeft,
|
||||
to: points.bottomRight,
|
||||
y: points.bottomLeft.y + sa + 30
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
return part;
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -1,39 +1,38 @@
|
|||
export default function(part) {
|
||||
let { paperless, sa, store, complete, points, options, macro, Point, paths, Path } = part.shorthand();
|
||||
let {
|
||||
paperless,
|
||||
sa,
|
||||
store,
|
||||
complete,
|
||||
points,
|
||||
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
|
||||
);
|
||||
points.edgeLeft = points.bottomLeft.shiftFractionTowards(points.topLeft, 1.25);
|
||||
points.edgeRight = new Point(
|
||||
points.topRight.x,
|
||||
points.edgeLeft.y
|
||||
);
|
||||
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)
|
||||
points.edgeLeft = points.bottomLeft.shiftFractionTowards(points.topLeft, 1.25)
|
||||
points.edgeRight = new Point(points.topRight.x, points.edgeLeft.y)
|
||||
if (options.pocketRadius > 0) {
|
||||
macro("round", {
|
||||
macro('round', {
|
||||
from: points.topLeft,
|
||||
to: points.bottomRight,
|
||||
via: points.bottomLeft,
|
||||
radius: store.get("pocketRadius"),
|
||||
prefix: "roundLeft"
|
||||
});
|
||||
macro("round", {
|
||||
radius: store.get('pocketRadius'),
|
||||
prefix: 'roundLeft'
|
||||
})
|
||||
macro('round', {
|
||||
from: points.bottomLeft,
|
||||
to: points.topRight,
|
||||
via: points.bottomRight,
|
||||
radius: store.get("pocketRadius"),
|
||||
prefix: "roundRight"
|
||||
});
|
||||
radius: store.get('pocketRadius'),
|
||||
prefix: 'roundRight'
|
||||
})
|
||||
|
||||
paths.seam = new Path()
|
||||
.move(points.edgeLeft)
|
||||
|
@ -45,60 +44,60 @@ export default function(part) {
|
|||
paths.seam = new Path()
|
||||
.move(points.edgeLeft)
|
||||
.line(points.bottomLeft)
|
||||
.line(points.bottomRight);
|
||||
.line(points.bottomRight)
|
||||
}
|
||||
|
||||
paths.seam = paths.seam
|
||||
.line(points.edgeRight)
|
||||
.line(points.edgeLeft)
|
||||
.close()
|
||||
.attr("class", "fabric");
|
||||
.attr('class', 'fabric')
|
||||
|
||||
paths.fold = new Path()
|
||||
.move(points.topLeft)
|
||||
.line(points.topRight)
|
||||
.attr("class", "fabric dashed");
|
||||
.attr('class', 'fabric dashed')
|
||||
|
||||
if (complete) {
|
||||
points.title = points.topLeft.shiftFractionTowards(points.bottomRight, 0.5);
|
||||
macro("title", {
|
||||
points.title = points.topLeft.shiftFractionTowards(points.bottomRight, 0.5)
|
||||
macro('title', {
|
||||
at: points.title,
|
||||
nr: 10,
|
||||
title: "pocket"
|
||||
});
|
||||
title: 'pocket'
|
||||
})
|
||||
|
||||
macro("grainline", {
|
||||
from: points.bottomLeft.shift(0, 10+ (store.get("pocketRadius") || 0)),
|
||||
to: points.edgeLeft.shift(0, 10+ (store.get("pocketRadius") || 0)),
|
||||
});
|
||||
macro('grainline', {
|
||||
from: points.bottomLeft.shift(0, 10 + (store.get('pocketRadius') || 0)),
|
||||
to: points.edgeLeft.shift(0, 10 + (store.get('pocketRadius') || 0))
|
||||
})
|
||||
|
||||
if (sa) paths.sa = paths.seam.offset(sa).attr("class", "fabric sa");
|
||||
if (sa) paths.sa = paths.seam.offset(sa).attr('class', 'fabric sa')
|
||||
|
||||
if (paperless) {
|
||||
macro("vd", {
|
||||
macro('vd', {
|
||||
from: points.bottomRight,
|
||||
to: points.topRight,
|
||||
x: points.topRight.x + sa + 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.bottomRight,
|
||||
to: points.edgeRight,
|
||||
x: points.topRight.x + sa + 30
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.edgeLeft,
|
||||
to: points.edgeRight,
|
||||
y: points.edgeRight.y - sa - 15
|
||||
});
|
||||
})
|
||||
if (options.pocketRadius > 0) {
|
||||
macro("hd", {
|
||||
macro('hd', {
|
||||
from: points.roundRightStart,
|
||||
to: points.roundRightEnd,
|
||||
y: points.bottomRight.y + sa + 15
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return part;
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -1,34 +1,36 @@
|
|||
export default function(part) {
|
||||
let { paperless, sa, store, complete, points, options, macro, Point, paths, Path } = part.shorthand();
|
||||
let {
|
||||
paperless,
|
||||
sa,
|
||||
store,
|
||||
complete,
|
||||
points,
|
||||
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
|
||||
);
|
||||
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", {
|
||||
macro('round', {
|
||||
from: points.topLeft,
|
||||
to: points.bottomRight,
|
||||
via: points.bottomLeft,
|
||||
radius: store.get("pocketFlapRadius"),
|
||||
prefix: "roundLeft"
|
||||
});
|
||||
macro("round", {
|
||||
radius: store.get('pocketFlapRadius'),
|
||||
prefix: 'roundLeft'
|
||||
})
|
||||
macro('round', {
|
||||
from: points.bottomLeft,
|
||||
to: points.topRight,
|
||||
via: points.bottomRight,
|
||||
radius: store.get("pocketFlapRadius"),
|
||||
prefix: "roundRight"
|
||||
});
|
||||
radius: store.get('pocketFlapRadius'),
|
||||
prefix: 'roundRight'
|
||||
})
|
||||
|
||||
paths.seam = new Path()
|
||||
.move(points.topLeft)
|
||||
|
@ -40,60 +42,58 @@ export default function(part) {
|
|||
paths.seam = new Path()
|
||||
.move(points.topLeft)
|
||||
.line(points.bottomLeft)
|
||||
.line(points.bottomRight);
|
||||
.line(points.bottomRight)
|
||||
}
|
||||
|
||||
paths.seam = paths.seam
|
||||
.line(points.topRight)
|
||||
.line(points.topLeft)
|
||||
.close()
|
||||
.attr("class", "fabric");
|
||||
.attr('class', 'fabric')
|
||||
|
||||
if (complete) {
|
||||
points.title = points.topLeft.shiftFractionTowards(points.bottomRight, 0.5);
|
||||
macro("title", {
|
||||
points.title = points.topLeft.shiftFractionTowards(points.bottomRight, 0.5)
|
||||
macro('title', {
|
||||
at: points.title,
|
||||
nr: 11,
|
||||
title: "pocketFlap"
|
||||
});
|
||||
title: 'pocketFlap'
|
||||
})
|
||||
|
||||
macro("grainline", {
|
||||
from: points.bottomLeft.shift(0, points.topRight.x/5 ),
|
||||
to: points.topLeft.shift(0, points.topRight.x/5)
|
||||
});
|
||||
macro('grainline', {
|
||||
from: points.bottomLeft.shift(0, points.topRight.x / 5),
|
||||
to: points.topLeft.shift(0, points.topRight.x / 5)
|
||||
})
|
||||
|
||||
if (sa) {
|
||||
paths.sa = paths.seam.offset(sa).attr("class", "fabric sa");
|
||||
paths.sa = paths.seam.offset(sa).attr('class', 'fabric sa')
|
||||
}
|
||||
|
||||
if (paperless) {
|
||||
macro("hd", {
|
||||
macro('hd', {
|
||||
from: points.topLeft,
|
||||
to: points.topRight,
|
||||
y: points.topLeft.y - sa - 15
|
||||
});
|
||||
})
|
||||
if (options.pocketFlapRadius > 0) {
|
||||
macro("vd", {
|
||||
macro('vd', {
|
||||
from: points.roundRightStart,
|
||||
to: points.roundRightEnd,
|
||||
x: points.topRight.x + sa + 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.roundRightStart,
|
||||
to: points.topRight,
|
||||
x: points.topRight.x + sa + 30
|
||||
});
|
||||
})
|
||||
} else {
|
||||
macro("vd", {
|
||||
macro('vd', {
|
||||
from: points.bottomRight,
|
||||
to: points.topRight,
|
||||
x: points.topRight.x + sa + 15
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return part;
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -1,26 +1,34 @@
|
|||
export default function(part) {
|
||||
let { paperless, sa, store, complete, points, options, macro, Point, paths, Path } = part.shorthand();
|
||||
let {
|
||||
paperless,
|
||||
sa,
|
||||
store,
|
||||
complete,
|
||||
points,
|
||||
options,
|
||||
macro,
|
||||
Point,
|
||||
paths,
|
||||
Path
|
||||
} = part.shorthand()
|
||||
|
||||
points.topLeft = points.bottomLeft.shiftFractionTowards(points.topLeft, 0.75);
|
||||
points.topRight = new Point(
|
||||
points.bottomRight.x,
|
||||
points.topLeft.y
|
||||
);
|
||||
points.topLeft = points.bottomLeft.shiftFractionTowards(points.topLeft, 0.75)
|
||||
points.topRight = new Point(points.bottomRight.x, points.topLeft.y)
|
||||
if (options.pocketRadius > 0) {
|
||||
macro("round", {
|
||||
macro('round', {
|
||||
from: points.topLeft,
|
||||
to: points.bottomRight,
|
||||
via: points.bottomLeft,
|
||||
radius: store.get("pocketRadius"),
|
||||
prefix: "roundLeft"
|
||||
});
|
||||
macro("round", {
|
||||
radius: store.get('pocketRadius'),
|
||||
prefix: 'roundLeft'
|
||||
})
|
||||
macro('round', {
|
||||
from: points.bottomLeft,
|
||||
to: points.topRight,
|
||||
via: points.bottomRight,
|
||||
radius: store.get("pocketRadius"),
|
||||
prefix: "roundRight"
|
||||
});
|
||||
radius: store.get('pocketRadius'),
|
||||
prefix: 'roundRight'
|
||||
})
|
||||
|
||||
paths.seam = new Path()
|
||||
.move(points.topLeft)
|
||||
|
@ -32,52 +40,52 @@ export default function(part) {
|
|||
paths.seam = new Path()
|
||||
.move(points.topLeft)
|
||||
.line(points.bottomLeft)
|
||||
.line(points.bottomRight);
|
||||
.line(points.bottomRight)
|
||||
}
|
||||
|
||||
paths.seam = paths.seam
|
||||
.line(points.topRight)
|
||||
.line(points.topLeft)
|
||||
.close()
|
||||
.attr("class", "lining");
|
||||
.attr('class', 'lining')
|
||||
|
||||
delete paths.fold;
|
||||
delete paths.fold
|
||||
|
||||
if (complete) {
|
||||
points.title = points.topLeft.shiftFractionTowards(points.bottomRight, 0.5);
|
||||
macro("title", {
|
||||
points.title = points.topLeft.shiftFractionTowards(points.bottomRight, 0.5)
|
||||
macro('title', {
|
||||
at: points.title,
|
||||
nr: 16,
|
||||
title: "pocketLining"
|
||||
});
|
||||
title: 'pocketLining'
|
||||
})
|
||||
|
||||
macro("grainline", {
|
||||
from: points.bottomLeft.shift(0, 10+ (store.get("pocketRadius") || 0)),
|
||||
to: points.topLeft.shift(0, 10+ (store.get("pocketRadius") || 0)),
|
||||
});
|
||||
macro('grainline', {
|
||||
from: points.bottomLeft.shift(0, 10 + (store.get('pocketRadius') || 0)),
|
||||
to: points.topLeft.shift(0, 10 + (store.get('pocketRadius') || 0))
|
||||
})
|
||||
|
||||
if (sa) paths.sa = paths.seam.offset(sa).attr("class", "lining sa");
|
||||
if (sa) paths.sa = paths.seam.offset(sa).attr('class', 'lining sa')
|
||||
|
||||
if (paperless) {
|
||||
macro("vd", {
|
||||
macro('vd', {
|
||||
from: points.bottomRight,
|
||||
to: points.topRight,
|
||||
x: points.topRight.x + sa + 15
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.topLeft,
|
||||
to: points.topRight,
|
||||
y: points.topRight.y - sa - 15
|
||||
});
|
||||
})
|
||||
if (options.pocketRadius > 0) {
|
||||
macro("hd", {
|
||||
macro('hd', {
|
||||
from: points.roundRightStart,
|
||||
to: points.roundRightEnd,
|
||||
y: points.bottomRight.y + sa + 15
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return part;
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
* This calculates a bunch of helper variables and stores them
|
||||
*/
|
||||
export const calculateRatios = part => {
|
||||
let { store, measurements, options } = part.shorthand();
|
||||
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('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"));
|
||||
};
|
||||
store.set('waistReduction', store.get('chest') - store.get('waist'))
|
||||
store.set('hipsReduction', store.get('chest') - store.get('hips'))
|
||||
}
|
||||
|
|
|
@ -1,24 +1,35 @@
|
|||
export default function(part) {
|
||||
let { units, paperless, sa, store, complete, points, macro, Point, paths, Path } = part.shorthand();
|
||||
let {
|
||||
units,
|
||||
paperless,
|
||||
sa,
|
||||
store,
|
||||
complete,
|
||||
points,
|
||||
macro,
|
||||
Point,
|
||||
paths,
|
||||
Path
|
||||
} = part.shorthand()
|
||||
|
||||
let length = store.get("waistToHem") - store.get("beltWidth")/2;
|
||||
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"));
|
||||
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;
|
||||
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);
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,7 +43,7 @@ export default function(part) {
|
|||
.move(points.waistMidTop)
|
||||
.line(points.waistTop)
|
||||
.line(points.cbTop)
|
||||
.attr("class", "fabric");
|
||||
.attr('class', 'fabric')
|
||||
|
||||
paths.folds = new Path()
|
||||
.move(points.fold1Top)
|
||||
|
@ -43,69 +54,72 @@ export default function(part) {
|
|||
.line(points.fold3Bottom)
|
||||
.move(points.fold4Top)
|
||||
.line(points.fold4Bottom)
|
||||
.attr("class", "lashed");
|
||||
.attr('class', 'lashed')
|
||||
|
||||
paths.hint = new Path()
|
||||
.move(points.cbMidTop)
|
||||
.line(points.cbMidBottom)
|
||||
.move(points.waistMidBottom)
|
||||
.line(points.waistMidTop)
|
||||
.attr("class", "fabric dashed");
|
||||
.attr('class', 'fabric dashed')
|
||||
|
||||
if (complete) {
|
||||
points.title = points.fold4Top.shiftFractionTowards(points.waistBottom, 0.5);
|
||||
macro("title", {
|
||||
points.title = points.fold4Top.shiftFractionTowards(points.waistBottom, 0.5)
|
||||
macro('title', {
|
||||
at: points.title,
|
||||
nr: 3,
|
||||
title: "tail"
|
||||
});
|
||||
title: 'tail'
|
||||
})
|
||||
|
||||
macro("grainline", {
|
||||
macro('grainline', {
|
||||
from: points.fold2Bottom.shift(0, 10),
|
||||
to: points.fold2Top.shift(0, 10)
|
||||
});
|
||||
})
|
||||
|
||||
if (sa) paths.sa = paths.seam.offset(sa).close().attr("class", "fabric sa");
|
||||
macro("vd", {
|
||||
if (sa)
|
||||
paths.sa = paths.seam
|
||||
.offset(sa)
|
||||
.close()
|
||||
.attr('class', 'fabric sa')
|
||||
macro('vd', {
|
||||
from: points.fold4Bottom.shift(0, 15),
|
||||
to: points.fold4Top.shift(0, 15),
|
||||
text: units(length)
|
||||
});
|
||||
})
|
||||
|
||||
if (paperless) {
|
||||
macro("hd", {
|
||||
macro('hd', {
|
||||
from: points.cbBottom,
|
||||
to: points.fold1Bottom,
|
||||
y: points.cbBottom.y + sa + 15
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.fold1Bottom,
|
||||
to: points.fold2Bottom,
|
||||
y: points.cbBottom.y + sa + 15
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.fold2Bottom,
|
||||
to: points.fold3Bottom,
|
||||
y: points.cbBottom.y + sa + 15
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.fold3Bottom,
|
||||
to: points.fold4Bottom,
|
||||
y: points.cbBottom.y + sa + 15
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.fold4Bottom,
|
||||
to: points.waistBottom,
|
||||
y: points.cbBottom.y + sa + 15
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.cbBottom,
|
||||
to: points.waistBottom,
|
||||
y: points.cbBottom.y + sa + 30
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return part;
|
||||
return part
|
||||
}
|
||||
|
||||
|
|
|
@ -1,25 +1,36 @@
|
|||
export default function(part) {
|
||||
let { paperless, sa, store, complete, points, measurements, options, macro, paths, Path } = part.shorthand();
|
||||
let {
|
||||
paperless,
|
||||
sa,
|
||||
store,
|
||||
complete,
|
||||
points,
|
||||
measurements,
|
||||
options,
|
||||
macro,
|
||||
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", {
|
||||
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,
|
||||
radius: length / 3,
|
||||
render: true,
|
||||
prefix: "round"
|
||||
});
|
||||
store.set("topCuffWidth", points.tsWristLeft.dist(points.tsWristRight));
|
||||
store.set("cuffLength", length);
|
||||
store.set("cuffRadius", length/3);
|
||||
prefix: 'round'
|
||||
})
|
||||
store.set('topCuffWidth', points.tsWristLeft.dist(points.tsWristRight))
|
||||
store.set('cuffLength', length)
|
||||
store.set('cuffRadius', length / 3)
|
||||
|
||||
// Clean up
|
||||
for (let i in paths) delete paths[i];
|
||||
for (let i in paths) delete paths[i]
|
||||
|
||||
// Paths
|
||||
paths.seam = new Path()
|
||||
|
@ -37,90 +48,89 @@ export default function(part) {
|
|||
.curve(points.topCpLeft, points.frontPitchPointCpTop, points.frontPitchPoint)
|
||||
.curve(points.frontPitchPointCpBottom, points.tsLeftEdgeCpRight, points.tsLeftEdge)
|
||||
.close()
|
||||
.attr("class", "fabric");
|
||||
.attr('class', 'fabric')
|
||||
|
||||
if (complete) {
|
||||
|
||||
macro("grainline", {
|
||||
macro('grainline', {
|
||||
from: points.boxBottom,
|
||||
to: points.top
|
||||
});
|
||||
})
|
||||
|
||||
if (sa) {
|
||||
paths.sa = paths.seam.offset(sa).attr("class", "fabric sa");
|
||||
paths.sa = paths.seam.offset(sa).attr('class', 'fabric sa')
|
||||
}
|
||||
|
||||
if (paperless) {
|
||||
macro("ld", {
|
||||
macro('ld', {
|
||||
from: points.tsWristLeft,
|
||||
to: points.tsWristRight,
|
||||
d: -15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.tsWristLeft,
|
||||
to: points.tsElbowLeft,
|
||||
x: points.tsLeftEdge.x - sa - 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.tsWristLeft,
|
||||
to: points.tsLeftEdge,
|
||||
x: points.tsLeftEdge.x - sa - 30
|
||||
});
|
||||
macro("ld", {
|
||||
})
|
||||
macro('ld', {
|
||||
from: points.cuffBottomLeft,
|
||||
to: points.tsWristLeft,
|
||||
d: 15 + sa
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.cuffBottomRight,
|
||||
to: points.usWristRight,
|
||||
x: points.usWristRight.x + 15 + sa
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.usWristRight,
|
||||
to: points.elbowRight,
|
||||
x: points.elbowRight.x + 15 + sa
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.usWristRight,
|
||||
to: points.tsRightEdge,
|
||||
x: points.elbowRight.x + 30 + sa
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.usWristRight,
|
||||
to: points.backPitchPoint,
|
||||
x: points.elbowRight.x + 45 + sa
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.usWristRight,
|
||||
to: points.top,
|
||||
x: points.elbowRight.x + 60 + sa
|
||||
});
|
||||
macro("ld", {
|
||||
})
|
||||
macro('ld', {
|
||||
from: points.tsElbowLeft,
|
||||
to: points.elbowRight
|
||||
});
|
||||
macro("ld", {
|
||||
})
|
||||
macro('ld', {
|
||||
from: points.tsLeftEdge,
|
||||
to: points.tsRightEdge
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.tsLeftEdge,
|
||||
to: points.top,
|
||||
y: points.top.y - sa - 15
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.tsLeftEdge,
|
||||
to: points.backPitchPoint,
|
||||
y: points.top.y - sa - 30
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.tsLeftEdge,
|
||||
to: points.tsRightEdge,
|
||||
y: points.top.y - sa - 45
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return part;
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -1,23 +1,35 @@
|
|||
export default function(part) {
|
||||
let { paperless, sa, store, complete, points, measurements, options, macro, Point, paths, Path } = part.shorthand();
|
||||
let {
|
||||
paperless,
|
||||
sa,
|
||||
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", {
|
||||
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,
|
||||
radius: length / 3,
|
||||
render: true,
|
||||
prefix: "round"
|
||||
});
|
||||
store.set("underCuffWidth", points.usWristLeft.dist(points.usWristRight));
|
||||
prefix: 'round'
|
||||
})
|
||||
store.set('underCuffWidth', points.usWristLeft.dist(points.usWristRight))
|
||||
|
||||
// Clean up
|
||||
for (let i in paths) delete paths[i];
|
||||
for (let i in paths) delete paths[i]
|
||||
|
||||
// Paths
|
||||
paths.seam = new Path()
|
||||
|
@ -34,79 +46,75 @@ export default function(part) {
|
|||
.curve(points.usTipCpBottom, points.usLeftEdgeCpRight, points.usLeftEdgeRight)
|
||||
.line(points.usLeftEdge)
|
||||
.close()
|
||||
.attr("class", "fabric");
|
||||
.attr('class', 'fabric')
|
||||
|
||||
if (complete) {
|
||||
|
||||
macro("grainline", {
|
||||
macro('grainline', {
|
||||
from: points.boxBottom,
|
||||
to: new Point(
|
||||
points.top.x,
|
||||
points.usLeftEdge.y
|
||||
)
|
||||
});
|
||||
to: new Point(points.top.x, points.usLeftEdge.y)
|
||||
})
|
||||
|
||||
if (sa) {
|
||||
paths.sa = paths.seam.offset(sa).attr("class", "fabric sa");
|
||||
paths.sa = paths.seam.offset(sa).attr('class', 'fabric sa')
|
||||
}
|
||||
|
||||
if (paperless) {
|
||||
macro("ld", {
|
||||
macro('ld', {
|
||||
from: points.usWristLeft,
|
||||
to: points.usWristRight,
|
||||
d: -15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.usWristLeft,
|
||||
to: points.usElbowLeft,
|
||||
x: points.usLeftEdge.x - sa - 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.usWristLeft,
|
||||
to: points.usLeftEdge,
|
||||
x: points.usLeftEdge.x - sa - 30
|
||||
});
|
||||
macro("ld", {
|
||||
})
|
||||
macro('ld', {
|
||||
from: points.cuffBottomLeft,
|
||||
to: points.usWristLeft,
|
||||
d: 15 + sa
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.cuffBottomRight,
|
||||
to: points.usWristRight,
|
||||
x: points.usWristRight.x + 15 + sa
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.usWristRight,
|
||||
to: points.elbowRight,
|
||||
x: points.elbowRight.x + 15 + sa
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.usWristRight,
|
||||
to: points.usTip,
|
||||
x: points.elbowRight.x + 30 + sa
|
||||
});
|
||||
macro("ld", {
|
||||
})
|
||||
macro('ld', {
|
||||
from: points.usElbowLeft,
|
||||
to: points.elbowRight
|
||||
});
|
||||
macro("ld", {
|
||||
})
|
||||
macro('ld', {
|
||||
from: points.usLeftEdge,
|
||||
to: points.usRightEdge,
|
||||
d: -15
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.usLeftEdge,
|
||||
to: points.usTip,
|
||||
y: points.usTip.y - sa - 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.usLeftEdge,
|
||||
to: points.usTip,
|
||||
x: points.usLeftEdge.x - sa - 15
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return part;
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -1,22 +1,15 @@
|
|||
import React from "react";
|
||||
import freesewing from "@freesewing/core";
|
||||
import Workbench from "@freesewing/components/Workbench";
|
||||
import "typeface-roboto-condensed";
|
||||
import "@freesewing/css-theme";
|
||||
import React from 'react'
|
||||
import freesewing from '@freesewing/core'
|
||||
import Workbench from '@freesewing/components/Workbench'
|
||||
import 'typeface-roboto-condensed'
|
||||
import '@freesewing/css-theme'
|
||||
|
||||
import Pattern from "pattern";
|
||||
import Pattern from 'pattern'
|
||||
|
||||
const App = props => {
|
||||
let instance = new Pattern();
|
||||
let config = instance.config;
|
||||
return (
|
||||
<Workbench
|
||||
freesewing={freesewing}
|
||||
Pattern={Pattern}
|
||||
config={config}
|
||||
userLanguage="en"
|
||||
/>
|
||||
);
|
||||
};
|
||||
let instance = new Pattern()
|
||||
let config = instance.config
|
||||
return <Workbench freesewing={freesewing} Pattern={Pattern} config={config} userLanguage="en" />
|
||||
}
|
||||
|
||||
export default App;
|
||||
export default App
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import App from "./App";
|
||||
import * as serviceWorker from "./serviceWorker";
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import App from './App'
|
||||
import * as serviceWorker from './serviceWorker'
|
||||
|
||||
ReactDOM.render(<App />, document.getElementById("root"));
|
||||
ReactDOM.render(<App />, document.getElementById('root'))
|
||||
|
||||
// If you want your app to work offline and load faster, you can change
|
||||
// unregister() to register() below. Note this comes with some pitfalls.
|
||||
// Learn more about service workers: http://bit.ly/CRA-PWA
|
||||
serviceWorker.unregister();
|
||||
serviceWorker.unregister()
|
||||
|
|
|
@ -9,46 +9,44 @@
|
|||
// This link also includes instructions on opting out of this behavior.
|
||||
|
||||
const isLocalhost = Boolean(
|
||||
window.location.hostname === "localhost" ||
|
||||
window.location.hostname === 'localhost' ||
|
||||
// [::1] is the IPv6 localhost address.
|
||||
window.location.hostname === "[::1]" ||
|
||||
window.location.hostname === '[::1]' ||
|
||||
// 127.0.0.1/8 is considered localhost for IPv4.
|
||||
window.location.hostname.match(
|
||||
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
|
||||
)
|
||||
);
|
||||
window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/)
|
||||
)
|
||||
|
||||
export function register(config) {
|
||||
if (process.env.NODE_ENV === "production" && "serviceWorker" in navigator) {
|
||||
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
|
||||
// The URL constructor is available in all browsers that support SW.
|
||||
const publicUrl = new URL(process.env.PUBLIC_URL, window.location);
|
||||
const publicUrl = new URL(process.env.PUBLIC_URL, window.location)
|
||||
if (publicUrl.origin !== window.location.origin) {
|
||||
// Our service worker won't work if PUBLIC_URL is on a different origin
|
||||
// from what our page is served on. This might happen if a CDN is used to
|
||||
// serve assets; see https://github.com/facebook/create-react-app/issues/2374
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
window.addEventListener("load", () => {
|
||||
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
|
||||
window.addEventListener('load', () => {
|
||||
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`
|
||||
|
||||
if (isLocalhost) {
|
||||
// This is running on localhost. Let's check if a service worker still exists or not.
|
||||
checkValidServiceWorker(swUrl, config);
|
||||
checkValidServiceWorker(swUrl, config)
|
||||
|
||||
// Add some additional logging to localhost, pointing developers to the
|
||||
// service worker/PWA documentation.
|
||||
navigator.serviceWorker.ready.then(() => {
|
||||
console.log(
|
||||
"This web app is being served cache-first by a service " +
|
||||
"worker. To learn more, visit https://goo.gl/SC7cgQ"
|
||||
);
|
||||
});
|
||||
'This web app is being served cache-first by a service ' +
|
||||
'worker. To learn more, visit https://goo.gl/SC7cgQ'
|
||||
)
|
||||
})
|
||||
} else {
|
||||
// Is not local host. Just register service worker
|
||||
registerValidSW(swUrl, config);
|
||||
registerValidSW(swUrl, config)
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,38 +55,38 @@ function registerValidSW(swUrl, config) {
|
|||
.register(swUrl)
|
||||
.then(registration => {
|
||||
registration.onupdatefound = () => {
|
||||
const installingWorker = registration.installing;
|
||||
const installingWorker = registration.installing
|
||||
installingWorker.onstatechange = () => {
|
||||
if (installingWorker.state === "installed") {
|
||||
if (installingWorker.state === 'installed') {
|
||||
if (navigator.serviceWorker.controller) {
|
||||
// At this point, the old content will have been purged and
|
||||
// the fresh content will have been added to the cache.
|
||||
// It's the perfect time to display a "New content is
|
||||
// available; please refresh." message in your web app.
|
||||
console.log("New content is available; please refresh.");
|
||||
console.log('New content is available; please refresh.')
|
||||
|
||||
// Execute callback
|
||||
if (config.onUpdate) {
|
||||
config.onUpdate(registration);
|
||||
config.onUpdate(registration)
|
||||
}
|
||||
} else {
|
||||
// At this point, everything has been precached.
|
||||
// It's the perfect time to display a
|
||||
// "Content is cached for offline use." message.
|
||||
console.log("Content is cached for offline use.");
|
||||
console.log('Content is cached for offline use.')
|
||||
|
||||
// Execute callback
|
||||
if (config.onSuccess) {
|
||||
config.onSuccess(registration);
|
||||
config.onSuccess(registration)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
})
|
||||
.catch(error => {
|
||||
console.error("Error during service worker registration:", error);
|
||||
});
|
||||
console.error('Error during service worker registration:', error)
|
||||
})
|
||||
}
|
||||
|
||||
function checkValidServiceWorker(swUrl, config) {
|
||||
|
@ -98,30 +96,28 @@ function checkValidServiceWorker(swUrl, config) {
|
|||
// Ensure service worker exists, and that we really are getting a JS file.
|
||||
if (
|
||||
response.status === 404 ||
|
||||
response.headers.get("content-type").indexOf("javascript") === -1
|
||||
response.headers.get('content-type').indexOf('javascript') === -1
|
||||
) {
|
||||
// No service worker found. Probably a different app. Reload the page.
|
||||
navigator.serviceWorker.ready.then(registration => {
|
||||
registration.unregister().then(() => {
|
||||
window.location.reload();
|
||||
});
|
||||
});
|
||||
window.location.reload()
|
||||
})
|
||||
})
|
||||
} else {
|
||||
// Service worker found. Proceed as normal.
|
||||
registerValidSW(swUrl, config);
|
||||
registerValidSW(swUrl, config)
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
console.log(
|
||||
"No internet connection found. App is running in offline mode."
|
||||
);
|
||||
});
|
||||
console.log('No internet connection found. App is running in offline mode.')
|
||||
})
|
||||
}
|
||||
|
||||
export function unregister() {
|
||||
if ("serviceWorker" in navigator) {
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.ready.then(registration => {
|
||||
registration.unregister();
|
||||
});
|
||||
registration.unregister()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,47 +1,27 @@
|
|||
export default function(part) {
|
||||
let {
|
||||
measurements,
|
||||
options,
|
||||
store,
|
||||
points,
|
||||
paths,
|
||||
Point,
|
||||
Path,
|
||||
utils,
|
||||
debug
|
||||
} = part.shorthand();
|
||||
let { measurements, options, store, points, paths, Point, Path, utils, debug } = part.shorthand()
|
||||
|
||||
// Where to divide our corset into panels
|
||||
if (options.panels === 11) store.set("gaps", [0.15, 0.275, 0.4, 0.6, 0.75]);
|
||||
else store.set("gaps", [0.2, 0.35, 0.5, 0.65, 0.8]);
|
||||
if (options.panels === 11) store.set('gaps', [0.15, 0.275, 0.4, 0.6, 0.75])
|
||||
else store.set('gaps', [0.2, 0.35, 0.5, 0.65, 0.8])
|
||||
|
||||
// Absolute values for some options
|
||||
store.set(
|
||||
"waistReduction",
|
||||
measurements.naturalWaist * options.waistReduction
|
||||
);
|
||||
store.set('waistReduction', measurements.naturalWaist * options.waistReduction)
|
||||
debug({
|
||||
type: "info",
|
||||
label: "✅ Waist reduction",
|
||||
msg: utils.units(store.get("waistReduction"))
|
||||
});
|
||||
store.set("backOpening", measurements.underbust * options.backOpening);
|
||||
type: 'info',
|
||||
label: '✅ Waist reduction',
|
||||
msg: utils.units(store.get('waistReduction'))
|
||||
})
|
||||
store.set('backOpening', measurements.underbust * options.backOpening)
|
||||
debug({
|
||||
type: "info",
|
||||
label: "✅ Back opening",
|
||||
msg: utils.units(store.get("backOpening"))
|
||||
});
|
||||
let len =
|
||||
measurements.naturalWaistToUnderbust + measurements.naturalWaistToHip;
|
||||
for (let option of [
|
||||
"backRise",
|
||||
"backDrop",
|
||||
"frontRise",
|
||||
"frontDrop",
|
||||
"hipRise"
|
||||
])
|
||||
store.set(option, len * options[option]);
|
||||
store.set("length", len);
|
||||
type: 'info',
|
||||
label: '✅ Back opening',
|
||||
msg: utils.units(store.get('backOpening'))
|
||||
})
|
||||
let len = measurements.naturalWaistToUnderbust + measurements.naturalWaistToHip
|
||||
for (let option of ['backRise', 'backDrop', 'frontRise', 'frontDrop', 'hipRise'])
|
||||
store.set(option, len * options[option])
|
||||
store.set('length', len)
|
||||
|
||||
/**
|
||||
* How much should we take in the corset at waist and bust
|
||||
|
@ -50,62 +30,47 @@ export default function(part) {
|
|||
* Can I be sure? Maybe not, but a larger underbust than hip
|
||||
* measurements seems very rare to say the least.
|
||||
*/
|
||||
store.set('width', 0.5 * (measurements.hipsCircumference - store.get('backOpening')))
|
||||
store.set(
|
||||
"width",
|
||||
0.5 * (measurements.hipsCircumference - store.get("backOpening"))
|
||||
);
|
||||
store.set(
|
||||
"waistIntake",
|
||||
0.5 *
|
||||
(measurements.hipsCircumference -
|
||||
measurements.naturalWaist +
|
||||
store.get("waistReduction"))
|
||||
);
|
||||
store.set(
|
||||
"bustIntake",
|
||||
0.5 * (measurements.hipsCircumference - measurements.underbust)
|
||||
);
|
||||
'waistIntake',
|
||||
0.5 * (measurements.hipsCircumference - measurements.naturalWaist + store.get('waistReduction'))
|
||||
)
|
||||
store.set('bustIntake', 0.5 * (measurements.hipsCircumference - measurements.underbust))
|
||||
|
||||
// Basic box (CB = Center back, CF = Center front)
|
||||
let wid = store.get("width");
|
||||
points.underbustCF = new Point(0, 0);
|
||||
points.hipsCF = new Point(0, len);
|
||||
points.hipsCB = new Point(wid, len);
|
||||
points.underbustCB = new Point(wid, 0);
|
||||
points.topSide = points.underbustCF.shiftFractionTowards(
|
||||
points.underbustCB,
|
||||
0.5
|
||||
);
|
||||
points.bottomSide = points.hipsCF.shiftFractionTowards(points.hipsCB, 0.5);
|
||||
points.waistCF = points.underbustCF.shift(
|
||||
-90,
|
||||
measurements.naturalWaistToUnderbust
|
||||
);
|
||||
points.waistCB = new Point(points.hipsCB.x, points.waistCF.y);
|
||||
let wid = store.get('width')
|
||||
points.underbustCF = new Point(0, 0)
|
||||
points.hipsCF = new Point(0, len)
|
||||
points.hipsCB = new Point(wid, len)
|
||||
points.underbustCB = new Point(wid, 0)
|
||||
points.topSide = points.underbustCF.shiftFractionTowards(points.underbustCB, 0.5)
|
||||
points.bottomSide = points.hipsCF.shiftFractionTowards(points.hipsCB, 0.5)
|
||||
points.waistCF = points.underbustCF.shift(-90, measurements.naturalWaistToUnderbust)
|
||||
points.waistCB = new Point(points.hipsCB.x, points.waistCF.y)
|
||||
|
||||
// frontRise
|
||||
points.topCF = points.underbustCF.shift(90, store.get("frontRise"));
|
||||
points.frontRiseStart = points.underbustCF.shift(0, wid * 0.15);
|
||||
points.frontRiseStartCp2 = points.underbustCF.shift(0, wid * 0.11);
|
||||
points.topCFCp1 = points.topCF.shift(0, wid * 0.11);
|
||||
points.topCF = points.underbustCF.shift(90, store.get('frontRise'))
|
||||
points.frontRiseStart = points.underbustCF.shift(0, wid * 0.15)
|
||||
points.frontRiseStartCp2 = points.underbustCF.shift(0, wid * 0.11)
|
||||
points.topCFCp1 = points.topCF.shift(0, wid * 0.11)
|
||||
|
||||
// frontDrop
|
||||
points.bottomCF = points.hipsCF.shift(-90, store.get("frontDrop"));
|
||||
points.bottomCFCp2 = points.bottomCF.shift(0, wid * 0.11);
|
||||
points.bottomCF = points.hipsCF.shift(-90, store.get('frontDrop'))
|
||||
points.bottomCFCp2 = points.bottomCF.shift(0, wid * 0.11)
|
||||
|
||||
// hipRise
|
||||
points.hipRise = points.bottomSide.shift(90, store.get("hipRise"));
|
||||
points.hipRiseCp1 = points.hipRise.shift(180, wid * 0.3);
|
||||
points.hipRiseCp2 = points.hipRise.shift(0, wid * 0.2);
|
||||
points.hipRise = points.bottomSide.shift(90, store.get('hipRise'))
|
||||
points.hipRiseCp1 = points.hipRise.shift(180, wid * 0.3)
|
||||
points.hipRiseCp2 = points.hipRise.shift(0, wid * 0.2)
|
||||
|
||||
// backDrop
|
||||
points.backDrop = points.hipsCB.shift(-90, store.get("backDrop"));
|
||||
points.backDropCp1 = points.backDrop.shift(180, wid * 0.3);
|
||||
points.backDrop = points.hipsCB.shift(-90, store.get('backDrop'))
|
||||
points.backDropCp1 = points.backDrop.shift(180, wid * 0.3)
|
||||
|
||||
// backRise
|
||||
points.backRise = points.underbustCB.shift(90, store.get("backRise"));
|
||||
points.backRiseCp1 = points.backRise.shift(180, wid * 0.4);
|
||||
points.topSideCp1 = points.topSide.shift(0, wid * 0.2);
|
||||
points.backRise = points.underbustCB.shift(90, store.get('backRise'))
|
||||
points.backRiseCp1 = points.backRise.shift(180, wid * 0.4)
|
||||
points.topSideCp1 = points.topSide.shift(0, wid * 0.2)
|
||||
|
||||
// Paths
|
||||
paths.help1 = new Path()
|
||||
|
@ -113,14 +78,14 @@ export default function(part) {
|
|||
.line(points.hipsCF)
|
||||
.line(points.hipsCB)
|
||||
.line(points.underbustCB)
|
||||
.close();
|
||||
.close()
|
||||
paths.help2 = new Path()
|
||||
.move(points.topSide)
|
||||
.line(points.bottomSide)
|
||||
.line(points.waistCF)
|
||||
.line(points.waistCB);
|
||||
paths.help1.render = false;
|
||||
paths.help2.render = false;
|
||||
.line(points.waistCB)
|
||||
paths.help1.render = false
|
||||
paths.help2.render = false
|
||||
|
||||
paths.outline = new Path()
|
||||
.move(points.bottomCF)
|
||||
|
@ -131,7 +96,7 @@ export default function(part) {
|
|||
.line(points.frontRiseStart)
|
||||
.curve(points.frontRiseStartCp2, points.topCFCp1, points.topCF)
|
||||
.line(points.bottomCF)
|
||||
.close();
|
||||
.close()
|
||||
|
||||
return part;
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
import freesewing from "@freesewing/core";
|
||||
import plugins from "@freesewing/plugin-bundle";
|
||||
import config from "../config";
|
||||
import freesewing from '@freesewing/core'
|
||||
import plugins from '@freesewing/plugin-bundle'
|
||||
import config from '../config'
|
||||
//Parts
|
||||
import draftBase from "./base";
|
||||
import draftPanels from "./panels";
|
||||
import draftPanel1 from "./panel1";
|
||||
import draftPanel2 from "./panel2";
|
||||
import draftPanel3 from "./panel3";
|
||||
import draftPanel4 from "./panel4";
|
||||
import draftPanel5 from "./panel5";
|
||||
import draftPanel6 from "./panel6";
|
||||
import draftBase from './base'
|
||||
import draftPanels from './panels'
|
||||
import draftPanel1 from './panel1'
|
||||
import draftPanel2 from './panel2'
|
||||
import draftPanel3 from './panel3'
|
||||
import draftPanel4 from './panel4'
|
||||
import draftPanel5 from './panel5'
|
||||
import draftPanel6 from './panel6'
|
||||
|
||||
// Create design
|
||||
const Pattern = new freesewing.Design(config, plugins);
|
||||
const Pattern = new freesewing.Design(config, plugins)
|
||||
|
||||
// Attach draft methods to prototype
|
||||
Pattern.prototype.draftBase = draftBase;
|
||||
Pattern.prototype.draftPanels = draftPanels;
|
||||
Pattern.prototype.draftPanel1 = draftPanel1;
|
||||
Pattern.prototype.draftPanel2 = draftPanel2;
|
||||
Pattern.prototype.draftPanel3 = draftPanel3;
|
||||
Pattern.prototype.draftPanel4 = draftPanel4;
|
||||
Pattern.prototype.draftPanel5 = draftPanel5;
|
||||
Pattern.prototype.draftPanel6 = draftPanel6;
|
||||
Pattern.prototype.draftBase = draftBase
|
||||
Pattern.prototype.draftPanels = draftPanels
|
||||
Pattern.prototype.draftPanel1 = draftPanel1
|
||||
Pattern.prototype.draftPanel2 = draftPanel2
|
||||
Pattern.prototype.draftPanel3 = draftPanel3
|
||||
Pattern.prototype.draftPanel4 = draftPanel4
|
||||
Pattern.prototype.draftPanel5 = draftPanel5
|
||||
Pattern.prototype.draftPanel6 = draftPanel6
|
||||
|
||||
export default Pattern;
|
||||
export default Pattern
|
||||
|
|
|
@ -1,73 +1,70 @@
|
|||
import draftPanel1ab from "./panel1ab";
|
||||
import draftPanel1ab from './panel1ab'
|
||||
|
||||
export default function(part) {
|
||||
let { macro, sa, paths, options, complete, paperless } = part.shorthand();
|
||||
let { macro, sa, paths, options, complete, paperless } = part.shorthand()
|
||||
|
||||
delete paths.outline;
|
||||
delete paths.panel2;
|
||||
delete paths.panel3;
|
||||
delete paths.panel4;
|
||||
delete paths.panel5;
|
||||
delete paths.panel6;
|
||||
delete paths.outline
|
||||
delete paths.panel2
|
||||
delete paths.panel3
|
||||
delete paths.panel4
|
||||
delete paths.panel5
|
||||
delete paths.panel6
|
||||
|
||||
if (options.panels === 13) return draftPanel1ab(part);
|
||||
if (options.panels === 13) return draftPanel1ab(part)
|
||||
|
||||
// Complete pattern?
|
||||
if (complete) {
|
||||
macro("cutonfold", {
|
||||
macro('cutonfold', {
|
||||
to: points.bottomCF,
|
||||
from: points.topCF,
|
||||
grainline: true
|
||||
});
|
||||
points.title = points.waistCF.shiftFractionTowards(
|
||||
points.underbustGap1Left,
|
||||
0.5
|
||||
);
|
||||
macro("title", {
|
||||
})
|
||||
points.title = points.waistCF.shiftFractionTowards(points.underbustGap1Left, 0.5)
|
||||
macro('title', {
|
||||
nr: 1,
|
||||
title: "",
|
||||
title: '',
|
||||
at: points.title
|
||||
});
|
||||
if (sa) paths.sa = paths.panel1.offset(sa).attr("class", "fabric sa");
|
||||
})
|
||||
if (sa) paths.sa = paths.panel1.offset(sa).attr('class', 'fabric sa')
|
||||
}
|
||||
|
||||
// Paperless?
|
||||
if (paperless) {
|
||||
macro("vd", {
|
||||
macro('vd', {
|
||||
from: points.bottomCF,
|
||||
to: points.waistCF,
|
||||
x: points.topCF.x - sa - 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.waistCF,
|
||||
to: points.topCF,
|
||||
x: points.topCF.x - sa - 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.hipsGap1,
|
||||
to: points.waistGap1Left,
|
||||
x: points.hipsGap1.x + sa + 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.waistGap1Left,
|
||||
to: points.underbustGap1Left,
|
||||
x: points.hipsGap1.x + sa + 15
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.bottomCF,
|
||||
to: points.hipsGap1,
|
||||
y: points.bottomCF.y + sa + 15
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.topCF,
|
||||
to: points.underbustGap1Left,
|
||||
y: points.topCF.y - sa - 15
|
||||
});
|
||||
macro("ld", {
|
||||
})
|
||||
macro('ld', {
|
||||
from: points.waistCF,
|
||||
to: points.waistGap1Left
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
return part;
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -1,28 +1,14 @@
|
|||
export default function(part) {
|
||||
let {
|
||||
macro,
|
||||
utils,
|
||||
sa,
|
||||
points,
|
||||
paths,
|
||||
Point,
|
||||
Path,
|
||||
complete,
|
||||
paperless
|
||||
} = part.shorthand();
|
||||
let { macro, utils, sa, points, paths, Point, Path, complete, paperless } = part.shorthand()
|
||||
|
||||
let top = new Path()
|
||||
.move(points.underbustGap1Left)
|
||||
.curve(points.frontRiseStartCp2, points.topCFCp1, points.topCF);
|
||||
points.topABsplit = top.shiftFractionAlong(0.3);
|
||||
.curve(points.frontRiseStartCp2, points.topCFCp1, points.topCF)
|
||||
points.topABsplit = top.shiftFractionAlong(0.3)
|
||||
let bottom = new Path()
|
||||
.move(points.bottomCF)
|
||||
.curve(
|
||||
paths.panel1.ops[1].cp1,
|
||||
paths.panel1.ops[1].cp2,
|
||||
paths.panel1.ops[1].to
|
||||
);
|
||||
points.bottomABsplit = bottom.shiftFractionAlong(0.3);
|
||||
.curve(paths.panel1.ops[1].cp1, paths.panel1.ops[1].cp2, paths.panel1.ops[1].to)
|
||||
points.bottomABsplit = bottom.shiftFractionAlong(0.3)
|
||||
|
||||
paths.panel1a = bottom
|
||||
.split(points.bottomABsplit)[0]
|
||||
|
@ -30,144 +16,134 @@ export default function(part) {
|
|||
.join(top.split(points.topABsplit)[1])
|
||||
.line(points.bottomCF)
|
||||
.close()
|
||||
.attr("class", "fabric");
|
||||
.attr('class', 'fabric')
|
||||
paths.panel1b = bottom
|
||||
.split(points.bottomABsplit)[1]
|
||||
.curve(points.hipsGap1Cp, points.waistGap1LeftCp1, points.waistGap1Left)
|
||||
.curve(
|
||||
points.waistGap1LeftCp2,
|
||||
points.underbustGap1LeftCp,
|
||||
points.underbustGap1Left
|
||||
)
|
||||
.curve(points.waistGap1LeftCp2, points.underbustGap1LeftCp, points.underbustGap1Left)
|
||||
.join(top.split(points.topABsplit)[0])
|
||||
.line(points.bottomABsplit)
|
||||
.close()
|
||||
.attr("class", "fabric");
|
||||
let translation = 5;
|
||||
if (sa) translation = 2 * sa + 5;
|
||||
paths.panel1b = paths.panel1b.translate(translation, 0);
|
||||
delete paths.panel1;
|
||||
.attr('class', 'fabric')
|
||||
let translation = 5
|
||||
if (sa) translation = 2 * sa + 5
|
||||
paths.panel1b = paths.panel1b.translate(translation, 0)
|
||||
delete paths.panel1
|
||||
|
||||
// Complete pattern?
|
||||
if (complete) {
|
||||
if (sa) {
|
||||
paths.saA = paths.panel1a.offset(sa).attr("class", "fabric sa");
|
||||
paths.saB = paths.panel1b.offset(sa).attr("class", "fabric sa");
|
||||
paths.saA = paths.panel1a.offset(sa).attr('class', 'fabric sa')
|
||||
paths.saB = paths.panel1b.offset(sa).attr('class', 'fabric sa')
|
||||
}
|
||||
macro("cutonfold", {
|
||||
macro('cutonfold', {
|
||||
to: points.bottomCF,
|
||||
from: points.topCF,
|
||||
grainline: true
|
||||
});
|
||||
macro("grainline", {
|
||||
})
|
||||
macro('grainline', {
|
||||
to: points.topABsplit.translate(translation, 0),
|
||||
from: new Point(
|
||||
points.topABsplit.translate(translation, 0).x,
|
||||
points.hipsGap1.translate(translation, 0).y
|
||||
)
|
||||
});
|
||||
points.midwayAB = points.topABsplit.shiftFractionTowards(
|
||||
points.bottomABsplit,
|
||||
0.5
|
||||
);
|
||||
points.titleA = points.underbustCF.shiftFractionTowards(
|
||||
points.midwayAB,
|
||||
0.5
|
||||
);
|
||||
macro("title", {
|
||||
nr: "1a",
|
||||
prefix: "panel1a",
|
||||
})
|
||||
points.midwayAB = points.topABsplit.shiftFractionTowards(points.bottomABsplit, 0.5)
|
||||
points.titleA = points.underbustCF.shiftFractionTowards(points.midwayAB, 0.5)
|
||||
macro('title', {
|
||||
nr: '1a',
|
||||
prefix: 'panel1a',
|
||||
at: points.titleA
|
||||
});
|
||||
})
|
||||
points.titleB = points.hipsGap1
|
||||
.translate(translation, 0)
|
||||
.shiftFractionTowards(points.midwayAB, 0.5);
|
||||
macro("title", {
|
||||
nr: "1b",
|
||||
prefix: "panel1b",
|
||||
.shiftFractionTowards(points.midwayAB, 0.5)
|
||||
macro('title', {
|
||||
nr: '1b',
|
||||
prefix: 'panel1b',
|
||||
at: points.titleB
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
// Paperless?
|
||||
if (paperless) {
|
||||
// 1a
|
||||
macro("vd", {
|
||||
macro('vd', {
|
||||
from: points.bottomCF,
|
||||
to: points.waistCF,
|
||||
x: points.topCF.x - sa - 30
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.waistCF,
|
||||
to: points.topCF,
|
||||
x: points.topCF.x - sa - 30
|
||||
});
|
||||
})
|
||||
points.waistAB = utils.beamsIntersect(
|
||||
points.topABsplit,
|
||||
points.bottomABsplit,
|
||||
points.waistCF,
|
||||
points.waistGap1
|
||||
);
|
||||
macro("vd", {
|
||||
)
|
||||
macro('vd', {
|
||||
from: points.bottomABsplit,
|
||||
to: points.waistAB,
|
||||
x: points.topCF.x - sa - 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.waistAB,
|
||||
to: points.topABsplit,
|
||||
x: points.topCF.x - sa - 15
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.bottomCF,
|
||||
to: points.bottomABsplit,
|
||||
y: points.bottomCF.y + sa + 15
|
||||
});
|
||||
macro("ld", {
|
||||
})
|
||||
macro('ld', {
|
||||
from: points.waistCF,
|
||||
to: points.waistAB
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.topCF,
|
||||
to: points.topABsplit,
|
||||
y: points.topCF.y - sa - 15
|
||||
});
|
||||
})
|
||||
// 1b
|
||||
macro("vd", {
|
||||
macro('vd', {
|
||||
from: points.hipsGap1.translate(translation, 0),
|
||||
to: points.waistGap1Left.translate(translation, 0),
|
||||
x: points.underbustGap1Left.translate(translation, 0).x + sa + 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.waistGap1Left.translate(translation, 0),
|
||||
to: points.underbustGap1Left.translate(translation, 0),
|
||||
x: points.underbustGap1Left.translate(translation, 0).x + sa + 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.bottomABsplit.translate(translation, 0),
|
||||
to: points.waistAB.translate(translation, 0),
|
||||
x: points.underbustGap1Left.translate(translation, 0).x + sa + 30
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.waistAB.translate(translation, 0),
|
||||
to: points.topABsplit.translate(translation, 0),
|
||||
x: points.underbustGap1Left.translate(translation, 0).x + sa + 30
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.bottomABsplit.translate(translation, 0),
|
||||
to: points.hipsGap1.translate(translation, 0),
|
||||
y: points.bottomABsplit.y + sa + 15
|
||||
});
|
||||
macro("ld", {
|
||||
})
|
||||
macro('ld', {
|
||||
from: points.waistAB.translate(translation, 0),
|
||||
to: points.waistGap1Left.translate(translation, 0)
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.topABsplit.translate(translation, 0),
|
||||
to: points.underbustGap1Left.translate(translation, 0),
|
||||
y: points.topABsplit.y - sa - 15
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
return part;
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -1,84 +1,70 @@
|
|||
export default function(part) {
|
||||
let {
|
||||
macro,
|
||||
sa,
|
||||
points,
|
||||
paths,
|
||||
Point,
|
||||
complete,
|
||||
paperless
|
||||
} = part.shorthand();
|
||||
let { macro, sa, points, paths, Point, complete, paperless } = part.shorthand()
|
||||
|
||||
delete paths.outline;
|
||||
delete paths.panel1;
|
||||
delete paths.panel3;
|
||||
delete paths.panel4;
|
||||
delete paths.panel5;
|
||||
delete paths.panel6;
|
||||
delete paths.outline
|
||||
delete paths.panel1
|
||||
delete paths.panel3
|
||||
delete paths.panel4
|
||||
delete paths.panel5
|
||||
delete paths.panel6
|
||||
|
||||
// Complete pattern?
|
||||
if (complete) {
|
||||
points.grainlineTop = new Point(
|
||||
points.waistGap1Right.shiftFractionTowards(points.waistGap2Left, 0.5).x,
|
||||
points.underbustGap1Right.y
|
||||
);
|
||||
points.grainlineBottom = new Point(
|
||||
points.grainlineTop.x,
|
||||
points.hipsGap2.y
|
||||
);
|
||||
macro("grainline", {
|
||||
)
|
||||
points.grainlineBottom = new Point(points.grainlineTop.x, points.hipsGap2.y)
|
||||
macro('grainline', {
|
||||
from: points.grainlineBottom,
|
||||
to: points.grainlineTop
|
||||
});
|
||||
points.title = points.grainlineTop.shift(
|
||||
-90,
|
||||
points.grainlineTop.dy(points.waistGap2Left) / 2
|
||||
);
|
||||
macro("title", {
|
||||
})
|
||||
points.title = points.grainlineTop.shift(-90, points.grainlineTop.dy(points.waistGap2Left) / 2)
|
||||
macro('title', {
|
||||
nr: 2,
|
||||
title: "",
|
||||
title: '',
|
||||
at: points.title
|
||||
});
|
||||
if (sa) paths.sa = paths.panel2.offset(sa).attr("class", "fabric sa");
|
||||
})
|
||||
if (sa) paths.sa = paths.panel2.offset(sa).attr('class', 'fabric sa')
|
||||
}
|
||||
|
||||
// Paperless?
|
||||
if (paperless) {
|
||||
macro("hd", {
|
||||
macro('hd', {
|
||||
from: points.hipsGap1,
|
||||
to: points.hipsGap2,
|
||||
y: points.hipsGap1.y + sa + 15
|
||||
});
|
||||
macro("ld", {
|
||||
})
|
||||
macro('ld', {
|
||||
from: points.waistGap1Right,
|
||||
to: points.waistGap2Left
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.underbustGap1Right,
|
||||
to: points.underbustGap2Left,
|
||||
y: points.underbustGap1Right.y - sa - 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.hipsGap1,
|
||||
to: points.waistGap1Right,
|
||||
x: points.hipsGap1.x - sa - 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.waistGap1Right,
|
||||
to: points.underbustGap1Right,
|
||||
x: points.hipsGap1.x - sa - 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.hipsGap2,
|
||||
to: points.waistGap1Right,
|
||||
x: points.hipsGap2.x + sa + 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.waistGap1Right,
|
||||
to: points.underbustGap2Left,
|
||||
x: points.hipsGap2.x + sa + 15
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
return part;
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -1,84 +1,70 @@
|
|||
export default function(part) {
|
||||
let {
|
||||
macro,
|
||||
sa,
|
||||
points,
|
||||
paths,
|
||||
Point,
|
||||
complete,
|
||||
paperless
|
||||
} = part.shorthand();
|
||||
let { macro, sa, points, paths, Point, complete, paperless } = part.shorthand()
|
||||
|
||||
delete paths.outline;
|
||||
delete paths.panel1;
|
||||
delete paths.panel2;
|
||||
delete paths.panel4;
|
||||
delete paths.panel5;
|
||||
delete paths.panel6;
|
||||
delete paths.outline
|
||||
delete paths.panel1
|
||||
delete paths.panel2
|
||||
delete paths.panel4
|
||||
delete paths.panel5
|
||||
delete paths.panel6
|
||||
|
||||
// Complete pattern?
|
||||
if (complete) {
|
||||
points.grainlineTop = new Point(
|
||||
points.waistGap2Right.shiftFractionTowards(points.waistGap3Left, 0.5).x,
|
||||
points.underbustGap2Right.y
|
||||
);
|
||||
points.grainlineBottom = new Point(
|
||||
points.grainlineTop.x,
|
||||
points.hipsGap3.y
|
||||
);
|
||||
macro("grainline", {
|
||||
)
|
||||
points.grainlineBottom = new Point(points.grainlineTop.x, points.hipsGap3.y)
|
||||
macro('grainline', {
|
||||
from: points.grainlineBottom,
|
||||
to: points.grainlineTop
|
||||
});
|
||||
points.title = points.grainlineTop.shift(
|
||||
-90,
|
||||
points.grainlineTop.dy(points.waistGap3Left) / 2
|
||||
);
|
||||
macro("title", {
|
||||
})
|
||||
points.title = points.grainlineTop.shift(-90, points.grainlineTop.dy(points.waistGap3Left) / 2)
|
||||
macro('title', {
|
||||
nr: 3,
|
||||
title: "",
|
||||
title: '',
|
||||
at: points.title
|
||||
});
|
||||
if (sa) paths.sa = paths.panel3.offset(sa).attr("class", "fabric sa");
|
||||
})
|
||||
if (sa) paths.sa = paths.panel3.offset(sa).attr('class', 'fabric sa')
|
||||
}
|
||||
|
||||
// Paperless?
|
||||
if (paperless) {
|
||||
macro("hd", {
|
||||
macro('hd', {
|
||||
from: points.hipsGap2,
|
||||
to: points.hipsGap3,
|
||||
y: points.hipsGap2.y + sa + 15
|
||||
});
|
||||
macro("ld", {
|
||||
})
|
||||
macro('ld', {
|
||||
from: points.waistGap2Right,
|
||||
to: points.waistGap3Left
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.underbustGap2Right,
|
||||
to: points.underbustGap3Left,
|
||||
y: points.underbustGap2Right.y - sa - 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.hipsGap2,
|
||||
to: points.waistGap2Right,
|
||||
x: points.hipsGap2.x - sa - 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.waistGap2Right,
|
||||
to: points.underbustGap2Right,
|
||||
x: points.hipsGap2.x - sa - 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.hipsGap3,
|
||||
to: points.waistGap2Right,
|
||||
x: points.hipsGap3.x + sa + 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.waistGap2Right,
|
||||
to: points.underbustGap3Left,
|
||||
x: points.hipsGap3.x + sa + 15
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
return part;
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -1,92 +1,73 @@
|
|||
export default function(part) {
|
||||
let {
|
||||
macro,
|
||||
sa,
|
||||
snippets,
|
||||
Snippet,
|
||||
points,
|
||||
paths,
|
||||
Point,
|
||||
complete,
|
||||
paperless
|
||||
} = part.shorthand();
|
||||
let { macro, sa, snippets, Snippet, points, paths, Point, complete, paperless } = part.shorthand()
|
||||
|
||||
delete paths.outline;
|
||||
delete paths.panel1;
|
||||
delete paths.panel2;
|
||||
delete paths.panel3;
|
||||
delete paths.panel5;
|
||||
delete paths.panel6;
|
||||
delete paths.outline
|
||||
delete paths.panel1
|
||||
delete paths.panel2
|
||||
delete paths.panel3
|
||||
delete paths.panel5
|
||||
delete paths.panel6
|
||||
|
||||
// Complete pattern?
|
||||
if (complete) {
|
||||
points.grainlineTop = new Point(
|
||||
points.waistGap3Right.shiftFractionTowards(points.waistGap4Left, 0.5).x,
|
||||
points.underbustGap3Right.y
|
||||
);
|
||||
points.grainlineBottom = new Point(
|
||||
points.grainlineTop.x,
|
||||
points.hipsGap4.y
|
||||
);
|
||||
macro("grainline", {
|
||||
)
|
||||
points.grainlineBottom = new Point(points.grainlineTop.x, points.hipsGap4.y)
|
||||
macro('grainline', {
|
||||
from: points.grainlineBottom,
|
||||
to: points.grainlineTop
|
||||
});
|
||||
points.title = points.grainlineTop.shift(
|
||||
-90,
|
||||
points.grainlineTop.dy(points.waistGap4Left) / 2
|
||||
);
|
||||
macro("title", {
|
||||
})
|
||||
points.title = points.grainlineTop.shift(-90, points.grainlineTop.dy(points.waistGap4Left) / 2)
|
||||
macro('title', {
|
||||
nr: 4,
|
||||
title: "",
|
||||
title: '',
|
||||
at: points.title
|
||||
});
|
||||
points.logo = points.grainlineTop.shiftFractionTowards(
|
||||
points.grainlineBottom,
|
||||
0.8
|
||||
);
|
||||
snippets.logo = new Snippet("logo", points.logo).attr("data-scale", 0.8);
|
||||
})
|
||||
points.logo = points.grainlineTop.shiftFractionTowards(points.grainlineBottom, 0.8)
|
||||
snippets.logo = new Snippet('logo', points.logo).attr('data-scale', 0.8)
|
||||
|
||||
if (sa) paths.sa = paths.panel4.offset(sa).attr("class", "fabric sa");
|
||||
if (sa) paths.sa = paths.panel4.offset(sa).attr('class', 'fabric sa')
|
||||
}
|
||||
|
||||
// Paperless?
|
||||
if (paperless) {
|
||||
macro("hd", {
|
||||
macro('hd', {
|
||||
from: points.hipsGap3,
|
||||
to: points.hipsGap4,
|
||||
y: points.hipsGap3.y + sa + 15
|
||||
});
|
||||
macro("ld", {
|
||||
})
|
||||
macro('ld', {
|
||||
from: points.waistGap3Right,
|
||||
to: points.waistGap4Left
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.underbustGap3Right,
|
||||
to: points.underbustGap4Left,
|
||||
y: points.underbustGap4Left.y - sa - 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.hipsGap3,
|
||||
to: points.waistGap3Right,
|
||||
x: points.hipsGap3.x - sa - 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.waistGap3Right,
|
||||
to: points.underbustGap3Right,
|
||||
x: points.hipsGap3.x - sa - 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.hipsGap4,
|
||||
to: points.waistGap3Right,
|
||||
x: points.hipsGap4.x + sa + 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.waistGap3Right,
|
||||
to: points.underbustGap4Left,
|
||||
x: points.hipsGap4.x + sa + 15
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
return part;
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -1,84 +1,70 @@
|
|||
export default function(part) {
|
||||
let {
|
||||
macro,
|
||||
sa,
|
||||
points,
|
||||
paths,
|
||||
Point,
|
||||
complete,
|
||||
paperless
|
||||
} = part.shorthand();
|
||||
let { macro, sa, points, paths, Point, complete, paperless } = part.shorthand()
|
||||
|
||||
delete paths.outline;
|
||||
delete paths.panel1;
|
||||
delete paths.panel2;
|
||||
delete paths.panel3;
|
||||
delete paths.panel4;
|
||||
delete paths.panel6;
|
||||
delete paths.outline
|
||||
delete paths.panel1
|
||||
delete paths.panel2
|
||||
delete paths.panel3
|
||||
delete paths.panel4
|
||||
delete paths.panel6
|
||||
|
||||
// Complete pattern?
|
||||
if (complete) {
|
||||
points.grainlineTop = new Point(
|
||||
points.waistGap4Right.shiftFractionTowards(points.waistGap5Left, 0.5).x,
|
||||
points.underbustGap4Right.y
|
||||
);
|
||||
points.grainlineBottom = new Point(
|
||||
points.grainlineTop.x,
|
||||
points.hipsGap5.y
|
||||
);
|
||||
macro("grainline", {
|
||||
)
|
||||
points.grainlineBottom = new Point(points.grainlineTop.x, points.hipsGap5.y)
|
||||
macro('grainline', {
|
||||
from: points.grainlineBottom,
|
||||
to: points.grainlineTop
|
||||
});
|
||||
points.title = points.grainlineTop.shift(
|
||||
-90,
|
||||
points.grainlineTop.dy(points.waistGap5Left) / 2
|
||||
);
|
||||
macro("title", {
|
||||
})
|
||||
points.title = points.grainlineTop.shift(-90, points.grainlineTop.dy(points.waistGap5Left) / 2)
|
||||
macro('title', {
|
||||
nr: 5,
|
||||
title: "",
|
||||
title: '',
|
||||
at: points.title
|
||||
});
|
||||
if (sa) paths.sa = paths.panel5.offset(sa).attr("class", "fabric sa");
|
||||
})
|
||||
if (sa) paths.sa = paths.panel5.offset(sa).attr('class', 'fabric sa')
|
||||
}
|
||||
|
||||
// Paperless?
|
||||
if (paperless) {
|
||||
macro("hd", {
|
||||
macro('hd', {
|
||||
from: points.hipsGap4,
|
||||
to: points.hipsGap5,
|
||||
y: points.hipsGap4.y + sa + 15
|
||||
});
|
||||
macro("ld", {
|
||||
})
|
||||
macro('ld', {
|
||||
from: points.waistGap4Right,
|
||||
to: points.waistGap5Left
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.underbustGap4Right,
|
||||
to: points.underbustGap5Left,
|
||||
y: points.underbustGap5Left.y - sa - 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.hipsGap4,
|
||||
to: points.waistGap4Right,
|
||||
x: points.hipsGap4.x - sa - 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.waistGap4Right,
|
||||
to: points.underbustGap4Right,
|
||||
x: points.hipsGap4.x - sa - 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.hipsGap5,
|
||||
to: points.waistGap4Right,
|
||||
x: points.hipsGap5.x + sa + 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.waistGap4Right,
|
||||
to: points.underbustGap5Left,
|
||||
x: points.hipsGap5.x + sa + 15
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
return part;
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -1,89 +1,75 @@
|
|||
export default function(part) {
|
||||
let {
|
||||
macro,
|
||||
sa,
|
||||
points,
|
||||
paths,
|
||||
Point,
|
||||
complete,
|
||||
paperless
|
||||
} = part.shorthand();
|
||||
let { macro, sa, points, paths, Point, complete, paperless } = part.shorthand()
|
||||
|
||||
delete paths.outline;
|
||||
delete paths.panel1;
|
||||
delete paths.panel2;
|
||||
delete paths.panel3;
|
||||
delete paths.panel4;
|
||||
delete paths.panel5;
|
||||
delete paths.outline
|
||||
delete paths.panel1
|
||||
delete paths.panel2
|
||||
delete paths.panel3
|
||||
delete paths.panel4
|
||||
delete paths.panel5
|
||||
|
||||
// Complete pattern?
|
||||
if (complete) {
|
||||
points.grainlineTop = new Point(
|
||||
points.waistGap5Right.shiftFractionTowards(points.waistCB, 0.5).x,
|
||||
points.underbustGap5Right.y
|
||||
);
|
||||
points.grainlineBottom = new Point(
|
||||
points.grainlineTop.x,
|
||||
points.hipsGap5.y
|
||||
);
|
||||
macro("grainline", {
|
||||
)
|
||||
points.grainlineBottom = new Point(points.grainlineTop.x, points.hipsGap5.y)
|
||||
macro('grainline', {
|
||||
from: points.grainlineBottom,
|
||||
to: points.grainlineTop
|
||||
});
|
||||
points.title = points.grainlineTop.shift(
|
||||
-90,
|
||||
points.grainlineTop.dy(points.waistGap5Right) / 2
|
||||
);
|
||||
macro("title", {
|
||||
})
|
||||
points.title = points.grainlineTop.shift(-90, points.grainlineTop.dy(points.waistGap5Right) / 2)
|
||||
macro('title', {
|
||||
nr: 6,
|
||||
title: "",
|
||||
title: '',
|
||||
at: points.title
|
||||
});
|
||||
points.scalebox = new Point(points.grainlineTop.x, points.hipsGap5.y - 55);
|
||||
macro("scalebox", {
|
||||
})
|
||||
points.scalebox = new Point(points.grainlineTop.x, points.hipsGap5.y - 55)
|
||||
macro('scalebox', {
|
||||
at: points.scalebox,
|
||||
rotate: 90
|
||||
});
|
||||
if (sa) paths.sa = paths.panel6.offset(sa).attr("class", "fabric sa");
|
||||
})
|
||||
if (sa) paths.sa = paths.panel6.offset(sa).attr('class', 'fabric sa')
|
||||
}
|
||||
|
||||
// Paperless?
|
||||
if (paperless) {
|
||||
macro("hd", {
|
||||
macro('hd', {
|
||||
from: points.hipsGap5,
|
||||
to: points.backDrop,
|
||||
y: points.backDrop.y + sa + 15
|
||||
});
|
||||
macro("ld", {
|
||||
})
|
||||
macro('ld', {
|
||||
from: points.waistGap5Right,
|
||||
to: points.waistCB
|
||||
});
|
||||
macro("hd", {
|
||||
})
|
||||
macro('hd', {
|
||||
from: points.underbustGap5Right,
|
||||
to: points.backRise,
|
||||
y: points.backRise.y - sa - 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.hipsGap5,
|
||||
to: points.waistGap5Right,
|
||||
x: points.hipsGap5.x - sa - 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.waistGap5Right,
|
||||
to: points.underbustGap5Right,
|
||||
x: points.hipsGap5.x - sa - 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.backDrop,
|
||||
to: points.waistCB,
|
||||
x: points.backDrop.x + sa + 15
|
||||
});
|
||||
macro("vd", {
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.waistCB,
|
||||
to: points.backRise,
|
||||
x: points.backDrop.x + sa + 15
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
return part;
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -1,205 +1,141 @@
|
|||
export default function(part) {
|
||||
let {
|
||||
measurements,
|
||||
options,
|
||||
store,
|
||||
points,
|
||||
paths,
|
||||
Point,
|
||||
Path,
|
||||
debug
|
||||
} = part.shorthand();
|
||||
let count = 1;
|
||||
let { measurements, options, store, points, paths, Point, Path, debug } = part.shorthand()
|
||||
let count = 1
|
||||
let bottom = new Path()
|
||||
.move(points.bottomCF)
|
||||
.curve(points.bottomCFCp2, points.hipRiseCp1, points.hipRise)
|
||||
.curve(points.hipRiseCp2, points.backDropCp1, points.backDrop)
|
||||
.attr("class", "lashed various stroke-xl");
|
||||
for (let gap of store.get("gaps")) {
|
||||
.attr('class', 'lashed various stroke-xl')
|
||||
for (let gap of store.get('gaps')) {
|
||||
// Underbust
|
||||
points[`underbustGap${count}`] = new Point(store.get("width") * gap, 0);
|
||||
points[`underbustGap${count}`] = new Point(store.get('width') * gap, 0)
|
||||
points[`underbustGap${count}Right`] = points[`underbustGap${count}`].shift(
|
||||
0,
|
||||
store.get("bustIntake") * 0.1
|
||||
);
|
||||
store.get('bustIntake') * 0.1
|
||||
)
|
||||
points[`underbustGap${count}Left`] = points[`underbustGap${count}`].shift(
|
||||
180,
|
||||
store.get("bustIntake") * 0.1
|
||||
);
|
||||
points[`underbustGap${count}RightCp`] = points[
|
||||
`underbustGap${count}Right`
|
||||
].shift(-90, measurements.naturalWaistToUnderbust * 0.15);
|
||||
points[`underbustGap${count}LeftCp`] = points[
|
||||
`underbustGap${count}Left`
|
||||
].shift(-90, measurements.naturalWaistToUnderbust * 0.15);
|
||||
store.get('bustIntake') * 0.1
|
||||
)
|
||||
points[`underbustGap${count}RightCp`] = points[`underbustGap${count}Right`].shift(
|
||||
-90,
|
||||
measurements.naturalWaistToUnderbust * 0.15
|
||||
)
|
||||
points[`underbustGap${count}LeftCp`] = points[`underbustGap${count}Left`].shift(
|
||||
-90,
|
||||
measurements.naturalWaistToUnderbust * 0.15
|
||||
)
|
||||
|
||||
// Waist
|
||||
points[`waistGap${count}`] = new Point(
|
||||
store.get("width") * gap,
|
||||
points.waistCF.y
|
||||
);
|
||||
points[`waistGap${count}`] = new Point(store.get('width') * gap, points.waistCF.y)
|
||||
points[`waistGap${count}Right`] = points[`waistGap${count}`].shift(
|
||||
0,
|
||||
store.get("waistIntake") * 0.1
|
||||
);
|
||||
store.get('waistIntake') * 0.1
|
||||
)
|
||||
points[`waistGap${count}Left`] = points[`waistGap${count}`].shift(
|
||||
180,
|
||||
store.get("waistIntake") * 0.1
|
||||
);
|
||||
store.get('waistIntake') * 0.1
|
||||
)
|
||||
points[`waistGap${count}RightCp1`] = points[`waistGap${count}Right`].shift(
|
||||
90,
|
||||
measurements.naturalWaistToUnderbust * 0.2
|
||||
);
|
||||
)
|
||||
points[`waistGap${count}LeftCp2`] = points[`waistGap${count}Left`].shift(
|
||||
90,
|
||||
measurements.naturalWaistToUnderbust * 0.2
|
||||
);
|
||||
)
|
||||
points[`waistGap${count}RightCp2`] = points[`waistGap${count}Right`].shift(
|
||||
-90,
|
||||
measurements.naturalWaistToHip * 0.2
|
||||
);
|
||||
)
|
||||
points[`waistGap${count}LeftCp1`] = points[`waistGap${count}Left`].shift(
|
||||
-90,
|
||||
measurements.naturalWaistToHip * 0.2
|
||||
);
|
||||
)
|
||||
|
||||
// Hips
|
||||
points[`hipsGap${count}`] = new Point(
|
||||
store.get("width") * gap,
|
||||
points.hipsCF.y
|
||||
);
|
||||
points[`hipsGap${count}`] = bottom
|
||||
.intersectsX(points[`waistGap${count}`].x)
|
||||
.pop();
|
||||
points[`hipsGap${count}Cp`] = points[
|
||||
`hipsGap${count}`
|
||||
].shiftFractionTowards(points[`waistGap${count}`], 0.2);
|
||||
points[`hipsGap${count}`] = new Point(store.get('width') * gap, points.hipsCF.y)
|
||||
points[`hipsGap${count}`] = bottom.intersectsX(points[`waistGap${count}`].x).pop()
|
||||
points[`hipsGap${count}Cp`] = points[`hipsGap${count}`].shiftFractionTowards(
|
||||
points[`waistGap${count}`],
|
||||
0.2
|
||||
)
|
||||
|
||||
count++;
|
||||
count++
|
||||
}
|
||||
// Paths
|
||||
paths.panel1 = bottom
|
||||
.split(points.hipsGap1)[0]
|
||||
.curve(points.hipsGap1Cp, points.waistGap1LeftCp1, points.waistGap1Left)
|
||||
.curve(
|
||||
points.waistGap1LeftCp2,
|
||||
points.underbustGap1LeftCp,
|
||||
points.underbustGap1Left
|
||||
)
|
||||
.curve(points.waistGap1LeftCp2, points.underbustGap1LeftCp, points.underbustGap1Left)
|
||||
.curve(points.frontRiseStartCp2, points.topCFCp1, points.topCF)
|
||||
.line(points.bottomCF)
|
||||
.close()
|
||||
.attr("class", "fabric");
|
||||
.attr('class', 'fabric')
|
||||
paths.panel2 = bottom
|
||||
.split(points.hipsGap2)[0]
|
||||
.split(points.hipsGap1)[1]
|
||||
.curve(points.hipsGap2Cp, points.waistGap2LeftCp1, points.waistGap2Left)
|
||||
.curve(
|
||||
points.waistGap2LeftCp2,
|
||||
points.underbustGap2LeftCp,
|
||||
points.underbustGap2Left
|
||||
)
|
||||
.curve(points.waistGap2LeftCp2, points.underbustGap2LeftCp, points.underbustGap2Left)
|
||||
.line(points.underbustGap1Right)
|
||||
.curve(
|
||||
points.underbustGap1RightCp,
|
||||
points.waistGap1RightCp1,
|
||||
points.waistGap1Right
|
||||
)
|
||||
.curve(points.underbustGap1RightCp, points.waistGap1RightCp1, points.waistGap1Right)
|
||||
.curve(points.waistGap1RightCp2, points.hipsGap1Cp, points.hipsGap1)
|
||||
.close()
|
||||
.attr("class", "fabric");
|
||||
.attr('class', 'fabric')
|
||||
let panel3 = new Path()
|
||||
.move(points.bottomCF)
|
||||
.curve(points.bottomCFCp2, points.hipRiseCp1, points.hipRise)
|
||||
.split(points.hipsGap2)[1];
|
||||
if (options.panels === 11) panel3 = panel3.split(points.hipsGap3)[0];
|
||||
.split(points.hipsGap2)[1]
|
||||
if (options.panels === 11) panel3 = panel3.split(points.hipsGap3)[0]
|
||||
paths.panel3 = panel3
|
||||
.curve(points.hipsGap3Cp, points.waistGap3LeftCp1, points.waistGap3Left)
|
||||
.curve(
|
||||
points.waistGap3LeftCp2,
|
||||
points.underbustGap3LeftCp,
|
||||
points.underbustGap3Left
|
||||
)
|
||||
.curve(points.waistGap3LeftCp2, points.underbustGap3LeftCp, points.underbustGap3Left)
|
||||
.line(points.underbustGap2Right)
|
||||
.curve(
|
||||
points.underbustGap2RightCp,
|
||||
points.waistGap2RightCp1,
|
||||
points.waistGap2Right
|
||||
)
|
||||
.curve(points.underbustGap2RightCp, points.waistGap2RightCp1, points.waistGap2Right)
|
||||
.curve(points.waistGap2RightCp2, points.hipsGap2Cp, points.hipsGap2)
|
||||
.close()
|
||||
.attr("class", "fabric");
|
||||
.attr('class', 'fabric')
|
||||
let topBack = new Path()
|
||||
.move(points.backRise)
|
||||
.curve(points.backRiseCp1, points.topSideCp1, points.topSide);
|
||||
points.underbustGap4Left = topBack
|
||||
.intersectsX(points.underbustGap4Left.x)
|
||||
.pop();
|
||||
.curve(points.backRiseCp1, points.topSideCp1, points.topSide)
|
||||
points.underbustGap4Left = topBack.intersectsX(points.underbustGap4Left.x).pop()
|
||||
paths.panel4 = new Path()
|
||||
.move(points.hipRise)
|
||||
.curve(points.hipRiseCp2, points.backDropCp1, points.backDrop)
|
||||
.split(points.hipsGap4)[0]
|
||||
.curve(points.hipsGap4Cp, points.waistGap4LeftCp1, points.waistGap4Left)
|
||||
.curve(
|
||||
points.waistGap4LeftCp2,
|
||||
points.underbustGap4LeftCp,
|
||||
points.underbustGap4Left
|
||||
)
|
||||
.join(topBack.split(points.underbustGap4Left)[1]);
|
||||
if (options.panels === 11) paths.panel4.line(points.underbustGap3Right);
|
||||
.curve(points.waistGap4LeftCp2, points.underbustGap4LeftCp, points.underbustGap4Left)
|
||||
.join(topBack.split(points.underbustGap4Left)[1])
|
||||
if (options.panels === 11) paths.panel4.line(points.underbustGap3Right)
|
||||
paths.panel4
|
||||
.curve(
|
||||
points.underbustGap3RightCp,
|
||||
points.waistGap3RightCp1,
|
||||
points.waistGap3Right
|
||||
)
|
||||
.curve(points.underbustGap3RightCp, points.waistGap3RightCp1, points.waistGap3Right)
|
||||
.curve(points.waistGap3RightCp2, points.hipsGap3Cp, points.hipsGap3)
|
||||
.close()
|
||||
.attr("class", "fabric");
|
||||
points.underbustGap4Right = topBack
|
||||
.intersectsX(points.underbustGap4Right.x)
|
||||
.pop();
|
||||
points.underbustGap5Left = topBack
|
||||
.intersectsX(points.underbustGap5Left.x)
|
||||
.pop();
|
||||
let top5 = topBack
|
||||
.split(points.underbustGap5Left)[1]
|
||||
.split(points.underbustGap4Right)[0];
|
||||
.attr('class', 'fabric')
|
||||
points.underbustGap4Right = topBack.intersectsX(points.underbustGap4Right.x).pop()
|
||||
points.underbustGap5Left = topBack.intersectsX(points.underbustGap5Left.x).pop()
|
||||
let top5 = topBack.split(points.underbustGap5Left)[1].split(points.underbustGap4Right)[0]
|
||||
paths.panel5 = bottom
|
||||
.split(points.hipsGap5)[0]
|
||||
.split(points.hipsGap4)[1]
|
||||
.curve(points.hipsGap5Cp, points.waistGap5LeftCp1, points.waistGap5Left)
|
||||
.curve(
|
||||
points.waistGap5LeftCp2,
|
||||
points.underbustGap5LeftCp,
|
||||
points.underbustGap5Left
|
||||
)
|
||||
.curve(points.waistGap5LeftCp2, points.underbustGap5LeftCp, points.underbustGap5Left)
|
||||
.curve(top5.ops[1].cp1, top5.ops[1].cp2, top5.ops[1].to)
|
||||
.curve(
|
||||
points.underbustGap4RightCp,
|
||||
points.waistGap4RightCp1,
|
||||
points.waistGap4Right
|
||||
)
|
||||
.curve(points.underbustGap4RightCp, points.waistGap4RightCp1, points.waistGap4Right)
|
||||
.curve(points.waistGap4RightCp2, points.hipsGap4Cp, points.hipsGap4)
|
||||
.close()
|
||||
.attr("class", "fabric");
|
||||
points.underbustGap5Right = topBack
|
||||
.intersectsX(points.underbustGap5Right.x)
|
||||
.pop();
|
||||
.attr('class', 'fabric')
|
||||
points.underbustGap5Right = topBack.intersectsX(points.underbustGap5Right.x).pop()
|
||||
paths.panel6 = bottom
|
||||
.split(points.hipsGap5)[1]
|
||||
.line(points.backRise)
|
||||
.join(topBack.split(points.underbustGap5Right)[0])
|
||||
.curve(
|
||||
points.underbustGap5RightCp,
|
||||
points.waistGap5RightCp1,
|
||||
points.waistGap5Right
|
||||
)
|
||||
.curve(points.underbustGap5RightCp, points.waistGap5RightCp1, points.waistGap5Right)
|
||||
.curve(points.waistGap5RightCp2, points.hipsGap5Cp, points.hipsGap5)
|
||||
.close()
|
||||
.attr("class", "fabric");
|
||||
.attr('class', 'fabric')
|
||||
|
||||
paths.outline.render = false;
|
||||
paths.outline.render = false
|
||||
|
||||
return part;
|
||||
return part
|
||||
}
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
export default [
|
||||
"Blockquote",
|
||||
"Draft",
|
||||
"DraftConfigurator",
|
||||
"Emblem",
|
||||
"Example",
|
||||
"Footer",
|
||||
"Icon",
|
||||
"Logo",
|
||||
"Navbar",
|
||||
"Ogol",
|
||||
"Robot",
|
||||
"Spinner",
|
||||
"SampleConfigurator",
|
||||
"withGist",
|
||||
"withLanguage",
|
||||
"withStorage",
|
||||
"Workbench"
|
||||
];
|
||||
'Blockquote',
|
||||
'Draft',
|
||||
'DraftConfigurator',
|
||||
'Emblem',
|
||||
'Example',
|
||||
'Footer',
|
||||
'Icon',
|
||||
'Logo',
|
||||
'Navbar',
|
||||
'Ogol',
|
||||
'Robot',
|
||||
'Spinner',
|
||||
'SampleConfigurator',
|
||||
'withGist',
|
||||
'withLanguage',
|
||||
'withStorage',
|
||||
'Workbench'
|
||||
]
|
||||
|
|
|
@ -1,99 +1,99 @@
|
|||
function Attributes() {
|
||||
this.list = {};
|
||||
this.list = {}
|
||||
}
|
||||
|
||||
/** Adds an attribute */
|
||||
Attributes.prototype.add = function(name, value) {
|
||||
if (typeof this.list[name] === "undefined") {
|
||||
this.list[name] = [];
|
||||
if (typeof this.list[name] === 'undefined') {
|
||||
this.list[name] = []
|
||||
}
|
||||
this.list[name].push(value);
|
||||
this.list[name].push(value)
|
||||
|
||||
return this;
|
||||
};
|
||||
return this
|
||||
}
|
||||
|
||||
/** Sets an attribute, overwriting existing value */
|
||||
Attributes.prototype.set = function(name, value) {
|
||||
this.list[name] = [value];
|
||||
this.list[name] = [value]
|
||||
|
||||
return this;
|
||||
};
|
||||
return this
|
||||
}
|
||||
|
||||
/** Removes an attribute */
|
||||
Attributes.prototype.remove = function(name) {
|
||||
delete this.list[name];
|
||||
delete this.list[name]
|
||||
|
||||
return this;
|
||||
};
|
||||
return this
|
||||
}
|
||||
|
||||
/** Retrieves an attribute */
|
||||
Attributes.prototype.get = function(name) {
|
||||
if (typeof this.list[name] === "undefined") return false;
|
||||
else return this.list[name].join(" ");
|
||||
};
|
||||
if (typeof this.list[name] === 'undefined') return false
|
||||
else return this.list[name].join(' ')
|
||||
}
|
||||
|
||||
/** Retrieves an attribute as array*/
|
||||
Attributes.prototype.getAsArray = function(name) {
|
||||
if (typeof this.list[name] === "undefined") return false;
|
||||
else return this.list[name];
|
||||
};
|
||||
if (typeof this.list[name] === 'undefined') return false
|
||||
else return this.list[name]
|
||||
}
|
||||
|
||||
/** Returns SVG code for attributes */
|
||||
Attributes.prototype.render = function() {
|
||||
let svg = "";
|
||||
let svg = ''
|
||||
for (let key in this.list) {
|
||||
svg += ` ${key}="${this.list[key].join(" ")}"`;
|
||||
svg += ` ${key}="${this.list[key].join(' ')}"`
|
||||
}
|
||||
|
||||
return svg;
|
||||
};
|
||||
return svg
|
||||
}
|
||||
|
||||
/** Returns CSS code for attributes */
|
||||
Attributes.prototype.renderAsCss = function() {
|
||||
let css = "";
|
||||
let css = ''
|
||||
for (let key in this.list) {
|
||||
css += ` ${key}:${this.list[key].join(" ")};`;
|
||||
css += ` ${key}:${this.list[key].join(' ')};`
|
||||
}
|
||||
|
||||
return css;
|
||||
};
|
||||
return css
|
||||
}
|
||||
|
||||
/** Returns SVG code for attributes with a fiven prefix
|
||||
* typically used for data-text*/
|
||||
Attributes.prototype.renderIfPrefixIs = function(prefix = "") {
|
||||
let svg = "";
|
||||
let prefixLen = prefix.length;
|
||||
Attributes.prototype.renderIfPrefixIs = function(prefix = '') {
|
||||
let svg = ''
|
||||
let prefixLen = prefix.length
|
||||
for (let key in this.list) {
|
||||
if (key.substr(0, prefixLen) === prefix) {
|
||||
svg += ` ${key.substr(prefixLen)}="${this.list[key].join(" ")}"`;
|
||||
svg += ` ${key.substr(prefixLen)}="${this.list[key].join(' ')}"`
|
||||
}
|
||||
}
|
||||
|
||||
return svg;
|
||||
};
|
||||
return svg
|
||||
}
|
||||
|
||||
/** Returns a props object for attributes with a fiven prefix
|
||||
* typically used for data-text*/
|
||||
Attributes.prototype.asPropsIfPrefixIs = function(prefix = "") {
|
||||
let props = {};
|
||||
let prefixLen = prefix.length;
|
||||
Attributes.prototype.asPropsIfPrefixIs = function(prefix = '') {
|
||||
let props = {}
|
||||
let prefixLen = prefix.length
|
||||
for (let key in this.list) {
|
||||
if (key.substr(0, prefixLen) === prefix) {
|
||||
let propKey = key.substr(prefixLen);
|
||||
if (propKey === "class") propKey = "className";
|
||||
props[propKey] = this.get(key);
|
||||
let propKey = key.substr(prefixLen)
|
||||
if (propKey === 'class') propKey = 'className'
|
||||
props[propKey] = this.get(key)
|
||||
}
|
||||
}
|
||||
|
||||
return props;
|
||||
};
|
||||
return props
|
||||
}
|
||||
|
||||
/** Returns a deep copy of this */
|
||||
Attributes.prototype.clone = function() {
|
||||
let clone = new Attributes();
|
||||
clone.list = JSON.parse(JSON.stringify(this.list));
|
||||
let clone = new Attributes()
|
||||
clone.list = JSON.parse(JSON.stringify(this.list))
|
||||
|
||||
return clone;
|
||||
};
|
||||
return clone
|
||||
}
|
||||
|
||||
export default Attributes;
|
||||
export default Attributes
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
import Pattern from "./pattern";
|
||||
import Pattern from './pattern'
|
||||
|
||||
export default function Design(config, plugins = false) {
|
||||
const pattern = function(settings) {
|
||||
Pattern.call(this, config);
|
||||
if (Array.isArray(plugins)) for (let plugin of plugins) this.use(plugin);
|
||||
else if (plugins) this.use(plugins);
|
||||
this.apply(settings);
|
||||
Pattern.call(this, config)
|
||||
if (Array.isArray(plugins)) for (let plugin of plugins) this.use(plugin)
|
||||
else if (plugins) this.use(plugins)
|
||||
this.apply(settings)
|
||||
|
||||
return this;
|
||||
};
|
||||
return this
|
||||
}
|
||||
|
||||
// Set up inheritance
|
||||
pattern.prototype = Object.create(Pattern.prototype);
|
||||
pattern.prototype.constructor = pattern;
|
||||
pattern.prototype = Object.create(Pattern.prototype)
|
||||
pattern.prototype.constructor = pattern
|
||||
|
||||
return pattern;
|
||||
return pattern
|
||||
}
|
||||
|
|
|
@ -8,5 +8,5 @@ export default function Hooks() {
|
|||
postRender: [],
|
||||
insertText: [],
|
||||
debug: []
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import Design from "./design";
|
||||
import Pattern from "./pattern";
|
||||
import Point from "./point";
|
||||
import Path from "./path";
|
||||
import Snippet from "./snippet";
|
||||
import * as utils from "./utils";
|
||||
import { version } from "../package.json";
|
||||
import Design from './design'
|
||||
import Pattern from './pattern'
|
||||
import Point from './point'
|
||||
import Path from './path'
|
||||
import Snippet from './snippet'
|
||||
import * as utils from './utils'
|
||||
import { version } from '../package.json'
|
||||
|
||||
export default {
|
||||
version,
|
||||
|
@ -16,4 +16,4 @@ export default {
|
|||
utils,
|
||||
patterns: {},
|
||||
plugins: {}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
function Option(config) {
|
||||
this.id = config.id;
|
||||
this.config = config;
|
||||
this.val = config.val;
|
||||
this.id = config.id
|
||||
this.config = config
|
||||
this.val = config.val
|
||||
|
||||
return this;
|
||||
return this
|
||||
}
|
||||
|
||||
export default Option;
|
||||
export default Option
|
||||
|
|
|
@ -1,202 +1,196 @@
|
|||
import * as utils from "./utils";
|
||||
import Point from "./point";
|
||||
import Path from "./path";
|
||||
import Snippet from "./snippet";
|
||||
import Attributes from "./attributes";
|
||||
import Hooks from "./hooks";
|
||||
import * as utils from './utils'
|
||||
import Point from './point'
|
||||
import Path from './path'
|
||||
import Snippet from './snippet'
|
||||
import Attributes from './attributes'
|
||||
import Hooks from './hooks'
|
||||
|
||||
function Part() {
|
||||
this.attributes = new Attributes();
|
||||
this.points = {};
|
||||
this.paths = {};
|
||||
this.snippets = {};
|
||||
this.freeId = 0;
|
||||
this.topLeft = false;
|
||||
this.bottomRight = false;
|
||||
this.width = false;
|
||||
this.height = false;
|
||||
this.render = true;
|
||||
this.utils = utils;
|
||||
this.attributes = new Attributes()
|
||||
this.points = {}
|
||||
this.paths = {}
|
||||
this.snippets = {}
|
||||
this.freeId = 0
|
||||
this.topLeft = false
|
||||
this.bottomRight = false
|
||||
this.width = false
|
||||
this.height = false
|
||||
this.render = true
|
||||
this.utils = utils
|
||||
|
||||
// Constructors so macros can create objects
|
||||
this.Point = Point;
|
||||
this.Path = Path;
|
||||
this.Snippet = Snippet;
|
||||
this.Point = Point
|
||||
this.Path = Path
|
||||
this.Snippet = Snippet
|
||||
|
||||
this.hooks = new Hooks(); // Hooks container
|
||||
this.hooks = new Hooks() // Hooks container
|
||||
|
||||
return this;
|
||||
return this
|
||||
}
|
||||
|
||||
Part.prototype.macroClosure = function(args) {
|
||||
let self = this;
|
||||
let self = this
|
||||
let method = function(key, args) {
|
||||
let macro = utils.macroName(key);
|
||||
if (typeof self[macro] === "function") {
|
||||
self[macro](args);
|
||||
let macro = utils.macroName(key)
|
||||
if (typeof self[macro] === 'function') {
|
||||
self[macro](args)
|
||||
} else {
|
||||
self.debug({
|
||||
type: "warning",
|
||||
label: "🚨 Macro not found",
|
||||
type: 'warning',
|
||||
label: '🚨 Macro not found',
|
||||
msg: `Macro ${key} is not registered`
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return method;
|
||||
};
|
||||
return method
|
||||
}
|
||||
|
||||
Part.prototype.debugClosure = function() {
|
||||
let self = this;
|
||||
let self = this
|
||||
let method = function(data) {
|
||||
self.debug(data);
|
||||
};
|
||||
self.debug(data)
|
||||
}
|
||||
|
||||
return method;
|
||||
};
|
||||
return method
|
||||
}
|
||||
|
||||
Part.prototype.runHooks = function(hookName, data = false) {
|
||||
if (data === false) data = this;
|
||||
let hooks = this.hooks[hookName];
|
||||
if (data === false) data = this
|
||||
let hooks = this.hooks[hookName]
|
||||
if (hooks && hooks.length > 0) {
|
||||
for (let hook of hooks) {
|
||||
hook.method(data, hook.data);
|
||||
hook.method(data, hook.data)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/** Debug method */
|
||||
Part.prototype.debug = function(data) {
|
||||
this.runHooks("debug", data);
|
||||
};
|
||||
this.runHooks('debug', data)
|
||||
}
|
||||
|
||||
/** Returns an unused ID */
|
||||
Part.prototype.getId = function() {
|
||||
this.freeId += 1;
|
||||
this.freeId += 1
|
||||
|
||||
return "" + this.freeId;
|
||||
};
|
||||
return '' + this.freeId
|
||||
}
|
||||
|
||||
/** Returns a value formatted for units provided in settings */
|
||||
Part.prototype.unitsClosure = function(value) {
|
||||
let self = this;
|
||||
let self = this
|
||||
let method = function(value) {
|
||||
return utils.units(value, self.context.settings.units);
|
||||
};
|
||||
return utils.units(value, self.context.settings.units)
|
||||
}
|
||||
|
||||
return method;
|
||||
};
|
||||
return method
|
||||
}
|
||||
|
||||
/** Calculates the part's bounding box and sets it */
|
||||
Part.prototype.boundary = function() {
|
||||
if (this.topLeft) return this; // Cached
|
||||
if (this.topLeft) return this // Cached
|
||||
|
||||
let topLeft = new Point(Infinity, Infinity);
|
||||
let bottomRight = new Point(-Infinity, -Infinity);
|
||||
let topLeft = new Point(Infinity, Infinity)
|
||||
let bottomRight = new Point(-Infinity, -Infinity)
|
||||
for (let key in this.paths) {
|
||||
let path = this.paths[key].boundary();
|
||||
let path = this.paths[key].boundary()
|
||||
if (path.render) {
|
||||
if (path.topLeft.x < topLeft.x) topLeft.x = path.topLeft.x;
|
||||
if (path.topLeft.y < topLeft.y) topLeft.y = path.topLeft.y;
|
||||
if (path.bottomRight.x > bottomRight.x)
|
||||
bottomRight.x = path.bottomRight.x;
|
||||
if (path.bottomRight.y > bottomRight.y)
|
||||
bottomRight.y = path.bottomRight.y;
|
||||
if (path.topLeft.x < topLeft.x) topLeft.x = path.topLeft.x
|
||||
if (path.topLeft.y < topLeft.y) topLeft.y = path.topLeft.y
|
||||
if (path.bottomRight.x > bottomRight.x) bottomRight.x = path.bottomRight.x
|
||||
if (path.bottomRight.y > bottomRight.y) bottomRight.y = path.bottomRight.y
|
||||
}
|
||||
}
|
||||
for (let key in this.points) {
|
||||
let point = this.points[key];
|
||||
let radius = point.attributes.get("data-circle");
|
||||
let point = this.points[key]
|
||||
let radius = point.attributes.get('data-circle')
|
||||
if (radius) {
|
||||
radius = parseFloat(radius);
|
||||
if (point.x - radius < topLeft.x) topLeft.x = point.x - radius;
|
||||
if (point.y - radius < topLeft.y) topLeft.y = point.y - radius;
|
||||
if (point.x + radius > bottomRight.x) bottomRight.x = point.x + radius;
|
||||
if (point.y + radius > bottomRight.y) bottomRight.y = point.y + radius;
|
||||
radius = parseFloat(radius)
|
||||
if (point.x - radius < topLeft.x) topLeft.x = point.x - radius
|
||||
if (point.y - radius < topLeft.y) topLeft.y = point.y - radius
|
||||
if (point.x + radius > bottomRight.x) bottomRight.x = point.x + radius
|
||||
if (point.y + radius > bottomRight.y) bottomRight.y = point.y + radius
|
||||
}
|
||||
}
|
||||
// Fix infinity if part has no paths
|
||||
if (topLeft.x === Infinity) topLeft.x = 0;
|
||||
if (topLeft.y === Infinity) topLeft.y = 0;
|
||||
if (bottomRight.x === -Infinity) bottomRight.x = 0;
|
||||
if (bottomRight.y === -Infinity) bottomRight.y = 0;
|
||||
if (topLeft.x === Infinity) topLeft.x = 0
|
||||
if (topLeft.y === Infinity) topLeft.y = 0
|
||||
if (bottomRight.x === -Infinity) bottomRight.x = 0
|
||||
if (bottomRight.y === -Infinity) bottomRight.y = 0
|
||||
// Add margin
|
||||
let margin = this.context.settings.margin;
|
||||
if (this.context.settings.paperless && margin < 10) margin = 10;
|
||||
this.topLeft = new Point(topLeft.x - margin, topLeft.y - margin);
|
||||
this.bottomRight = new Point(bottomRight.x + margin, bottomRight.y + margin);
|
||||
this.width = this.bottomRight.x - this.topLeft.x;
|
||||
this.height = this.bottomRight.y - this.topLeft.y;
|
||||
let margin = this.context.settings.margin
|
||||
if (this.context.settings.paperless && margin < 10) margin = 10
|
||||
this.topLeft = new Point(topLeft.x - margin, topLeft.y - margin)
|
||||
this.bottomRight = new Point(bottomRight.x + margin, bottomRight.y + margin)
|
||||
this.width = this.bottomRight.x - this.topLeft.x
|
||||
this.height = this.bottomRight.y - this.topLeft.y
|
||||
|
||||
return this;
|
||||
};
|
||||
return this
|
||||
}
|
||||
|
||||
/** Stacks part so that its top left corner is in (0,0) */
|
||||
Part.prototype.stack = function() {
|
||||
if (this.topLeft !== false) return this;
|
||||
else this.boundary();
|
||||
if (this.topLeft.x == 0 && this.topLeft.y == 0) return this;
|
||||
else
|
||||
this.attr(
|
||||
"transform",
|
||||
`translate(${this.topLeft.x * -1}, ${this.topLeft.y * -1})`
|
||||
);
|
||||
if (this.topLeft !== false) return this
|
||||
else this.boundary()
|
||||
if (this.topLeft.x == 0 && this.topLeft.y == 0) return this
|
||||
else this.attr('transform', `translate(${this.topLeft.x * -1}, ${this.topLeft.y * -1})`)
|
||||
|
||||
return this;
|
||||
};
|
||||
return this
|
||||
}
|
||||
|
||||
/** Adds an attribute. This is here to make this call chainable in assignment */
|
||||
Part.prototype.attr = function(name, value, overwrite = false) {
|
||||
if (overwrite) this.attributes.set(name, value);
|
||||
else this.attributes.add(name, value);
|
||||
if (overwrite) this.attributes.set(name, value)
|
||||
else this.attributes.add(name, value)
|
||||
|
||||
return this;
|
||||
};
|
||||
return this
|
||||
}
|
||||
|
||||
/** Copies point/path/snippet data from part orig into this */
|
||||
Part.prototype.inject = function(orig) {
|
||||
const findBasePoint = p => {
|
||||
for (let i in orig.points) {
|
||||
if (orig.points[i] === p) return i;
|
||||
if (orig.points[i] === p) return i
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
return false
|
||||
}
|
||||
|
||||
for (let i in orig.points) this.points[i] = orig.points[i].clone();
|
||||
for (let i in orig.points) this.points[i] = orig.points[i].clone()
|
||||
for (let i in orig.paths) {
|
||||
this.paths[i] = orig.paths[i].clone();
|
||||
this.paths[i] = orig.paths[i].clone()
|
||||
// Keep link between points and path ops where possible
|
||||
for (let j in orig.paths[i].ops) {
|
||||
let op = orig.paths[i].ops[j];
|
||||
if (op.type !== "close") {
|
||||
let toPoint = findBasePoint(op.to);
|
||||
if (toPoint) this.paths[i].ops[j].to = this.points[toPoint];
|
||||
let op = orig.paths[i].ops[j]
|
||||
if (op.type !== 'close') {
|
||||
let toPoint = findBasePoint(op.to)
|
||||
if (toPoint) this.paths[i].ops[j].to = this.points[toPoint]
|
||||
}
|
||||
if (op.type === "curve") {
|
||||
let cp1Point = findBasePoint(op.cp1);
|
||||
if (cp1Point) this.paths[i].ops[j].cp1 = this.points[cp1Point];
|
||||
let cp2Point = findBasePoint(op.cp2);
|
||||
if (cp2Point) this.paths[i].ops[j].cp2 = this.points[cp2Point];
|
||||
if (op.type === 'curve') {
|
||||
let cp1Point = findBasePoint(op.cp1)
|
||||
if (cp1Point) this.paths[i].ops[j].cp1 = this.points[cp1Point]
|
||||
let cp2Point = findBasePoint(op.cp2)
|
||||
if (cp2Point) this.paths[i].ops[j].cp2 = this.points[cp2Point]
|
||||
}
|
||||
}
|
||||
}
|
||||
for (let i in orig.snippets) {
|
||||
this.snippets[i] = orig.snippets[i].clone();
|
||||
this.snippets[i] = orig.snippets[i].clone()
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
return this
|
||||
}
|
||||
|
||||
Part.prototype.units = function(input) {
|
||||
return utils.units(input, this.context.settings.units);
|
||||
};
|
||||
return utils.units(input, this.context.settings.units)
|
||||
}
|
||||
|
||||
/** Returns an object with shorthand access for pattern design */
|
||||
Part.prototype.shorthand = function() {
|
||||
let complete = this.context.settings.complete ? true : false;
|
||||
let paperless = this.context.settings.paperless === true ? true : false;
|
||||
let sa = this.context.settings.complete ? this.context.settings.sa || 0 : 0;
|
||||
let complete = this.context.settings.complete ? true : false
|
||||
let paperless = this.context.settings.paperless === true ? true : false
|
||||
let sa = this.context.settings.complete ? this.context.settings.sa || 0 : 0
|
||||
return {
|
||||
sa,
|
||||
measurements: this.context.settings.measurements || {},
|
||||
|
@ -214,7 +208,7 @@ Part.prototype.shorthand = function() {
|
|||
complete,
|
||||
paperless,
|
||||
debug: this.debugClosure()
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export default Part;
|
||||
export default Part
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,72 +1,63 @@
|
|||
import { macroName, round, sampleStyle, capitalize } from "./utils";
|
||||
import Part from "./part";
|
||||
import Point from "./point";
|
||||
import Path from "./path";
|
||||
import Snippet from "./snippet";
|
||||
import Svg from "./svg";
|
||||
import pack from "bin-pack";
|
||||
import Store from "./store";
|
||||
import Hooks from "./hooks";
|
||||
import Attributes from "./attributes";
|
||||
import { macroName, round, sampleStyle, capitalize } from './utils'
|
||||
import Part from './part'
|
||||
import Point from './point'
|
||||
import Path from './path'
|
||||
import Snippet from './snippet'
|
||||
import Svg from './svg'
|
||||
import pack from 'bin-pack'
|
||||
import Store from './store'
|
||||
import Hooks from './hooks'
|
||||
import Attributes from './attributes'
|
||||
|
||||
export default function Pattern(config = { options: {} }) {
|
||||
this.config = config; // Pattern configuration
|
||||
this.width = 0; // Will be set after render
|
||||
this.height = 0; // Will be set after render
|
||||
this.is = ""; // Will be set when drafting/sampling
|
||||
this.config = config // Pattern configuration
|
||||
this.width = 0 // Will be set after render
|
||||
this.height = 0 // Will be set after render
|
||||
this.is = '' // Will be set when drafting/sampling
|
||||
|
||||
this.store = new Store(); // Store for sharing data across parts
|
||||
this.parts = {}; // Parts container
|
||||
this.hooks = new Hooks(); // Hooks container
|
||||
this.Point = Point; // Point constructor
|
||||
this.Path = Path; // Path constructor
|
||||
this.Snippet = Snippet; // Snippet constructor
|
||||
this.Attributes = Attributes; // Attributes constructor
|
||||
this.store = new Store() // Store for sharing data across parts
|
||||
this.parts = {} // Parts container
|
||||
this.hooks = new Hooks() // Hooks container
|
||||
this.Point = Point // Point constructor
|
||||
this.Path = Path // Path constructor
|
||||
this.Snippet = Snippet // Snippet constructor
|
||||
this.Attributes = Attributes // Attributes constructor
|
||||
|
||||
// Default settings
|
||||
this.settings = {
|
||||
complete: true,
|
||||
idPrefix: "fs-",
|
||||
locale: "en",
|
||||
units: "metric",
|
||||
idPrefix: 'fs-',
|
||||
locale: 'en',
|
||||
units: 'metric',
|
||||
margin: 2,
|
||||
layout: true,
|
||||
options: {}
|
||||
};
|
||||
}
|
||||
|
||||
if (typeof this.config.dependencies === "undefined")
|
||||
this.config.dependencies = {};
|
||||
if (typeof this.config.inject === "undefined") this.config.inject = {};
|
||||
if (typeof this.config.hide === "undefined") this.config.hide = [];
|
||||
this.config.resolvedDependencies = this.resolveDependencies(
|
||||
this.config.dependencies
|
||||
);
|
||||
this.config.draftOrder = this.draftOrder(this.config.resolvedDependencies);
|
||||
if (typeof this.config.dependencies === 'undefined') this.config.dependencies = {}
|
||||
if (typeof this.config.inject === 'undefined') this.config.inject = {}
|
||||
if (typeof this.config.hide === 'undefined') this.config.hide = []
|
||||
this.config.resolvedDependencies = this.resolveDependencies(this.config.dependencies)
|
||||
this.config.draftOrder = this.draftOrder(this.config.resolvedDependencies)
|
||||
|
||||
// Convert options
|
||||
for (let i in config.options) {
|
||||
let option = config.options[i];
|
||||
if (typeof option === "object") {
|
||||
if (typeof option.pct !== "undefined")
|
||||
this.settings.options[i] = option.pct / 100;
|
||||
else if (typeof option.mm !== "undefined")
|
||||
this.settings.options[i] = option.mm;
|
||||
else if (typeof option.deg !== "undefined")
|
||||
this.settings.options[i] = option.deg;
|
||||
else if (typeof option.count !== "undefined")
|
||||
this.settings.options[i] = option.count;
|
||||
else if (typeof option.bool !== "undefined")
|
||||
this.settings.options[i] = option.bool;
|
||||
else if (typeof option.dflt !== "undefined")
|
||||
this.settings.options[i] = option.dflt;
|
||||
else throw new Error("Unknown option type: " + JSON.stringify(option));
|
||||
let option = config.options[i]
|
||||
if (typeof option === 'object') {
|
||||
if (typeof option.pct !== 'undefined') this.settings.options[i] = option.pct / 100
|
||||
else if (typeof option.mm !== 'undefined') this.settings.options[i] = option.mm
|
||||
else if (typeof option.deg !== 'undefined') this.settings.options[i] = option.deg
|
||||
else if (typeof option.count !== 'undefined') this.settings.options[i] = option.count
|
||||
else if (typeof option.bool !== 'undefined') this.settings.options[i] = option.bool
|
||||
else if (typeof option.dflt !== 'undefined') this.settings.options[i] = option.dflt
|
||||
else throw new Error('Unknown option type: ' + JSON.stringify(option))
|
||||
} else {
|
||||
this.settings.options[i] = option;
|
||||
this.settings.options[i] = option
|
||||
}
|
||||
}
|
||||
|
||||
// Macros
|
||||
this.macros = {};
|
||||
this.macros = {}
|
||||
|
||||
// Context object to add to Part closure
|
||||
const context = {
|
||||
|
@ -75,406 +66,385 @@ export default function Pattern(config = { options: {} }) {
|
|||
settings: this.settings,
|
||||
store: this.store,
|
||||
macros: this.macros
|
||||
};
|
||||
}
|
||||
|
||||
// Part closure
|
||||
this.Part = function() {
|
||||
let part = new Part();
|
||||
part.context = context;
|
||||
let part = new Part()
|
||||
part.context = context
|
||||
for (let macro in context.macros) {
|
||||
part[macroName(macro)] = context.macros[macro];
|
||||
part[macroName(macro)] = context.macros[macro]
|
||||
}
|
||||
return part
|
||||
}
|
||||
return part;
|
||||
};
|
||||
}
|
||||
|
||||
// Merges settings object with this.settings
|
||||
Pattern.prototype.apply = function(settings) {
|
||||
if (typeof settings !== "object") return this;
|
||||
if (typeof settings !== 'object') return this
|
||||
for (let key of Object.keys(settings)) {
|
||||
if (Array.isArray(settings[key])) {
|
||||
if (Array.isArray(this.settings[key])) {
|
||||
for (let entry of settings[key]) this.settings[key].push(entry);
|
||||
} else this.settings[key] = settings[key];
|
||||
} else if (typeof settings[key] === "object") {
|
||||
for (let entry of settings[key]) this.settings[key].push(entry)
|
||||
} else this.settings[key] = settings[key]
|
||||
} else if (typeof settings[key] === 'object') {
|
||||
this.settings[key] = {
|
||||
...this.settings[key],
|
||||
...settings[key]
|
||||
};
|
||||
} else this.settings[key] = settings[key];
|
||||
}
|
||||
} else this.settings[key] = settings[key]
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
return this
|
||||
}
|
||||
|
||||
Pattern.prototype.runHooks = function(hookName, data = false) {
|
||||
if (data === false) data = this;
|
||||
let hooks = this.hooks[hookName];
|
||||
if (data === false) data = this
|
||||
let hooks = this.hooks[hookName]
|
||||
if (hooks.length > 0) {
|
||||
for (let hook of hooks) {
|
||||
hook.method(data, hook.data);
|
||||
hook.method(data, hook.data)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* The default draft method with pre- and postDraft hooks
|
||||
*/
|
||||
Pattern.prototype.draft = function() {
|
||||
if (this.is !== "sample") this.is = "draft";
|
||||
this.runHooks("preDraft");
|
||||
if (this.is !== 'sample') this.is = 'draft'
|
||||
this.runHooks('preDraft')
|
||||
for (let partName of this.config.draftOrder) {
|
||||
this.parts[partName] = new this.Part();
|
||||
if (typeof this.config.inject[partName] === "string") {
|
||||
this.parts[partName].inject(this.parts[this.config.inject[partName]]);
|
||||
this.parts[partName] = new this.Part()
|
||||
if (typeof this.config.inject[partName] === 'string') {
|
||||
this.parts[partName].inject(this.parts[this.config.inject[partName]])
|
||||
}
|
||||
if (this.needs(partName)) {
|
||||
let method = "draft" + capitalize(partName);
|
||||
if (typeof this[method] !== "function")
|
||||
let method = 'draft' + capitalize(partName)
|
||||
if (typeof this[method] !== 'function')
|
||||
throw new Error('Method "' + method + '" on pattern object is not callable')
|
||||
this.parts[partName] = this[method](this.parts[partName])
|
||||
if (typeof this.parts[partName] === 'undefined')
|
||||
throw new Error(
|
||||
'Method "' + method + '" on pattern object is not callable'
|
||||
);
|
||||
this.parts[partName] = this[method](this.parts[partName]);
|
||||
if (typeof this.parts[partName] === "undefined")
|
||||
throw new Error(
|
||||
"Result of " +
|
||||
method +
|
||||
"() was undefined. Did you forget to return the Part object?"
|
||||
);
|
||||
'Result of ' + method + '() was undefined. Did you forget to return the Part object?'
|
||||
)
|
||||
this.parts[partName].render =
|
||||
this.parts[partName].render === false ? false : this.wants(partName);
|
||||
this.parts[partName].render === false ? false : this.wants(partName)
|
||||
} else {
|
||||
this.parts[partName].render = false;
|
||||
this.parts[partName].render = false
|
||||
}
|
||||
}
|
||||
this.runHooks("postDraft");
|
||||
this.runHooks('postDraft')
|
||||
|
||||
return this;
|
||||
};
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles pattern sampling
|
||||
*/
|
||||
Pattern.prototype.sample = function() {
|
||||
if (this.settings.sample.type === "option") {
|
||||
return this.sampleOption(this.settings.sample.option);
|
||||
} else if (this.settings.sample.type === "measurement") {
|
||||
return this.sampleMeasurement(this.settings.sample.measurement);
|
||||
} else if (this.settings.sample.type === "models") {
|
||||
return this.sampleModels(
|
||||
this.settings.sample.models,
|
||||
this.settings.sample.focus || false
|
||||
);
|
||||
if (this.settings.sample.type === 'option') {
|
||||
return this.sampleOption(this.settings.sample.option)
|
||||
} else if (this.settings.sample.type === 'measurement') {
|
||||
return this.sampleMeasurement(this.settings.sample.measurement)
|
||||
} else if (this.settings.sample.type === 'models') {
|
||||
return this.sampleModels(this.settings.sample.models, this.settings.sample.focus || false)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Pattern.prototype.sampleParts = function() {
|
||||
let parts = {};
|
||||
this.settings.complete = false;
|
||||
this.settings.paperless = false;
|
||||
this.draft();
|
||||
let parts = {}
|
||||
this.settings.complete = false
|
||||
this.settings.paperless = false
|
||||
this.draft()
|
||||
for (let i in this.parts) {
|
||||
parts[i] = new this.Part();
|
||||
parts[i].render = this.parts[i].render;
|
||||
parts[i] = new this.Part()
|
||||
parts[i].render = this.parts[i].render
|
||||
}
|
||||
return parts;
|
||||
};
|
||||
return parts
|
||||
}
|
||||
|
||||
Pattern.prototype.sampleRun = function(
|
||||
parts,
|
||||
anchors,
|
||||
run,
|
||||
runs,
|
||||
extraClass = false
|
||||
) {
|
||||
this.draft();
|
||||
Pattern.prototype.sampleRun = function(parts, anchors, run, runs, extraClass = false) {
|
||||
this.draft()
|
||||
for (let i in this.parts) {
|
||||
let anchor = false;
|
||||
let dx = 0;
|
||||
let dy = 0;
|
||||
let anchor = false
|
||||
let dx = 0
|
||||
let dy = 0
|
||||
if (this.parts[i].points.anchor) {
|
||||
if (typeof anchors[i] === "undefined")
|
||||
anchors[i] = this.parts[i].points.anchor;
|
||||
if (typeof anchors[i] === 'undefined') anchors[i] = this.parts[i].points.anchor
|
||||
else {
|
||||
if (!anchors[i].sitsOn(this.parts[i].points.anchor)) {
|
||||
dx = this.parts[i].points.anchor.dx(anchors[i]);
|
||||
dy = this.parts[i].points.anchor.dy(anchors[i]);
|
||||
dx = this.parts[i].points.anchor.dx(anchors[i])
|
||||
dy = this.parts[i].points.anchor.dy(anchors[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
for (let j in this.parts[i].paths) {
|
||||
parts[i].paths[j + "_" + run] = this.parts[i].paths[j]
|
||||
parts[i].paths[j + '_' + run] = this.parts[i].paths[j]
|
||||
.clone()
|
||||
.attr("style", sampleStyle(run, runs));
|
||||
.attr('style', sampleStyle(run, runs))
|
||||
if (this.parts[i].points.anchor)
|
||||
parts[i].paths[j + "_" + run] = parts[i].paths[j + "_" + run].translate(
|
||||
dx,
|
||||
dy
|
||||
);
|
||||
if (extraClass !== false)
|
||||
parts[i].paths[j + "_" + run].attributes.add("class", extraClass);
|
||||
parts[i].paths[j + '_' + run] = parts[i].paths[j + '_' + run].translate(dx, dy)
|
||||
if (extraClass !== false) parts[i].paths[j + '_' + run].attributes.add('class', extraClass)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles option sampling
|
||||
*/
|
||||
Pattern.prototype.sampleOption = function(optionName) {
|
||||
this.is = "sample";
|
||||
this.runHooks("preSample");
|
||||
let step, val;
|
||||
let factor = 1;
|
||||
let anchors = {};
|
||||
let parts = this.sampleParts();
|
||||
let option = this.config.options[optionName];
|
||||
if (typeof option.list === "object") {
|
||||
return this.sampleListOption(optionName);
|
||||
this.is = 'sample'
|
||||
this.runHooks('preSample')
|
||||
let step, val
|
||||
let factor = 1
|
||||
let anchors = {}
|
||||
let parts = this.sampleParts()
|
||||
let option = this.config.options[optionName]
|
||||
if (typeof option.list === 'object') {
|
||||
return this.sampleListOption(optionName)
|
||||
}
|
||||
if (typeof option.min === "undefined" || typeof option.max === "undefined") {
|
||||
let min = option * 0.9;
|
||||
let max = option * 1.1;
|
||||
option = { min, max };
|
||||
if (typeof option.min === 'undefined' || typeof option.max === 'undefined') {
|
||||
let min = option * 0.9
|
||||
let max = option * 1.1
|
||||
option = { min, max }
|
||||
}
|
||||
if (typeof option.pct !== "undefined") factor = 100;
|
||||
val = option.min / factor;
|
||||
step = (option.max / factor - val) / 9;
|
||||
if (typeof option.pct !== 'undefined') factor = 100
|
||||
val = option.min / factor
|
||||
step = (option.max / factor - val) / 9
|
||||
for (let run = 1; run < 11; run++) {
|
||||
this.settings.options[optionName] = val;
|
||||
this.settings.options[optionName] = val
|
||||
this.debug({
|
||||
type: "info",
|
||||
label: "🏃🏿♀️ Sample run",
|
||||
type: 'info',
|
||||
label: '🏃🏿♀️ Sample run',
|
||||
msg: `Sampling option ${optionName} with value ${round(val)}`
|
||||
});
|
||||
this.sampleRun(parts, anchors, run, 10);
|
||||
val += step;
|
||||
})
|
||||
this.sampleRun(parts, anchors, run, 10)
|
||||
val += step
|
||||
}
|
||||
this.parts = parts;
|
||||
this.runHooks("postSample");
|
||||
this.parts = parts
|
||||
this.runHooks('postSample')
|
||||
|
||||
return this;
|
||||
};
|
||||
return this
|
||||
}
|
||||
|
||||
Pattern.prototype.sampleListOption = function(optionName) {
|
||||
let parts = this.sampleParts();
|
||||
let option = this.config.options[optionName];
|
||||
let anchors = {};
|
||||
let run = 1;
|
||||
let runs = option.list.length;
|
||||
let parts = this.sampleParts()
|
||||
let option = this.config.options[optionName]
|
||||
let anchors = {}
|
||||
let run = 1
|
||||
let runs = option.list.length
|
||||
for (let val of option.list) {
|
||||
this.settings.options[optionName] = val;
|
||||
this.settings.options[optionName] = val
|
||||
this.debug({
|
||||
type: "info",
|
||||
label: "🏃🏿♀️ Sample run",
|
||||
type: 'info',
|
||||
label: '🏃🏿♀️ Sample run',
|
||||
msg: `Sampling option ${optionName} with value ${round(val)}`
|
||||
});
|
||||
this.sampleRun(parts, anchors, run, runs);
|
||||
run++;
|
||||
})
|
||||
this.sampleRun(parts, anchors, run, runs)
|
||||
run++
|
||||
}
|
||||
this.parts = parts;
|
||||
this.parts = parts
|
||||
|
||||
return this;
|
||||
};
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles measurement sampling
|
||||
*/
|
||||
Pattern.prototype.sampleMeasurement = function(measurementName) {
|
||||
this.is = "sample";
|
||||
this.runHooks("preSample");
|
||||
let anchors = {};
|
||||
let parts = this.sampleParts();
|
||||
let val = this.settings.measurements[measurementName];
|
||||
this.is = 'sample'
|
||||
this.runHooks('preSample')
|
||||
let anchors = {}
|
||||
let parts = this.sampleParts()
|
||||
let val = this.settings.measurements[measurementName]
|
||||
if (val === undefined)
|
||||
throw new Error(
|
||||
"Cannot sample a measurement that is undefined: " + measurementName
|
||||
);
|
||||
let step = val / 50;
|
||||
val = val * 0.9;
|
||||
throw new Error('Cannot sample a measurement that is undefined: ' + measurementName)
|
||||
let step = val / 50
|
||||
val = val * 0.9
|
||||
for (let run = 1; run < 11; run++) {
|
||||
this.settings.measurements[measurementName] = val;
|
||||
this.settings.measurements[measurementName] = val
|
||||
this.debug({
|
||||
type: "info",
|
||||
label: "🏃🏿♀️ Sample run",
|
||||
type: 'info',
|
||||
label: '🏃🏿♀️ Sample run',
|
||||
msg: `Sampling option ${measurementName} with value ${round(val)}`
|
||||
});
|
||||
this.sampleRun(parts, anchors, run, 10);
|
||||
val += step;
|
||||
})
|
||||
this.sampleRun(parts, anchors, run, 10)
|
||||
val += step
|
||||
}
|
||||
this.parts = parts;
|
||||
this.runHooks("postSample");
|
||||
this.parts = parts
|
||||
this.runHooks('postSample')
|
||||
|
||||
return this;
|
||||
};
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles models sampling
|
||||
*/
|
||||
Pattern.prototype.sampleModels = function(models, focus = false) {
|
||||
this.is = "sample";
|
||||
this.runHooks("preSample");
|
||||
let anchors = {};
|
||||
let parts = this.sampleParts();
|
||||
let run = 0;
|
||||
let runs = Object.keys(models).length;
|
||||
this.is = 'sample'
|
||||
this.runHooks('preSample')
|
||||
let anchors = {}
|
||||
let parts = this.sampleParts()
|
||||
let run = 0
|
||||
let runs = Object.keys(models).length
|
||||
for (let l in models) {
|
||||
run++;
|
||||
this.settings.measurements = models[l];
|
||||
run++
|
||||
this.settings.measurements = models[l]
|
||||
this.debug({
|
||||
type: "info",
|
||||
label: "🏃🏿♀️ Sample run",
|
||||
type: 'info',
|
||||
label: '🏃🏿♀️ Sample run',
|
||||
msg: `Sampling model ${l}`
|
||||
});
|
||||
let className = l === focus ? "sample-focus" : "";
|
||||
this.sampleRun(parts, anchors, run, runs, className);
|
||||
})
|
||||
let className = l === focus ? 'sample-focus' : ''
|
||||
this.sampleRun(parts, anchors, run, runs, className)
|
||||
}
|
||||
this.parts = parts;
|
||||
this.runHooks("postSample");
|
||||
this.parts = parts
|
||||
this.runHooks('postSample')
|
||||
|
||||
return this;
|
||||
};
|
||||
return this
|
||||
}
|
||||
|
||||
/** Debug method, exposes debug hook */
|
||||
Pattern.prototype.debug = function(data) {
|
||||
this.runHooks("debug", data);
|
||||
};
|
||||
this.runHooks('debug', data)
|
||||
}
|
||||
|
||||
Pattern.prototype.render = function() {
|
||||
this.svg = new Svg(this);
|
||||
this.svg.hooks = this.hooks;
|
||||
this.svg = new Svg(this)
|
||||
this.svg.hooks = this.hooks
|
||||
|
||||
return this.pack().svg.render(this);
|
||||
};
|
||||
return this.pack().svg.render(this)
|
||||
}
|
||||
|
||||
Pattern.prototype.on = function(hook, method, data) {
|
||||
this.hooks[hook].push({ method, data });
|
||||
};
|
||||
this.hooks[hook].push({ method, data })
|
||||
}
|
||||
|
||||
Pattern.prototype.use = function(plugin, data = false) {
|
||||
this.debug({
|
||||
type: "success",
|
||||
label: "🔌 Plugin loaded",
|
||||
type: 'success',
|
||||
label: '🔌 Plugin loaded',
|
||||
msg: `${plugin.name} v${plugin.version}`
|
||||
});
|
||||
if (plugin.hooks) this.loadPluginHooks(plugin, data);
|
||||
if (plugin.macros) this.loadPluginMacros(plugin);
|
||||
})
|
||||
if (plugin.hooks) this.loadPluginHooks(plugin, data)
|
||||
if (plugin.macros) this.loadPluginMacros(plugin)
|
||||
|
||||
return this;
|
||||
};
|
||||
return this
|
||||
}
|
||||
|
||||
Pattern.prototype.loadPluginHooks = function(plugin, data) {
|
||||
for (let hook of Object.keys(this.hooks)) {
|
||||
if (typeof plugin.hooks[hook] === "function") {
|
||||
this.on(hook, plugin.hooks[hook], data);
|
||||
if (typeof plugin.hooks[hook] === 'function') {
|
||||
this.on(hook, plugin.hooks[hook], data)
|
||||
} else if (Array.isArray(plugin.hooks[hook])) {
|
||||
for (let method of plugin.hooks[hook]) {
|
||||
this.on(hook, method, data);
|
||||
this.on(hook, method, data)
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Pattern.prototype.loadPluginMacros = function(plugin) {
|
||||
for (let macro in plugin.macros) {
|
||||
if (typeof plugin.macros[macro] === "function") {
|
||||
this.macro(macro, plugin.macros[macro]);
|
||||
if (typeof plugin.macros[macro] === 'function') {
|
||||
this.macro(macro, plugin.macros[macro])
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Pattern.prototype.macro = function(key, method) {
|
||||
this.macros[key] = method;
|
||||
};
|
||||
this.macros[key] = method
|
||||
}
|
||||
|
||||
/** Packs parts in a 2D space and sets pattern size */
|
||||
Pattern.prototype.pack = function() {
|
||||
let bins = [];
|
||||
let bins = []
|
||||
for (let key in this.parts) {
|
||||
let part = this.parts[key];
|
||||
let part = this.parts[key]
|
||||
// Avoid multiple render calls to cause stacking of transforms
|
||||
part.attributes.remove("transform");
|
||||
part.attributes.remove('transform')
|
||||
if (part.render) {
|
||||
part.stack();
|
||||
let width = part.bottomRight.x - part.topLeft.x;
|
||||
let height = part.bottomRight.y - part.topLeft.y;
|
||||
if (this.settings.layout === true) bins.push({ id: key, width, height });
|
||||
part.stack()
|
||||
let width = part.bottomRight.x - part.topLeft.x
|
||||
let height = part.bottomRight.y - part.topLeft.y
|
||||
if (this.settings.layout === true) bins.push({ id: key, width, height })
|
||||
else {
|
||||
if (this.width < width) this.width = width;
|
||||
if (this.height < height) this.height = height;
|
||||
if (this.width < width) this.width = width
|
||||
if (this.height < height) this.height = height
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.settings.layout === true) {
|
||||
let size = pack(bins, { inPlace: true });
|
||||
let size = pack(bins, { inPlace: true })
|
||||
for (let bin of bins) {
|
||||
let part = this.parts[bin.id];
|
||||
if (bin.x !== 0 || bin.y !== 0)
|
||||
part.attr("transform", `translate (${bin.x}, ${bin.y})`);
|
||||
let part = this.parts[bin.id]
|
||||
if (bin.x !== 0 || bin.y !== 0) part.attr('transform', `translate (${bin.x}, ${bin.y})`)
|
||||
}
|
||||
this.width = size.width;
|
||||
this.height = size.height;
|
||||
} else if (typeof this.settings.layout === "object") {
|
||||
this.width = this.settings.layout.width;
|
||||
this.height = this.settings.layout.height;
|
||||
this.width = size.width
|
||||
this.height = size.height
|
||||
} else if (typeof this.settings.layout === 'object') {
|
||||
this.width = this.settings.layout.width
|
||||
this.height = this.settings.layout.height
|
||||
for (let partId of Object.keys(this.settings.layout.parts)) {
|
||||
let transforms = this.settings.layout.parts[partId];
|
||||
let transforms = this.settings.layout.parts[partId]
|
||||
// Moving
|
||||
if (typeof transforms.move === "object") {
|
||||
if (typeof transforms.move === 'object') {
|
||||
this.parts[partId].attributes.set(
|
||||
"transform",
|
||||
"translate(" + transforms.move.x + ", " + transforms.move.y + ")"
|
||||
);
|
||||
'transform',
|
||||
'translate(' + transforms.move.x + ', ' + transforms.move.y + ')'
|
||||
)
|
||||
}
|
||||
// Mirrorring
|
||||
let center = this.parts[partId].topLeft.shiftFractionTowards(
|
||||
this.parts[partId].bottomRight,
|
||||
0.5
|
||||
);
|
||||
let anchor = { x: 0, y: 0 };
|
||||
)
|
||||
let anchor = { x: 0, y: 0 }
|
||||
if (transforms.flipX) {
|
||||
let dx = anchor.x - center.x;
|
||||
let transform = `translate(${center.x * -1}, ${center.y * -1})`;
|
||||
transform += " scale(-1, 1)";
|
||||
transform += ` translate(${center.x * -1 + 2 * dx}, ${center.y})`;
|
||||
this.parts[partId].attributes.add("transform", transform);
|
||||
let dx = anchor.x - center.x
|
||||
let transform = `translate(${center.x * -1}, ${center.y * -1})`
|
||||
transform += ' scale(-1, 1)'
|
||||
transform += ` translate(${center.x * -1 + 2 * dx}, ${center.y})`
|
||||
this.parts[partId].attributes.add('transform', transform)
|
||||
}
|
||||
if (transforms.flipY) {
|
||||
let dy = anchor.y - center.y;
|
||||
let transform = `translate(${center.x * -1}, ${center.y * -1})`;
|
||||
transform += " scale(1, -1)";
|
||||
transform += ` translate(${center.x}, ${center.y * -1 + 2 * dy})`;
|
||||
this.parts[partId].attributes.add("transform", transform);
|
||||
let dy = anchor.y - center.y
|
||||
let transform = `translate(${center.x * -1}, ${center.y * -1})`
|
||||
transform += ' scale(1, -1)'
|
||||
transform += ` translate(${center.x}, ${center.y * -1 + 2 * dy})`
|
||||
this.parts[partId].attributes.add('transform', transform)
|
||||
}
|
||||
if (transforms.rotate) {
|
||||
let transform = `rotate(${transforms.rotate}, ${center.x -
|
||||
anchor.x}, ${center.y - anchor.y})`;
|
||||
this.parts[partId].attributes.add("transform", transform);
|
||||
let transform = `rotate(${transforms.rotate}, ${center.x - anchor.x}, ${center.y -
|
||||
anchor.y})`
|
||||
this.parts[partId].attributes.add('transform', transform)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
return this
|
||||
}
|
||||
|
||||
/** Determines the order to draft parts in, based on dependencies */
|
||||
Pattern.prototype.draftOrder = function(graph = this.resolveDependencies()) {
|
||||
let sorted = [];
|
||||
let visited = {};
|
||||
let sorted = []
|
||||
let visited = {}
|
||||
Object.keys(graph).forEach(function visit(name, ancestors) {
|
||||
if (!Array.isArray(ancestors)) ancestors = [];
|
||||
ancestors.push(name);
|
||||
visited[name] = true;
|
||||
if (typeof graph[name] !== "undefined") {
|
||||
if (!Array.isArray(ancestors)) ancestors = []
|
||||
ancestors.push(name)
|
||||
visited[name] = true
|
||||
if (typeof graph[name] !== 'undefined') {
|
||||
graph[name].forEach(function(dep) {
|
||||
if (visited[dep]) return;
|
||||
visit(dep, ancestors.slice(0));
|
||||
});
|
||||
if (visited[dep]) return
|
||||
visit(dep, ancestors.slice(0))
|
||||
})
|
||||
}
|
||||
if (sorted.indexOf(name) < 0) sorted.push(name);
|
||||
});
|
||||
if (sorted.indexOf(name) < 0) sorted.push(name)
|
||||
})
|
||||
|
||||
return sorted;
|
||||
};
|
||||
return sorted
|
||||
}
|
||||
|
||||
/** Recursively solves part dependencies for a part */
|
||||
Pattern.prototype.resolveDependency = function(
|
||||
|
@ -483,135 +453,119 @@ Pattern.prototype.resolveDependency = function(
|
|||
graph = this.config.dependencies,
|
||||
deps = []
|
||||
) {
|
||||
if (typeof seen[part] === "undefined") seen[part] = true;
|
||||
if (typeof graph[part] === "string") {
|
||||
if (deps.indexOf(graph[part]) === -1) deps.push(graph[part]);
|
||||
return this.resolveDependency(seen, graph[part], graph, deps);
|
||||
if (typeof seen[part] === 'undefined') seen[part] = true
|
||||
if (typeof graph[part] === 'string') {
|
||||
if (deps.indexOf(graph[part]) === -1) deps.push(graph[part])
|
||||
return this.resolveDependency(seen, graph[part], graph, deps)
|
||||
} else if (Array.isArray(graph[part])) {
|
||||
if (graph[part].length === 0) return [];
|
||||
if (graph[part].length === 0) return []
|
||||
else {
|
||||
if (deps.length === 0) deps = graph[part];
|
||||
for (let apart of graph[part])
|
||||
deps.concat(this.resolveDependency(seen, apart, graph, deps));
|
||||
if (deps.length === 0) deps = graph[part]
|
||||
for (let apart of graph[part]) deps.concat(this.resolveDependency(seen, apart, graph, deps))
|
||||
}
|
||||
}
|
||||
|
||||
return deps;
|
||||
};
|
||||
return deps
|
||||
}
|
||||
|
||||
/** Resolves part dependencies into a flat array */
|
||||
Pattern.prototype.resolveDependencies = function(
|
||||
graph = this.config.dependencies
|
||||
) {
|
||||
Pattern.prototype.resolveDependencies = function(graph = this.config.dependencies) {
|
||||
for (let i in this.config.inject) {
|
||||
let dependency = this.config.inject[i];
|
||||
if (typeof this.config.dependencies[i] === "undefined")
|
||||
this.config.dependencies[i] = dependency;
|
||||
let dependency = this.config.inject[i]
|
||||
if (typeof this.config.dependencies[i] === 'undefined') this.config.dependencies[i] = dependency
|
||||
else if (this.config.dependencies[i] !== dependency) {
|
||||
if (typeof this.config.dependencies[i] === "string")
|
||||
this.config.dependencies[i] = [this.config.dependencies[i], dependency];
|
||||
if (typeof this.config.dependencies[i] === 'string')
|
||||
this.config.dependencies[i] = [this.config.dependencies[i], dependency]
|
||||
else if (Array.isArray(this.config.dependencies[i])) {
|
||||
if (this.config.dependencies[i].indexOf(dependency) === -1)
|
||||
this.config.dependencies[i].push(dependency);
|
||||
} else
|
||||
throw new Error(
|
||||
"Part dependencies should be a string or an array of strings"
|
||||
);
|
||||
this.config.dependencies[i].push(dependency)
|
||||
} else throw new Error('Part dependencies should be a string or an array of strings')
|
||||
}
|
||||
// Parts both in the parts and dependencies array trip up the dependency resolver
|
||||
if (Array.isArray(this.config.parts)) {
|
||||
let pos = this.config.parts.indexOf(this.config.inject[i]);
|
||||
if (pos !== -1) this.config.parts.splice(pos, 1);
|
||||
let pos = this.config.parts.indexOf(this.config.inject[i])
|
||||
if (pos !== -1) this.config.parts.splice(pos, 1)
|
||||
}
|
||||
}
|
||||
|
||||
// Include parts outside the dependency graph
|
||||
if (Array.isArray(this.config.parts)) {
|
||||
for (let part of this.config.parts) {
|
||||
if (typeof this.config.dependencies[part] === "undefined")
|
||||
this.config.dependencies[part] = [];
|
||||
if (typeof this.config.dependencies[part] === 'undefined') this.config.dependencies[part] = []
|
||||
}
|
||||
}
|
||||
|
||||
let resolved = {};
|
||||
let seen = {};
|
||||
for (let part in graph)
|
||||
resolved[part] = this.resolveDependency(seen, part, graph);
|
||||
for (let part in seen)
|
||||
if (typeof resolved[part] === "undefined") resolved[part] = [];
|
||||
let resolved = {}
|
||||
let seen = {}
|
||||
for (let part in graph) resolved[part] = this.resolveDependency(seen, part, graph)
|
||||
for (let part in seen) if (typeof resolved[part] === 'undefined') resolved[part] = []
|
||||
|
||||
return resolved;
|
||||
};
|
||||
return resolved
|
||||
}
|
||||
|
||||
/** Determines whether a part is needed
|
||||
* This depends on the 'only' setting and the
|
||||
* configured dependencies.
|
||||
*/
|
||||
Pattern.prototype.needs = function(partName) {
|
||||
if (typeof this.settings.only === "undefined" || this.settings.only === false)
|
||||
return true;
|
||||
else if (typeof this.settings.only === "string") {
|
||||
if (this.settings.only === partName) return true;
|
||||
if (typeof this.settings.only === 'undefined' || this.settings.only === false) return true
|
||||
else if (typeof this.settings.only === 'string') {
|
||||
if (this.settings.only === partName) return true
|
||||
if (Array.isArray(this.config.resolvedDependencies[this.settings.only])) {
|
||||
for (let dependency of this.config.resolvedDependencies[
|
||||
this.settings.only
|
||||
]) {
|
||||
if (dependency === partName) return true;
|
||||
for (let dependency of this.config.resolvedDependencies[this.settings.only]) {
|
||||
if (dependency === partName) return true
|
||||
}
|
||||
}
|
||||
} else if (Array.isArray(this.settings.only)) {
|
||||
for (let part of this.settings.only) {
|
||||
if (part === partName) return true;
|
||||
if (part === partName) return true
|
||||
for (let dependency of this.config.resolvedDependencies[part]) {
|
||||
if (dependency === partName) return true;
|
||||
if (dependency === partName) return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
return false
|
||||
}
|
||||
|
||||
/* Checks whether a part is hidden in the config */
|
||||
Pattern.prototype.isHidden = function(partName) {
|
||||
if (Array.isArray(this.config.hide)) {
|
||||
if (this.config.hide.indexOf(partName) !== -1) return true;
|
||||
if (this.config.hide.indexOf(partName) !== -1) return true
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
return false
|
||||
}
|
||||
|
||||
/** Determines whether a part is wanted by the user
|
||||
* This depends on the 'only' setting
|
||||
*/
|
||||
Pattern.prototype.wants = function(partName) {
|
||||
if (
|
||||
typeof this.settings.only === "undefined" ||
|
||||
this.settings.only === false
|
||||
) {
|
||||
if (this.isHidden(partName)) return false;
|
||||
} else if (typeof this.settings.only === "string") {
|
||||
if (this.settings.only === partName) return true;
|
||||
return false;
|
||||
if (typeof this.settings.only === 'undefined' || this.settings.only === false) {
|
||||
if (this.isHidden(partName)) return false
|
||||
} else if (typeof this.settings.only === 'string') {
|
||||
if (this.settings.only === partName) return true
|
||||
return false
|
||||
} else if (Array.isArray(this.settings.only)) {
|
||||
for (let part of this.settings.only) {
|
||||
if (part === partName) return true;
|
||||
if (part === partName) return true
|
||||
}
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
return true
|
||||
}
|
||||
|
||||
/** Returns props required to render this pattern through
|
||||
* an external renderer (eg. a React component)
|
||||
*/
|
||||
Pattern.prototype.getRenderProps = function() {
|
||||
this.pack();
|
||||
let props = {};
|
||||
props.width = this.width;
|
||||
props.height = this.height;
|
||||
props.settings = this.settings;
|
||||
props.parts = {};
|
||||
this.pack()
|
||||
let props = {}
|
||||
props.width = this.width
|
||||
props.height = this.height
|
||||
props.settings = this.settings
|
||||
props.parts = {}
|
||||
for (let p in this.parts) {
|
||||
if (this.parts[p].render) {
|
||||
props.parts[p] = {
|
||||
|
@ -623,9 +577,9 @@ Pattern.prototype.getRenderProps = function() {
|
|||
width: this.parts[p].width,
|
||||
bottomRight: this.parts[p].bottomRight,
|
||||
topLeft: this.parts[p].topLeft
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return props;
|
||||
};
|
||||
return props
|
||||
}
|
||||
|
|
|
@ -1,142 +1,139 @@
|
|||
import Attributes from "./attributes";
|
||||
import { round } from "./utils";
|
||||
import Attributes from './attributes'
|
||||
import { round } from './utils'
|
||||
|
||||
function Point(x, y) {
|
||||
this.x = round(x);
|
||||
this.y = round(y);
|
||||
this.attributes = new Attributes();
|
||||
this.x = round(x)
|
||||
this.y = round(y)
|
||||
this.attributes = new Attributes()
|
||||
}
|
||||
|
||||
/** Radians to degrees */
|
||||
Point.prototype.rad2deg = function(radians) {
|
||||
return radians * 57.29577951308232;
|
||||
};
|
||||
return radians * 57.29577951308232
|
||||
}
|
||||
|
||||
/** Degrees to radians */
|
||||
Point.prototype.deg2rad = function(degrees) {
|
||||
return degrees / 57.29577951308232;
|
||||
};
|
||||
return degrees / 57.29577951308232
|
||||
}
|
||||
|
||||
/** Adds an attribute. This is here to make this call chainable in assignment */
|
||||
Point.prototype.attr = function(name, value, overwrite = false) {
|
||||
if (overwrite) this.attributes.set(name, value);
|
||||
else this.attributes.add(name, value);
|
||||
if (overwrite) this.attributes.set(name, value)
|
||||
else this.attributes.add(name, value)
|
||||
|
||||
return this;
|
||||
};
|
||||
return this
|
||||
}
|
||||
|
||||
/** Returns the distance between this point and that point */
|
||||
Point.prototype.dist = function(that) {
|
||||
let dx = this.x - that.x;
|
||||
let dy = this.y - that.y;
|
||||
let dx = this.x - that.x
|
||||
let dy = this.y - that.y
|
||||
|
||||
return round(Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2)));
|
||||
};
|
||||
return round(Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2)))
|
||||
}
|
||||
|
||||
/** Returns slope of a line made by this point and that point */
|
||||
Point.prototype.slope = function(that) {
|
||||
return (that.y - this.y) / (that.x - this.x);
|
||||
};
|
||||
return (that.y - this.y) / (that.x - this.x)
|
||||
}
|
||||
|
||||
/** Returns the x-delta between this point and that point */
|
||||
Point.prototype.dx = function(that) {
|
||||
return that.x - this.x;
|
||||
};
|
||||
return that.x - this.x
|
||||
}
|
||||
|
||||
/** Returns the y-delta between this point and that point */
|
||||
Point.prototype.dy = function(that) {
|
||||
return that.y - this.y;
|
||||
};
|
||||
return that.y - this.y
|
||||
}
|
||||
|
||||
/** Returns the angle between this point and that point */
|
||||
Point.prototype.angle = function(that) {
|
||||
let rad = Math.atan2(-1 * this.dy(that), this.dx(that));
|
||||
while (rad < 0) rad += 2 * Math.PI;
|
||||
let rad = Math.atan2(-1 * this.dy(that), this.dx(that))
|
||||
while (rad < 0) rad += 2 * Math.PI
|
||||
|
||||
return this.rad2deg(rad);
|
||||
};
|
||||
return this.rad2deg(rad)
|
||||
}
|
||||
|
||||
/** Rotate this point deg around that point */
|
||||
Point.prototype.rotate = function(deg, that) {
|
||||
let radius = this.dist(that);
|
||||
let angle = this.angle(that);
|
||||
let x = that.x + radius * Math.cos(this.deg2rad(angle + deg)) * -1;
|
||||
let y = that.y + radius * Math.sin(this.deg2rad(angle + deg));
|
||||
let radius = this.dist(that)
|
||||
let angle = this.angle(that)
|
||||
let x = that.x + radius * Math.cos(this.deg2rad(angle + deg)) * -1
|
||||
let y = that.y + radius * Math.sin(this.deg2rad(angle + deg))
|
||||
|
||||
return new Point(x, y);
|
||||
};
|
||||
return new Point(x, y)
|
||||
}
|
||||
|
||||
/** returns an identical copy of this point */
|
||||
Point.prototype.copy = function() {
|
||||
return new Point(this.x, this.y);
|
||||
};
|
||||
return new Point(this.x, this.y)
|
||||
}
|
||||
|
||||
/** Mirrors this point around X value of that point */
|
||||
Point.prototype.flipX = function(that = false) {
|
||||
if (that === false || that.x === 0) return new Point(this.x * -1, this.y);
|
||||
else return new Point(that.x + this.dx(that), this.y);
|
||||
};
|
||||
if (that === false || that.x === 0) return new Point(this.x * -1, this.y)
|
||||
else return new Point(that.x + this.dx(that), this.y)
|
||||
}
|
||||
|
||||
/** Mirrors this point around Y value of that point */
|
||||
Point.prototype.flipY = function(that = false) {
|
||||
if (that === false || that.y === 0) return new Point(this.x, this.y * -1);
|
||||
else return new Point(this.x, that.y + this.dy(that));
|
||||
};
|
||||
if (that === false || that.y === 0) return new Point(this.x, this.y * -1)
|
||||
else return new Point(this.x, that.y + this.dy(that))
|
||||
}
|
||||
|
||||
/** Shifts this point distance in the deg direction */
|
||||
Point.prototype.shift = function(deg, distance) {
|
||||
let p = this.copy();
|
||||
p.x += distance;
|
||||
let p = this.copy()
|
||||
p.x += distance
|
||||
|
||||
return p.rotate(deg, this);
|
||||
};
|
||||
return p.rotate(deg, this)
|
||||
}
|
||||
|
||||
/** Shifts this point distance in the direction of that point */
|
||||
Point.prototype.shiftTowards = function(that, distance) {
|
||||
return this.shift(this.angle(that), distance);
|
||||
};
|
||||
return this.shift(this.angle(that), distance)
|
||||
}
|
||||
|
||||
/** Checks whether this has the same coordinates as that */
|
||||
Point.prototype.sitsOn = function(that) {
|
||||
if (this.x === that.x && this.y === that.y) return true;
|
||||
else return false;
|
||||
};
|
||||
if (this.x === that.x && this.y === that.y) return true
|
||||
else return false
|
||||
}
|
||||
|
||||
/** Checks whether this has roughly the same coordinates as that */
|
||||
Point.prototype.sitsRoughlyOn = function(that) {
|
||||
if (
|
||||
Math.round(this.x) === Math.round(that.x) &&
|
||||
Math.round(this.y) === Math.round(that.y)
|
||||
)
|
||||
return true;
|
||||
else return false;
|
||||
};
|
||||
if (Math.round(this.x) === Math.round(that.x) && Math.round(this.y) === Math.round(that.y))
|
||||
return true
|
||||
else return false
|
||||
}
|
||||
|
||||
/** Shifts this point fraction of the distance towards that point */
|
||||
Point.prototype.shiftFractionTowards = function(that, fraction) {
|
||||
return this.shiftTowards(that, this.dist(that) * fraction);
|
||||
};
|
||||
return this.shiftTowards(that, this.dist(that) * fraction)
|
||||
}
|
||||
|
||||
/** Shifts this point distance beyond that point */
|
||||
Point.prototype.shiftOutwards = function(that, distance) {
|
||||
return this.shiftTowards(that, this.dist(that) + distance);
|
||||
};
|
||||
return this.shiftTowards(that, this.dist(that) + distance)
|
||||
}
|
||||
|
||||
/** Returns a deep copy of this */
|
||||
Point.prototype.clone = function() {
|
||||
let clone = new Point(this.x, this.y);
|
||||
clone.attributes = this.attributes.clone();
|
||||
let clone = new Point(this.x, this.y)
|
||||
clone.attributes = this.attributes.clone()
|
||||
|
||||
return clone;
|
||||
};
|
||||
return clone
|
||||
}
|
||||
|
||||
/** Applies a translate transform */
|
||||
Point.prototype.translate = function(x, y) {
|
||||
let p = this.copy();
|
||||
p.x += x;
|
||||
p.y += y;
|
||||
let p = this.copy()
|
||||
p.x += x
|
||||
p.y += y
|
||||
|
||||
return p;
|
||||
};
|
||||
return p
|
||||
}
|
||||
|
||||
export default Point;
|
||||
export default Point
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
import Attributes from "./attributes";
|
||||
import Attributes from './attributes'
|
||||
|
||||
function Snippet(def, anchor) {
|
||||
this.def = def;
|
||||
this.anchor = anchor;
|
||||
this.attributes = new Attributes();
|
||||
this.def = def
|
||||
this.anchor = anchor
|
||||
this.attributes = new Attributes()
|
||||
|
||||
return this;
|
||||
return this
|
||||
}
|
||||
|
||||
/** Adds an attribute. This is here to make this call chainable in assignment */
|
||||
Snippet.prototype.attr = function(name, value, overwrite = false) {
|
||||
if (overwrite) this.attributes.set(name, value);
|
||||
else this.attributes.add(name, value);
|
||||
if (overwrite) this.attributes.set(name, value)
|
||||
else this.attributes.add(name, value)
|
||||
|
||||
return this;
|
||||
};
|
||||
return this
|
||||
}
|
||||
|
||||
/** Returns a deep copy of this */
|
||||
Snippet.prototype.clone = function() {
|
||||
let clone = new Snippet(this.def, this.anchor.clone());
|
||||
clone.attributes = this.attributes.clone();
|
||||
let clone = new Snippet(this.def, this.anchor.clone())
|
||||
clone.attributes = this.attributes.clone()
|
||||
|
||||
return clone;
|
||||
};
|
||||
return clone
|
||||
}
|
||||
|
||||
export default Snippet;
|
||||
export default Snippet
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
function Store() {
|
||||
this.data = new Map();
|
||||
this.data = new Map()
|
||||
}
|
||||
|
||||
/** Sets a value under index key */
|
||||
Store.prototype.set = function(key, value) {
|
||||
this.data.set(key, value);
|
||||
};
|
||||
this.data.set(key, value)
|
||||
}
|
||||
|
||||
/** Sets a value under index key */
|
||||
Store.prototype.setIfUnset = function(key, value) {
|
||||
if (!this.data.has(key)) this.data.set(key, value);
|
||||
};
|
||||
if (!this.data.has(key)) this.data.set(key, value)
|
||||
}
|
||||
|
||||
/** Gets a value under index key */
|
||||
Store.prototype.get = function(key) {
|
||||
return this.data.get(key);
|
||||
};
|
||||
return this.data.get(key)
|
||||
}
|
||||
|
||||
export default Store;
|
||||
export default Store
|
||||
|
|
|
@ -1,319 +1,306 @@
|
|||
import Attributes from "./attributes";
|
||||
import Attributes from './attributes'
|
||||
|
||||
import { version } from "../package.json";
|
||||
import { version } from '../package.json'
|
||||
|
||||
function Svg(pattern) {
|
||||
this.openGroups = [];
|
||||
this.layout = {};
|
||||
this.freeId = 0;
|
||||
this.body = "";
|
||||
this.style = "";
|
||||
this.script = "";
|
||||
this.defs = "";
|
||||
this.pattern = pattern; // Needed to expose pattern to hooks
|
||||
this.prefix = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>';
|
||||
this.attributes = new Attributes();
|
||||
this.attributes.add("xmlns", "http://www.w3.org/2000/svg");
|
||||
this.attributes.add("xmlns:svg", "http://www.w3.org/2000/svg");
|
||||
this.attributes.add("xmlns:xlink", "http://www.w3.org/1999/xlink");
|
||||
this.attributes.add("xml:lang", pattern.settings.locale);
|
||||
this.attributes.add(
|
||||
"xmlns:freesewing",
|
||||
"http://freesewing.org/namespaces/freesewing"
|
||||
);
|
||||
this.attributes.add("freesewing", version);
|
||||
this.openGroups = []
|
||||
this.layout = {}
|
||||
this.freeId = 0
|
||||
this.body = ''
|
||||
this.style = ''
|
||||
this.script = ''
|
||||
this.defs = ''
|
||||
this.pattern = pattern // Needed to expose pattern to hooks
|
||||
this.prefix = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>'
|
||||
this.attributes = new Attributes()
|
||||
this.attributes.add('xmlns', 'http://www.w3.org/2000/svg')
|
||||
this.attributes.add('xmlns:svg', 'http://www.w3.org/2000/svg')
|
||||
this.attributes.add('xmlns:xlink', 'http://www.w3.org/1999/xlink')
|
||||
this.attributes.add('xml:lang', pattern.settings.locale)
|
||||
this.attributes.add('xmlns:freesewing', 'http://freesewing.org/namespaces/freesewing')
|
||||
this.attributes.add('freesewing', version)
|
||||
}
|
||||
|
||||
Svg.prototype.runHooks = function(hookName, data = false) {
|
||||
if (data === false) data = this;
|
||||
let hooks = this.hooks[hookName];
|
||||
if (data === false) data = this
|
||||
let hooks = this.hooks[hookName]
|
||||
if (hooks.length > 0) {
|
||||
for (let hook of hooks) {
|
||||
hook.method(data, hook.data);
|
||||
hook.method(data, hook.data)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/** Runs insertText hooks */
|
||||
Svg.prototype.insertText = function(text) {
|
||||
if (this.hooks.insertText.length > 0) {
|
||||
for (let hook of this.hooks.insertText)
|
||||
text = hook.method(this.pattern.settings.locale, text, hook.data);
|
||||
text = hook.method(this.pattern.settings.locale, text, hook.data)
|
||||
}
|
||||
|
||||
return text;
|
||||
};
|
||||
return text
|
||||
}
|
||||
|
||||
/** Debug method, exposes debug hook */
|
||||
Svg.prototype.debug = function() {};
|
||||
Svg.prototype.debug = function() {}
|
||||
|
||||
/** Renders a draft object as SVG */
|
||||
Svg.prototype.render = function(pattern) {
|
||||
this.idPrefix = pattern.settings.idPrefix;
|
||||
this.runHooks("preRender");
|
||||
this.idPrefix = pattern.settings.idPrefix
|
||||
this.runHooks('preRender')
|
||||
if (!pattern.settings.embed) {
|
||||
this.attributes.add("width", pattern.width + "mm");
|
||||
this.attributes.add("height", pattern.height + "mm");
|
||||
this.attributes.add('width', pattern.width + 'mm')
|
||||
this.attributes.add('height', pattern.height + 'mm')
|
||||
}
|
||||
this.attributes.add("viewBox", `0 0 ${pattern.width} ${pattern.height}`);
|
||||
this.head = this.renderHead();
|
||||
this.tail = this.renderTail();
|
||||
this.svg = "";
|
||||
this.layout = {}; // Reset layout
|
||||
this.attributes.add('viewBox', `0 0 ${pattern.width} ${pattern.height}`)
|
||||
this.head = this.renderHead()
|
||||
this.tail = this.renderTail()
|
||||
this.svg = ''
|
||||
this.layout = {} // Reset layout
|
||||
for (let partId in pattern.parts) {
|
||||
let part = pattern.parts[partId];
|
||||
let part = pattern.parts[partId]
|
||||
if (part.render) {
|
||||
let partSvg = this.renderPart(part);
|
||||
let partSvg = this.renderPart(part)
|
||||
this.layout[partId] = {
|
||||
svg: partSvg,
|
||||
transform: part.attributes.getAsArray("transform")
|
||||
};
|
||||
this.svg += this.openGroup(
|
||||
`${this.idPrefix}part-${partId}`,
|
||||
part.attributes
|
||||
);
|
||||
this.svg += partSvg;
|
||||
this.svg += this.closeGroup();
|
||||
transform: part.attributes.getAsArray('transform')
|
||||
}
|
||||
this.svg += this.openGroup(`${this.idPrefix}part-${partId}`, part.attributes)
|
||||
this.svg += partSvg
|
||||
this.svg += this.closeGroup()
|
||||
}
|
||||
}
|
||||
this.svg =
|
||||
this.prefix + this.renderSvgTag() + this.head + this.svg + this.tail;
|
||||
this.runHooks("postRender");
|
||||
this.svg = this.prefix + this.renderSvgTag() + this.head + this.svg + this.tail
|
||||
this.runHooks('postRender')
|
||||
|
||||
return this.svg;
|
||||
};
|
||||
return this.svg
|
||||
}
|
||||
|
||||
/** Renders SVG head section */
|
||||
Svg.prototype.renderHead = function() {
|
||||
let svg = this.renderStyle();
|
||||
svg += this.renderScript();
|
||||
svg += this.renderDefs();
|
||||
svg += this.openGroup(this.idPrefix + "container");
|
||||
let svg = this.renderStyle()
|
||||
svg += this.renderScript()
|
||||
svg += this.renderDefs()
|
||||
svg += this.openGroup(this.idPrefix + 'container')
|
||||
|
||||
return svg;
|
||||
};
|
||||
return svg
|
||||
}
|
||||
|
||||
/** Renders SVG closing section */
|
||||
Svg.prototype.renderTail = function() {
|
||||
let svg = "";
|
||||
svg += this.closeGroup();
|
||||
svg += this.nl() + "</svg>";
|
||||
let svg = ''
|
||||
svg += this.closeGroup()
|
||||
svg += this.nl() + '</svg>'
|
||||
|
||||
return svg;
|
||||
};
|
||||
return svg
|
||||
}
|
||||
|
||||
/** Returns SVG code for the opening SVG tag */
|
||||
Svg.prototype.renderSvgTag = function() {
|
||||
let svg = "<svg";
|
||||
this.indent();
|
||||
svg += this.nl() + this.attributes.render();
|
||||
this.outdent();
|
||||
svg += this.nl() + ">" + this.nl();
|
||||
let svg = '<svg'
|
||||
this.indent()
|
||||
svg += this.nl() + this.attributes.render()
|
||||
this.outdent()
|
||||
svg += this.nl() + '>' + this.nl()
|
||||
|
||||
return svg;
|
||||
};
|
||||
return svg
|
||||
}
|
||||
|
||||
/** Returns SVG code for the style block */
|
||||
Svg.prototype.renderStyle = function() {
|
||||
let svg = '<style type="text/css"> <![CDATA[ ';
|
||||
this.indent();
|
||||
svg += this.nl() + this.style;
|
||||
this.outdent();
|
||||
svg += this.nl() + "]]>" + this.nl() + "</style>" + this.nl();
|
||||
return svg;
|
||||
};
|
||||
let svg = '<style type="text/css"> <![CDATA[ '
|
||||
this.indent()
|
||||
svg += this.nl() + this.style
|
||||
this.outdent()
|
||||
svg += this.nl() + ']]>' + this.nl() + '</style>' + this.nl()
|
||||
return svg
|
||||
}
|
||||
|
||||
/** Returns SVG code for the script block */
|
||||
Svg.prototype.renderScript = function() {
|
||||
let svg = '<script type="text/javascript"> <![CDATA[';
|
||||
this.indent();
|
||||
svg += this.nl() + this.script;
|
||||
this.outdent();
|
||||
svg += this.nl() + "]]>" + this.nl() + "</script>" + this.nl();
|
||||
let svg = '<script type="text/javascript"> <![CDATA['
|
||||
this.indent()
|
||||
svg += this.nl() + this.script
|
||||
this.outdent()
|
||||
svg += this.nl() + ']]>' + this.nl() + '</script>' + this.nl()
|
||||
|
||||
return svg;
|
||||
};
|
||||
return svg
|
||||
}
|
||||
|
||||
/** Returns SVG code for the defs block */
|
||||
Svg.prototype.renderDefs = function() {
|
||||
let svg = "<defs>";
|
||||
this.indent();
|
||||
svg += this.nl() + this.defs;
|
||||
this.outdent();
|
||||
svg += this.nl() + "</defs>" + this.nl();
|
||||
let svg = '<defs>'
|
||||
this.indent()
|
||||
svg += this.nl() + this.defs
|
||||
this.outdent()
|
||||
svg += this.nl() + '</defs>' + this.nl()
|
||||
|
||||
return svg;
|
||||
};
|
||||
return svg
|
||||
}
|
||||
|
||||
/** Returns SVG code for a Part object */
|
||||
Svg.prototype.renderPart = function(part) {
|
||||
let svg = "";
|
||||
let svg = ''
|
||||
for (let key in part.paths) {
|
||||
let path = part.paths[key];
|
||||
if (path.render) svg += this.renderPath(path);
|
||||
let path = part.paths[key]
|
||||
if (path.render) svg += this.renderPath(path)
|
||||
}
|
||||
for (let key in part.points) {
|
||||
if (part.points[key].attributes.get("data-text")) {
|
||||
svg += this.renderText(part.points[key]);
|
||||
if (part.points[key].attributes.get('data-text')) {
|
||||
svg += this.renderText(part.points[key])
|
||||
}
|
||||
if (part.points[key].attributes.get("data-circle")) {
|
||||
svg += this.renderCircle(part.points[key]);
|
||||
if (part.points[key].attributes.get('data-circle')) {
|
||||
svg += this.renderCircle(part.points[key])
|
||||
}
|
||||
}
|
||||
for (let key in part.snippets) {
|
||||
let snippet = part.snippets[key];
|
||||
svg += this.renderSnippet(snippet, part);
|
||||
let snippet = part.snippets[key]
|
||||
svg += this.renderSnippet(snippet, part)
|
||||
}
|
||||
|
||||
return svg;
|
||||
};
|
||||
return svg
|
||||
}
|
||||
|
||||
/** Returns SVG code for a Path object */
|
||||
Svg.prototype.renderPath = function(path) {
|
||||
if (!path.attributes.get("id"))
|
||||
path.attributes.add("id", this.idPrefix + this.getId());
|
||||
path.attributes.set("d", path.asPathstring());
|
||||
if (!path.attributes.get('id')) path.attributes.add('id', this.idPrefix + this.getId())
|
||||
path.attributes.set('d', path.asPathstring())
|
||||
|
||||
return `${this.nl()}<path ${path.attributes.render()} />${this.renderPathText(
|
||||
path
|
||||
)}`;
|
||||
};
|
||||
return `${this.nl()}<path ${path.attributes.render()} />${this.renderPathText(path)}`
|
||||
}
|
||||
|
||||
Svg.prototype.renderPathText = function(path) {
|
||||
let text = path.attributes.get("data-text");
|
||||
if (!text) return "";
|
||||
else this.text = this.insertText(text);
|
||||
let attributes = path.attributes.renderIfPrefixIs("data-text-");
|
||||
let text = path.attributes.get('data-text')
|
||||
if (!text) return ''
|
||||
else this.text = this.insertText(text)
|
||||
let attributes = path.attributes.renderIfPrefixIs('data-text-')
|
||||
// Sadly aligning text along a patch can't be done in CSS only
|
||||
let offset = "";
|
||||
let align = path.attributes.get("data-text-class");
|
||||
if (align && align.indexOf("center") > -1) offset = ' startOffset="50%" ';
|
||||
else if (align && align.indexOf("right") > -1)
|
||||
offset = ' startOffset="100%" ';
|
||||
let svg = this.nl() + "<text>";
|
||||
this.indent();
|
||||
svg += `<textPath xlink:href="#${path.attributes.get(
|
||||
"id"
|
||||
)}" ${offset}><tspan ${attributes}>${this.text}</tspan></textPath>`;
|
||||
this.outdent();
|
||||
svg += this.nl() + "</text>";
|
||||
let offset = ''
|
||||
let align = path.attributes.get('data-text-class')
|
||||
if (align && align.indexOf('center') > -1) offset = ' startOffset="50%" '
|
||||
else if (align && align.indexOf('right') > -1) offset = ' startOffset="100%" '
|
||||
let svg = this.nl() + '<text>'
|
||||
this.indent()
|
||||
svg += `<textPath xlink:href="#${path.attributes.get('id')}" ${offset}><tspan ${attributes}>${
|
||||
this.text
|
||||
}</tspan></textPath>`
|
||||
this.outdent()
|
||||
svg += this.nl() + '</text>'
|
||||
|
||||
return svg;
|
||||
};
|
||||
return svg
|
||||
}
|
||||
|
||||
Svg.prototype.renderText = function(point) {
|
||||
let text = point.attributes.getAsArray("data-text");
|
||||
let text = point.attributes.getAsArray('data-text')
|
||||
if (text !== false) {
|
||||
let joint = "";
|
||||
let joint = ''
|
||||
for (let string of text) {
|
||||
this.text = this.insertText(string);
|
||||
joint += this.text + " ";
|
||||
this.text = this.insertText(string)
|
||||
joint += this.text + ' '
|
||||
}
|
||||
this.text = this.insertText(joint);
|
||||
this.text = this.insertText(joint)
|
||||
}
|
||||
point.attributes.set("data-text-x", point.x);
|
||||
point.attributes.set("data-text-y", point.y);
|
||||
let lineHeight = point.attributes.get("data-text-lineheight") || 12;
|
||||
point.attributes.remove("data-text-lineheight");
|
||||
let svg = `${this.nl()}<text ${point.attributes.renderIfPrefixIs(
|
||||
"data-text-"
|
||||
)}>`;
|
||||
this.indent();
|
||||
point.attributes.set('data-text-x', point.x)
|
||||
point.attributes.set('data-text-y', point.y)
|
||||
let lineHeight = point.attributes.get('data-text-lineheight') || 12
|
||||
point.attributes.remove('data-text-lineheight')
|
||||
let svg = `${this.nl()}<text ${point.attributes.renderIfPrefixIs('data-text-')}>`
|
||||
this.indent()
|
||||
// Multi-line text?
|
||||
if (this.text.indexOf("\n") !== -1) {
|
||||
let lines = this.text.split("\n");
|
||||
svg += `<tspan>${lines.shift()}</tspan>`;
|
||||
if (this.text.indexOf('\n') !== -1) {
|
||||
let lines = this.text.split('\n')
|
||||
svg += `<tspan>${lines.shift()}</tspan>`
|
||||
for (let line of lines) {
|
||||
svg += `<tspan x="${point.x}" dy="${lineHeight}">${line}</tspan>`;
|
||||
svg += `<tspan x="${point.x}" dy="${lineHeight}">${line}</tspan>`
|
||||
}
|
||||
} else {
|
||||
svg += `<tspan>${this.text}</tspan>`;
|
||||
svg += `<tspan>${this.text}</tspan>`
|
||||
}
|
||||
this.outdent();
|
||||
svg += this.nl() + "</text>";
|
||||
this.outdent()
|
||||
svg += this.nl() + '</text>'
|
||||
|
||||
return svg;
|
||||
};
|
||||
return svg
|
||||
}
|
||||
|
||||
Svg.prototype.renderCircle = function(point) {
|
||||
return `<circle cx="${point.x}" cy="${point.y}" r="${point.attributes.get(
|
||||
"data-circle"
|
||||
)}" ${point.attributes.renderIfPrefixIs("data-circle-")}></circle>`;
|
||||
};
|
||||
'data-circle'
|
||||
)}" ${point.attributes.renderIfPrefixIs('data-circle-')}></circle>`
|
||||
}
|
||||
|
||||
/** Returns SVG code for a snippet */
|
||||
Svg.prototype.renderSnippet = function(snippet, part) {
|
||||
let x = snippet.anchor.x;
|
||||
let y = snippet.anchor.y;
|
||||
let scale = snippet.attributes.get("data-scale");
|
||||
let x = snippet.anchor.x
|
||||
let y = snippet.anchor.y
|
||||
let scale = snippet.attributes.get('data-scale')
|
||||
if (scale) {
|
||||
snippet.attributes.add("transform", `translate(${x}, ${y})`);
|
||||
snippet.attributes.add("transform", `scale(${scale})`);
|
||||
snippet.attributes.add("transform", `translate(${x * -1}, ${y * -1})`);
|
||||
snippet.attributes.add('transform', `translate(${x}, ${y})`)
|
||||
snippet.attributes.add('transform', `scale(${scale})`)
|
||||
snippet.attributes.add('transform', `translate(${x * -1}, ${y * -1})`)
|
||||
}
|
||||
let rotate = snippet.attributes.get("data-rotate");
|
||||
let rotate = snippet.attributes.get('data-rotate')
|
||||
if (rotate) {
|
||||
snippet.attributes.add("transform", `rotate(${rotate}, ${x}, ${y})`);
|
||||
snippet.attributes.add('transform', `rotate(${rotate}, ${x}, ${y})`)
|
||||
}
|
||||
let svg = this.nl();
|
||||
svg += `<use x="${x}" y="${y}" `;
|
||||
svg += `xlink:href="#${snippet.def}" ${snippet.attributes.render()}>`;
|
||||
svg += "</use>";
|
||||
let svg = this.nl()
|
||||
svg += `<use x="${x}" y="${y}" `
|
||||
svg += `xlink:href="#${snippet.def}" ${snippet.attributes.render()}>`
|
||||
svg += '</use>'
|
||||
|
||||
return svg;
|
||||
};
|
||||
return svg
|
||||
}
|
||||
|
||||
/** Returns SVG code to open a group */
|
||||
Svg.prototype.openGroup = function(id, attributes = false) {
|
||||
let svg = this.nl() + this.nl();
|
||||
svg += `<!-- Start of group #${id} -->`;
|
||||
svg += this.nl();
|
||||
svg += `<g id="${id}"`;
|
||||
if (attributes) svg += ` ${attributes.render()}`;
|
||||
svg += ">";
|
||||
this.indent();
|
||||
this.openGroups.push(id);
|
||||
let svg = this.nl() + this.nl()
|
||||
svg += `<!-- Start of group #${id} -->`
|
||||
svg += this.nl()
|
||||
svg += `<g id="${id}"`
|
||||
if (attributes) svg += ` ${attributes.render()}`
|
||||
svg += '>'
|
||||
this.indent()
|
||||
this.openGroups.push(id)
|
||||
|
||||
return svg;
|
||||
};
|
||||
return svg
|
||||
}
|
||||
|
||||
/** Returns SVG code to close a group */
|
||||
Svg.prototype.closeGroup = function() {
|
||||
this.outdent();
|
||||
this.outdent()
|
||||
|
||||
return `${this.nl()}</g>${this.nl()}<!-- end of group #${this.openGroups.pop()} -->`;
|
||||
};
|
||||
return `${this.nl()}</g>${this.nl()}<!-- end of group #${this.openGroups.pop()} -->`
|
||||
}
|
||||
|
||||
/** Returns a linebreak + identation */
|
||||
Svg.prototype.nl = function() {
|
||||
return "\n" + this.tab();
|
||||
};
|
||||
return '\n' + this.tab()
|
||||
}
|
||||
|
||||
/** Returns indentation */
|
||||
Svg.prototype.tab = function() {
|
||||
let space = "";
|
||||
let space = ''
|
||||
for (let i = 0; i < this.tabs; i++) {
|
||||
space += " ";
|
||||
space += ' '
|
||||
}
|
||||
|
||||
return space;
|
||||
};
|
||||
return space
|
||||
}
|
||||
|
||||
/** Increases indentation by 1 */
|
||||
Svg.prototype.indent = function() {
|
||||
this.tabs += 1;
|
||||
};
|
||||
this.tabs += 1
|
||||
}
|
||||
|
||||
/** Decreases indentation by 1 */
|
||||
Svg.prototype.outdent = function() {
|
||||
this.tabs -= 1;
|
||||
};
|
||||
this.tabs -= 1
|
||||
}
|
||||
|
||||
/** Returns an unused ID */
|
||||
Svg.prototype.getId = function() {
|
||||
this.freeId += 1;
|
||||
this.freeId += 1
|
||||
|
||||
return "" + this.freeId;
|
||||
};
|
||||
return '' + this.freeId
|
||||
}
|
||||
|
||||
export default Svg;
|
||||
export default Svg
|
||||
|
|
|
@ -1,95 +1,89 @@
|
|||
import Path from "./path";
|
||||
import Point from "./point";
|
||||
import Bezier from "bezier-js";
|
||||
import Path from './path'
|
||||
import Point from './point'
|
||||
import Bezier from 'bezier-js'
|
||||
|
||||
export function capitalize(string) {
|
||||
return string.charAt(0).toUpperCase() + string.slice(1);
|
||||
return string.charAt(0).toUpperCase() + string.slice(1)
|
||||
}
|
||||
|
||||
/** Returns internal hook name for a macro */
|
||||
export function macroName(name) {
|
||||
return `_macro_${name}`;
|
||||
return `_macro_${name}`
|
||||
}
|
||||
|
||||
/** Find intersection of two (endless) lines */
|
||||
export function beamsIntersect(a1, a2, b1, b2) {
|
||||
let slopeA = a1.slope(a2);
|
||||
let slopeB = b1.slope(b2);
|
||||
if (slopeA === slopeB) return false; // Parallel lines
|
||||
let slopeA = a1.slope(a2)
|
||||
let slopeB = b1.slope(b2)
|
||||
if (slopeA === slopeB) return false // Parallel lines
|
||||
|
||||
if (a1.x === a2.x)
|
||||
return new Point(a1.x, slopeB * a1.x + (b1.y - slopeB * b1.x));
|
||||
if (a1.x === a2.x) return new Point(a1.x, slopeB * a1.x + (b1.y - slopeB * b1.x))
|
||||
// Vertical line A
|
||||
else if (b1.x === b2.x)
|
||||
return new Point(b1.x, slopeA * b1.x + (a1.y - slopeA * a1.x));
|
||||
else if (b1.x === b2.x) return new Point(b1.x, slopeA * b1.x + (a1.y - slopeA * a1.x))
|
||||
// Vertical line B
|
||||
else {
|
||||
// Swap points if line A or B goes from right to left
|
||||
if (a1.x > a2.x) a1 = a2.copy();
|
||||
if (b1.x > b2.x) b1 = b2.copy();
|
||||
if (a1.x > a2.x) a1 = a2.copy()
|
||||
if (b1.x > b2.x) b1 = b2.copy()
|
||||
// Find y intercept
|
||||
let iA = a1.y - slopeA * a1.x;
|
||||
let iB = b1.y - slopeB * b1.x;
|
||||
let iA = a1.y - slopeA * a1.x
|
||||
let iB = b1.y - slopeB * b1.x
|
||||
|
||||
// Find intersection
|
||||
let x = (iB - iA) / (slopeA - slopeB);
|
||||
let y = slopeA * x + iA;
|
||||
let x = (iB - iA) / (slopeA - slopeB)
|
||||
let y = slopeA * x + iA
|
||||
|
||||
return new Point(x, y);
|
||||
return new Point(x, y)
|
||||
}
|
||||
}
|
||||
|
||||
/** Find intersection of two line segments */
|
||||
export function linesIntersect(a1, a2, b1, b2) {
|
||||
let p = beamsIntersect(a1, a2, b1, b2);
|
||||
if (!p) return false;
|
||||
let lenA = a1.dist(a2);
|
||||
let lenB = b1.dist(b2);
|
||||
let lenC = a1.dist(p) + p.dist(a2);
|
||||
let lenD = b1.dist(p) + p.dist(b2);
|
||||
if (
|
||||
Math.round(lenA) == Math.round(lenC) &&
|
||||
Math.round(lenB) == Math.round(lenD)
|
||||
)
|
||||
return p;
|
||||
else return false;
|
||||
let p = beamsIntersect(a1, a2, b1, b2)
|
||||
if (!p) return false
|
||||
let lenA = a1.dist(a2)
|
||||
let lenB = b1.dist(b2)
|
||||
let lenC = a1.dist(p) + p.dist(a2)
|
||||
let lenD = b1.dist(p) + p.dist(b2)
|
||||
if (Math.round(lenA) == Math.round(lenC) && Math.round(lenB) == Math.round(lenD)) return p
|
||||
else return false
|
||||
}
|
||||
|
||||
/** Finds out whether a point lies on an endless line */
|
||||
export function pointOnBeam(from, to, check, precision = 1e6) {
|
||||
if (from.sitsOn(check)) return true;
|
||||
if (to.sitsOn(check)) return true;
|
||||
let cross = check.dx(from) * to.dy(from) - check.dy(from) * to.dx(from);
|
||||
if (from.sitsOn(check)) return true
|
||||
if (to.sitsOn(check)) return true
|
||||
let cross = check.dx(from) * to.dy(from) - check.dy(from) * to.dx(from)
|
||||
|
||||
if (Math.abs(Math.round(cross * precision) / precision) === 0) return true;
|
||||
else return false;
|
||||
if (Math.abs(Math.round(cross * precision) / precision) === 0) return true
|
||||
else return false
|
||||
}
|
||||
|
||||
/** Finds out whether a point lies on a line segment */
|
||||
export function pointOnLine(from, to, check, precision = 1e6) {
|
||||
if (!pointOnBeam(from, to, check, precision)) return false;
|
||||
let lenA = from.dist(to);
|
||||
let lenB = from.dist(check) + check.dist(to);
|
||||
if (Math.round(lenA) == Math.round(lenB)) return true;
|
||||
else return false;
|
||||
if (!pointOnBeam(from, to, check, precision)) return false
|
||||
let lenA = from.dist(to)
|
||||
let lenB = from.dist(check) + check.dist(to)
|
||||
if (Math.round(lenA) == Math.round(lenB)) return true
|
||||
else return false
|
||||
}
|
||||
|
||||
/** Finds out whether a point lies on a curve */
|
||||
export function pointOnCurve(start, cp1, cp2, end, check) {
|
||||
if (start.sitsOn(check)) return true;
|
||||
if (end.sitsOn(check)) return true;
|
||||
if (start.sitsOn(check)) return true
|
||||
if (end.sitsOn(check)) return true
|
||||
let curve = new Bezier(
|
||||
{ x: start.x, y: start.y },
|
||||
{ x: cp1.x, y: cp1.y },
|
||||
{ x: cp2.x, y: cp2.y },
|
||||
{ x: end.x, y: end.y }
|
||||
);
|
||||
)
|
||||
let intersections = curve.intersects({
|
||||
p1: { x: check.x - 1, y: check.y },
|
||||
p2: { x: check.x + 1, y: check.y }
|
||||
});
|
||||
if (intersections.length > 0) return intersections.shift();
|
||||
else return false;
|
||||
})
|
||||
if (intersections.length > 0) return intersections.shift()
|
||||
else return false
|
||||
}
|
||||
|
||||
/** Splits a curve on a point */
|
||||
|
@ -97,7 +91,7 @@ export function splitCurve(start, cp1, cp2, end, split) {
|
|||
let [c1, c2] = new Path()
|
||||
.move(start)
|
||||
.curve(cp1, cp2, end)
|
||||
.split(split);
|
||||
.split(split)
|
||||
|
||||
return [
|
||||
{
|
||||
|
@ -112,215 +106,201 @@ export function splitCurve(start, cp1, cp2, end, split) {
|
|||
cp2: c2.ops[1].cp2,
|
||||
end: c2.ops[1].to
|
||||
}
|
||||
];
|
||||
]
|
||||
}
|
||||
|
||||
/** Find where an (endless) line intersects with a certain X-value */
|
||||
export function beamIntersectsX(from, to, x) {
|
||||
if (from.x === to.x) return false; // Vertical line
|
||||
let top = new Point(x, -10);
|
||||
let bottom = new Point(x, 10);
|
||||
if (from.x === to.x) return false // Vertical line
|
||||
let top = new Point(x, -10)
|
||||
let bottom = new Point(x, 10)
|
||||
|
||||
return beamsIntersect(from, to, top, bottom);
|
||||
return beamsIntersect(from, to, top, bottom)
|
||||
}
|
||||
|
||||
/** Find where an (endless) line intersects with a certain Y-value */
|
||||
export function beamIntersectsY(from, to, y) {
|
||||
if (from.y === to.y) return false; // Horizontal line
|
||||
let left = new Point(-10, y);
|
||||
let right = new Point(10, y);
|
||||
if (from.y === to.y) return false // Horizontal line
|
||||
let left = new Point(-10, y)
|
||||
let right = new Point(10, y)
|
||||
|
||||
return beamsIntersect(from, to, left, right);
|
||||
return beamsIntersect(from, to, left, right)
|
||||
}
|
||||
|
||||
/** Convert value in mm to cm or imperial units */
|
||||
export function units(value, to = "metric") {
|
||||
if (to === "imperial") return round(value / 25.4) + '"';
|
||||
else return round(value / 10) + "cm";
|
||||
export function units(value, to = 'metric') {
|
||||
if (to === 'imperial') return round(value / 25.4) + '"'
|
||||
else return round(value / 10) + 'cm'
|
||||
}
|
||||
|
||||
/** Find where a curve intersects with line */
|
||||
export function lineIntersectsCurve(start, end, from, cp1, cp2, to) {
|
||||
let intersections = [];
|
||||
let intersections = []
|
||||
let bz = new Bezier(
|
||||
{ x: from.x, y: from.y },
|
||||
{ x: cp1.x, y: cp1.y },
|
||||
{ x: cp2.x, y: cp2.y },
|
||||
{ x: to.x, y: to.y }
|
||||
);
|
||||
)
|
||||
let line = {
|
||||
p1: { x: start.x, y: start.y },
|
||||
p2: { x: end.x, y: end.y }
|
||||
};
|
||||
}
|
||||
for (let t of bz.intersects(line)) {
|
||||
let isect = bz.get(t);
|
||||
intersections.push(new Point(isect.x, isect.y));
|
||||
let isect = bz.get(t)
|
||||
intersections.push(new Point(isect.x, isect.y))
|
||||
}
|
||||
|
||||
if (intersections.length === 0) return false;
|
||||
else if (intersections.length === 1) return intersections[0];
|
||||
else return intersections;
|
||||
if (intersections.length === 0) return false
|
||||
else if (intersections.length === 1) return intersections[0]
|
||||
else return intersections
|
||||
}
|
||||
|
||||
/** Find where a curve intersects with a given X-value */
|
||||
export function curveIntersectsX(from, cp1, cp2, to, x) {
|
||||
let start = new Point(x, -10000);
|
||||
let end = new Point(x, 10000);
|
||||
return lineIntersectsCurve(start, end, from, cp1, cp2, to);
|
||||
let start = new Point(x, -10000)
|
||||
let end = new Point(x, 10000)
|
||||
return lineIntersectsCurve(start, end, from, cp1, cp2, to)
|
||||
}
|
||||
|
||||
/** Find where a curve intersects with a given Y-value */
|
||||
export function curveIntersectsY(from, cp1, cp2, to, y) {
|
||||
let start = new Point(-10000, y);
|
||||
let end = new Point(10000, y);
|
||||
return lineIntersectsCurve(start, end, from, cp1, cp2, to);
|
||||
let start = new Point(-10000, y)
|
||||
let end = new Point(10000, y)
|
||||
return lineIntersectsCurve(start, end, from, cp1, cp2, to)
|
||||
}
|
||||
|
||||
/** Find where a curve intersects with another curve */
|
||||
export function curvesIntersect(
|
||||
fromA,
|
||||
cp1A,
|
||||
cp2A,
|
||||
toA,
|
||||
fromB,
|
||||
cp1B,
|
||||
cp2B,
|
||||
toB
|
||||
) {
|
||||
let precision = 0.005; // See https://github.com/Pomax/bezierjs/issues/99
|
||||
let intersections = [];
|
||||
export function curvesIntersect(fromA, cp1A, cp2A, toA, fromB, cp1B, cp2B, toB) {
|
||||
let precision = 0.005 // See https://github.com/Pomax/bezierjs/issues/99
|
||||
let intersections = []
|
||||
let curveA = new Bezier(
|
||||
{ x: fromA.x, y: fromA.y },
|
||||
{ x: cp1A.x, y: cp1A.y },
|
||||
{ x: cp2A.x, y: cp2A.y },
|
||||
{ x: toA.x, y: toA.y }
|
||||
);
|
||||
)
|
||||
let curveB = new Bezier(
|
||||
{ x: fromB.x, y: fromB.y },
|
||||
{ x: cp1B.x, y: cp1B.y },
|
||||
{ x: cp2B.x, y: cp2B.y },
|
||||
{ x: toB.x, y: toB.y }
|
||||
);
|
||||
)
|
||||
|
||||
for (let tvalues of curveA.intersects(curveB, precision)) {
|
||||
let intersection = curveA.get(tvalues.substr(0, tvalues.indexOf("/")));
|
||||
intersections.push(new Point(intersection.x, intersection.y));
|
||||
let intersection = curveA.get(tvalues.substr(0, tvalues.indexOf('/')))
|
||||
intersections.push(new Point(intersection.x, intersection.y))
|
||||
}
|
||||
|
||||
if (intersections.length === 0) return false;
|
||||
else if (intersections.length === 1) return intersections.shift();
|
||||
if (intersections.length === 0) return false
|
||||
else if (intersections.length === 1) return intersections.shift()
|
||||
else {
|
||||
let unique = [];
|
||||
let unique = []
|
||||
for (let i of intersections) {
|
||||
let dupe = false;
|
||||
let dupe = false
|
||||
for (let u of unique) {
|
||||
if (i.sitsRoughlyOn(u)) dupe = true;
|
||||
if (i.sitsRoughlyOn(u)) dupe = true
|
||||
}
|
||||
if (!dupe) unique.push(i);
|
||||
if (!dupe) unique.push(i)
|
||||
}
|
||||
return unique;
|
||||
return unique
|
||||
}
|
||||
}
|
||||
|
||||
/** Find the intersections between two circles */
|
||||
export function circlesIntersect(c1, r1, c2, r2, sort = "x") {
|
||||
let dx = c1.dx(c2);
|
||||
let dy = c1.dy(c2);
|
||||
let dist = c1.dist(c2);
|
||||
export function circlesIntersect(c1, r1, c2, r2, sort = 'x') {
|
||||
let dx = c1.dx(c2)
|
||||
let dy = c1.dy(c2)
|
||||
let dist = c1.dist(c2)
|
||||
// Check for edge cases
|
||||
if (dist > parseFloat(r1) + parseFloat(r2)) return false; // Circles do not intersect
|
||||
if (dist < parseFloat(r2) - parseFloat(r1)) return false; // One circle is contained in the other
|
||||
if (dist === 0 && r1 === r2) return false; // Two circles are identical
|
||||
let chorddistance =
|
||||
(Math.pow(r1, 2) - Math.pow(r2, 2) + Math.pow(dist, 2)) / (2 * dist);
|
||||
let halfchordlength = Math.sqrt(Math.pow(r1, 2) - Math.pow(chorddistance, 2));
|
||||
let chordmidpointx = c1.x + (chorddistance * dx) / dist;
|
||||
let chordmidpointy = c1.y + (chorddistance * dy) / dist;
|
||||
if (dist > parseFloat(r1) + parseFloat(r2)) return false // Circles do not intersect
|
||||
if (dist < parseFloat(r2) - parseFloat(r1)) return false // One circle is contained in the other
|
||||
if (dist === 0 && r1 === r2) return false // Two circles are identical
|
||||
let chorddistance = (Math.pow(r1, 2) - Math.pow(r2, 2) + Math.pow(dist, 2)) / (2 * dist)
|
||||
let halfchordlength = Math.sqrt(Math.pow(r1, 2) - Math.pow(chorddistance, 2))
|
||||
let chordmidpointx = c1.x + (chorddistance * dx) / dist
|
||||
let chordmidpointy = c1.y + (chorddistance * dy) / dist
|
||||
let i1 = new Point(
|
||||
chordmidpointx + (halfchordlength * dy) / dist,
|
||||
chordmidpointy - (halfchordlength * dx) / dist
|
||||
);
|
||||
)
|
||||
let i2 = new Point(
|
||||
chordmidpointx - (halfchordlength * dy) / dist,
|
||||
chordmidpointy + (halfchordlength * dx) / dist
|
||||
);
|
||||
)
|
||||
|
||||
if ((sort === "x" && i1.x <= i2.x) || (sort === "y" && i1.y <= i2.y))
|
||||
return [i1, i2];
|
||||
else return [i2, i1];
|
||||
if ((sort === 'x' && i1.x <= i2.x) || (sort === 'y' && i1.y <= i2.y)) return [i1, i2]
|
||||
else return [i2, i1]
|
||||
}
|
||||
|
||||
/** Find the intersections between a beam and a circle */
|
||||
export function beamIntersectsCircle(c, r, p1, p2, sort = "x") {
|
||||
let dx = p2.x - p1.x;
|
||||
let dy = p2.y - p1.y;
|
||||
let A = Math.pow(dx, 2) + Math.pow(dy, 2);
|
||||
let B = 2 * (dx * (p1.x - c.x) + dy * (p1.y - c.y));
|
||||
let C = Math.pow(p1.x - c.x, 2) + Math.pow(p1.y - c.y, 2) - Math.pow(r, 2);
|
||||
export function beamIntersectsCircle(c, r, p1, p2, sort = 'x') {
|
||||
let dx = p2.x - p1.x
|
||||
let dy = p2.y - p1.y
|
||||
let A = Math.pow(dx, 2) + Math.pow(dy, 2)
|
||||
let B = 2 * (dx * (p1.x - c.x) + dy * (p1.y - c.y))
|
||||
let C = Math.pow(p1.x - c.x, 2) + Math.pow(p1.y - c.y, 2) - Math.pow(r, 2)
|
||||
|
||||
let det = Math.pow(B, 2) - 4 * A * C;
|
||||
let det = Math.pow(B, 2) - 4 * A * C
|
||||
|
||||
if (A <= 0.0000001 || det < 0) return false;
|
||||
if (A <= 0.0000001 || det < 0) return false
|
||||
// No real solutions
|
||||
else if (det === 0) {
|
||||
// One solution
|
||||
let t = (-1 * B) / (2 * A);
|
||||
let i1 = new Point(p1.x + t * dx, p1.y + t * dy);
|
||||
return [i1];
|
||||
let t = (-1 * B) / (2 * A)
|
||||
let i1 = new Point(p1.x + t * dx, p1.y + t * dy)
|
||||
return [i1]
|
||||
} else {
|
||||
// Two solutions
|
||||
let t = (-1 * B + Math.sqrt(det)) / (2 * A);
|
||||
let i1 = new Point(p1.x + t * dx, p1.y + t * dy);
|
||||
t = (-1 * B - Math.sqrt(det)) / (2 * A);
|
||||
let i2 = new Point(p1.x + t * dx, p1.y + t * dy);
|
||||
if ((sort === "x" && i1.x <= i2.x) || (sort === "y" && i1.y <= i2.y))
|
||||
return [i1, i2];
|
||||
else return [i2, i1];
|
||||
let t = (-1 * B + Math.sqrt(det)) / (2 * A)
|
||||
let i1 = new Point(p1.x + t * dx, p1.y + t * dy)
|
||||
t = (-1 * B - Math.sqrt(det)) / (2 * A)
|
||||
let i2 = new Point(p1.x + t * dx, p1.y + t * dy)
|
||||
if ((sort === 'x' && i1.x <= i2.x) || (sort === 'y' && i1.y <= i2.y)) return [i1, i2]
|
||||
else return [i2, i1]
|
||||
}
|
||||
}
|
||||
/** Find the intersections between a line and a circle */
|
||||
export function lineIntersectsCircle(c, r, p1, p2, sort = "x") {
|
||||
let intersections = beamIntersectsCircle(c, r, p1, p2, sort);
|
||||
if (intersections === false) return false;
|
||||
export function lineIntersectsCircle(c, r, p1, p2, sort = 'x') {
|
||||
let intersections = beamIntersectsCircle(c, r, p1, p2, sort)
|
||||
if (intersections === false) return false
|
||||
else {
|
||||
if (intersections.length === 1) {
|
||||
if (pointOnLine(p1, p2, intersections[0])) return intersections;
|
||||
else return false;
|
||||
if (pointOnLine(p1, p2, intersections[0])) return intersections
|
||||
else return false
|
||||
} else {
|
||||
let i1 = intersections[0];
|
||||
let i2 = intersections[1];
|
||||
if (!pointOnLine(p1, p2, i1, 5) && !pointOnLine(p1, p2, i2, 5))
|
||||
return false;
|
||||
let i1 = intersections[0]
|
||||
let i2 = intersections[1]
|
||||
if (!pointOnLine(p1, p2, i1, 5) && !pointOnLine(p1, p2, i2, 5)) return false
|
||||
else if (pointOnLine(p1, p2, i1, 5) && pointOnLine(p1, p2, i2, 5)) {
|
||||
if ((sort === "x" && i1.x <= i2.x) || (sort === "y" && i1.y <= i2.y))
|
||||
return [i1, i2];
|
||||
else return [i2, i1];
|
||||
} else if (pointOnLine(p1, p2, i1, 5)) return [i1];
|
||||
else if (pointOnLine(p1, p2, i2, 5)) return [i2];
|
||||
if ((sort === 'x' && i1.x <= i2.x) || (sort === 'y' && i1.y <= i2.y)) return [i1, i2]
|
||||
else return [i2, i1]
|
||||
} else if (pointOnLine(p1, p2, i1, 5)) return [i1]
|
||||
else if (pointOnLine(p1, p2, i2, 5)) return [i2]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function curveEdge(curve, edge, steps = 500) {
|
||||
let x = Infinity;
|
||||
let y = Infinity;
|
||||
let p;
|
||||
if (edge === "bottom") y = -Infinity;
|
||||
if (edge === "right") x = -Infinity;
|
||||
let x = Infinity
|
||||
let y = Infinity
|
||||
let p
|
||||
if (edge === 'bottom') y = -Infinity
|
||||
if (edge === 'right') x = -Infinity
|
||||
for (let i = 0; i < steps; i++) {
|
||||
p = curve.get(i / steps);
|
||||
p = curve.get(i / steps)
|
||||
if (
|
||||
(edge === "top" && p.y < y) ||
|
||||
(edge === "bottom" && p.y > y) ||
|
||||
(edge === "right" && p.x > x) ||
|
||||
(edge === "left" && p.x < x)
|
||||
(edge === 'top' && p.y < y) ||
|
||||
(edge === 'bottom' && p.y > y) ||
|
||||
(edge === 'right' && p.x > x) ||
|
||||
(edge === 'left' && p.x < x)
|
||||
) {
|
||||
x = p.x;
|
||||
y = p.y;
|
||||
x = p.x
|
||||
y = p.y
|
||||
}
|
||||
}
|
||||
|
||||
return new Point(x, y);
|
||||
return new Point(x, y)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -335,23 +315,23 @@ export function curveEdge(curve, edge, steps = 500) {
|
|||
* This method does that calculation.
|
||||
*/
|
||||
export function stretchToScale(stretch) {
|
||||
return 1 / (1 + parseFloat(stretch));
|
||||
return 1 / (1 + parseFloat(stretch))
|
||||
}
|
||||
|
||||
export function round(value) {
|
||||
return Math.round(value * 1e2) / 1e2;
|
||||
return Math.round(value * 1e2) / 1e2
|
||||
}
|
||||
|
||||
export function sampleStyle(run, runs) {
|
||||
let hue = (run - 1) * (330 / runs);
|
||||
let hue = (run - 1) * (330 / runs)
|
||||
|
||||
return `stroke: hsl(${hue}, 100%, 35%);`;
|
||||
return `stroke: hsl(${hue}, 100%, 35%);`
|
||||
}
|
||||
|
||||
export function deg2rad(degrees) {
|
||||
return degrees * (Math.PI / 180);
|
||||
return degrees * (Math.PI / 180)
|
||||
}
|
||||
|
||||
export function rad2deg(radians) {
|
||||
return (radians / Math.PI) * 180;
|
||||
return (radians / Math.PI) * 180
|
||||
}
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
import React from "react";
|
||||
import freesewing from "@freesewing/core";
|
||||
import Workbench from "@freesewing/components/Workbench";
|
||||
import "typeface-roboto-condensed";
|
||||
import "@freesewing/css-theme";
|
||||
import React from 'react'
|
||||
import freesewing from '@freesewing/core'
|
||||
import Workbench from '@freesewing/components/Workbench'
|
||||
import 'typeface-roboto-condensed'
|
||||
import '@freesewing/css-theme'
|
||||
|
||||
import Pattern from "pattern";
|
||||
import Pattern from 'pattern'
|
||||
|
||||
const App = props => {
|
||||
let instance = new Pattern();
|
||||
let config = instance.config;
|
||||
let instance = new Pattern()
|
||||
let config = instance.config
|
||||
return (
|
||||
<Workbench
|
||||
freesewing={freesewing}
|
||||
|
@ -16,7 +16,7 @@ const App = props => {
|
|||
config={config}
|
||||
userLanguage="{{language}}"
|
||||
/>
|
||||
);
|
||||
};
|
||||
)
|
||||
}
|
||||
|
||||
export default App;
|
||||
export default App
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import App from "./App";
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import App from './App'
|
||||
|
||||
it("renders without crashing", () => {
|
||||
const div = document.createElement("div");
|
||||
ReactDOM.render(<App />, div);
|
||||
ReactDOM.unmountComponentAtNode(div);
|
||||
});
|
||||
it('renders without crashing', () => {
|
||||
const div = document.createElement('div')
|
||||
ReactDOM.render(<App />, div)
|
||||
ReactDOM.unmountComponentAtNode(div)
|
||||
})
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue