1
0
Fork 0
freesewing/packages/carlton/src/collar.js

185 lines
6 KiB
JavaScript
Raw Normal View History

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