1
0
Fork 0
freesewing/packages/carlton/src/collar.js
2021-04-24 10:16:31 +02:00

245 lines
7.6 KiB
JavaScript

/**
* 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, 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)
// 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.saBase = 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)
paths.seam = paths.saBase.clone().line(points.standTop).close().attr('class', 'fabric')
if (complete) {
points.title = points.standTopCp.clone()
macro('title', {
at: points.title,
nr: 8,
title: 'collar',
})
// Remove grainline from collarstand part
delete paths.grainline
macro('cutonfold', {
from: points.topLeft,
to: points.standTop,
grainline: true,
})
if (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')
}
if (paperless) {
macro('hd', {
from: points.standTop,
to: points.rot3standTip,
y: points.rot4bottomRight.y + sa + 15,
})
macro('hd', {
from: points.standTop,
to: points.rot4bottomRight,
y: points.rot4bottomRight.y + sa + 30,
})
macro('hd', {
from: points.standTop,
to: points.rot4topRight,
y: points.rot4bottomRight.y + sa + 45,
})
macro('vd', {
from: points.standTop,
to: points.topLeft,
x: points.topLeft.x - 15,
})
macro('vd', {
from: points.rot3standTip,
to: points.topLeft,
x: points.topLeft.x - 30,
})
macro('vd', {
from: points.rot4topRight,
to: points.topLeft,
x: points.rot4topRight.x + sa + 15,
})
macro('vd', {
from: points.rot4bottomRight,
to: points.topLeft,
x: points.rot4topRight.x + sa + 30,
})
macro('ld', {
from: points.rot4bottomRight,
to: points.rot4topRight,
d: -1 * sa - 15,
})
macro('ld', {
from: points.rot3standTip,
to: points.rot4bottomRight,
d: -1 * sa - 15,
})
}
}
return part
}