2021-10-17 18:26:00 +02:00
|
|
|
---
|
2021-08-25 16:09:31 +02:00
|
|
|
title: Shaping the straps
|
2024-11-18 11:05:16 +01:00
|
|
|
sidebar_position: 90
|
2021-10-17 18:26:00 +02:00
|
|
|
---
|
2021-08-25 16:09:31 +02:00
|
|
|
|
|
|
|
Our straps should follow the neck opening, which isn't that hard to do.
|
|
|
|
We just need to keep the control points of our curves at similar proportions.
|
|
|
|
Which means, halfway between the start of the curve, and the corner of our rectangle.
|
|
|
|
|
2024-09-28 13:13:48 +02:00
|
|
|
:::note
|
2021-08-25 16:09:31 +02:00
|
|
|
|
2023-01-06 19:29:29 -08:00
|
|
|
For this, we'll be using a new method: `Point.shiftFractionTowards()`. We've already
|
2021-08-25 16:09:31 +02:00
|
|
|
used `Point.shift()` and there's also `Point.shiftTowards()` and `Point.shiftOutwards()`.
|
|
|
|
As always, [the API docs](/reference/api/point/) have all the details.
|
|
|
|
|
2024-09-28 13:13:48 +02:00
|
|
|
:::
|
2021-08-25 16:09:31 +02:00
|
|
|
|
2022-10-11 01:37:09 +02:00
|
|
|
<Example tutorial caption="All of a sudden, things are starting to look like a bib">
|
2024-03-16 21:06:19 +00:00
|
|
|
```design/src/bib.mjs
|
2023-01-06 19:29:29 -08:00
|
|
|
function draftBib({
|
|
|
|
Path,
|
|
|
|
Point,
|
|
|
|
paths,
|
|
|
|
points,
|
2022-10-10 17:09:17 +02:00
|
|
|
measurements,
|
|
|
|
options,
|
|
|
|
part,
|
|
|
|
}) {
|
2021-08-25 16:09:31 +02:00
|
|
|
|
2024-11-18 11:05:16 +01:00
|
|
|
/\*
|
|
|
|
|
|
|
|
- Construct the quarter neck opening
|
|
|
|
_/
|
2022-10-10 17:09:17 +02:00
|
|
|
let tweak = 1
|
2024-11-18 11:05:16 +01:00
|
|
|
let target = (measurements.head _ options.neckRatio) /4
|
2022-10-10 17:09:17 +02:00
|
|
|
let delta
|
|
|
|
do {
|
2024-11-18 11:05:16 +01:00
|
|
|
points.right = new Point(
|
|
|
|
tweak _ measurements.head / 10,
|
|
|
|
0
|
|
|
|
)
|
|
|
|
points.bottom = new Point(
|
|
|
|
0,
|
|
|
|
tweak _ measurements.head / 12
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2024-03-13 01:19:02 +00:00
|
|
|
points.rightCp1 = points.right.shift(
|
2024-11-18 11:05:16 +01:00
|
|
|
90,
|
2024-03-13 01:19:02 +00:00
|
|
|
points.bottom.dy(points.right) / 2
|
|
|
|
)
|
|
|
|
points.bottomCp2 = points.bottom.shift(
|
2024-11-18 11:05:16 +01:00
|
|
|
0,
|
2024-03-13 01:19:02 +00:00
|
|
|
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)
|
2024-03-13 01:19:02 +00:00
|
|
|
.curve(
|
2024-11-18 11:05:16 +01:00
|
|
|
points.rightCp1,
|
|
|
|
points.bottomCp2,
|
2024-03-13 01:19:02 +00:00
|
|
|
points.bottom
|
|
|
|
)
|
2023-09-30 14:04:18 +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 17:09:17 +02:00
|
|
|
if (delta > 0) tweak = tweak * 0.99
|
|
|
|
else tweak = tweak * 1.02
|
2021-08-25 16:09:31 +02:00
|
|
|
|
2024-11-18 11:05:16 +01:00
|
|
|
} while (Math.abs(delta) > 1)
|
|
|
|
|
|
|
|
/\*
|
|
|
|
|
|
|
|
- Construct the complete neck opening
|
|
|
|
\*/
|
2022-10-10 17:09:17 +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()
|
|
|
|
|
2024-11-18 11:05:16 +01:00
|
|
|
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)
|
2023-01-06 19:29:29 -08:00
|
|
|
|
2024-03-20 00:49:55 +00:00
|
|
|
// strikeout-start
|
2024-11-18 11:05:16 +01:00
|
|
|
/\*
|
|
|
|
|
|
|
|
- Remove this path
|
2024-03-20 00:49:55 +00:00
|
|
|
|
2022-10-10 17:09:17 +02:00
|
|
|
paths.rect = new Path()
|
2024-11-18 11:05:16 +01:00
|
|
|
.move(points.topLeft)
|
|
|
|
.line(points.bottomLeft)
|
|
|
|
.line(points.bottomRight)
|
|
|
|
.line(points.topRight)
|
|
|
|
.line(points.topLeft)
|
|
|
|
.close()
|
|
|
|
.addClass('fabric')
|
|
|
|
\*/
|
|
|
|
// strikeout-end
|
2021-08-25 16:09:31 +02:00
|
|
|
|
2024-03-16 21:06:19 +00:00
|
|
|
// highlight-start
|
2024-11-18 11:05:16 +01:00
|
|
|
/\*
|
|
|
|
|
|
|
|
- Shape the straps
|
|
|
|
\*/
|
2022-10-10 17:09:17 +02:00
|
|
|
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)
|
2023-01-06 19:29:29 -08:00
|
|
|
|
2024-11-18 11:05:16 +01:00
|
|
|
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-01-06 19:29:29 -08:00
|
|
|
|
2024-11-18 11:05:16 +01:00
|
|
|
- Now, adapt our `rect` path so it's no longer a rectangle:
|
|
|
|
\*/
|
2022-10-10 17:09:17 +02:00
|
|
|
paths.rect = new Path()
|
2024-11-18 11:05:16 +01:00
|
|
|
.move(points.edgeTop)
|
|
|
|
.curve(points.edgeTopLeftCp, points.edgeLeftCp, points.edgeLeft)
|
|
|
|
.line(points.bottomLeft)
|
|
|
|
.line(points.bottomRight)
|
|
|
|
.line(points.edgeRight)
|
|
|
|
.curve(points.edgeRightCp, points.edgeTopRightCp, points.edgeTop)
|
|
|
|
.close()
|
2021-08-25 16:09:31 +02:00
|
|
|
|
2024-03-16 21:06:19 +00:00
|
|
|
// highlight-end
|
|
|
|
|
2024-11-18 11:05:16 +01:00
|
|
|
return part
|
2022-10-10 17:09:17 +02:00
|
|
|
}
|
2024-11-18 11:05:16 +01:00
|
|
|
|
2022-10-10 17:09:17 +02:00
|
|
|
```
|
2022-01-19 11:31:39 +01:00
|
|
|
</Example>
|
2024-11-18 11:05:16 +01:00
|
|
|
```
|