chore: Merged in left behind PRs from markdown repo
This commit is contained in:
parent
b34a2ee2ed
commit
97b8a93a85
126 changed files with 2327 additions and 486 deletions
|
@ -4,7 +4,7 @@ order: 130
|
|||
---
|
||||
|
||||
FreeSewing is all about *made-to-measure* sewing patterns;
|
||||
We are going to draft our pattern according to the measurements provided to us.
|
||||
we are going to draft our pattern according to the measurements provided to us.
|
||||
|
||||
Which begs the question, which measurements?
|
||||
|
||||
|
@ -35,10 +35,10 @@ This change will also get picked up by the development environment, and you'll n
|
|||
|
||||

|
||||
|
||||
Since it's just one measurements, let's simply enter a value by hand.
|
||||
Since it's just one measurement, let's simply enter a value by hand.
|
||||
For example `38` as 38cm is a realistic head circumference measurement for a baby.
|
||||
|
||||
Enter `38` in the box, and click on **Draft your pattern** in the top navigation bar to get back to your draft
|
||||
Enter `38` in the box, and click on **Draft your pattern** in the top navigation bar to get back to your draft,
|
||||
which for now still looks like this:
|
||||
|
||||
<Example pattern="tutorial" part="step1" caption="Nothing has changed, yet" />
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 66 KiB |
|
@ -51,12 +51,12 @@ Let's do something similar for the width and length of our bib:
|
|||
options: {
|
||||
neckRatio: { pct: 80, min: 70, max: 90 },
|
||||
widthRatio: { pct: 45, min: 35, max: 55 },
|
||||
lengthRatio: { pct: 50, min: 40, max: 65 },
|
||||
lengthRatio: { pct: 75, min: 55, max: 85 },
|
||||
}
|
||||
```
|
||||
|
||||
- You've added `widthRatio` and `lengthRatio` options
|
||||
- You've given all options sensible defauls
|
||||
- You've given all options sensible defaults
|
||||
- You've given all options sensible maximum and minimum boundaries
|
||||
|
||||
<Note>
|
||||
|
|
|
@ -27,24 +27,24 @@ let rotateThese = [
|
|||
"tipRightBottom",
|
||||
"top",
|
||||
"topCp2"
|
||||
];
|
||||
]
|
||||
```
|
||||
|
||||
Now you can rotate them. How far? Until the strap no longer overlaps:
|
||||
|
||||
```js
|
||||
while (points.tipRightBottomStart.x > -1) {
|
||||
for (let p of rotateThese) points[p] = points[p].rotate(1, points.edgeLeft);
|
||||
for (let p of rotateThese) points[p] = points[p].rotate(1, points.edgeLeft)
|
||||
}
|
||||
```
|
||||
|
||||
We're rotating all the points in the `rotateThese` array around the `edgeLeft` points.
|
||||
We're using increments of 1 degree until the `tipRightBottomStart` point is 1mm passed the center of our bib.
|
||||
|
||||
While we're add it, let's add a point where the closure's snap should go:
|
||||
While we're at it, let's add a point where the closure's snap should go:
|
||||
|
||||
```js
|
||||
points.snapLeft = points.top.shiftFractionTowards(points.edgeTop, 0.5);
|
||||
points.snapLeft = points.top.shiftFractionTowards(points.edgeTop, 0.5)
|
||||
```
|
||||
|
||||
<Example pattern="tutorial" part="step8" caption="The right part looks a bit wonky now, but we'll get to that" />
|
||||
|
|
|
@ -9,16 +9,16 @@ on the other side. You can just flip them over, so to speak. And that's exactly
|
|||
First create some new points:
|
||||
|
||||
```js
|
||||
points.rightCp2 = points.rightCp1.flipY();
|
||||
points.bottomCp1 = points.bottomCp2.flipX();
|
||||
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.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();
|
||||
points.top = points.bottom.flipY()
|
||||
points.topCp1 = points.bottomCp2.flipY()
|
||||
points.topCp2 = points.bottomCp1.flipY()
|
||||
```
|
||||
|
||||
<Note>
|
||||
|
@ -37,7 +37,7 @@ paths.neck = new Path()
|
|||
.curve(points.leftCp2, points.bottomCp1, points.bottom)
|
||||
.curve(points.bottomCp2, points.rightCp1, points.right)
|
||||
.curve(points.rightCp2, points.topCp1, points.top)
|
||||
.close();
|
||||
.close()
|
||||
```
|
||||
|
||||
<Example pattern="tutorial" part="step4" caption="And now you have a complete neck opening" />
|
||||
|
|
|
@ -7,7 +7,7 @@ When we started out, we said a good part boilerplate looks like this:
|
|||
|
||||
```js
|
||||
export default function(part) {
|
||||
let { Point, points, Path, paths } = part.shorthand();
|
||||
let { Point, points, Path, paths, complete, sa, paperless } = part.shorthand()
|
||||
// Design pattern here
|
||||
|
||||
// Complete?
|
||||
|
@ -18,7 +18,7 @@ export default function(part) {
|
|||
if (paperless) {
|
||||
}
|
||||
}
|
||||
return part;
|
||||
return part
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -30,7 +30,7 @@ the area under *// Complete?*
|
|||
###### The point of (non) complete patterns
|
||||
|
||||
Users can set the `complete` setting to `false`. When that's the case, you
|
||||
should draft a base outline of the pattern, rather than a fully detailed pattern.i
|
||||
should draft a base outline of the pattern, rather than a fully detailed pattern.
|
||||
|
||||
This has different uses, such as generating patterns to be cut out with a laser cutter.
|
||||
|
||||
|
@ -47,13 +47,16 @@ let {
|
|||
points,
|
||||
Path,
|
||||
paths,
|
||||
complete,
|
||||
sa,
|
||||
paperless,
|
||||
measurements,
|
||||
options,
|
||||
macro,
|
||||
complete,
|
||||
snippets,
|
||||
Snippet
|
||||
} = part.shorthand();
|
||||
} = part.shorthand()
|
||||
```
|
||||
|
||||
## Adding snippets
|
||||
|
@ -64,9 +67,9 @@ Things like buttons or buttonholes, a logo, or snaps:
|
|||
```js
|
||||
// Complete?
|
||||
if (complete) {
|
||||
snippets.snapMale = new Snippet("snap-male", points.snapLeft);
|
||||
snippets.snapFemale = new Snippet("snap-female", points.snapRight)
|
||||
.attr("opacity", 0.5);
|
||||
snippets.snapStud = new Snippet("snap-stud", points.snapLeft)
|
||||
snippets.snapSocket = new Snippet("snap-socket", points.snapRight)
|
||||
.attr("opacity", 0.5)
|
||||
|
||||
if (sa) {
|
||||
}
|
||||
|
@ -76,9 +79,9 @@ if (complete) {
|
|||
}
|
||||
```
|
||||
|
||||
We've added a `snap-male` and `snap-female` snippet to the points we had foreseen for that.
|
||||
We've added a `snap-stud` and `snap-socket` snippet to the points we had foreseen for that.
|
||||
|
||||
Because the female snippet is at the back of the fabric, we've made it semi-transparent by
|
||||
Because the socket snippet is at the back of the fabric, we've made it semi-transparent by
|
||||
setting the `opacity` attribute to `0.5`. Yes, you can do that.
|
||||
|
||||
<Tip>
|
||||
|
@ -90,10 +93,16 @@ Any attributes you set will be added to the SVG output.
|
|||
Since we're adding snippets, let's throw a logo on there too:
|
||||
|
||||
```js
|
||||
points.logo = new Point(0, 0);
|
||||
snippets.logo = new Snippet("logo", points.logo);
|
||||
points.logo = new Point(0, 0)
|
||||
snippets.logo = new Snippet("logo", points.logo)
|
||||
```
|
||||
|
||||
<Note>
|
||||
|
||||
You can find all possible snippets in [our documentation](/reference/snippets/).
|
||||
|
||||
</Note>
|
||||
|
||||
## Seam allowance
|
||||
|
||||
Just like users can choose whether they want a complete pattern or not, they can choose
|
||||
|
@ -110,7 +119,7 @@ Our bib does not use seam allowance. Instead we'll finish it with bias tape.
|
|||
So you can simply remove that condition.
|
||||
|
||||
However, for future refefence, `sa` is a variable that you can get from `part.shorthand()`
|
||||
just like `complete`. But instead of `true` or `false` it will hold the amount if seam allowance
|
||||
just like `complete`. But instead of `true` or `false` it will hold the amount of seam allowance
|
||||
in mm.
|
||||
|
||||
Note that you can still do `if (sa)` because zero is *falsy*.
|
||||
|
@ -124,11 +133,11 @@ paths.bias = paths.seam
|
|||
.offset(-5)
|
||||
.attr("class", "various dashed")
|
||||
.attr("data-text", "finishWithBiasTape")
|
||||
.attr("data-text-class", "center fill-various");
|
||||
.attr("data-text-class", "center fill-various")
|
||||
```
|
||||
|
||||
The `path.offset()` method makes it trivial to add seam allowance, since it will contruct
|
||||
a path parallel at the distance you pass it. 9 times out of 10, you'll be using it as `path.offset(sa)`.
|
||||
a path parallel to the given path at the distance you pass it. 9 times out of 10, you'll be using it as `path.offset(sa)`.
|
||||
|
||||
Note that we're also using the attributes again, to change the look of the line, and add text to it,
|
||||
as explained in [Adding text](/concepts/adding-text).
|
||||
|
@ -145,25 +154,25 @@ That's why you should number your parts and give them a name.
|
|||
The `title` macro can help you with that:
|
||||
|
||||
```js
|
||||
points.title = points.bottom.shift(-90, 45);
|
||||
points.title = points.bottom.shift(-90, 45)
|
||||
macro("title", {
|
||||
at: points.title,
|
||||
nr: 1,
|
||||
title: "bib"
|
||||
});
|
||||
})
|
||||
```
|
||||
|
||||
The `scalebox` macro prints a box of an exact size.
|
||||
It is used by people who print the pattern to make sure their print is correctly scaled.
|
||||
|
||||
```js
|
||||
points.scalebox = points.title.shift(-90, 55);
|
||||
macro("scalebox", { at: points.scalebox });
|
||||
points.scalebox = points.title.shift(-90, 55)
|
||||
macro("scalebox", { at: points.scalebox })
|
||||
```
|
||||
|
||||
And with that, our pattern is now *complete*:
|
||||
|
||||
<Example pattern="tutorial" part="step11" caption="We used attributed to add color, dashes, text on a path and even opacity" />
|
||||
<Example pattern="tutorial" part="step11" caption="We used attributes to add color, dashes, text on a path and even opacity" />
|
||||
|
||||
We're not done yet though. There's one more thing the user can ask for: a *paperless* pattern.
|
||||
|
||||
|
|
|
@ -6,11 +6,11 @@ order: 280
|
|||
Congratulations, you have created your first pattern. And while it's arguably rather simple,
|
||||
you have learned a bunch of things along the way. Let's list some of the things you've learned:
|
||||
|
||||
- You have learned how to [setup your development environment](/tutorials/pattern-design/create-freesewing-pattern) with `npm init freesewing-pattern`
|
||||
- You have learned how to [setup your development environment](/tutorials/pattern-design/create-freesewing-pattern) with `npx create-freesewing-pattern`
|
||||
- You learned how to [add parts](/tutorials/pattern-design/your-first-part), [measurements](/tutorials/pattern-design/adding-measurements), and [options](/tutorials/pattern-design/adding-options) to your pattern's configuration file
|
||||
- You learned what [a good boilerplate is to start with a new part](/tutorials/pattern-design/part-structure)
|
||||
- You've learned [how to add points and draw paths](/tutorials/pattern-design/constructing-the-neck-opening)
|
||||
- You learned how you can make changes in a loop to [adapt the neckopening](/tutorials/pattern-design/fitting-the-neck-opening) or [rotate the straps](/tutorials/pattern-design/avoiding-overlap) until they were just right
|
||||
- You learned how you can make changes in a loop to [adapt the neck opening](/tutorials/pattern-design/fitting-the-neck-opening) or [rotate the straps](/tutorials/pattern-design/avoiding-overlap) until they were just right
|
||||
- You learned about [macros and how to use them](/tutorials/pattern-design/creating-the-closure)
|
||||
- You learned different methods to manipulate [points](/reference/api/point/) and [paths](/reference/api/path/)
|
||||
- You learned about using [attributes](/reference/api/attributes/) to influence the appearance of points and paths
|
||||
|
|
|
@ -20,22 +20,25 @@ let {
|
|||
points,
|
||||
Path,
|
||||
paths,
|
||||
complete,
|
||||
sa,
|
||||
paperless,
|
||||
measurements,
|
||||
options
|
||||
} = part.shorthand();
|
||||
} = part.shorthand()
|
||||
```
|
||||
|
||||
Great. Now let's get to work:
|
||||
|
||||
```js
|
||||
// Design pattern here
|
||||
points.right = new Point(measurements.head / 10, 0);
|
||||
points.bottom = new Point(0, measurements.head / 12);
|
||||
points.right = new Point(measurements.head / 10, 0)
|
||||
points.bottom = new Point(0, measurements.head / 12)
|
||||
|
||||
points.rightCp1 = points.right
|
||||
.shift(90, points.bottom.dy(points.right)/2);
|
||||
.shift(90, points.bottom.dy(points.right)/2)
|
||||
points.bottomCp2 = points.bottom
|
||||
.shift(0, points.bottom.dx(points.right)/2);
|
||||
.shift(0, points.bottom.dx(points.right)/2)
|
||||
|
||||
paths.neck = new Path()
|
||||
.move(points.right)
|
||||
|
@ -45,11 +48,11 @@ paths.neck = new Path()
|
|||
You've added some points to your part, and drawn your first path. Let's look at each line in detail:
|
||||
|
||||
```js
|
||||
points.right = new Point(measurements.head / 10, 0);
|
||||
points.right = new Point(measurements.head / 10, 0)
|
||||
```
|
||||
|
||||
- We're adding a point named `right` to `points` which holds our part's points
|
||||
- We're using the Point constructor, which takes two arguments: The points X and Y values
|
||||
- We're using the Point constructor, which takes two arguments: The point's X and Y values
|
||||
- The X value is `measurements.head / 10`
|
||||
- The Y value is `0`
|
||||
|
||||
|
@ -57,7 +60,7 @@ The `bottom` part is very similar, so let's skip to the next line:
|
|||
|
||||
```js
|
||||
points.rightCp1 = points.right
|
||||
.shift(90, points.bottom.dy(points.right)/2);
|
||||
.shift(90, points.bottom.dy(points.right)/2)
|
||||
```
|
||||
|
||||
- We're adding a point named `rightCp1`, which will become the *control point* of the right part
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 151 KiB After Width: | Height: | Size: 82 KiB |
|
@ -3,10 +3,18 @@ title: Setting up the development environment
|
|||
order: 100
|
||||
---
|
||||
|
||||
<Note>
|
||||
|
||||
###### Already did the Getting started tutorial?
|
||||
|
||||
If you already set up the FreeSewing development environment and created a pattern, you can use that pattern and skip these steps. You can move on to [Your first part](/tutorials/pattern-design/your-first-part/).
|
||||
|
||||
</Note>
|
||||
|
||||
Open a terminal and enter the following command:
|
||||
|
||||
```bash
|
||||
npm init freesewing-pattern
|
||||
npx create-freesewing-pattern
|
||||
```
|
||||
|
||||
This will load a few dependencies, and then ask you the following questions:
|
||||
|
@ -18,7 +26,7 @@ This will load a few dependencies, and then ask you the following questions:
|
|||
- **Department**: Use the arrow keys to select `Accessories`
|
||||
- **Author**: Enter your GitHub username
|
||||
- **GitHub repository**: This will be prefilled for you, so just hit Enter
|
||||
- **Package manager**: Use the arrow to choose. Pick `NPM` if you're not sure.
|
||||
- **Package manager**: Use the arrow to choose. Pick `npm` if you're not sure.
|
||||
|
||||
After you've answered these questions, the default template will be copied, after which all dependencies will be installed.
|
||||
|
||||
|
@ -28,26 +36,11 @@ This will take a few minutes because we're loading some software for your develo
|
|||
|
||||
</Note>
|
||||
|
||||
When it's ready, you'll need to run two commands in parallel. In the current terminal,
|
||||
enter the directory that was just created for our `tutorial` pattern and start rollup in watch mode:
|
||||
|
||||
```bash
|
||||
cd tutorial
|
||||
npm run start
|
||||
```
|
||||
|
||||
Or if you chose to use Yarn as package manager:
|
||||
|
||||
```bash
|
||||
cd tutorial
|
||||
yarn start
|
||||
```
|
||||
|
||||
Now open a second terminal, and navigate to the `example` subfolder and run the same command there:
|
||||
When it's ready, enter the directory that was just created for our `tutorial` pattern and navigate to the `example` subfolder. There, start the development environment:
|
||||
|
||||
```bash:
|
||||
cd tutorial/example
|
||||
npm run start
|
||||
npm start
|
||||
```
|
||||
|
||||
Or if you chose to use Yarn as package manager:
|
||||
|
@ -63,10 +56,7 @@ If all goes well, your browser will open and show the following landing page:
|
|||
|
||||
<Note>
|
||||
|
||||
###### Using Windows?
|
||||
|
||||
We have tested this on Linux and MacOS, but not on Windows since I (joost) don't have
|
||||
a Windows machine I can test this on.
|
||||
###### Need help?
|
||||
|
||||
If you run into any issues, join [our chatroom](https://discord.freesewing.org/) and
|
||||
we'll figure it out together.
|
||||
|
|
|
@ -21,10 +21,13 @@ let {
|
|||
points,
|
||||
Path,
|
||||
paths,
|
||||
complete,
|
||||
sa,
|
||||
paperless,
|
||||
measurements,
|
||||
options,
|
||||
macro
|
||||
} = part.shorthand();
|
||||
} = part.shorthand()
|
||||
```
|
||||
|
||||
We need a half circle here, but the `round` macro works on 90° angles, so you'll use it twice.
|
||||
|
@ -32,11 +35,11 @@ We need a half circle here, but the `round` macro works on 90° angles, so you'l
|
|||
As such, let's add some points to guide the macro, and then put it to work:
|
||||
|
||||
```js
|
||||
let strap = points.edgeTop.dy(points.top);
|
||||
let 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);
|
||||
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,
|
||||
|
@ -44,17 +47,17 @@ macro("round", {
|
|||
via: points.tipRightTop,
|
||||
prefix: "tipRightTop",
|
||||
render: true
|
||||
});
|
||||
})
|
||||
macro("round", {
|
||||
from: points.tipRight,
|
||||
to: points.top,
|
||||
via: points.tipRightBottom,
|
||||
prefix: "tipRightBottom",
|
||||
render: true
|
||||
});
|
||||
})
|
||||
```
|
||||
|
||||
<Fixme> Add link to macro/extend docs </Fixme>
|
||||
<Note> You can find more information on the `round` macro in [the macros docs](/reference/macros/round/).</Note>
|
||||
|
||||
<Example pattern="tutorial" part="step7" caption="Pretty good, but how are we going to fit it over the baby's head?" />
|
||||
|
||||
|
|
|
@ -6,16 +6,16 @@ order: 190
|
|||
With our neck opening in place, let's draw the basic outline of our bib:
|
||||
|
||||
```js
|
||||
let width = measurements.head * options.widthRatio;
|
||||
let length = measurements.head * options.lengthRatio;
|
||||
let width = measurements.head * options.widthRatio
|
||||
let 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);
|
||||
points.topRight = points.topLeft.shift(0, width)
|
||||
points.bottomLeft = points.topLeft.shift(-90, length)
|
||||
points.bottomRight = points.topRight.shift(-90, length)
|
||||
|
||||
paths.rect = new Path()
|
||||
.move(points.topLeft)
|
||||
|
@ -23,15 +23,15 @@ paths.rect = new Path()
|
|||
.line(points.bottomRight)
|
||||
.line(points.topRight)
|
||||
.line(points.topLeft)
|
||||
.close();
|
||||
.close()
|
||||
```
|
||||
|
||||
First thing we did was create the `width` and `length` variables to
|
||||
save ourselves some typing:
|
||||
|
||||
```js
|
||||
let width = measurements.head * options.widthRatio;
|
||||
let length = measurements.head * options.lengthRatio;
|
||||
let width = measurements.head * options.widthRatio
|
||||
let length = measurements.head * options.lengthRatio
|
||||
```
|
||||
|
||||
Both the length and width of your bib are a factor of the head circumference.
|
||||
|
@ -44,10 +44,10 @@ Once we have our variables, we're adding some new points, and a second path call
|
|||
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);
|
||||
)
|
||||
points.topRight = points.topLeft.shift(0, width)
|
||||
points.bottomLeft = points.topLeft.shift(-90, length)
|
||||
points.bottomRight = points.topRight.shift(-90, length)
|
||||
|
||||
paths.rect = new Path()
|
||||
.move(points.topLeft)
|
||||
|
@ -55,7 +55,7 @@ paths.rect = new Path()
|
|||
.line(points.bottomRight)
|
||||
.line(points.topRight)
|
||||
.line(points.topLeft)
|
||||
.close();
|
||||
.close()
|
||||
```
|
||||
|
||||
We're calculating the `topLeft` point so that the top edge of our bib
|
||||
|
|
|
@ -9,17 +9,17 @@ and create one single path that follows our bib outline.
|
|||
First, let's create the points:
|
||||
|
||||
```js
|
||||
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();
|
||||
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()
|
||||
```
|
||||
|
||||
Now, remove the `neck` and `rect` paths that we created earlier, and replace
|
||||
|
@ -82,9 +82,35 @@ paths.seam = new Path()
|
|||
points.edgeLeft
|
||||
)
|
||||
.close()
|
||||
.attr("class", "fabric");
|
||||
.attr("class", "fabric")
|
||||
```
|
||||
|
||||
The `round` macro we added earlier is still drawing a half-circle. We cannot remove the macros, or the points it creates would also disappear. Luckily, we can simply set `render` to `false` and keep the points without drawing the curves between them:
|
||||
|
||||
```js
|
||||
macro("round", {
|
||||
from: points.edgeTop,
|
||||
to: points.tipRight,
|
||||
via: points.tipRightTop,
|
||||
prefix: "tipRightTop",
|
||||
render: false // set this from true to false
|
||||
})
|
||||
macro("round", {
|
||||
from: points.tipRight,
|
||||
to: points.top,
|
||||
via: points.tipRightBottom,
|
||||
prefix: "tipRightBottom",
|
||||
render: false // set this from true to false
|
||||
})
|
||||
|
||||
```
|
||||
|
||||
<Note>
|
||||
|
||||
You can also remove the `render` line completely. More on this in the next section.
|
||||
|
||||
</Note>
|
||||
|
||||
With that out of the way, our bib now looks like this:
|
||||
|
||||
<Example pattern="tutorial" part="step9" caption="That is looking a lot like a bib" />
|
||||
|
|
|
@ -6,24 +6,24 @@ order: 170
|
|||
Here's how we'll make sure the neck opening is *just right*:
|
||||
|
||||
```js
|
||||
let tweak = 1;
|
||||
let target = (measurements.head * options.neckRatio) /4;
|
||||
let delta;
|
||||
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.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);
|
||||
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.neck = new Path()
|
||||
.move(points.right)
|
||||
.curve(points.rightCp1, points.bottomCp2, points.bottom);
|
||||
.curve(points.rightCp1, points.bottomCp2, points.bottom)
|
||||
|
||||
delta = paths.neck.length() - target;
|
||||
if (delta > 0) tweak = tweak * 0.99;
|
||||
else tweak = tweak * 1.02;
|
||||
} while (Math.abs(delta) > 1);
|
||||
delta = paths.neck.length() - target
|
||||
if (delta > 0) tweak = tweak * 0.99
|
||||
else tweak = tweak * 1.02
|
||||
} while (Math.abs(delta) > 1)
|
||||
```
|
||||
|
||||
We've added a few new variables:
|
||||
|
@ -41,7 +41,7 @@ length of our neck path.
|
|||
If the delta is positive, our path is too long and we reduce the tweak factor.
|
||||
If the delta is negative, our path is too short and we increase the tweak factor.
|
||||
|
||||
We keep on doing this until `Math.abs(delta)` is less than 1. Meaning that we are withing 1mm or our target value.
|
||||
We keep on doing this until `Math.abs(delta)` is less than 1. Meaning that we are within 1mm of our target value.
|
||||
|
||||
<Example pattern="tutorial" part="step2" caption="It might look the same as before, but now it's just right" />
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ order: 270
|
|||
Users can request paperless patterns by setting the `paperless` setting to `true`.
|
||||
|
||||
We can get that value of the setting from the `part.shorthand()` method.
|
||||
It will be the last shorthand we need:
|
||||
It will be the last shorthand we will put to use:
|
||||
|
||||
```js
|
||||
let {
|
||||
|
@ -14,14 +14,15 @@ let {
|
|||
points,
|
||||
Path,
|
||||
paths,
|
||||
complete,
|
||||
sa,
|
||||
paperless, // <- this one here
|
||||
measurements,
|
||||
options,
|
||||
macro,
|
||||
complete,
|
||||
snippets,
|
||||
Snippet,
|
||||
paperless
|
||||
} = part.shorthand();
|
||||
Snippet
|
||||
} = part.shorthand()
|
||||
```
|
||||
|
||||
The idea behind *paperless patterns* is that users don't need to print your
|
||||
|
@ -30,7 +31,7 @@ Instead, we include dimensions on the pattern that allows them to transfer
|
|||
the pattern directly onto fabric, or onto an intermediate medium such as tracing paper.
|
||||
|
||||
In addition, FreeSewing will automatically render a grid for each pattern part with metric or imperial
|
||||
marcations, depending on the units requested by the user.
|
||||
markings, depending on the units requested by the user.
|
||||
|
||||
While the grid gets added automatically, the dimensions you have to add yourself.
|
||||
Thankfully, there's macros that can help you with that, specifically:
|
||||
|
@ -40,7 +41,7 @@ Thankfully, there's macros that can help you with that, specifically:
|
|||
- The `ld` macro adds a linear dimension
|
||||
- The `pd` macro adds a path dimension that follows a given path
|
||||
|
||||
<Fixme> Add links to macro docs </Fixme>
|
||||
<Note> The documentation, as always, holds [all the information about the macros](/reference/macros/). </Note>
|
||||
|
||||
Let's look at the code:
|
||||
|
||||
|
@ -51,36 +52,36 @@ if (paperless) {
|
|||
from: points.bottomLeftStart,
|
||||
to: points.bottomRightEnd,
|
||||
y: points.bottomLeft.y + 15
|
||||
});
|
||||
})
|
||||
macro("vd", {
|
||||
from: points.bottomRightStart,
|
||||
to: points.bottom,
|
||||
x: points.bottomRight.x + 15
|
||||
});
|
||||
})
|
||||
macro("vd", {
|
||||
from: points.bottomRightStart,
|
||||
to: points.right,
|
||||
x: points.bottomRight.x + 30
|
||||
});
|
||||
})
|
||||
macro("vd", {
|
||||
from: points.bottomRightStart,
|
||||
to: points.tipLeftTopStart,
|
||||
x: points.bottomRight.x + 45
|
||||
});
|
||||
})
|
||||
macro("hd", {
|
||||
from: points.left,
|
||||
to: points.right,
|
||||
y: points.left.y + 25
|
||||
});
|
||||
})
|
||||
macro("ld", {
|
||||
from: points.tipLeftBottomEnd,
|
||||
to: points.tipLeftTopStart,
|
||||
d: 15
|
||||
});
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
There's a lot going on, but it's mostly repetition. Let's look at the end result, and discuss:
|
||||
There's a lot going on, but it's mostly repetition. To see what that did to your pattern, you have to enable *paperless mode* in your developing environment; you can find the option under *Pattern options* on the right. Let's look at the end result, and discuss:
|
||||
|
||||
<Example pattern="tutorial" part="bib" caption="Your paperless bib" settings={{paperless: true}} />
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ Open `src/bib.js` and make sure it looks like this:
|
|||
|
||||
```js
|
||||
export default function(part) {
|
||||
let { Point, points, Path, paths } = part.shorthand();
|
||||
let { Point, points, Path, paths, complete, sa, paperless } = part.shorthand()
|
||||
// Design pattern here
|
||||
|
||||
// Complete?
|
||||
|
@ -19,7 +19,7 @@ export default function(part) {
|
|||
if (paperless) {
|
||||
}
|
||||
}
|
||||
return part;
|
||||
return part
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -36,7 +36,7 @@ export default function(part) {
|
|||
|
||||
// ...
|
||||
|
||||
return part;
|
||||
return part
|
||||
}
|
||||
|
||||
```
|
||||
|
@ -57,7 +57,7 @@ let {
|
|||
points,
|
||||
Path,
|
||||
paths,
|
||||
} = part.shorthand();
|
||||
} = part.shorthand()
|
||||
```
|
||||
|
||||
This is FreeSewing's **shorthand** method. It returns an object with a bunch of handy helpers
|
||||
|
@ -70,10 +70,21 @@ The example above makes the following variables available:
|
|||
- `Path`: The Path constructor
|
||||
- `paths`: A reference to the part's paths
|
||||
|
||||
These will make it possible for you to draw points and paths easily.
|
||||
|
||||
The following three variables are also needed to create a full-fledged FreeSewing pattern; their function and usage will
|
||||
be covered in detail [later on in this tutorial](/tutorials/pattern-design/completing-your-pattern/):
|
||||
|
||||
- `complete`: create a *complete* pattern (or not)
|
||||
- `sa`: include *seam allowance* (or not)
|
||||
- `paperless`: allow the pattern to be *paperless*
|
||||
|
||||
For now, we only need these so that the pattern skeleton compiles properly.
|
||||
|
||||
<Note>
|
||||
|
||||
This will all become clear, but if you're curious, the API docs have all the details
|
||||
on [the Part.shorthand() method](/reference/api/part/#shorthand)
|
||||
on [the Part.shorthand() method](/reference/api/part/#shorthand).
|
||||
|
||||
</Note>
|
||||
|
||||
|
|
|
@ -13,18 +13,18 @@ macro("round", {
|
|||
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"
|
||||
});
|
||||
})
|
||||
```
|
||||
|
||||
But there's still something to be learned here. If you look at our earlier use of the `round` macro,
|
||||
you'll notice that we used this line:
|
||||
you'll notice that we used this line in the beginning:
|
||||
|
||||
```js
|
||||
render: true,
|
||||
|
@ -37,7 +37,13 @@ Typically, your rounded corner will be part of a larger path and so you don't wa
|
|||
to draw it. That's why the `round` macro's `render` property defaults to `false`.
|
||||
|
||||
We've left it out here, and you should also remove it from your earlier use of the `round` macro.
|
||||
We merely set `render` to `true` at that time so you could see what the macro was doing.
|
||||
We merely set `render` to `true` and then `false` at that time so you could see what the macro was doing.
|
||||
|
||||
<Note>
|
||||
|
||||
There is no need to explicitly specify a default value. While writing `render: false,` also works, it clutters up your code a bit.
|
||||
|
||||
</Note>
|
||||
|
||||
With our corners rounded, we should update our path.
|
||||
Fortunately, we merely have to update the start of it. Replace this:
|
||||
|
|
|
@ -16,17 +16,17 @@ As always, [the API docs](/reference/api/point/) have all the details.
|
|||
</Note>
|
||||
|
||||
```js
|
||||
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.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.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();
|
||||
)
|
||||
points.edgeTopRightCp = points.edgeTopLeftCp.flipX()
|
||||
```
|
||||
|
||||
Now, adapt our `rect` path so it's no longer a rectangle:
|
||||
|
@ -39,7 +39,7 @@ paths.rect = new Path()
|
|||
.line(points.bottomRight)
|
||||
.line(points.edgeRight)
|
||||
.curve(points.edgeRightCp, points.edgeTopRightCp, points.edgeTop)
|
||||
.close();
|
||||
.close()
|
||||
```
|
||||
|
||||
All of a sudden, things are starting to look like a bib:
|
||||
|
|
|
@ -19,7 +19,7 @@ for different measurements and options to see how well it adapts.
|
|||
|
||||
If testing your pattern sounds like a lot of work, you're in luck. FreeSewing can do it
|
||||
for you. Click the **Test your pattern** button in the top navigation bar of your
|
||||
development environment, and you'll see a number of choices at the right:
|
||||
development environment, and you'll see a number of choices on the right:
|
||||
|
||||
- Test pattern options
|
||||
- Test measurements
|
||||
|
@ -81,7 +81,7 @@ For a the same `head` measurement, varying this option should result in increasi
|
|||
|
||||
If we test it, we can see that it works as intended. But there's one thing that perhaps requires your attention.
|
||||
Making the bib wider shortens the length from the bottom of the neck opening to the bottom of the bib.
|
||||
Thereby making the bib shortern when its worn.
|
||||
Thereby making the bib shorter when it's worn.
|
||||
|
||||
Even if the *total length* of the bib stays the same, the *useable length* shortens when the bib is made wider.
|
||||
Users will not expect this, so it's something that we should fix in our pattern.
|
||||
|
@ -136,7 +136,7 @@ only uses one measurement. So testing that one measurement ends up being the sam
|
|||
set of measurements.
|
||||
|
||||
But most patterns use multiple measurements, and you'll find this test gives you insight into how your
|
||||
pattern will adapt to differently sizes bodies.
|
||||
pattern will adapt to differently sized bodies.
|
||||
|
||||
<Example
|
||||
sample
|
||||
|
@ -175,7 +175,7 @@ that will not properly scale.
|
|||
Many drafting books will tell you to *add 3cm there* or *measure 2 inch to the right*. Those instructions
|
||||
don't scale, and you should avoid them.
|
||||
|
||||
The best patterns will pass the antperson test with 2 exact pattern. One will simply be 1/10th the scale of the other.
|
||||
The best patterns will pass the antperson test with 2 patterns exactly the same, where one will simply be 1/10th the scale of the other.
|
||||
|
||||
<Example
|
||||
sample
|
||||
|
|
|
@ -24,6 +24,14 @@ Update the **parts** array with `bib`, rather than `box`:
|
|||
```js
|
||||
parts: ["bib"],
|
||||
```
|
||||
<Note>
|
||||
|
||||
##### Don't worry about the big red error
|
||||
|
||||
This will (temporarily) cause en error to appear in your development environment, because the rest of the code is still expecting to find a part named `box`, but we will fix this in the next steps.
|
||||
|
||||
</Note>
|
||||
|
||||
|
||||
When that's done, rename the `src/box.js` file into `src/bib.js`.
|
||||
|
||||
|
@ -31,20 +39,20 @@ Then, in the `src/index.js` file, change the import accordingly:
|
|||
|
||||
```js
|
||||
// Change this line
|
||||
//import draftBox from "./box";
|
||||
//import draftBox from "./box"
|
||||
|
||||
// Into this
|
||||
import draftBib from "./bib";
|
||||
import draftBib from "./bib"
|
||||
```
|
||||
|
||||
Finally, still in the `src/index.js` file, update the draftmethod:
|
||||
|
||||
```js
|
||||
// Change this line
|
||||
//Pattern.prototype.draftBox = draftBox;
|
||||
//Pattern.prototype.draftBox = draftBox
|
||||
|
||||
// Into this
|
||||
Pattern.prototype.draftBib = draftBib;
|
||||
Pattern.prototype.draftBib = draftBib
|
||||
```
|
||||
|
||||
<Tip>
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 146 KiB After Width: | Height: | Size: 130 KiB |
Loading…
Add table
Add a link
Reference in a new issue