diff --git a/packages/charlie/config/index.js b/packages/charlie/config/index.js index ec040212d9c..866017aa8a1 100644 --- a/packages/charlie/config/index.js +++ b/packages/charlie/config/index.js @@ -20,9 +20,17 @@ export default { 'backPocketWidth', 'backPocketDepth' ], - frontPockets: ['frontPocketSlantDepth', 'frontPocketSlantWidth'] + frontPockets: [ + 'frontPocketSlantDepth', + 'frontPocketSlantWidth', + 'frontPocketOpening', + 'frontPocketEntry', + 'frontPocketWidth', + 'frontPocketDepth' + ] } ], + waistband: ['splitWaistband', 'waistbandWidth'], advanced: [ 'crossSeamCurveStart', 'crossSeamCurveBend', @@ -53,7 +61,16 @@ export default { hide: ['titanBack', 'titanFront'], inject: { back: 'titanBack', - front: 'titanFront' + front: 'titanFront', + frontPocket: 'front' + }, + parts: ['backPocket', 'backPocketFacing'], + dependencies: { + // The inheritance makes this a bit messy + back: ['titanBack', 'titanFront', 'front'], + waistband: ['titanBack', 'titanFront', 'front', 'back'], + waistbandButtonSide: 'waistband', + waistbandButtonholeSide: 'waistband' }, options: { // Constants (from Titan) @@ -67,6 +84,7 @@ export default { // Charlie constants waistbandReduction: 0.3, // See src/index.js + waistbandFactor: 0.1, // Fit (from Titan) waistEase: { pct: 3, min: 0, max: 10 }, @@ -91,20 +109,27 @@ export default { backPocketVerticalPlacement: { pct: 24, min: 18, max: 30 }, backPocketHorizontalPlacement: { pct: 55, min: 48, max: 62 }, backPocketWidth: { pct: 55, min: 50, max: 60 }, - backPocketDepth: { pct: 20, min: 10, max: 40 }, + backPocketDepth: { pct: 60, min: 40, max: 80 }, + backPocketFacing: { bool: true }, - // Back pockets + // Front pockets frontPocketSlantDepth: { pct: 75, min: 50, max: 100 }, frontPocketSlantWidth: { pct: 20, min: 10, max: 30 }, + frontPocketOpening: { pct: 80, min: 60, max: 90 }, + frontPocketEntry: { pct: 20, min: 10, max: 30 }, + frontPocketWidth: { pct: 55, min: 45, max: 65 }, + frontPocketDepth: { pct: 100, min: 85, max: 110 }, // Belt waistbandWidth: { mm: 25, min: 5, max: 45 }, - // Advanced - Fly + // Fly flyCurve: { pct: 66, min: 50, max: 100 }, flyLength: { pct: 35, min: 0, max: 70 }, - flyWidth: { pct: 15, min: 10, max: 20 } + flyWidth: { pct: 15, min: 10, max: 20 }, - // Pockets + // Waistband + splitWaistband: { bool: true }, + waistbandWidth: { pct: 50, min: 25, max: 75 } } } diff --git a/packages/charlie/src/back-pocket-facing.js b/packages/charlie/src/back-pocket-facing.js new file mode 100644 index 00000000000..baf03e4eabd --- /dev/null +++ b/packages/charlie/src/back-pocket-facing.js @@ -0,0 +1,73 @@ +export default (part) => { + // Shorthand + let { + points, + Point, + paths, + Path, + measurements, + options, + complete, + paperless, + store, + macro, + utils, + snippets, + Snippet, + sa + } = part.shorthand() + + points.leftNotch = new Point(store.get('backPocketWidth') / -2, 0) + points.rightNotch = points.leftNotch.flipX() + points.topLeft = new Point(points.leftNotch.x * 1.2, store.get('backPocketToWaistband') * -1) + points.topRight = points.topLeft.flipX() + points.bottomLeft = new Point(points.leftNotch.x * 1.2, points.rightNotch.x * 0.6) + points.bottomRight = points.bottomLeft.flipX() + + paths.saBase = new Path() + .move(points.bottomRight) + .line(points.topRight) + .line(points.topLeft) + .line(points.bottomLeft) + .setRender(false) + paths.seam = paths.saBase + .clone() + .line(points.bottomRight) + .close() + .setRender(true) + .attr('class', 'fabric') + + if (complete) { + paths.opening = new Path() + .move(points.leftNotch) + .line(points.rightNotch) + .attr('class', 'dashed') + points.titleAnchor = new Point(0, 0) + macro('title', { + at: points.titleAnchor, + nr: '5b', + title: 'pocketFacing' + }) + points.grainlineTop = points.topLeft.shiftFractionTowards(points.topRight, 0.15) + points.grainlineBottom = points.bottomLeft.shiftFractionTowards(points.bottomRight, 0.15) + macro('grainline', { + from: points.grainlineTop, + to: points.grainlineBottom + }) + + if (sa) { + let saBase = paths.saBase.offset(sa) + paths.sa = new Path() + .move(points.bottomRight) + .line(saBase.start()) + .join(saBase) + .line(points.bottomLeft) + .attr('class', 'sa fabric') + } + + if (paperless) { + } + } + + return part +} diff --git a/packages/charlie/src/back-pocket.js b/packages/charlie/src/back-pocket.js new file mode 100644 index 00000000000..6e9f945eba5 --- /dev/null +++ b/packages/charlie/src/back-pocket.js @@ -0,0 +1,79 @@ +export default (part) => { + // Shorthand + let { + points, + Point, + paths, + Path, + measurements, + options, + complete, + paperless, + store, + macro, + utils, + snippets, + Snippet, + sa + } = part.shorthand() + + //store.set('backPocketToWaistband', base * options.backPocketVerticalPlacement) + //store.set('backPocketWidth', base * options.backPocketWidth) + //store.set('backPocketDepth', base * options.backPocketDepth) + + points.leftNotch = new Point(store.get('backPocketWidth') / -2, 0) + points.rightNotch = points.leftNotch.flipX() + points.waistbandLeft = new Point( + points.leftNotch.x * 1.2, + store.get('backPocketToWaistband') * -1 + ) + points.waistbandRight = points.waistbandLeft.flipX() + points.foldLeft = new Point( + points.waistbandLeft.x, + points.leftNotch.y + store.get('backPocketDepth') + ) + points.foldRight = points.foldLeft.flipX() + points.bottomLeft = new Point( + points.waistbandLeft.x, + points.foldLeft.y + store.get('backPocketDepth') + ) + points.bottomRight = points.bottomLeft.flipX() + + paths.seam = new Path() + .move(points.waistbandRight) + .line(points.waistbandLeft) + .line(points.bottomLeft) + .line(points.bottomRight) + .line(points.waistbandRight) + .close() + .attr('class', 'lining') + + if (complete) { + paths.opening = new Path() + .move(points.leftNotch) + .line(points.rightNotch) + .attr('class', 'dashed') + paths.fold = new Path().move(points.foldLeft).line(points.foldRight).attr('class', 'help') + points.titleAnchor = points.rightNotch.shiftFractionTowards(points.foldLeft, 0.5) + macro('title', { + at: points.titleAnchor, + nr: 5, + title: 'pocketBag' + }) + points.logoAnchor = points.foldLeft.shiftFractionTowards(points.bottomRight, 0.5) + snippets.logo = new Snippet('logo', points.logoAnchor) + points.grainlineTop = points.waistbandLeft.shiftFractionTowards(points.waistbandRight, 0.15) + points.grainlineBottom = points.bottomLeft.shiftFractionTowards(points.bottomRight, 0.15) + macro('grainline', { + from: points.grainlineTop, + to: points.grainlineBottom + }) + + if (sa) paths.sa = paths.seam.offset(sa).attr('class', 'lining sa') + + if (paperless) { + } + } + + return part +} diff --git a/packages/charlie/src/back.js b/packages/charlie/src/back.js index 062be53d172..545c069ca99 100644 --- a/packages/charlie/src/back.js +++ b/packages/charlie/src/back.js @@ -1,40 +1,25 @@ export default (part) => { - - /* - * Helper method to draw the inseam path - */ - const drawInseam = () => - options.fitKnee - ? new Path() - .move(points.fork) - .curve(points.forkCp2, points.kneeInCp1, points.kneeIn) - .line(points.floorIn) - : new Path().move(points.fork).curve(points.forkCp2, points.kneeInCp1, points.floorIn) - /* - * Helper method to draw the outseam path - */ + // Helper method to draw the outseam path const drawOutseam = () => { let waistOut = points.styleWaistOut || points.waistOut - if (options.fitKnee) { - if (points.waistOut.x > points.seatOut.x) - return new Path() - .move(points.floorOut) - .line(points.kneeOut) - .curve(points.kneeOutCp2, points.seatOut, waistOut) - else - return new Path() - .move(points.floorOut) - .line(points.kneeOut) - .curve(points.kneeOutCp2, points.seatOutCp1, points.seatOut) - .curve_(points.seatOutCp2, points.waistOut) + if (points.waistOut.x > points.seatOut.x) { + let outseam = new Path() + .move(points.styleWaistOut) + .curve(points.seatOut, points.kneeOutCp2, points.floorOut) + return new Path() + .move(points.slantOut) + .line(points.pocketOpeningTop) + .line(points.pocketOpeningTopIn) + .line(points.pocketOpeningBottomIn) + .line(points.pocketOpeningBottom) + .line(points.slantBottom) + .join(outseam.split(points.slantBottom).pop()) + .reverse() } else { - if (points.waistOut.x > points.seatOut.x) - return new Path().move(points.floorOut).curve(points.kneeOutCp2, points.seatOut, waistOut) - else - return new Path() - .move(points.floorOut) - .curve(points.kneeOutCp2, points.seatOutCp1, points.seatOut) - .curve_(points.seatOutCp2, waistOut) + return new Path() + .move(points.floorOut) + .curve(points.kneeOutCp2, points.seatOutCp1, points.seatOut) + .curve_(points.seatOutCp2, waistOut) } } /* @@ -42,19 +27,16 @@ export default (part) => { */ const drawPath = () => { let waistIn = points.styleWaistIn || points.waistIn - return drawInseam() - .line(points.floorOut) - .join(drawOutseam()) + return drawOutseam() .line(points.backDartRight) .noop('dart') .line(points.backDartLeft) .line(waistIn) .line(points.crossSeamCurveStart) .curve(points.crossSeamCurveCp1, points.crossSeamCurveCp2, points.fork) - .close() + .curve(points.forkCp2, points.kneeInCp1, points.floorIn) } - // Shorthand let { points, @@ -75,33 +57,68 @@ export default (part) => { // Mark back pocket let base = points.styleWaistIn.dist(points.styleWaistOut) - let v = base * options.backPocketVerticalPlacement - let h = base * options.backPocketHorizontalPlacement - let w = base * options.backPocketWidth - let d = base * options.backPocketDepth - let a = points.styleWaistIn.angle(points.styleWaistOut) - points.waistPocketCenter = points.styleWaistIn.shiftFractionTowards(points.styleWaistOut, options.backPocketHorizontalPlacement) - points.pocketCenter = points.waistPocketCenter.shift(a-90, v) - points.pocketRight = points.pocketCenter.shift(a, w/2) - points.pocketLeft = points.pocketCenter.shift(a, w/-2) + let angle = points.styleWaistIn.angle(points.styleWaistOut) + store.set('backPocketToWaistband', base * options.backPocketVerticalPlacement) + store.set('backPocketWidth', base * options.backPocketWidth) + store.set('backPocketDepth', base * options.backPocketDepth) + points.waistPocketCenter = points.styleWaistIn.shiftFractionTowards( + points.styleWaistOut, + options.backPocketHorizontalPlacement + ) + points.pocketCenter = points.waistPocketCenter.shift( + angle - 90, + store.get('backPocketToWaistband') + ) + points.pocketRight = points.pocketCenter.shift(angle, store.get('backPocketWidth') / 2) + points.pocketLeft = points.pocketCenter.shift(angle, store.get('backPocketWidth') / -2) // Back dart points.tmp1 = points.waistPocketCenter.rotate(6.66, points.pocketCenter) points.tmp2 = points.waistPocketCenter.rotate(-6.66, points.pocketCenter) points.backDartLeft = points.pocketCenter.shiftFractionTowards(points.tmp1, 1.05) points.backDartRight = points.pocketCenter.shiftFractionTowards(points.tmp2, 1.05) - let newBase = points.styleWaistIn.dist(points.backDartLeft) - + points.styleWaistOut.dist(points.backDartRight) + let newBase = + points.styleWaistIn.dist(points.backDartLeft) + points.styleWaistOut.dist(points.backDartRight) let delta = base - newBase // Adapt waist to new darted reality for (let p of ['styleWaistIn', 'crossSeamCurveStart', 'crossSeamCurveCp1']) { - points[p] = points[p].shift(a + 180, delta/2) + points[p] = points[p].shift(angle + 180, delta / 2) } - points.styleWaistOut = points.styleWaistOut.shift(a, delta/2) + points.styleWaistOut = points.styleWaistOut.shift(angle, delta / 2) + + // Construct pocket tab + if (points.waistOut.x > points.seatOut.x) { + let outseam = new Path() + .move(points.styleWaistOut) + .curve(points.seatOut, points.kneeOutCp2, points.floorOut) + points.slantBottom = outseam.shiftAlong(store.get('slantLength')) + } + points.slantOut = points.styleWaistIn.shiftOutwards(points.styleWaistOut, store.get('slantWidth')) + points.pocketOpeningTop = points.slantOut.shiftTowards( + points.slantBottom, + store.get('pocketTabStart') + ) + points.pocketOpeningBottom = points.pocketOpeningTop.shiftTowards( + points.slantBottom, + store.get('pocketTabInnerLength') + ) + let slant = points.slantOut.angle(points.slantBottom) + points.pocketOpeningTopIn = points.pocketOpeningTop.shift(slant + 90, store.get('pocketTabWidth')) + points.pocketOpeningBottomIn = points.pocketOpeningTopIn.shift( + slant, + store.get('pocketTabOuterLength') + ) + + // Store waistband length + store.set( + 'waistbandBack', + points.styleWaistIn.dist(points.backDartLeft) + points.backDartRight.dist(points.styleWaistOut) + ) paths.saBase = drawPath() paths.seam = paths.saBase .insop('dart', new Path().line(points.pocketCenter)) + .close() .attr('class', 'fabric') paths.saBase.setRender(false) @@ -110,7 +127,33 @@ export default (part) => { .move(points.pocketLeft) .line(points.pocketRight) .attr('class', 'fabric dashed') + points.titleAnchor = new Point(points.knee.x, points.fork.y) + macro('title', { + at: points.titleAnchor, + nr: 1, + title: 'back' + }) + snippets.logo = new Snippet('logo', points.titleAnchor.shiftFractionTowards(points.knee, 0.5)) + macro('sprinkle', { + snippet: 'bnotch', + on: ['grainlineBottom', 'slantBottom', 'styleWaistOut'] + }) + paths.fold = new Path() + .move(points.pocketOpeningTop) + .line(points.pocketOpeningBottom) + .attr('class', 'help') + if (sa) { + paths.sa = paths.saBase + .offset(sa) + .join( + new Path() + .move(points.floorIn) + .line(points.floorOut) + .offset(sa * 3) + ) + .close() + .attr('class', 'fabric sa') } if (paperless) { diff --git a/packages/charlie/src/front-pocket.js b/packages/charlie/src/front-pocket.js new file mode 100644 index 00000000000..6cc32bbafb5 --- /dev/null +++ b/packages/charlie/src/front-pocket.js @@ -0,0 +1,80 @@ +export default (part) => { + // Shorthand + let { + points, + Point, + paths, + Path, + measurements, + options, + complete, + paperless, + store, + macro, + utils, + snippets, + Snippet, + sa + } = part.shorthand() + + // Clean up + for (let id in paths) delete paths[id] + for (let id in snippets) delete snippets[id] + + // Straighten part + let slant = points.pocketbagBottomRight.angle(points.pocketbagTopRight) + for (let id of [ + 'topPleat', + 'pocketbagTopLeft', + 'mirroredPocketOpeningTopIn', + 'mirroredPocketOpeningBottomIn', + 'pocketbagBump', + 'pocketbagBottomCp', + 'pocketbagBottom', + 'pocketbagBottomRight' + ]) + points[id] = points[id].rotate(-1 * (slant - 90), points.pocketbagTopRight) + console.log(slant) + + paths.saBase = new Path() + .move(points.pocketbagTopRight) + .line(points.pocketbagTopLeft) + .line(points.mirroredPocketOpeningBottomIn) + .curve(points.pocketbagBump, points.pocketbagBottomCp, points.pocketbagBottom) + .line(points.pocketbagBottomRight) + paths.seam = paths.saBase + .clone() + .line(points.pocketbagTopRight) + .close() + .attr('class', 'lining', true) + + if (complete) { + points.titleAnchor = points.pocketbagTopRight.shiftFractionTowards( + points.pocketbagBottomCp, + 0.5 + ) + macro('title', { + at: points.titleAnchor, + nr: 4, + title: 'pocketBag' + }) + macro('cutonfold', { + from: points.pocketbagBottomRight, + to: points.pocketbagTopRight, + grainline: true + }) + + if (sa) { + paths.sa = new Path() + .move(points.pocketbagTopRight) + .join(paths.saBase.offset(sa)) + .line(points.pocketbagBottomRight) + .attr('class', 'lining sa') + } + + if (paperless) { + } + } + + return part +} diff --git a/packages/charlie/src/front.js b/packages/charlie/src/front.js index 598d177b5d1..bd0c4c3de14 100644 --- a/packages/charlie/src/front.js +++ b/packages/charlie/src/front.js @@ -1,44 +1,20 @@ export default (part) => { // Helper method to draw the outseam path - const drawOutseam = () => { - // Helper object holding the Titan side seam path - let sideSeam = - points.waistOut.x < points.seatOut.x - ? new Path() - .move(points.styleWaistOut) - .curve(points.seatOut, points.kneeOutCp1, points.floorOut) - : new Path() - .move(points.styleWaistOut) - ._curve(points.seatOutCp1, points.seatOut) - .curve(points.seatOutCp2, points.kneeOutCp1, points.floorOut) - // Draw in pocket slant - points.pocketSlantTop = points.styleWaistIn.shiftFractionTowards( - points.styleWaistOut, - 1 - options.frontPocketSlantWidth - ) - // Find lowest possible pocket slant point - points.pocketSlantLowest = sideSeam.intersectsY(points.fork.y).pop() - // Length to lowest possible slant point - store.set( - 'slantLength', - sideSeam.split(points.pocketSlantLowest).shift().length() * options.frontPocketSlantDepth - ) - // Create actual slant point - points.pocketSlantBottom = sideSeam.shiftAlong(store.get('slantLength')) - - // Handy for later - store.set('frontSideSeam', sideSeam) - - return new Path() + const drawOutseam = () => + new Path() .move(points.pocketSlantTop) + .line(points.pocketOpeningTop) + .line(points.pocketOpeningTopIn) + .line(points.pocketOpeningBottomIn) + .line(points.pocketOpeningBottom) .line(points.pocketSlantBottom) .join(sideSeam.split(points.pocketSlantBottom).pop()) - } // Helper method to draw the outline path - const drawPath = () => - drawOutseam() - .line(points.floorIn) + const drawPath = () => { + let outseam = drawOutseam() + return new Path() + .move(points.floorIn) .curve(points.kneeInCp2, points.forkCp1, points.fork) .join( new Path() @@ -51,7 +27,8 @@ export default (part) => { .line(points.flyTop) .line(points.styleWaistIn) .line(points.pocketSlantTop) - .close() + .join(outseam) + } // Shorthand let { @@ -91,8 +68,97 @@ export default (part) => { points.flyCurveCp1 = points.flyBottom.shiftFractionTowards(points.flyCorner, options.flyCurve) points.flyCurveCp2 = points.flyCurveStart.shiftFractionTowards(points.flyCorner, options.flyCurve) + // Helper object holding the Titan side seam path + const sideSeam = + points.waistOut.x < points.seatOut.x + ? new Path() + .move(points.styleWaistOut) + .curve(points.seatOut, points.kneeOutCp1, points.floorOut) + : new Path() + .move(points.styleWaistOut) + ._curve(points.seatOutCp1, points.seatOut) + .curve(points.seatOutCp2, points.kneeOutCp1, points.floorOut) + + // Construct pocket slant + points.pocketSlantTop = points.styleWaistIn.shiftFractionTowards( + points.styleWaistOut, + 1 - options.frontPocketSlantWidth + ) + points.pocketSlantLowest = sideSeam.intersectsY(points.fork.y).pop() + store.set('slantWidth', points.styleWaistOut.dist(points.pocketSlantTop)) + store.set( + 'slantLength', + sideSeam.split(points.pocketSlantLowest).shift().length() * options.frontPocketSlantDepth + ) + points.pocketSlantBottom = sideSeam.shiftAlong(store.get('slantLength')) + + // Construct front pocket + let slant = points.pocketSlantTop.angle(points.pocketSlantBottom) + let base = points.pocketSlantTop.dist(points.pocketSlantBottom) + points.pocketOpeningTop = points.pocketSlantTop.shift( + slant, + (base * (1 - options.frontPocketOpening)) / 2 + ) + points.pocketOpeningBottom = points.pocketSlantBottom.shift( + slant + 180, + (base * (1 - options.frontPocketOpening)) / 2 + ) + points.pocketOpeningTopIn = points.pocketOpeningTop.shift( + slant - 90, + base * options.frontPocketEntry + ) + points.pocketOpeningBottomIn = utils.beamIntersectsY( + points.pocketOpeningTopIn, + points.pocketOpeningTopIn.shift(slant, 666), + points.pocketSlantBottom.y + ) + macro('mirror', { + mirror: [points.pocketOpeningTop, points.pocketOpeningBottom], + points: [points.pocketOpeningTopIn, points.pocketOpeningBottomIn] + }) + store.set('pocketTabWidth', base * options.frontPocketEntry) + store.set('pocketTabInnerLength', points.pocketOpeningTop.dist(points.pocketOpeningBottom)) + store.set( + 'pocketTabOuterLength', + points.mirroredPocketOpeningTopIn.dist(points.mirroredPocketOpeningBottomIn) + ) + store.set('pocketTabStart', points.pocketSlantTop.dist(points.pocketOpeningTop)) + + // Construct pocket bag + points.pocketbagTopLeft = utils.beamsIntersect( + points.mirroredPocketOpeningBottomIn, + points.mirroredPocketOpeningTopIn, + points.pocketSlantTop, + points.styleWaistIn + ) + points.pocketbagTopRight = points.pocketbagTopLeft.shiftFractionTowards( + points.styleWaistIn, + options.frontPocketWidth + ) + points.pocketbagBottomRight = points.pocketbagTopRight.shift( + points.pocketbagTopLeft.angle(points.pocketbagTopRight) - 90, + points.styleWaistIn.dy(points.fork) * options.frontPocketDepth * 1.5 + ) + points.pocketbagBump = utils.beamIntersectsY( + points.mirroredPocketOpeningTopIn, + points.mirroredPocketOpeningBottomIn, + points.pocketSlantLowest.y + ) + points.pocketbagBottomCp = new Point( + points.mirroredPocketOpeningBottomIn.x, + points.pocketbagBottomRight.y + ) + points.pocketbagBottom = points.pocketbagBottomRight.shiftFractionTowards( + points.pocketbagBottomCp, + 0.5 + ) + // Draw path - paths.seam = drawPath().attr('class', 'fabric') + paths.seam = drawPath().close().attr('class', 'fabric') + + // Store waistband length + store.set('waistbandFront', points.styleWaistIn.dist(points.styleWaistOut)) + store.set('waistbandFly', points.styleWaistIn.dist(points.flyTop)) if (complete) { points.titleAnchor = new Point(points.knee.x, points.fork.y) @@ -101,7 +167,7 @@ export default (part) => { nr: 2, title: 'front' }) - snippets.logo = new Snippet('logo', points.titleAnchor.shiftFractionTowards(points.knee, 0.5)) + snippets.logo = new Snippet('logo', points.titleAnchor.shiftFractionTowards(points.knee, 0.666)) points.topPleat = utils.beamsIntersect( points.styleWaistIn, points.styleWaistOut, @@ -123,13 +189,40 @@ export default (part) => { .shift() ) .attr('class', 'fabric stoke-sm dashed') - paths.slantHint = new Path() - .move(points.pocketSlantTop) - .line(points.styleWaistOut) - .join(store.get('frontSideSeam').split(points.pocketSlantBottom).shift()) - .attr('class', 'fabric stoke-sm dashed') + paths.pocketEntry = new Path() + .move(points.pocketOpeningTop) + .line(points.mirroredPocketOpeningTopIn) + .line(points.mirroredPocketOpeningBottomIn) + .line(points.pocketOpeningBottom) + .attr('class', 'fabric dashed stroke-sm') + paths.pocketFold = new Path() + .move(points.pocketOpeningTop) + .line(points.pocketOpeningBottom) + .attr('class', 'help') + paths.pocketBag = new Path() + .move(points.pocketbagTopRight) + .line(points.pocketbagBottomRight) + .line(points.pocketbagBottom) + .curve(points.pocketbagBottomCp, points.pocketbagBump, points.mirroredPocketOpeningBottomIn) + .line(points.pocketbagTopLeft) + .attr('class', 'lining dashed') + macro('sprinkle', { + snippet: 'notch', + on: ['pocketbagTopLeft', 'pocketbagTopRight'] + }) if (sa) { + paths.sa = drawPath() + .offset(sa) + .join( + new Path() + .move(points.floorOut) + .line(points.floorIn) + .offset(sa * 3) + ) + .close() + .trim() + .attr('class', 'fabric sa') } if (paperless) { diff --git a/packages/charlie/src/index.js b/packages/charlie/src/index.js index efa207acb51..6ccc044e677 100644 --- a/packages/charlie/src/index.js +++ b/packages/charlie/src/index.js @@ -1,11 +1,17 @@ import freesewing from '@freesewing/core' import Titan from '@freesewing/titan' import plugins from '@freesewing/plugin-bundle' - +import mirrorPlugin from '@freesewing/plugin-mirror' import config from '../config' // Parts import draftBack from './back' import draftFront from './front' +import draftWaistband from './waistband' +import draftWaistbandButtonSide from './waistband-button-side' +import draftWaistbandButtonholeSide from './waistband-buttonhole-side' +import draftFrontPocket from './front-pocket' +import draftBackPocket from './back-pocket' +import draftBackPocketFacing from './back-pocket-facing' // Hack the waistHeight option to make room for waistband const waistbandPlugin = { @@ -21,7 +27,7 @@ const waistbandPlugin = { } // Create design -const Pattern = new freesewing.Design(config, [plugins, waistbandPlugin]) +const Pattern = new freesewing.Design(config, [plugins, mirrorPlugin, waistbandPlugin]) // Attach titan draft methods to prototype for (let p of ['Front', 'Back']) { @@ -33,5 +39,11 @@ for (let p of ['Front', 'Back']) { // Attach charlie draft methods to prototype Pattern.prototype.draftBack = (part) => draftBack(part) Pattern.prototype.draftFront = (part) => draftFront(part) +Pattern.prototype.draftWaistband = (part) => draftWaistband(part) +Pattern.prototype.draftWaistbandButtonSide = (part) => draftWaistbandButtonSide(part) +Pattern.prototype.draftWaistbandButtonholeSide = (part) => draftWaistbandButtonholeSide(part) +Pattern.prototype.draftFrontPocket = (part) => draftFrontPocket(part) +Pattern.prototype.draftBackPocket = (part) => draftBackPocket(part) +Pattern.prototype.draftBackPocketFacing = (part) => draftBackPocketFacing(part) export default Pattern diff --git a/packages/charlie/src/waistband-button-side.js b/packages/charlie/src/waistband-button-side.js new file mode 100644 index 00000000000..3899c5e1c79 --- /dev/null +++ b/packages/charlie/src/waistband-button-side.js @@ -0,0 +1,87 @@ +export default (part) => { + // Shorthand + let { + points, + Point, + paths, + Path, + measurements, + options, + complete, + paperless, + store, + macro, + utils, + snippets, + Snippet, + sa + } = part.shorthand() + + if (!options.splitWaistband) return part + + points.topLeft = new Point(0, 0) + points.top = new Point(measurements.waist * options.waistbandWidth * options.waistbandFactor, 0) + points.topRight = new Point(points.top.x * 2, 0) + points.bottomLeft = new Point( + 0, + store.get('waistbandBack') + store.get('waistbandFront') + store.get('waistbandFly') + ) + points.bottom = new Point(points.top.x, points.bottomLeft.y) + points.bottomRight = new Point(points.topRight.x, points.bottomLeft.y) + + paths.saBase = new Path() + .move(points.topLeft) + .line(points.topRight) + .line(points.bottomRight) + .setRender(false) + paths.seam = paths.saBase + .clone() + .line(points.bottomLeft) + .line(points.topLeft) + .close() + .attr('class', 'fabric') + .setRender(true) + + if (complete) { + points.flyNotchRight = points.topRight.shift(-90, store.get('waistbandFly')) + points.flyNotchLeft = new Point(0, points.flyNotchRight.y) + points.firstSideNotchRight = points.flyNotchRight.shift(-90, store.get('waistbandFront')) + points.firstSideNotchLeft = new Point(0, points.firstSideNotchRight.y) + macro('sprinkle', { + snippet: 'notch', + on: ['flyNotchRight', 'flyNotchLeft', 'firstSideNotchRight', 'firstSideNotchLeft', 'bottom'] + }) + points.titleAnchor = points.top.shiftFractionTowards(points.bottom, 0.25) + points.logoAnchor = points.top.shiftFractionTowards(points.bottom, 0.75) + macro('title', { + at: points.titleAnchor, + nr: '3a', + title: 'waistbandButtonSide', + rotation: 90 + }) + macro('grainline', { + from: points.firstSideNotchLeft, + to: points.firstSideNotchRight + }) + snippets.logo = new Snippet('logo', points.logoAnchor) + paths.fold = new Path().move(points.top).line(points.bottom).attr('class', 'fabric help') + if (sa) { + paths.sa = paths.saBase + .offset(sa * -1) + .join( + new Path() + .move(points.bottomRight) + .line(points.bottomLeft) + .line(points.topLeft) + .offset(sa * -2) + ) + .close() + .attr('class', 'fabric sa') + } + + if (paperless) { + } + } + + return part +} diff --git a/packages/charlie/src/waistband-buttonhole-side.js b/packages/charlie/src/waistband-buttonhole-side.js new file mode 100644 index 00000000000..0c5dcb9d307 --- /dev/null +++ b/packages/charlie/src/waistband-buttonhole-side.js @@ -0,0 +1,81 @@ +export default (part) => { + // Shorthand + let { + points, + Point, + paths, + Path, + measurements, + options, + complete, + paperless, + store, + macro, + utils, + snippets, + Snippet, + sa + } = part.shorthand() + + if (!options.splitWaistband) return part + + points.topLeft = new Point(0, 0) + points.top = new Point(measurements.waist * options.waistbandWidth * options.waistbandFactor, 0) + points.topRight = new Point(points.top.x * 2, 0) + points.bottomLeft = new Point(0, store.get('waistbandFront') + store.get('waistbandBack')) + points.bottom = new Point(points.top.x, points.bottomLeft.y) + points.bottomRight = new Point(points.topRight.x, points.bottomLeft.y) + + paths.saBase = new Path() + .move(points.topRight) + .line(points.bottomRight) + .line(points.bottomLeft) + .setRender(false) + paths.seam = paths.saBase + .clone() + .line(points.topLeft) + .close() + .attr('class', 'fabric') + .setRender(true) + + if (complete) { + points.firstSideNotchRight = points.topRight.shift(-90, store.get('waistbandBack')) + points.firstSideNotchLeft = new Point(0, points.firstSideNotchRight.y) + macro('sprinkle', { + snippet: 'notch', + on: ['firstSideNotchRight', 'firstSideNotchLeft', 'top'] + }) + points.titleAnchor = points.top.shiftFractionTowards(points.bottom, 0.25) + points.logoAnchor = points.top.shiftFractionTowards(points.bottom, 0.75) + macro('title', { + at: points.titleAnchor, + nr: '3b', + title: 'waistbandButtonholeSide', + rotation: 90 + }) + macro('grainline', { + from: points.firstSideNotchLeft, + to: points.firstSideNotchRight + }) + snippets.logo = new Snippet('logo', points.logoAnchor) + paths.fold = new Path().move(points.top).line(points.bottom).attr('class', 'fabric help') + if (sa) { + paths.sa = paths.saBase + .offset(sa * -1) + .join( + new Path() + .move(points.bottomLeft) + .line(points.topLeft) + .line(points.topRight) + .offset(sa * -2) + ) + .close() + .attr('class', 'fabric sa') + } + + if (paperless) { + } + } + + return part +} diff --git a/packages/charlie/src/waistband.js b/packages/charlie/src/waistband.js new file mode 100644 index 00000000000..b20723630b4 --- /dev/null +++ b/packages/charlie/src/waistband.js @@ -0,0 +1,96 @@ +export default (part) => { + // Shorthand + let { + points, + Point, + paths, + Path, + measurements, + options, + complete, + paperless, + store, + macro, + utils, + snippets, + Snippet, + sa + } = part.shorthand() + + if (options.splitWaistband) return part + + points.topLeft = new Point(0, 0) + points.top = new Point(measurements.waist * options.waistbandWidth * options.waistbandFactor, 0) + points.topRight = new Point(points.top.x * 2, 0) + points.bottomLeft = new Point( + 0, + 2 * store.get('waistbandBack') + 2 * store.get('waistbandFront') + store.get('waistbandFly') + ) + points.bottom = new Point(points.top.x, points.bottomLeft.y) + points.bottomRight = new Point(points.topRight.x, points.bottomLeft.y) + + paths.saBase = new Path() + .move(points.topLeft) + .line(points.topRight) + .line(points.bottomRight) + .line(points.bottomLeft) + .setRender(false) + paths.seam = paths.saBase.clone().close().attr('class', 'fabric').setRender(true) + + if (complete) { + points.flyNotchRight = points.topRight.shift(-90, store.get('waistbandFly')) + points.flyNotchLeft = new Point(0, points.flyNotchRight.y) + points.firstSideNotchRight = points.flyNotchRight.shift(-90, store.get('waistbandFront')) + points.firstSideNotchLeft = new Point(0, points.firstSideNotchRight.y) + points.cbNotchRight = points.firstSideNotchRight.shift(-90, store.get('waistbandBack')) + points.cbNotchLeft = new Point(0, points.cbNotchRight.y) + points.secondSideNotchRight = points.cbNotchRight.shift(-90, store.get('waistbandBack')) + points.secondSideNotchLeft = new Point(0, points.secondSideNotchRight.y) + macro('sprinkle', { + snippet: 'notch', + on: [ + 'flyNotchRight', + 'flyNotchLeft', + 'firstSideNotchRight', + 'firstSideNotchLeft', + 'cbNotchRight', + 'cbNotchLeft', + 'secondSideNotchRight', + 'secondSideNotchLeft' + ] + }) + points.titleAnchor = points.cbNotchLeft.shiftFractionTowards(points.cbNotchRight, 0.5) + points.logoAnchor = points.secondSideNotchLeft.shiftFractionTowards( + points.secondSideNotchRight, + 0.5 + ) + macro('title', { + at: points.titleAnchor, + nr: 3, + title: 'waistband' + }) + macro('grainline', { + from: points.firstSideNotchLeft, + to: points.firstSideNotchRight + }) + snippets.logo = new Snippet('logo', points.logoAnchor) + paths.fold = new Path().move(points.top).line(points.bottom).attr('class', 'fabric help') + if (sa) { + paths.sa = paths.saBase + .offset(sa * -1) + .join( + new Path() + .move(points.bottomLeft) + .line(points.topLeft) + .offset(sa * -2) + ) + .close() + .attr('class', 'fabric sa') + } + + if (paperless) { + } + } + + return part +}