wip(markdown): Work on tutorial
This commit is contained in:
parent
ed576747d8
commit
2d5cdf5806
6 changed files with 339 additions and 153 deletions
|
@ -3,67 +3,129 @@ title: Completing the neck opening
|
||||||
order: 180
|
order: 180
|
||||||
---
|
---
|
||||||
|
|
||||||
## Hiding our quarter neck
|
|
||||||
|
|
||||||
We've constructed the perfectly sized quarter neck, and we're going to use this
|
We've constructed the perfectly sized quarter neck, and we're going to use this
|
||||||
to create our complete neck path by flipping and mirroring it.
|
to create our complete neck path by flipping and mirroring it.
|
||||||
|
|
||||||
|
## Hiding our quarter neck opening
|
||||||
|
|
||||||
To make our code easier to understand, we're going to leave the `quarterNeck` path
|
To make our code easier to understand, we're going to leave the `quarterNeck` path
|
||||||
as it is, and simply chose to not show it.
|
as it is, and simply chose to not show it.
|
||||||
|
|
||||||
To accomplish this, update the code and add this one line:
|
To accomplish this, we'll call the `hide()` method on our path:
|
||||||
|
|
||||||
|
<Example tutorial caption="A hidden path is not shown">
|
||||||
```js
|
```js
|
||||||
paths.quarterNeck = new Path()
|
function draftBib({
|
||||||
.move(points.right)
|
Path,
|
||||||
.curve(points.rightCp1, points.bottomCp2, points.bottom)
|
Point,
|
||||||
.setRender(false) // <== Add this line
|
paths,
|
||||||
```
|
points,
|
||||||
|
measurements,
|
||||||
|
options,
|
||||||
|
part,
|
||||||
|
}) {
|
||||||
|
|
||||||
We're saying: don't render this path. In other words, don't show it.
|
// Construct the quarter neck opening
|
||||||
The path is now known, and we can still use it to calculate the length of the 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)
|
||||||
|
|
||||||
|
return part
|
||||||
|
}
|
||||||
|
```
|
||||||
|
</Example>
|
||||||
|
|
||||||
|
We're saying: _hide this path_. In other words, don't show it.
|
||||||
|
The path is still known, and we can still use it to calculate the length of the neck opening.
|
||||||
But it won't show up on screen or on the page.
|
But it won't show up on screen or on the page.
|
||||||
|
|
||||||
## Create the complete neck path
|
## Create the complete neck opening
|
||||||
|
|
||||||
Now that we've hidden our homework, let's create the complete neck path.
|
Now that we've hidden our homework, let's create the complete neck path.
|
||||||
As the neck opening is symmetrical, there's no need to re-calculate the points
|
As the neck opening is symmetrical, there's no need to re-calculate the points
|
||||||
on the other side. You can just flip them over, so to speak. And that's exactly what you'll do.
|
on the other side. You can just flip them over, so to speak. And that's exactly
|
||||||
|
what you'll do.
|
||||||
|
|
||||||
Below your code (under the line with `while` on it), let's add some more points:
|
Let's add some more points, and then construct the complete path for the neck
|
||||||
|
opening.
|
||||||
|
|
||||||
|
<Example tutorial caption="Our completed neck opening">
|
||||||
```js
|
```js
|
||||||
points.rightCp2 = points.rightCp1.flipY()
|
function draftBib({
|
||||||
points.bottomCp1 = points.bottomCp2.flipX()
|
Path,
|
||||||
|
Point,
|
||||||
|
paths,
|
||||||
|
points,
|
||||||
|
measurements,
|
||||||
|
options,
|
||||||
|
part,
|
||||||
|
}) {
|
||||||
|
|
||||||
points.left = points.right.flipX()
|
// Construct the quarter neck opening
|
||||||
points.leftCp1 = points.rightCp2.flipX()
|
let tweak = 1
|
||||||
points.leftCp2 = points.rightCp1.flipX()
|
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)
|
||||||
|
|
||||||
points.top = points.bottom.flipY()
|
// Construct the complete neck opening
|
||||||
points.topCp1 = points.bottomCp2.flipY()
|
points.rightCp2 = points.rightCp1.flipY()
|
||||||
points.topCp2 = points.bottomCp1.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()
|
||||||
|
|
||||||
|
paths.neck = new Path()
|
||||||
|
.move(points.top)
|
||||||
|
.curve(points.topCp2, points.leftCp1, points.left)
|
||||||
|
.curve(points.leftCp2, points.bottomCp1, points.bottom)
|
||||||
|
.curve(points.bottomCp2, points.rightCp1, points.right)
|
||||||
|
.curve(points.rightCp2, points.topCp1, points.top)
|
||||||
|
.close()
|
||||||
|
.addClass('fabric')
|
||||||
|
|
||||||
|
return part
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
<Note>
|
|
||||||
|
|
||||||
We're using the `Point.flipX()` and `Point.flipY()` methods here.
|
|
||||||
Perhaps you can figure out what they do? If not, check [the API documentation](/reference/api/point/).
|
|
||||||
|
|
||||||
</Note>
|
|
||||||
|
|
||||||
Then, below those new points, and the following code to create your path for the neck opening:
|
|
||||||
|
|
||||||
```js
|
|
||||||
paths.neck = new Path()
|
|
||||||
.move(points.top)
|
|
||||||
.curve(points.topCp2, points.leftCp1, points.left)
|
|
||||||
.curve(points.leftCp2, points.bottomCp1, points.bottom)
|
|
||||||
.curve(points.bottomCp2, points.rightCp1, points.right)
|
|
||||||
.curve(points.rightCp2, points.topCp1, points.top)
|
|
||||||
.close()
|
|
||||||
```
|
|
||||||
|
|
||||||
<Example pattern="tutorial" part="step4">
|
|
||||||
And now you have a complete neck opening
|
|
||||||
</Example>
|
</Example>
|
||||||
|
|
||||||
|
To add the points, we're using the `Point.flipX()` and `Point.flipY()` methods
|
||||||
|
here. There's a few new Path methods to, like `close()` and `addClass()`.
|
||||||
|
|
||||||
|
Perhaps you can figure out what they do? If not, both [the Point
|
||||||
|
documentation](/reference/api/point/) and [the Path
|
||||||
|
documentation](/reference/api/path) have detailed info on all the methods
|
||||||
|
available, including these.
|
||||||
|
|
|
@ -3,83 +3,119 @@ title: Constructing the neck opening
|
||||||
order: 160
|
order: 160
|
||||||
---
|
---
|
||||||
|
|
||||||
Your goal is to construct a slightly oval neck opening that has a circumference that is
|
Our goal is to construct an oval neck opening that has a circumference
|
||||||
the `head` measurements multiplied by the `neckRatio` option.
|
that is the `head` measurements multiplied by the `neckRatio` option.
|
||||||
|
|
||||||
That might involve some trial and error. But since the neck opening will be symetric
|
That might involve some trial and error. But since the neck opening will be symetric
|
||||||
both horizontal and vertical, you only need to construct one quadrant.
|
both horizontal and vertical, we only need to construct one quadrant.
|
||||||
|
|
||||||
We'll be adding some points to our pattern to do just that. But we want to have access
|
## Desructuring measurements and options
|
||||||
to our measurements and options to do so. For this, you first update the shorthand call
|
|
||||||
to indicate you also want access to `measurements` and `options`:
|
|
||||||
|
|
||||||
```js
|
We'll be adding some points to our pattern to do just that. But we want to have
|
||||||
const {
|
access to our measurements and options to do so. For this, we first destructure
|
||||||
Point,
|
`measurements` and `options` so we can access them:
|
||||||
points,
|
|
||||||
Path,
|
```design/src/bib.mjs
|
||||||
paths,
|
function draftBib({
|
||||||
complete,
|
Path,
|
||||||
sa,
|
Point,
|
||||||
paperless,
|
paths,
|
||||||
|
points,
|
||||||
|
// Add the following two lines:
|
||||||
measurements,
|
measurements,
|
||||||
options
|
options
|
||||||
} = part.shorthand()
|
part,
|
||||||
|
}) {
|
||||||
|
|
||||||
|
return part
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Great. Now let's get to work:
|
Great. Now let's get to work.
|
||||||
|
|
||||||
|
## Drawing our first path
|
||||||
|
|
||||||
|
Let's add some points, and use them to draw our first curve:
|
||||||
|
|
||||||
|
<Example tutorial caption="Our very first path forms a quarter of our neck opening">
|
||||||
```js
|
```js
|
||||||
// Design pattern here
|
function draftBib({
|
||||||
points.right = new Point(measurements.head / 10, 0)
|
Path,
|
||||||
points.bottom = new Point(0, measurements.head / 12)
|
Point,
|
||||||
|
paths,
|
||||||
|
points,
|
||||||
|
measurements,
|
||||||
|
options,
|
||||||
|
part,
|
||||||
|
}) {
|
||||||
|
|
||||||
points.rightCp1 = points.right
|
// Construct the quarter neck opening
|
||||||
.shift(90, points.bottom.dy(points.right)/2)
|
points.right = new Point(measurements.head / 10, 0)
|
||||||
points.bottomCp2 = points.bottom
|
points.bottom = new Point(0, measurements.head / 12)
|
||||||
.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.quarterNeck = new Path()
|
||||||
|
.move(points.right)
|
||||||
|
.curve(points.rightCp1, points.bottomCp2, points.bottom)
|
||||||
|
|
||||||
paths.quarterNeck = new Path()
|
return part
|
||||||
.move(points.right)
|
}
|
||||||
.curve(points.rightCp1, points.bottomCp2, points.bottom)
|
|
||||||
```
|
```
|
||||||
|
</Example>
|
||||||
|
|
||||||
You've added some points to your part, and drawn your first path. Let's look at each line in detail:
|
You've added some points to your part, and drawn your first path.
|
||||||
|
Let's look at each line in detail.
|
||||||
|
|
||||||
|
## Adding points
|
||||||
|
|
||||||
```js
|
```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 adding a point named `right` to the `points` object which holds our
|
||||||
- We're using the Point constructor, which takes two arguments: The point's X and Y values
|
part's points
|
||||||
|
- 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 X value is `measurements.head / 10`
|
||||||
- The Y value is `0`
|
- The Y value is `0`
|
||||||
|
|
||||||
The `bottom` part is very similar, so let's skip to the next line:
|
The creation of `points.bottom` is very similar, so let's skip to the next line:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
points.rightCp1 = points.right
|
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
|
- We're adding a point named `rightCp1`, which will become the _control point_
|
||||||
- Instead of using the Point constructor, we're calling the `Point.shift()` method on an existing point
|
of the right part
|
||||||
|
- Instead of using the Point constructor, we're calling the `Point.shift()`
|
||||||
|
method on an existing point
|
||||||
- It takes two arguments: The angle to shift towards, and the distance
|
- It takes two arguments: The angle to shift towards, and the distance
|
||||||
- You can see that we're shifting 90 degrees (that means up) but the distance uses another method
|
- You can see that we're shifting 90 degrees (that means up) but the distance
|
||||||
- The `Point.dy()` method returns the delta along the Y axis between the point you call it on and the point you pass it
|
uses another method
|
||||||
|
- The `Point.dy()` method returns the delta along the Y axis between the point
|
||||||
|
you call it on and the point you pass it
|
||||||
- We shift half of the Y-delta
|
- We shift half of the Y-delta
|
||||||
|
|
||||||
The next point is very similar again, except that this time we're shifting to the right (0 degrees) for half of
|
The next point is very similar again, except that this time we're shifting to
|
||||||
the X-delta between points `bottom` and `right`.
|
the right (0 degrees) for half of the X-delta between points `bottom` and
|
||||||
|
`right`.
|
||||||
|
|
||||||
<Tip>
|
<Tip>
|
||||||
|
##### Further reading
|
||||||
|
The `Point.shift()` and `Point.dy()` are just the tip of the iceberg.
|
||||||
Points come with a bunch of these methods.
|
Points come with a bunch of these methods.
|
||||||
You can find them all in [the Point API docs](/reference/api/point/).
|
You can find them all in [the Point API docs](/reference/api/point/).
|
||||||
|
|
||||||
</Tip>
|
</Tip>
|
||||||
|
|
||||||
The next line introduces you to something new: Paths:
|
## Adding paths
|
||||||
|
|
||||||
|
Adding points is typically merely a means to an end. And that end gets
|
||||||
|
introduced on the next line: Paths.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
paths.quarterNeck = new Path()
|
paths.quarterNeck = new Path()
|
||||||
|
@ -87,20 +123,20 @@ paths.quarterNeck = new Path()
|
||||||
.curve(points.rightCp1, points.bottomCp2, points.bottom)
|
.curve(points.rightCp1, points.bottomCp2, points.bottom)
|
||||||
```
|
```
|
||||||
|
|
||||||
- We're adding a path named `quarterNeck` to `paths` which holds our part's paths
|
- We're adding a path named `quarterNeck` to the `paths` object which holds our
|
||||||
|
part's paths
|
||||||
- We're using the Path constructor, which takes no arguments
|
- We're using the Path constructor, which takes no arguments
|
||||||
- We're following up with a `Path.move()` call that takes one Point as argument
|
- We're following up with a `Path.move()` call that takes one Point as argument
|
||||||
- Then, there's a `Path.curve()` call that takes 3 points as arguments
|
- Then, there's a `Path.curve()` call that takes 3 points as arguments
|
||||||
|
|
||||||
If you've read through the high-level [Pattern guide](/guides/patterns/) you will have learned that paths
|
If you've read through the high-level [Pattern guide](/guides/patterns) you
|
||||||
always start with a `move()` operation. In this case, we moved to our `right` points.
|
will have learned that paths always start with a `move()` operation. In this
|
||||||
|
case, we moved to our `right` points.
|
||||||
|
|
||||||
From there, we drew a Bezier curve to our `bottom` point by using `rightCp1` and `bottomCp2` as control points.
|
From there, we drew a cubic Bezier curve to our `bottom` point by using
|
||||||
|
`rightCp1` and `bottomCp2` as control points.
|
||||||
When all is said and done, we now have a quarter of our neck opening:
|
|
||||||
|
|
||||||
<Example pattern="tutorial" part="step2">You have drawn your first path</Example>
|
|
||||||
|
|
||||||
|
When all is said and done, we now have a quarter of our neck opening.
|
||||||
The only problem is, we have no guarantee whatsoever that this opening is the correct size.
|
The only problem is, we have no guarantee whatsoever that this opening is the correct size.
|
||||||
|
|
||||||
Rather than hope it is the correct size, you'll make sure it is next.
|
Rather than hope it is the correct size, we'll make sure it is next.
|
||||||
|
|
|
@ -28,6 +28,16 @@ need to draft your method. Destructuring is a way to *pull things out of the
|
||||||
object into their own variable*. It saves us a bunch of typing as these two are
|
object into their own variable*. It saves us a bunch of typing as these two are
|
||||||
equivalent:
|
equivalent:
|
||||||
|
|
||||||
|
<Tabs tabs="Without destructuring, With destructuring">
|
||||||
|
<Tab>
|
||||||
|
```design/src/bib.mjs
|
||||||
|
function draftBib({ part }) {
|
||||||
|
|
||||||
|
return part
|
||||||
|
}
|
||||||
|
```
|
||||||
|
</Tab>
|
||||||
|
<Tab>
|
||||||
```design/src/bib.mjs
|
```design/src/bib.mjs
|
||||||
function draftBib(props) {
|
function draftBib(props) {
|
||||||
|
|
||||||
|
@ -35,13 +45,8 @@ function draftBib(props) {
|
||||||
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
</Tab>
|
||||||
```design/src/bib.mjs
|
</Tabs>
|
||||||
function draftBib({ part }) {
|
|
||||||
|
|
||||||
return part
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
As we'll make our way through this tutorial, we'll need more and more stuff, so
|
As we'll make our way through this tutorial, we'll need more and more stuff, so
|
||||||
we'll be pulling it out of the object passed to the draft method via
|
we'll be pulling it out of the object passed to the draft method via
|
||||||
|
|
|
@ -3,35 +3,92 @@ title: Drawing the bib outline
|
||||||
order: 190
|
order: 190
|
||||||
---
|
---
|
||||||
|
|
||||||
With our neck opening in place, let's draw the basic outline of our bib:
|
With our neck opening in place, let us draw the basic outline of our bib.
|
||||||
|
|
||||||
|
<Example tutorial caption="Note how the neck opening is the same distance from the left, right, and top edge">
|
||||||
```js
|
```js
|
||||||
let width = measurements.head * options.widthRatio
|
function draftBib({
|
||||||
let length = measurements.head * options.lengthRatio
|
Path,
|
||||||
|
Point,
|
||||||
|
paths,
|
||||||
|
points,
|
||||||
|
measurements,
|
||||||
|
options,
|
||||||
|
part,
|
||||||
|
}) {
|
||||||
|
|
||||||
points.topLeft = new Point(
|
// Construct the quarter neck opening
|
||||||
width / -2,
|
let tweak = 1
|
||||||
points.top.y - (width / 2 - points.right.x)
|
let target = (measurements.head * options.neckRatio) /4
|
||||||
);
|
let delta
|
||||||
points.topRight = points.topLeft.shift(0, width)
|
do {
|
||||||
points.bottomLeft = points.topLeft.shift(-90, length)
|
points.right = new Point(tweak * measurements.head / 10, 0)
|
||||||
points.bottomRight = points.topRight.shift(-90, length)
|
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)
|
||||||
|
|
||||||
paths.rect = new Path()
|
// Construct the complete neck opening
|
||||||
.move(points.topLeft)
|
points.rightCp2 = points.rightCp1.flipY()
|
||||||
.line(points.bottomLeft)
|
points.bottomCp1 = points.bottomCp2.flipX()
|
||||||
.line(points.bottomRight)
|
points.left = points.right.flipX()
|
||||||
.line(points.topRight)
|
points.leftCp1 = points.rightCp2.flipX()
|
||||||
.line(points.topLeft)
|
points.leftCp2 = points.rightCp1.flipX()
|
||||||
.close()
|
points.top = points.bottom.flipY()
|
||||||
|
points.topCp1 = points.bottomCp2.flipY()
|
||||||
|
points.topCp2 = points.bottomCp1.flipY()
|
||||||
|
|
||||||
|
paths.neck = new Path()
|
||||||
|
.move(points.top)
|
||||||
|
.curve(points.topCp2, points.leftCp1, points.left)
|
||||||
|
.curve(points.leftCp2, points.bottomCp1, points.bottom)
|
||||||
|
.curve(points.bottomCp2, points.rightCp1, points.right)
|
||||||
|
.curve(points.rightCp2, points.topCp1, points.top)
|
||||||
|
.close()
|
||||||
|
.addClass('fabric')
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
|
||||||
|
paths.rect = new Path()
|
||||||
|
.move(points.topLeft)
|
||||||
|
.line(points.bottomLeft)
|
||||||
|
.line(points.bottomRight)
|
||||||
|
.line(points.topRight)
|
||||||
|
.line(points.topLeft)
|
||||||
|
.close()
|
||||||
|
.addClass('fabric')
|
||||||
|
|
||||||
|
return part
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
</Example>
|
||||||
|
|
||||||
First thing we did was create the `width` and `length` variables to
|
First thing we did was create the `width` and `length` variables to
|
||||||
save ourselves some typing:
|
save ourselves some typing:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
let width = measurements.head * options.widthRatio
|
const width = measurements.head * options.widthRatio
|
||||||
let length = measurements.head * options.lengthRatio
|
const length = measurements.head * options.lengthRatio
|
||||||
```
|
```
|
||||||
|
|
||||||
Both the length and width of your bib are a factor of the head circumference.
|
Both the length and width of your bib are a factor of the head circumference.
|
||||||
|
@ -56,13 +113,11 @@ paths.rect = new Path()
|
||||||
.line(points.topRight)
|
.line(points.topRight)
|
||||||
.line(points.topLeft)
|
.line(points.topLeft)
|
||||||
.close()
|
.close()
|
||||||
|
.addClass('fabric')
|
||||||
```
|
```
|
||||||
|
|
||||||
We're calculating the `topLeft` point so that the top edge of our bib
|
We're calculating the `topLeft` point so that the top edge of our bib
|
||||||
and the sides are equidistant from the neck neck opening.
|
and the sides are equidistant from the neck neck opening.
|
||||||
|
|
||||||
You didn't have to do that. But it looks nicely balanced this way:
|
We didn't have to do that. But it looks nicely balanced this way.
|
||||||
|
|
||||||
<Example pattern="tutorial" part="step5">
|
|
||||||
Note how the neck opening is the same distance from the left, right, and top edge
|
|
||||||
</Example>
|
|
||||||
|
|
|
@ -5,6 +5,14 @@ title: Pattern design tutorial
|
||||||
Welcome to the FreeSewing pattern design tutorial, where you'll learn how to
|
Welcome to the FreeSewing pattern design tutorial, where you'll learn how to
|
||||||
design a made-to-measure sewing pattern, start to finish.
|
design a made-to-measure sewing pattern, start to finish.
|
||||||
|
|
||||||
|
<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
|
||||||
|
terminology and concepts that we'll use throughout this guide.
|
||||||
|
</Tip>
|
||||||
|
|
||||||
You will be designing a pattern for a baby bib. It's a very simple pattern, but
|
You will be designing a pattern for a baby bib. It's a very simple pattern, but
|
||||||
that's the point. Your focus today is on learning FreeSewing and how to
|
that's the point. Your focus today is on learning FreeSewing and how to
|
||||||
translate your designs into code.
|
translate your designs into code.
|
||||||
|
|
|
@ -3,48 +3,68 @@ title: Fitting the neck opening
|
||||||
order: 170
|
order: 170
|
||||||
---
|
---
|
||||||
|
|
||||||
Here's how we'll make sure the neck opening is _just right_:
|
We are not going to create some opening that we _hope_ is the right size, we're
|
||||||
|
going to make sure it is. Here's how we'll make sure the neck opening is _just
|
||||||
|
right_:
|
||||||
|
|
||||||
|
<Example tutorial caption="It might look the same as before, but now it's just right">
|
||||||
```js
|
```js
|
||||||
let tweak = 1
|
function draftBib({
|
||||||
let target = (measurements.head * options.neckRatio) /4
|
Path,
|
||||||
let delta
|
Point,
|
||||||
do {
|
paths,
|
||||||
points.right = new Point(tweak * measurements.head / 10, 0)
|
points,
|
||||||
points.bottom = new Point(0, tweak * measurements.head / 12)
|
measurements,
|
||||||
|
options,
|
||||||
|
part,
|
||||||
|
}) {
|
||||||
|
|
||||||
points.rightCp1 = points.right.shift(90, points.bottom.dy(points.right)/2)
|
// Construct the quarter neck opening
|
||||||
points.bottomCp2 = points.bottom.shift(0, points.bottom.dx(points.right)/2)
|
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)
|
||||||
|
|
||||||
|
delta = paths.quarterNeck.length() - target
|
||||||
|
if (delta > 0) tweak = tweak * 0.99
|
||||||
|
else tweak = tweak * 1.02
|
||||||
|
} while (Math.abs(delta) > 1)
|
||||||
|
|
||||||
paths.quarterNeck = new Path()
|
return part
|
||||||
.move(points.right)
|
}
|
||||||
.curve(points.rightCp1, points.bottomCp2, points.bottom)
|
|
||||||
|
|
||||||
delta = paths.quarterNeck.length() - target
|
|
||||||
if (delta > 0) tweak = tweak * 0.99
|
|
||||||
else tweak = tweak * 1.02
|
|
||||||
} while (Math.abs(delta) > 1)
|
|
||||||
```
|
```
|
||||||
|
</Example>
|
||||||
|
|
||||||
We've added a few new variables:
|
We've added a few new variables:
|
||||||
|
|
||||||
- `tweak`: A _tweak factor_ that we'll use to increase or decrease the neck opening by making it more or less than 1
|
- `tweak`: A _tweak factor_ that we'll use to increase or decrease the neck
|
||||||
|
opening by making it more or less than 1
|
||||||
- `target`: How long our (quarter) neck opening should be
|
- `target`: How long our (quarter) neck opening should be
|
||||||
- `delta`: How far we're off. Positive numbers mean it's too long, negative means too short
|
- `delta`: How far we're off. Positive numbers mean it's too long, negative
|
||||||
|
means too short
|
||||||
|
|
||||||
Now that we know what `target` is, we construct our path as we did before.
|
Now that we know what `target` is, we construct our path as we did before. But
|
||||||
But this time around, we multiply our point coordinates with our `tweak` variable (1 at the start).
|
this time around, we multiply our point coordinates with our `tweak` variable
|
||||||
|
(1 at the start).
|
||||||
|
|
||||||
Then, we compare our `target` to the result of `paths.neck.length()` which — you guessed it — returns the
|
Then, we compare our `target` to the result of `paths.neck.length()` which —
|
||||||
length of our neck path.
|
you guessed it — returns the 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 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.
|
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 within 1mm of 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">
|
Now that we're happy with the length of our quarter neck opening, let's
|
||||||
It might look the same as before, but now it's just right
|
construct the entire neck opening.
|
||||||
</Example>
|
|
||||||
|
|
||||||
Now that we're happy with the length of our quarter neck opening, let's construct the entire neck opening.
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue