1
0
Fork 0
freesewing/markdown/dev/tutorials/pattern-design/en.md

269 lines
7.7 KiB
Markdown
Raw Normal View History

---
title: Pattern design tutorial
---
2023-09-28 09:11:06 +02:00
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.
2022-10-10 04:50:43 +02:00
<Tip>
##### Before you start
If you haven't done so yet, read the [Before you start
guide](/guides/prerequisites). It's very short, but covers some basic
2022-10-10 04:50:43 +02:00
terminology and concepts that we'll use throughout this guide.
</Tip>
2023-09-28 09:11:06 +02:00
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.
2023-09-28 09:11:06 +02:00
At the end of this tutorial, I will have created this pattern, and if you
follow along, so will you:
<Example tutorial="1" previewFirst="1" caption="Our end result">
2023-08-08 13:20:46 -05:00
```design/src/bib.mjs
function draftBib({
Path,
Point,
paths,
points,
measurements,
options,
macro,
2023-09-28 09:11:06 +02:00
store,
complete,
snippets,
Snippet,
part,
}) {
2023-09-28 09:11:06 +02:00
/*
* Construct the quarter neck opening
*/
let tweak = 1
let target = (measurements.head * options.neckRatio) /4
let delta
do {
2023-08-08 13:20:46 -05:00
points.right = new Point(tweak * measurements.head / 10, 0)
points.bottom = new Point(0, tweak * measurements.head / 12)
2023-08-08 13:20:46 -05:00
points.rightCp1 = points.right.shift(90, points.bottom.dy(points.right)/2)
points.bottomCp2 = points.bottom.shift(0, points.bottom.dx(points.right)/2)
2023-08-08 13:20:46 -05:00
paths.quarterNeck = new Path()
.move(points.right)
.curve(points.rightCp1, points.bottomCp2, points.bottom)
.hide() // Add this line
2023-08-08 13:20:46 -05:00
delta = paths.quarterNeck.length() - target
if (delta > 0) tweak = tweak * 0.99
else tweak = tweak * 1.02
} while (Math.abs(delta) > 1)
2023-09-28 09:11:06 +02:00
/*
* 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()
2023-09-28 09:11:06 +02:00
/*
* 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()
2023-09-28 09:11:06 +02:00
/*
* 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)
}
2023-09-28 09:11:06 +02:00
/*
* Snap anchor
*/
points.snapLeft = points.top.shiftFractionTowards(points.edgeTop, 0.5)
2023-09-28 09:11:06 +02:00
/*
* 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()
2023-09-28 09:11:06 +02:00
/*
* 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"
})
2023-09-28 09:11:06 +02:00
/*
* 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")
2023-09-28 09:11:06 +02:00
/*
* 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
})
2023-09-28 09:11:06 +02:00
// Scalbox
points.scalebox = points.title.shift(-90, 55)
macro("scalebox", { at: points.scalebox })
return part
}
```
</Example>
## Prerequisites
2023-09-28 09:11:06 +02:00
Before I can get started, I want to make sure I have the required software
installed on my computer.
2022-10-04 23:36:08 +02:00
FreeSewing is a JavaScript library that can run in the browser, on
2023-09-28 09:11:06 +02:00
[Node.js](https://nodejs.org/), or a variety of other runtimes such as Bun,
Deno, AWS Lambda, and so on.
2023-09-28 09:11:06 +02:00
For development, I will use Node.js. If you don't have Node.js on our system,
follow the link above and install it.
2022-10-04 23:36:08 +02:00
2023-09-28 09:11:06 +02:00
<Tip compact>You need Node.js 18 (lts/hydrogen) or higher to use FreeSewing</Tip>
2023-09-28 09:11:06 +02:00
To test whether NodeJS is installed, and see it's version, you can run this command:
2022-10-04 23:36:08 +02:00
```sh
node -v
```
2023-09-28 09:11:06 +02:00
If you get the Node.js version number, that means NodeJs is installed. Yay!