1
0
Fork 0
freesewing/markdown/dev/tutorials/pattern-design/en.md
2023-09-28 09:11:06 +02:00

7.7 KiB

title
Pattern design tutorial

Hello there, and welcome to this FreeSewing pattern design tutorial. My name is Joost, and in this tutorial I will show you how to design a made-to-measure sewing pattern, start to finish.

##### Before you start

If you haven't done so yet, read the Before you start guide. It's very short, but covers some basic terminology and concepts that we'll use throughout this guide.

I will be designing a pattern for a baby bib. It's a very simple pattern, but that's ok. It is a tutorial after all. This will give us plenty to work with.

At the end of this tutorial, I will have created this pattern, and if you follow along, so will you:

```design/src/bib.mjs function draftBib({ Path, Point, paths, points, measurements, options, macro, store, complete, snippets, Snippet, part, }) {

/*

  • Construct the quarter neck opening */ let tweak = 1 let target = (measurements.head * options.neckRatio) /4 let delta do { points.right = new Point(tweak * measurements.head / 10, 0) points.bottom = new Point(0, tweak * measurements.head / 12)
points.rightCp1 = points.right.shift(90, points.bottom.dy(points.right)/2)
points.bottomCp2 = points.bottom.shift(0, points.bottom.dx(points.right)/2)

paths.quarterNeck = new Path()
  .move(points.right)
  .curve(points.rightCp1, points.bottomCp2, points.bottom)
  .hide() // Add this line

delta = paths.quarterNeck.length() - target
if (delta > 0) tweak = tweak * 0.99
else tweak = tweak * 1.02

} while (Math.abs(delta) > 1)

/*

  • Construct the complete neck opening */ points.rightCp2 = points.rightCp1.flipY() points.bottomCp1 = points.bottomCp2.flipX() points.left = points.right.flipX() points.leftCp1 = points.rightCp2.flipX() points.leftCp2 = points.rightCp1.flipX() points.top = points.bottom.flipY() points.topCp1 = points.bottomCp2.flipY() points.topCp2 = points.bottomCp1.flipY()

/*

  • Drawing the bib outline */ const width = measurements.head * options.widthRatio const length = measurements.head * options.lengthRatio

points.topLeft = new Point( width / -2, points.top.y - (width / 2 - points.right.x) ) points.topRight = points.topLeft.shift(0, width) points.bottomLeft = points.topLeft.shift(-90, length) points.bottomRight = points.topRight.shift(-90, length)

// Shape the straps points.edgeLeft = new Point(points.topLeft.x, points.left.y) points.edgeRight = new Point(points.topRight.x, points.right.y) points.edgeTop = new Point(0, points.topLeft.y)

points.edgeLeftCp = points.edgeLeft.shiftFractionTowards(points.topLeft, 0.5) points.edgeRightCp = points.edgeLeftCp.flipX() points.edgeTopLeftCp = points.edgeTop.shiftFractionTowards( points.topLeft, 0.5 ) points.edgeTopRightCp = points.edgeTopLeftCp.flipX()

/*

  • Round the straps */ const strap = points.edgeTop.dy(points.top)

points.tipRight = points.edgeTop.translate(strap / 2, strap / 2) points.tipRightTop = new Point(points.tipRight.x, points.edgeTop.y) points.tipRightBottom = new Point(points.tipRight.x, points.top.y)

macro("round", { from: points.edgeTop, to: points.tipRight, via: points.tipRightTop, prefix: "tipRightTop", }) macro("round", { from: points.tipRight, to: points.top, via: points.tipRightBottom, prefix: "tipRightBottom", }) const rotateThese = [ "edgeTopLeftCp", "edgeTop", "tipRight", "tipRightTop", "tipRightTopStart", "tipRightTopCp1", "tipRightTopCp2", "tipRightTopEnd", "tipRightBottomStart", "tipRightBottomCp1", "tipRightBottomCp2", "tipRightBottomEnd", "tipRightBottom", "top", "topCp2" ] while (points.tipRightBottomStart.x > -1) { for (const p of rotateThese) points[p] = points[p].rotate(1, points.edgeLeft) }

/*

  • Snap anchor */ points.snapLeft = points.top.shiftFractionTowards(points.edgeTop, 0.5)

/*

  • Add points for second strap */ points.edgeTopRightCp = points.edgeTopLeftCp.flipX() points.topCp1 = points.topCp2.flipX() points.tipLeftTopStart = points.tipRightTopStart.flipX() points.tipLeftTopCp1 = points.tipRightTopCp1.flipX() points.tipLeftTopCp2 = points.tipRightTopCp2.flipX() points.tipLeftTopEnd = points.tipRightTopEnd.flipX() points.tipLeftBottomStart = points.tipRightBottomStart.flipX() points.tipLeftBottomCp1 = points.tipRightBottomCp1.flipX() points.tipLeftBottomCp2 = points.tipRightBottomCp2.flipX() points.tipLeftBottomEnd = points.tipRightBottomEnd.flipX() points.snapRight = points.snapLeft.flipX()

/*

  • Round the bottom corners */ macro("round", { from: points.topLeft, to: points.bottomRight, via: points.bottomLeft, radius: points.bottomRight.x / 4, prefix: "bottomLeft" }) macro("round", { from: points.bottomLeft, to: points.topRight, via: points.bottomRight, radius: points.bottomRight.x / 4, prefix: "bottomRight" })

/*

  • Create one path for the bib outline */ paths.seam = new Path() .move(points.edgeLeft) .line(points.bottomLeftStart) .curve(points.bottomLeftCp1, points.bottomLeftCp2, points.bottomLeftEnd) .line(points.bottomRightStart) .curve(points.bottomRightCp1, points.bottomRightCp2, points.bottomRightEnd) .line(points.edgeRight) .curve(points.edgeRightCp, points.edgeTopRightCp, points.tipLeftTopStart) .curve(points.tipLeftTopCp1, points.tipLeftTopCp2, points.tipLeftTopEnd) .curve(points.tipLeftBottomCp1, points.tipLeftBottomCp2, points.tipLeftBottomEnd) .curve(points.topCp1, points.rightCp2, points.right) .curve(points.rightCp1, points.bottomCp2, points.bottom) .curve(points.bottomCp1, points.leftCp2, points.left) .curve(points.leftCp1, points.topCp2, points.tipRightBottomEnd) .curve(points.tipRightBottomCp2, points.tipRightBottomCp1, points.tipRightBottomStart) .curve(points.tipRightTopCp2, points.tipRightTopCp1, points.tipRightTopStart) .curve(points.edgeTopLeftCp, points.edgeLeftCp, points.edgeLeft) .close() .addClass("fabric")

/*

  • Mark the bias tape, but only if complete is set / if (complete) paths.bias = paths.seam .offset(-5) .addClass("various dashed") .addText("finishWithBiasTape", "center fill-various") /
  • Annotations */

// Cutlist store.cutlist.setCut({ cut: 1, from: 'fabric' })

// Snaps points.snapLeft = points.top.shiftFractionTowards(points.edgeTop, 0.5) points.snapRight = points.snapLeft.flipX() snippets.snapStud = new Snippet('snap-stud', points.snapLeft) snippets.snapSocket = new Snippet('snap-socket', points.snapRight).attr('opacity', 0.5)

// Logo points.logo = new Point(0, 0) snippets.logo = new Snippet("logo", points.logo)

// Title points.title = points.bottom.shift(-90, 45) macro("title", { at: points.title, nr: 1, title: "bib", scale: 0.7 })

// Scalbox points.scalebox = points.title.shift(-90, 55) macro("scalebox", { at: points.scalebox })

return part }

</Example>

## Prerequisites

Before I can get started, I want to make sure I have the required software
installed on my computer.

FreeSewing is a JavaScript library that can run in the browser, on
[Node.js](https://nodejs.org/), or a variety of other runtimes such as Bun, 
Deno, AWS Lambda, and so on.

For development, I will use Node.js. If you don't have Node.js on our system,
follow the link above and install it.

<Tip compact>You need Node.js 18 (lts/hydrogen) or higher to use FreeSewing</Tip>

To test whether NodeJS is installed, and see it's version, you can run this command:

```sh
node -v

If you get the Node.js version number, that means NodeJs is installed. Yay!