2021-10-17 18:26:00 +02:00
|
|
|
---
|
2021-08-25 16:09:31 +02:00
|
|
|
title: Completing the neck opening
|
2023-09-30 14:04:18 +02:00
|
|
|
order: 80
|
2021-10-17 18:26:00 +02:00
|
|
|
---
|
2021-08-25 16:09:31 +02:00
|
|
|
|
2021-09-04 14:31:21 +02:00
|
|
|
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.
|
|
|
|
|
2022-10-10 04:50:43 +02:00
|
|
|
## Hiding our quarter neck opening
|
|
|
|
|
2021-09-04 14:31:21 +02:00
|
|
|
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.
|
|
|
|
|
2022-10-10 04:50:43 +02:00
|
|
|
To accomplish this, we'll call the `hide()` method on our path:
|
2021-09-04 14:31:21 +02:00
|
|
|
|
2022-10-10 04:50:43 +02:00
|
|
|
<Example tutorial caption="A hidden path is not shown">
|
2024-03-14 02:13:56 +00:00
|
|
|
```design/src/bib.mjs
|
2023-01-06 19:29:29 -08:00
|
|
|
function draftBib({
|
|
|
|
Path,
|
|
|
|
Point,
|
|
|
|
paths,
|
|
|
|
points,
|
2022-10-10 04:50:43 +02:00
|
|
|
measurements,
|
|
|
|
options,
|
|
|
|
part,
|
|
|
|
}) {
|
|
|
|
|
2023-09-30 14:04:18 +02:00
|
|
|
/*
|
|
|
|
* Construct the quarter neck opening
|
|
|
|
*/
|
2022-10-10 04:50:43 +02:00
|
|
|
let tweak = 1
|
2024-03-13 01:19:02 +00:00
|
|
|
let target = (measurements.head * options.neckRatio) /4
|
2022-10-10 04:50:43 +02:00
|
|
|
let delta
|
|
|
|
do {
|
2023-09-30 14:04:18 +02:00
|
|
|
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
|
|
|
|
)
|
2023-01-06 19:29:29 -08:00
|
|
|
|
2023-08-08 13:20:46 -05:00
|
|
|
paths.quarterNeck = new Path()
|
|
|
|
.move(points.right)
|
2023-09-30 14:04:18 +02:00
|
|
|
.curve(
|
|
|
|
points.rightCp1,
|
|
|
|
points.bottomCp2,
|
|
|
|
points.bottom
|
|
|
|
)
|
2024-03-14 02:13:56 +00:00
|
|
|
// highlight-start
|
2022-10-11 01:37:09 +02:00
|
|
|
.hide()
|
2024-03-14 02:13:56 +00:00
|
|
|
// highlight-end
|
2023-01-06 19:29:29 -08:00
|
|
|
|
2023-08-08 13:20:46 -05:00
|
|
|
delta = paths.quarterNeck.length() - target
|
2022-10-10 04:50:43 +02:00
|
|
|
if (delta > 0) tweak = tweak * 0.99
|
|
|
|
else tweak = tweak * 1.02
|
|
|
|
} while (Math.abs(delta) > 1)
|
|
|
|
|
|
|
|
return part
|
|
|
|
}
|
2021-09-04 14:31:21 +02:00
|
|
|
```
|
2022-10-10 04:50:43 +02:00
|
|
|
</Example>
|
2021-09-04 14:31:21 +02:00
|
|
|
|
2022-10-10 04:50:43 +02:00
|
|
|
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.
|
2021-09-04 14:31:21 +02:00
|
|
|
But it won't show up on screen or on the page.
|
|
|
|
|
2022-10-10 04:50:43 +02:00
|
|
|
## Create the complete neck opening
|
2021-09-04 14:31:21 +02:00
|
|
|
|
|
|
|
Now that we've hidden our homework, let's create the complete neck path.
|
2021-08-25 16:09:31 +02:00
|
|
|
As the neck opening is symmetrical, there's no need to re-calculate the points
|
2023-01-06 19:29:29 -08:00
|
|
|
on the other side. We can just flip them over, so to speak. And that's exactly
|
|
|
|
what we'll do.
|
2021-08-25 16:09:31 +02:00
|
|
|
|
2022-10-10 04:50:43 +02:00
|
|
|
Let's add some more points, and then construct the complete path for the neck
|
|
|
|
opening.
|
2021-08-25 16:09:31 +02:00
|
|
|
|
2022-10-10 04:50:43 +02:00
|
|
|
<Example tutorial caption="Our completed neck opening">
|
2024-03-14 02:13:56 +00:00
|
|
|
```design/src/bib.mjs
|
2023-01-06 19:29:29 -08:00
|
|
|
function draftBib({
|
|
|
|
Path,
|
|
|
|
Point,
|
|
|
|
paths,
|
|
|
|
points,
|
2022-10-10 04:50:43 +02:00
|
|
|
measurements,
|
|
|
|
options,
|
|
|
|
part,
|
|
|
|
}) {
|
|
|
|
|
2023-09-30 14:04:18 +02:00
|
|
|
/*
|
|
|
|
* Construct the quarter neck opening
|
|
|
|
*/
|
2022-10-10 04:50:43 +02:00
|
|
|
let tweak = 1
|
2024-03-13 01:19:02 +00:00
|
|
|
let target = (measurements.head * options.neckRatio) /4
|
2022-10-10 04:50:43 +02:00
|
|
|
let delta
|
|
|
|
do {
|
2024-03-13 01:19:02 +00:00
|
|
|
points.right = new Point(
|
|
|
|
tweak * measurements.head / 10,
|
|
|
|
0
|
|
|
|
)
|
|
|
|
points.bottom = new Point(
|
|
|
|
0,
|
|
|
|
tweak * measurements.head / 12
|
|
|
|
)
|
2023-01-06 19:29:29 -08:00
|
|
|
|
2024-03-13 01:19:02 +00: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)
|
2024-03-13 01:19:02 +00:00
|
|
|
.curve(
|
|
|
|
points.rightCp1,
|
|
|
|
points.bottomCp2,
|
|
|
|
points.bottom
|
|
|
|
)
|
2022-10-11 01:37:09 +02:00
|
|
|
.hide()
|
2023-01-06 19:29:29 -08:00
|
|
|
|
2023-08-08 13:20:46 -05:00
|
|
|
delta = paths.quarterNeck.length() - target
|
2022-10-10 04:50:43 +02:00
|
|
|
if (delta > 0) tweak = tweak * 0.99
|
|
|
|
else tweak = tweak * 1.02
|
|
|
|
} while (Math.abs(delta) > 1)
|
|
|
|
|
2024-03-14 02:13:56 +00:00
|
|
|
// highlight-start
|
2023-09-30 14:04:18 +02:00
|
|
|
/*
|
|
|
|
* Construct the complete neck opening
|
|
|
|
*/
|
2022-10-10 04:50:43 +02:00
|
|
|
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()
|
|
|
|
|
|
|
|
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')
|
2024-03-14 02:13:56 +00:00
|
|
|
// highlight-end
|
2022-10-10 04:50:43 +02:00
|
|
|
return part
|
|
|
|
}
|
2021-08-25 16:09:31 +02:00
|
|
|
```
|
2022-10-10 04:50:43 +02:00
|
|
|
</Example>
|
2021-08-25 16:09:31 +02:00
|
|
|
|
2022-10-10 04:50:43 +02:00
|
|
|
To add the points, we're using the `Point.flipX()` and `Point.flipY()` methods
|
2023-03-21 23:03:19 -07:00
|
|
|
here. There's a few new Path methods too, like `close()` and `addClass()`.
|
2021-08-25 16:09:31 +02:00
|
|
|
|
2022-10-10 04:50:43 +02:00
|
|
|
Perhaps you can figure out what they do? If not, both [the Point
|
2023-01-06 19:29:29 -08:00
|
|
|
documentation](/reference/api/point/) and [the Path
|
2022-10-10 04:50:43 +02:00
|
|
|
documentation](/reference/api/path) have detailed info on all the methods
|
|
|
|
available, including these.
|