1
0
Fork 0

fix(dev): One-liner admonitions

This commit is contained in:
Joost De Cock 2024-09-29 07:14:59 +02:00
parent a6d656c19e
commit da41cc0fc9
60 changed files with 860 additions and 659 deletions

View file

@ -1,59 +1,67 @@
--- ---
title: "Include Cutting Instructions" title: 'Include Cutting Instructions'
--- ---
To include cutting instructions with your part, use the [annotations plugin](/reference/plugins/annotations) (included by default via [core-plugins](/reference/plugins/core)) to add the `cutlist.addCut` method to your part's [`store`](/reference/api/store/extend). To include cutting instructions with your part, use the [annotations plugin](/reference/plugins/annotations) (included by default via [core-plugins](/reference/plugins/core)) to add the `cutlist.addCut` method to your part's [`store`](/reference/api/store/extend).
:::tipThe [grainline macro](/reference/macros/grainline) and the [cutonfold macro](/reference/macros/cutonfold) will automatically add grain and fold information to the cutting instructions ::: :::tip
The [grainline macro](/reference/macros/grainline) and the [cutonfold
macro](/reference/macros/cutonfold) will automatically add grain and fold
information to the cutting instructions
:::
:::tipThese cutting instructions get used by the [title macro](/reference/macros/title), so be sure to add them before adding your part's title. ::: :::tip
These cutting instructions get used by the [title
macro](/reference/macros/title), so be sure to add them before adding your
part's title.
:::
:::note :::note
<details> <details>
<summary>addCut() Parameters</summary> <summary>addCut() Parameters</summary>
Pass an object to the `store.cutlist.addCut` method with any of the following keys; any you don't provide will be filled with the defaults: Pass an object to the `store.cutlist.addCut` method with any of the following keys; any you don't provide will be filled with the defaults:
| Key | Type | Default | Description | | Key | Type | Default | Description |
| :-- | :--- | :------ | :---------- | | :----------- | :------------ | :------- | :--------------------------------------------------------------------------------------------------------------------------------- |
| cut | Number\|false | 2 | the number of pieces to cut from the specified material. Pass `false` to clear all cutting instructions for the material | | cut | Number\|false | 2 | the number of pieces to cut from the specified material. Pass `false` to clear all cutting instructions for the material |
| material | String | 'fabric' | the translation key of the material to cut from | | material | String | 'fabric' | the translation key of the material to cut from |
| identical | Boolean | false | should even numbers of pieces be cut in the same direction? false for mirrored | | identical | Boolean | false | should even numbers of pieces be cut in the same direction? false for mirrored |
| bias | Boolean | false | should the pieces in these cutting instructions be cut on the bias? 'false' uses grainline instruction or leaves orientation as is | | bias | Boolean | false | should the pieces in these cutting instructions be cut on the bias? 'false' uses grainline instruction or leaves orientation as is |
| ignoreOnFold | Boolean | false | should these cutting instructions ignore any cutOnFold information set by the part | | ignoreOnFold | Boolean | false | should these cutting instructions ignore any cutOnFold information set by the part |
You can use any `string` you want for your material, but here are some standard ones we have translation for You can use any `string` you want for your material, but here are some standard ones we have translation for
| Key | Translation | | Key | Translation |
|:--|:--| | :---------- | :-------------------------- |
| fabric | Main Fabric | | fabric | Main Fabric |
| lining | Lining | | lining | Lining |
| canvas | Canvas | | canvas | Canvas |
| lmhCanavas | Light to Medium Hair Canvas | | lmhCanavas | Light to Medium Hair Canvas |
| heavyCanvas | Heavyweight Hair Canvas | | heavyCanvas | Heavyweight Hair Canvas |
| interfacing | Interfacing | | interfacing | Interfacing |
| plastic | Plastic | | plastic | Plastic |
| ribbing | Ribbing | | ribbing | Ribbing |
</details> </details>
::: :::
## Basic Usage ## Basic Usage
For simple cutting instructions, you can rely on the default method parameters For simple cutting instructions, you can rely on the default method parameters
```js ```js
const part = { const part = {
name: 'example.front', name: 'example.front',
draft: ({part, store}) => { draft: ({ part, store }) => {
// add instructions to cut two mirrored from main fabric // add instructions to cut two mirrored from main fabric
store.cutlist.addCut() store.cutlist.addCut()
} },
} }
``` ```
## Intermediate Usage ## Intermediate Usage
For many designs, you'll want more than just "Cut 2 mirrored from Main Fabric" For many designs, you'll want more than just "Cut 2 mirrored from Main Fabric"
### Specifying materials, number of pieces, orientation ### Specifying materials, number of pieces, orientation
@ -62,72 +70,74 @@ You can override the default values to specify different materials, number of pi
```js ```js
const part = { const part = {
name: 'example.front', name: 'example.front',
draft: ({part, store}) => { draft: ({ part, store }) => {
// add instructions to cut three identical from lining // add instructions to cut three identical from lining
store.cutlist.addCut({cut: 3, material: 'lining', identical: true}) store.cutlist.addCut({ cut: 3, material: 'lining', identical: true })
} },
} }
``` ```
### Instructions for multiple materials ### Instructions for multiple materials
You can add as many sets of instructions as you need You can add as many sets of instructions as you need
```js ```js
const part = { const part = {
name: 'example.front', name: 'example.front',
draft: ({part, store}) => { draft: ({ part, store }) => {
// add instructions to cut four mirrored from main fabric // add instructions to cut four mirrored from main fabric
store.cutlist.addCut({cut: 4}) store.cutlist.addCut({ cut: 4 })
// add instructions to cut three identical from lining // add instructions to cut three identical from lining
store.cutlist.addCut({cut: 3, material: 'lining', identical: true}) store.cutlist.addCut({ cut: 3, material: 'lining', identical: true })
} },
} }
``` ```
## Advanced usage ## Advanced usage
### Cut some on the fold, some not ### Cut some on the fold, some not
Sometimes you want some pieces cut on the fold and others cut as halves to seam together. Sometimes you want some pieces cut on the fold and others cut as halves to seam together.
```js ```js
const part = { const part = {
name: 'example.front', name: 'example.front',
draft: ({part, points, Point, macro, store}) => { draft: ({ part, points, Point, macro, store }) => {
// set the cut on fold line // set the cut on fold line
points.p1 = new Point(0, 0) points.p1 = new Point(0, 0)
points.p2 = new Point(0, 10) points.p2 = new Point(0, 10)
// pieces should be cut on the fold // pieces should be cut on the fold
macro('cutonfold', {from: points.p1, to: points.p2}) macro('cutonfold', { from: points.p1, to: points.p2 })
// cut two on the fold // cut two on the fold
store.cutlist.addCut() store.cutlist.addCut()
// cut two, not on the fold // cut two, not on the fold
store.cutlist.addCut({cut: 2, ignoreOnFold: true}) store.cutlist.addCut({ cut: 2, ignoreOnFold: true })
} },
} }
``` ```
### Cut some on the grain, some on the bias ### Cut some on the grain, some on the bias
You set the grainline on a piece, but you also need some to be cut on the bias You set the grainline on a piece, but you also need some to be cut on the bias
```js ```js
const part = { const part = {
name: 'example.front', name: 'example.front',
draft: ({part, points, Point, macro, store}) => { draft: ({ part, points, Point, macro, store }) => {
// set the cut on fold line // set the cut on fold line
points.p1 = new Point(0, 0) points.p1 = new Point(0, 0)
points.p2 = new Point(0, 10) points.p2 = new Point(0, 10)
// the grain runs from p1 to p2 // the grain runs from p1 to p2
macro('grainline', {from: points.p1, to: points.p2}) macro('grainline', { from: points.p1, to: points.p2 })
// cut two mirrored on the grain // cut two mirrored on the grain
store.cutlist.addCut() store.cutlist.addCut()
// cut two mirrored on the bias // cut two mirrored on the bias
store.cutlist.addCut({cut: 2, bias: true}) store.cutlist.addCut({ cut: 2, bias: true })
} },
} }
``` ```

View file

@ -1,5 +1,5 @@
--- ---
title: Design title: Design
--- ---
The `Design` named export in FreeSewing's core library is a constructor that The `Design` named export in FreeSewing's core library is a constructor that
@ -17,7 +17,7 @@ Pattern Design({
## Example ## Example
```js ```js
const Sorcha = new Design({ const Sorcha = new Design({
// design configuration here // design configuration here
}) })
``` ```
@ -32,12 +32,14 @@ the Design configuration object only requires a `parts` property that should
hold an array of parts to include in the Design. hold an array of parts to include in the Design.
```js ```js
const Sorcha = new Design({ const Sorcha = new Design({
parts: [ front, back, sleeve ], parts: [front, back, sleeve],
}) })
``` ```
:::tipA Design in FreeSewing is little more than a container for various Parts::: :::tip
A Design in FreeSewing is little more than a container for various Parts
:::
Optionally, you can also pass it a `data` attribute Optionally, you can also pass it a `data` attribute
to hold any custom data you'd like to add to your Design. to hold any custom data you'd like to add to your Design.
@ -46,20 +48,19 @@ Any `data` you add to the Design constructor will be added
to [the Store](/reference/api/store). to [the Store](/reference/api/store).
```js ```js
const Sorcha = new Design({ const Sorcha = new Design({
parts: [ front, back, sleeve ], parts: [front, back, sleeve],
data: { data: {
version: 3, version: 3,
price: 12, price: 12,
currency: 'euro' currency: 'euro',
} },
}) })
``` ```
## Notes ## Notes
The Design constructor is a _super-constructor_.
The Design constructor is a _super-constructor_.
It will return a constructor method that will a pattern based on your design. It will return a constructor method that will a pattern based on your design.
## Properties ## Properties
@ -74,4 +75,3 @@ This holds the design configuration as passed to the Design constructor.
### Design.patternConfig ### Design.patternConfig
Holds the resolved pattern configuration based on the configuration passed to the Design constructor. Holds the resolved pattern configuration based on the configuration passed to the Design constructor.

View file

@ -4,8 +4,13 @@ title: Hiding parts
The `hide` option of a part's configuration controls how to hide it and/or its dependencies. The `hide` option of a part's configuration controls how to hide it and/or its dependencies.
:::tipA hidden part will not be included in the output when it's rendered::: :::tip
:::tipThe `hide` configuration from parts that you include in your design will always override configuration from inherited parts.::: A hidden part will not be included in the output when it's rendered
:::
:::tip
The `hide` configuration from parts that you include in your design will always override configuration from inherited parts.
:::
## Settings ## Settings
@ -20,12 +25,11 @@ const part = {
name: 'example.front', name: 'example.front',
after: [exampleBase], after: [exampleBase],
// hide `exampleBase` // hide `exampleBase`
hide: {after: true}, hide: { after: true },
draft: ({ part }) => part draft: ({ part }) => part,
} }
``` ```
### hide.always ### hide.always
To hide a specific part that would otherwise not be hidden by other configuration, add its name to the `hide.always` array To hide a specific part that would otherwise not be hidden by other configuration, add its name to the `hide.always` array
@ -37,8 +41,8 @@ const part = {
name: 'example.front', name: 'example.front',
after: [exampleBase, exampleBack], after: [exampleBase, exampleBack],
// hide `exampleBack` // hide `exampleBack`
hide: {always: ['example.back']}, hide: { always: ['example.back'] },
draft: ({ part }) => part draft: ({ part }) => part,
} }
``` ```
@ -53,16 +57,23 @@ const part = {
name: 'other.base', name: 'other.base',
from: exampleBase, from: exampleBase,
// hide exampleBase // hide exampleBase
hide: {from: true}, hide: { from: true },
draft: ({ part }) => part draft: ({ part }) => part,
} }
``` ```
### hide.inherited ### hide.inherited
To hide parts that you have not explicitly included in this part that may be pulled in by the explicitly included `from` and `after` parts, set `hide.inherited` to a truthy value. To hide parts that you have not explicitly included in this part that may be
pulled in by the explicitly included `from` and `after` parts, set
`hide.inherited` to a truthy value.
:::noteThis setting will hide any part included as `from` or `after` by your explicitly included `from` part or its dependency chain. It will also hide any part included as `from` by your explicitly included `after` part or its dependency chain. It will not hide the `after` parts of `after` parts::: :::note
This setting will hide any part included as `from` or `after` by your
explicitly included `from` part or its dependency chain. It will also hide any
part included as `from` by your explicitly included `after` part or its
dependency chain. It will not hide the `after` parts of `after` parts
:::
```js ```js
// the "after" chain // the "after" chain
@ -109,30 +120,32 @@ const mainBack = {
} }
``` ```
:::tip :::tip
<details> <details>
<summary>Need more clarity?</summary> <summary>Need more clarity?</summary>
In the above example, the dependency tree for the part `example.mainBack` resolves to the following, with `from` dependencies in **bold** and `after` dependencies *italicized*. In the above example, the dependency tree for the part `example.mainBack` resolves to the following, with `from` dependencies in **bold** and `after` dependencies _italicized_.
| Part | Dependency Type | Hidden |
| :---------------------------- | :-------------- | :----- |
| example.mainBack | root | false |
| - **other.parent** | from | false |
| - - **other.grandParent** | inherited from | true |
| - - - _other.grandParentBase_ | inherited after | true |
| - _example.mainFront_ | after | false |
| - - _example.mainFrontBase_ | after | false |
| - - **other.mainFront** | inherited from | true |
| Part | Dependency Type | Hidden | Dependencies are considered inherited if they have two or more dashes (-) next to them, and are either **bold** themselves, or underneath a **bold** part.
| :---------- | :---------- | :-----|
| example.mainBack | root | false |
| - **other.parent** | from | false |
| - - **other.grandParent** | inherited from | true |
| - - - *other.grandParentBase* | inherited after | true |
| - *example.mainFront* | after | false |
| - - *example.mainFrontBase* | after | false |
| - - **other.mainFront** | inherited from | true |
Dependencies are considered inherited if they have two or more dashes (-) next to them, and are either **bold** themselves, or underneath a **bold** part.
</details> </details>
::: :::
### hide.never ### hide.never
To __not__ hide a specific part that would otherwise be hidden by other configuration, add its name to the `hide.never` array To **not** hide a specific part that would otherwise be hidden by other configuration, add its name to the `hide.never` array
```js ```js
import { exampleBase } from './base.mjs' import { exampleBase } from './base.mjs'
@ -144,9 +157,9 @@ const part = {
// hide exampleBase and exampleBack // hide exampleBase and exampleBack
after: true, after: true,
// override hiding exampleBack so that it is shown // override hiding exampleBack so that it is shown
never: ['example.back'] never: ['example.back'],
}, },
draft: ({ part }) => part draft: ({ part }) => part,
} }
``` ```
@ -158,18 +171,31 @@ To hide the current part, set `hide.self` to a truthy value:
const part = { const part = {
name: 'example.front', name: 'example.front',
// hide `example.front` // hide `example.front`
hide: {self: true}, hide: { self: true },
draft: (({ part }) => part) draft: ({ part }) => part,
} }
``` ```
## Presets ## Presets
We provide two presets for common hiding configurations. For convenience, you can pass a preset to the `hide` configuration as a string like `hide: <preset name>`, or you can use `import { hidePresets } from '@freesewing.core` and pass `hide: hidePresets.<preset name>`
:::tip If you don't like to remember strings and you're working in development a environment that has code completion, importing the presets from `@freesewing/core` will help you be sure you're definitely using an available preset ::: We provide two presets for common hiding configurations. For convenience, you
can pass a preset to the `hide` configuration as a string like `hide: <preset
name>`, or you can use `import { hidePresets } from '@freesewing.core` and pass
`hide: hidePresets.<preset name>`
:::tip
If you don't like to remember strings and you're working in development a
environment that has code completion, importing the presets from
`@freesewing/core` will help you be sure you're definitely using an available
preset
:::
### HIDE_ALL ### HIDE_ALL
For a shortcut to setting all `boolean` hiding options ([`after`](#hideafter), [`from`](#hidefrom), [`inherited`](#hideinherited), and [`self`](#hideself)) to true, use `HIDE_ALL`
For a shortcut to setting all `boolean` hiding options ([`after`](#hideafter),
[`from`](#hidefrom), [`inherited`](#hideinherited), and [`self`](#hideself)) to
true, use `HIDE_ALL`
:::note :::note
This is equivalent to using This is equivalent to using
@ -181,9 +207,11 @@ This is equivalent to using
inherited: true inherited: true
} }
``` ```
::: :::
To use it as an imported preset: To use it as an imported preset:
```js ```js
import { hidePresets } from '@freesewing/core' import { hidePresets } from '@freesewing/core'
import { exampleBase } from './base.mjs' import { exampleBase } from './base.mjs'
@ -200,8 +228,8 @@ const part = {
} }
``` ```
To use it as a string To use it as a string
```js ```js
import { exampleBase } from './base.mjs' import { exampleBase } from './base.mjs'
import { exampleBack } from './back.mjs' import { exampleBack } from './back.mjs'
@ -213,11 +241,12 @@ const part = {
// hide `example.front`, `exmpleBase`, and `exampleBack` // hide `example.front`, `exmpleBase`, and `exampleBack`
// as well as any inherited parts // as well as any inherited parts
hide: 'HIDE_ALL', hide: 'HIDE_ALL',
draft: ({ part }) => part draft: ({ part }) => part,
} }
``` ```
### HIDE_TREE ### HIDE_TREE
For a shortcut to setting [`from: true`](#hidefrom) and [`inherited: true`](#hideinherited), use `HIDE_TREE` For a shortcut to setting [`from: true`](#hidefrom) and [`inherited: true`](#hideinherited), use `HIDE_TREE`
:::note :::note
@ -228,13 +257,16 @@ This is equivalent to using
from: true, from: true,
inherited: true inherited: true
} }
```` ```
::: :::
:::note RELATED :::note RELATED
See [`hide.inherited`](#hideinherited) for a full explanation of how that option works See [`hide.inherited`](#hideinherited) for a full explanation of how that option works
::: :::
To use it as an imported preset: To use it as an imported preset:
```js ```js
import { hidePresets } from '@freesewing/core' import { hidePresets } from '@freesewing/core'
import { exampleBase } from './base.mjs' import { exampleBase } from './base.mjs'
@ -245,12 +277,12 @@ const part = {
from: exampleBase, from: exampleBase,
// hide `exmpleBase`, and all inherited parts // hide `exmpleBase`, and all inherited parts
hide: hidePresets.HIDE_TREE, hide: hidePresets.HIDE_TREE,
draft: ({ part }) => part draft: ({ part }) => part,
} }
``` ```
To use it as a string To use it as a string
```js ```js
import { exampleBase } from './base.mjs' import { exampleBase } from './base.mjs'
import { exampleBack } from './back.mjs' import { exampleBack } from './back.mjs'
@ -260,6 +292,6 @@ const part = {
from: exampleBase, from: exampleBase,
// hide `exmpleBase`, and all inherited parts // hide `exmpleBase`, and all inherited parts
hide: 'HIDE_TREE', hide: 'HIDE_TREE',
draft: ({ part }) => part draft: ({ part }) => part,
} }
``` ```

View file

@ -6,7 +6,9 @@ The `measurements` and `optionalMeasurements` properties on the
part configuration object list the part's required and optional part configuration object list the part's required and optional
measurements respectively. measurements respectively.
:::tipYou should only include what's required by the part itself, not its dependencies::: :::tip
You should only include what's required by the part itself, not its dependencies
:::
## measurements ## measurements
@ -16,8 +18,8 @@ that are required to draft the current part.
```js ```js
const part = { const part = {
name: 'example.front', name: 'example.front',
measurements: [ 'head', 'chest' ], measurements: ['head', 'chest'],
draft: ({ part }) => part draft: ({ part }) => part,
} }
``` ```
@ -31,9 +33,9 @@ import { pluginBust } from '@freesewing/plugin-bust'
const part = { const part = {
name: 'example.front', name: 'example.front',
plugins: [ pluginBust ], plugins: [pluginBust],
measurements: [ 'head', 'chest' ], measurements: ['head', 'chest'],
optionalMeasurements: [ 'highBust' ], optionalMeasurements: ['highBust'],
draft: ({ part }) => part draft: ({ part }) => part,
} }
``` ```

View file

@ -1,5 +1,5 @@
--- ---
title: "Path._curve()" title: 'Path._curve()'
--- ---
The `Path._curve()` method draws a cubic Bézier curve The `Path._curve()` method draws a cubic Bézier curve
@ -13,7 +13,9 @@ so you do not need to provide it.
Path path._curve(Point cp2, Point to) Path path._curve(Point cp2, Point to)
``` ```
:::tipThis method is chainable as it returns the `Path` object::: :::tip
This method is chainable as it returns the `Path` object
:::
## Example ## Example
@ -21,19 +23,20 @@ Path path._curve(Point cp2, Point to)
```js ```js
({ Point, points, Path, paths, part }) => { ({ Point, points, Path, paths, part }) => {
points.from = new Point(5, 20) points.from = new Point(5, 20)
points.cp2 = new Point(60, 50) points.cp2 = new Point(60, 50)
points.to = new Point(90, 20) points.to = new Point(90, 20)
paths.line = new Path() paths.line = new Path()
.move(points.from) .move(points.from)
._curve(points.cp2, points.to) .\_curve(points.cp2, points.to)
.setText("Path._curve()", "text-sm center fill-note") .setText("Path.\_curve()", "text-sm center fill-note")
.attr("data-text-dy", -1) .attr("data-text-dy", -1)
return part return part
} }
```
````
</Example> </Example>
@ -45,4 +48,4 @@ as the two following calls yield the same result:
```js ```js
path.curve(point1, point1, point2) path.curve(point1, point1, point2)
path._curve(point1, point2) path._curve(point1, point2)
``` ````

View file

@ -10,7 +10,9 @@ The `Path.addClass()` method adds a CSS class to the path.
Path path.addClass(string className) Path path.addClass(string className)
``` ```
:::tipThis method is chainable as it returns the `Path` object::: :::tip
This method is chainable as it returns the `Path` object
:::
## Example ## Example
@ -18,17 +20,18 @@ Path path.addClass(string className)
```js ```js
({ Point, points, Path, paths, part }) => { ({ Point, points, Path, paths, part }) => {
points.from = new Point(5, 10) points.from = new Point(5, 10)
points.to = new Point(95, 10) points.to = new Point(95, 10)
paths.line = new Path() paths.line = new Path()
.move(points.from) .move(points.from)
.line(points.to) .line(points.to)
.addClass('note dashed') .addClass('note dashed')
return part return part
} }
```
````
</Example> </Example>
## Notes ## Notes
@ -39,4 +42,4 @@ as the two following calls yield the same result:
```js ```js
path.attr('class', 'fabric') path.attr('class', 'fabric')
path.addClass('fabric') path.addClass('fabric')
``` ````

View file

@ -12,7 +12,9 @@ Path path.addText(string text, string className = '')
The second argument will optionally be used to set the CSS class for the text. The second argument will optionally be used to set the CSS class for the text.
:::tipThis method is chainable as it returns the `Path` object::: :::tip
This method is chainable as it returns the `Path` object
:::
## Example ## Example
@ -22,14 +24,15 @@ The second argument will optionally be used to set the CSS class for the text.
points.from = new Point(5, 10) points.from = new Point(5, 10)
points.to = new Point(95, 10) points.to = new Point(95, 10)
paths.line = new Path() paths.line = new Path()
.move(points.from) .move(points.from)
.line(points.to) .line(points.to)
.addText('FreeSewing rocks') .addText('FreeSewing rocks')
return part return part
} }
```
````
</Example> </Example>
## Notes ## Notes
@ -40,7 +43,7 @@ as the two following calls yield the same result:
```js ```js
path.attr('data-text', 'Hello') path.attr('data-text', 'Hello')
path.addText('Hello') path.addText('Hello')
``` ````
The difference with [Path.setText()](/reference/api/path/addtext) is that this The difference with [Path.setText()](/reference/api/path/addtext) is that this
method will add to the existing text whereas `Path.setText()` will overwrite method will add to the existing text whereas `Path.setText()` will overwrite

View file

@ -18,7 +18,9 @@ Path path.attr(
) )
``` ```
:::tipThis method is chainable as it returns the `Path` object::: :::tip
This method is chainable as it returns the `Path` object
:::
## Example ## Example
@ -26,19 +28,20 @@ Path path.attr(
```js ```js
({ Point, points, Path, paths, part }) => { ({ Point, points, Path, paths, part }) => {
points.from = new Point(10, 20) points.from = new Point(10, 20)
points.cp1 = new Point(20, -10) points.cp1 = new Point(20, -10)
points.cp2 = new Point(50, 50) points.cp2 = new Point(50, 50)
points.to = new Point(70, 20) points.to = new Point(70, 20)
paths.example = new Path() paths.example = new Path()
.move(points.from) .move(points.from)
.curve(points.cp1, points.cp2, points.to) .curve(points.cp1, points.cp2, points.to)
.attr("class", "canvas") .attr("class", "canvas")
.setText("FreeSewing rocks", "text-xs center") .setText("FreeSewing rocks", "text-xs center")
return part return part
} }
``` ```
</Example> </Example>
@ -54,3 +57,4 @@ all call this method under the hood.
See [Using Attributes](/howtos/code/attributes) See [Using Attributes](/howtos/code/attributes)
for information about custom Attributes that can be used with Paths. for information about custom Attributes that can be used with Paths.
```

View file

@ -11,10 +11,12 @@ A negative angle results in a clockwise arc.
:::tip :::tip
The new endpoint of this path is the same point The new endpoint of this path is the same point
that that
```js ```js
path.end().rotate(deg, origin) path.end().rotate(deg, origin)
``` ```
would return. would return.
::: :::
@ -24,7 +26,9 @@ would return.
Path path.circleSegment(deg, origin) Path path.circleSegment(deg, origin)
``` ```
:::tipThis method is chainable as it returns the `Path` object::: :::tip
This method is chainable as it returns the `Path` object
:::
## Example ## Example
@ -48,5 +52,7 @@ paths.helper = new Path()
return part return part
} }
``` ```
</Example> </Example>
```

View file

@ -10,7 +10,9 @@ The `Path.close()` method closes a path by drawing a straight line from the curr
Path path.close() Path path.close()
``` ```
:::tipThis method is chainable as it returns the `Path` object::: :::tip
This method is chainable as it returns the `Path` object
:::
## Example ## Example
@ -18,18 +20,20 @@ Path path.close()
```js ```js
({ Point, points, Path, paths, part }) => { ({ Point, points, Path, paths, part }) => {
points.from = new Point(10, 20) points.from = new Point(10, 20)
points.cp2 = new Point(60, 30) points.cp2 = new Point(60, 30)
points.to = new Point(90, 20) points.to = new Point(90, 20)
paths.line = new Path() paths.line = new Path()
.move(points.from) .move(points.from)
._curve(points.cp2, points.to) .\_curve(points.cp2, points.to)
.close() .close()
.reverse() // To keep text from being upside-down .reverse() // To keep text from being upside-down
.setText('Path._close()', 'text-sm right fill-note') .setText('Path.\_close()', 'text-sm right fill-note')
return part return part
} }
``` ```
</Example> </Example>
```

View file

@ -11,7 +11,9 @@ via two control points to a given endpoint.
Path path.curve(Point cp1, Point cp2, Point to) Path path.curve(Point cp1, Point cp2, Point to)
``` ```
:::tipThis method is chainable as it returns the `Path` object::: :::tip
This method is chainable as it returns the `Path` object
:::
## Example ## Example
@ -19,17 +21,19 @@ Path path.curve(Point cp1, Point cp2, Point to)
```js ```js
({ Point, points, Path, paths, part }) => { ({ Point, points, Path, paths, part }) => {
points.from = new Point(10, 20) points.from = new Point(10, 20)
points.cp1 = new Point(40, 0) points.cp1 = new Point(40, 0)
points.cp2 = new Point(60, 40) points.cp2 = new Point(60, 40)
points.to = new Point(90, 20) points.to = new Point(90, 20)
paths.line = new Path() paths.line = new Path()
.move(points.from) .move(points.from)
.curve(points.cp1, points.cp2, points.to) .curve(points.cp1, points.cp2, points.to)
.setText("Path.curve()", "text-sm center fill-note") .setText("Path.curve()", "text-sm center fill-note")
return part return part
} }
``` ```
</Example> </Example>
```

View file

@ -3,7 +3,7 @@ title: Path.curve_()
--- ---
The `Path.curve_()` method draws a cubic Bézier curve from the current position The `Path.curve_()` method draws a cubic Bézier curve from the current position
via two control points to a given endpoint. However, the end control point is via two control points to a given endpoint. However, the end control point is
identical to the end point. identical to the end point.
## Signature ## Signature
@ -12,16 +12,16 @@ identical to the end point.
Path path.curve_(Point cp1, Point to) Path path.curve_(Point cp1, Point to)
``` ```
:::tipThis method is chainable as it returns the `Path` object::: :::tip
This method is chainable as it returns the `Path` object
:::
## Example ## Example
<Example caption="Example of the Path.curve\_() method"> <Example caption="Example of the Path.curve\_() method">
```js ```js
({ Point, points, Path, paths, part }) => { ;({ Point, points, Path, paths, part }) => {
points.from = new Point(10, 20) points.from = new Point(10, 20)
points.cp1 = new Point(40, 0) points.cp1 = new Point(40, 0)
points.to = new Point(90, 20) points.to = new Point(90, 20)
@ -29,12 +29,13 @@ Path path.curve_(Point cp1, Point to)
paths.line = new Path() paths.line = new Path()
.move(points.from) .move(points.from)
.curve_(points.cp1, points.to) .curve_(points.cp1, points.to)
.setText("Path.curve_()", "text-sm center fill-note") .setText('Path.curve_()', 'text-sm center fill-note')
.attr("data-text-dy", -1) .attr('data-text-dy', -1)
return part return part
} }
``` ```
</Example> </Example>
## Notes ## Notes

View file

@ -10,7 +10,9 @@ The `Path.end()` method returns the Point object at the end of the path.
Point path.end() Point path.end()
``` ```
:::tipThis method is chainable as it returns the `Path` object::: :::tip
This method is chainable as it returns the `Path` object
:::
## Example ## Example
@ -18,20 +20,22 @@ Point path.end()
```js ```js
({ Point, points, Path, paths, snippets, Snippet, part }) => { ({ Point, points, Path, paths, snippets, Snippet, part }) => {
points.A = new Point(45, 60) points.A = new Point(45, 60)
points.B = new Point(10, 30) points.B = new Point(10, 30)
points.BCp2 = new Point(40, 20) points.BCp2 = new Point(40, 20)
points.C = new Point(90, 30) points.C = new Point(90, 30)
points.CCp1 = new Point(50, -30) points.CCp1 = new Point(50, -30)
paths.demo = new Path() paths.demo = new Path()
.move(points.A) .move(points.A)
.line(points.B) .line(points.B)
.curve(points.BCp2, points.CCp1, points.C) .curve(points.BCp2, points.CCp1, points.C)
snippets.end = new Snippet("notch", paths.demo.end()) snippets.end = new Snippet("notch", paths.demo.end())
return part return part
} }
``` ```
</Example> </Example>
```

View file

@ -10,7 +10,9 @@ The `Path.hide()` hides the path so it does not appear in the output.
Path path.hide() Path path.hide()
``` ```
:::tipThis method is chainable as it returns the `Path` object::: :::tip
This method is chainable as it returns the `Path` object
:::
## Example ## Example
@ -18,15 +20,17 @@ Path path.hide()
```js ```js
({ Point, points, Path, paths, part }) => { ({ Point, points, Path, paths, part }) => {
points.top = new Point(50, 0) points.top = new Point(50, 0)
points.left = new Point (20,50) points.left = new Point (20,50)
points.right = new Point (80,50) points.right = new Point (80,50)
paths.a = new Path().move(points.top).line(points.right).setText('a') paths.a = new Path().move(points.top).line(points.right).setText('a')
paths.b = new Path().move(points.right).line(points.left).setText('b').hide() paths.b = new Path().move(points.right).line(points.left).setText('b').hide()
paths.c = new Path().move(points.left).line(points.top).setText('c') paths.c = new Path().move(points.left).line(points.top).setText('c')
return part return part
} }
``` ```
</Example> </Example>
```

View file

@ -11,40 +11,43 @@ operation](/reference/api/path/noop) with id `id`.
Path path.insop(string id, Path path) Path path.insop(string id, Path path)
``` ```
:::tipThis method is chainable as it returns the `Path` object::: :::tip
This method is chainable as it returns the `Path` object
:::
<Example caption="Example of the Path.insop() method"> <Example caption="Example of the Path.insop() method">
```js ```js
({ Point, points, Path, paths, part }) => { ({ Point, points, Path, paths, part }) => {
points.left = new Point(10,10) points.left = new Point(10,10)
points.dartLeft = new Point(40, 10) points.dartLeft = new Point(40, 10)
points.dartTip = new Point(50, 50) points.dartTip = new Point(50, 50)
points.dartRight = new Point(60, 10) points.dartRight = new Point(60, 10)
points.right = new Point(90, 10) points.right = new Point(90, 10)
paths.withoutDart = new Path() paths.withoutDart = new Path()
.move(points.left) .move(points.left)
.line(points.dartLeft) .line(points.dartLeft)
.noop('dart') .noop('dart')
.line(points.right) .line(points.right)
paths.withDart = paths.withoutDart paths.withDart = paths.withoutDart
.clone() .clone()
.insop( .insop(
'dart', 'dart',
new Path() new Path()
.line(points.dartTip) .line(points.dartTip)
.line(points.dartRight) .line(points.dartRight)
) )
.attr('style', 'stroke-width: 2px; stroke-opacity: 0.5; stroke: orange;') .attr('style', 'stroke-width: 2px; stroke-opacity: 0.5; stroke: orange;')
return part return part
} }
``` ```
</Example> </Example>
## Notes ## Notes
This is often used to insert darts into a path. This is often used to insert darts into a path.
```

View file

@ -11,7 +11,9 @@ given point.
Path path.line(Point to) Path path.line(Point to)
``` ```
:::tipThis method is chainable as it returns the `Path` object::: :::tip
This method is chainable as it returns the `Path` object
:::
## Example ## Example
@ -19,15 +21,17 @@ Path path.line(Point to)
```js ```js
({ Point, points, Path, paths, part }) => { ({ Point, points, Path, paths, part }) => {
points.from = new Point(10, 10) points.from = new Point(10, 10)
points.to = new Point(90, 10) points.to = new Point(90, 10)
paths.line = new Path() paths.line = new Path()
.move(points.from) .move(points.from)
.line(points.to) .line(points.to)
.setText("Path.line()", "text-sm center fill-note") .setText("Path.line()", "text-sm center fill-note")
return part return part
} }
``` ```
</Example> </Example>
```

View file

@ -12,7 +12,9 @@ with [`Path.insop()`](/reference/api/path/insop).
Path path.noop(string id) Path path.noop(string id)
``` ```
:::tipThis method is chainable as it returns the `Path` object::: :::tip
This method is chainable as it returns the `Path` object
:::
## Example ## Example
@ -20,29 +22,31 @@ Path path.noop(string id)
```js ```js
({ Point, points, Path, paths, part }) => { ({ Point, points, Path, paths, part }) => {
points.left = new Point(10,10) points.left = new Point(10,10)
points.dartLeft = new Point(40, 10) points.dartLeft = new Point(40, 10)
points.dartTip = new Point(50, 50) points.dartTip = new Point(50, 50)
points.dartRight = new Point(60, 10) points.dartRight = new Point(60, 10)
points.right = new Point(90, 10) points.right = new Point(90, 10)
paths.withoutDart = new Path() paths.withoutDart = new Path()
.move(points.left) .move(points.left)
.line(points.dartLeft) .line(points.dartLeft)
.noop('dart') .noop('dart')
.line(points.right) .line(points.right)
paths.withDart = paths.withoutDart paths.withDart = paths.withoutDart
.clone() .clone()
.insop( .insop(
'dart', 'dart',
new Path() new Path()
.line(points.dartTip) .line(points.dartTip)
.line(points.dartRight) .line(points.dartRight)
) )
.attr('style', 'stroke-width: 2px; stroke-opacity: 0.5; stroke: orange;') .attr('style', 'stroke-width: 2px; stroke-opacity: 0.5; stroke: orange;')
return part return part
} }
``` ```
</Example> </Example>
```

View file

@ -10,7 +10,9 @@ The `Path.setClass()` method sets the CSS class(es) of the path.
Path path.setClass(string className) Path path.setClass(string className)
``` ```
:::tipThis method is chainable as it returns the `Path` object::: :::tip
This method is chainable as it returns the `Path` object
:::
## Example ## Example
@ -18,17 +20,18 @@ Path path.setClass(string className)
```js ```js
({ Point, points, Path, paths, part }) => { ({ Point, points, Path, paths, part }) => {
points.from = new Point(5, 10) points.from = new Point(5, 10)
points.to = new Point(95, 10) points.to = new Point(95, 10)
paths.line = new Path() paths.line = new Path()
.move(points.from) .move(points.from)
.line(points.to) .line(points.to)
.setClass('note dashed') .setClass('note dashed')
return part return part
} }
```
````
</Example> </Example>
## Notes ## Notes
@ -39,4 +42,4 @@ as the two following calls yield the same result:
```js ```js
path.attr('class', 'fabric', true) path.attr('class', 'fabric', true)
path.setClass('fabric') path.setClass('fabric')
``` ````

View file

@ -11,7 +11,9 @@ value you pass it.
Path path.setHidden(bool hidden = false) Path path.setHidden(bool hidden = false)
``` ```
:::tipThis method is chainable as it returns the `Path` object::: :::tip
This method is chainable as it returns the `Path` object
:::
## Example ## Example
@ -19,15 +21,17 @@ Path path.setHidden(bool hidden = false)
```js ```js
({ Point, points, Path, paths, part }) => { ({ Point, points, Path, paths, part }) => {
points.top = new Point(50, 0) points.top = new Point(50, 0)
points.left = new Point (20,50) points.left = new Point (20,50)
points.right = new Point (80,50) points.right = new Point (80,50)
paths.a = new Path().move(points.top).line(points.right).setText('a') paths.a = new Path().move(points.top).line(points.right).setText('a')
paths.b = new Path().move(points.right).line(points.left).setText('b').setHidden(true) paths.b = new Path().move(points.right).line(points.left).setText('b').setHidden(true)
paths.c = new Path().move(points.left).line(points.top).setText('c') paths.c = new Path().move(points.left).line(points.top).setText('c')
return part return part
} }
``` ```
</Example> </Example>
```

View file

@ -12,7 +12,9 @@ Path path.setText(string text, string className = '')
The second argument will optionally be used to set the CSS class for the text. The second argument will optionally be used to set the CSS class for the text.
:::tipThis method is chainable as it returns the `Path` object::: :::tip
This method is chainable as it returns the `Path` object
:::
## Example ## Example
@ -22,14 +24,15 @@ The second argument will optionally be used to set the CSS class for the text.
points.from = new Point(5, 10) points.from = new Point(5, 10)
points.to = new Point(95, 10) points.to = new Point(95, 10)
paths.line = new Path() paths.line = new Path()
.move(points.from) .move(points.from)
.line(points.to) .line(points.to)
.setText('FreeSewing rocks') .setText('FreeSewing rocks')
return part return part
} }
```
````
</Example> </Example>
## Notes ## Notes
@ -40,7 +43,7 @@ as the two following calls yield the same result:
```js ```js
path.attr('data-text', 'Hello') path.attr('data-text', 'Hello')
path.setText('Hello') path.setText('Hello')
``` ````
The difference with [Path.addText()](/reference/api/path/addtext) is that this The difference with [Path.addText()](/reference/api/path/addtext) is that this
method will overwrite existing text on the path, whereas `Path.addText()` will method will overwrite existing text on the path, whereas `Path.addText()` will

View file

@ -11,7 +11,9 @@ A smooth curve means it will use the reflection of the end control point of the
Path path.smurve(Point cp2, Point end) Path path.smurve(Point cp2, Point end)
``` ```
:::tipThis method is chainable as it returns the `Path` object::: :::tip
This method is chainable as it returns the `Path` object
:::
## Example ## Example
@ -19,22 +21,24 @@ Path path.smurve(Point cp2, Point end)
```js ```js
({ Point, points, Path, paths, part }) => { ({ Point, points, Path, paths, part }) => {
points.aFrom = new Point(10, 10) points.aFrom = new Point(10, 10)
points.aCp1 = new Point(40, 40) points.aCp1 = new Point(40, 40)
points.aCp2 = new Point(70, -20) points.aCp2 = new Point(70, -20)
points.aTo = new Point(100, 10) points.aTo = new Point(100, 10)
points.bCp2 = new Point(50,50) points.bCp2 = new Point(50,50)
points.bTo = new Point(10,50) points.bTo = new Point(10,50)
paths.smurve = new Path() paths.smurve = new Path()
.move(points.aFrom) .move(points.aFrom)
.curve(points.aCp1, points.aCp2,points.aTo) .curve(points.aCp1, points.aCp2,points.aTo)
.smurve(points.bCp2, points.bTo) .smurve(points.bCp2, points.bTo)
.reverse() // Puts text at the end .reverse() // Puts text at the end
.setText('Path.smurve()') .setText('Path.smurve()')
return part return part
} }
``` ```
</Example> </Example>
```

View file

@ -13,7 +13,9 @@ A smooth curve means it will use the reflection of the end control point of the
Path path.smurve_(Point cp2, Point end) Path path.smurve_(Point cp2, Point end)
``` ```
:::tipThis method is chainable as it returns the `Path` object::: :::tip
This method is chainable as it returns the `Path` object
:::
## Example ## Example
@ -21,21 +23,23 @@ Path path.smurve_(Point cp2, Point end)
```js ```js
({ Point, points, Path, paths, part }) => { ({ Point, points, Path, paths, part }) => {
points.aFrom = new Point(10, 10) points.aFrom = new Point(10, 10)
points.aCp1 = new Point(40, 40) points.aCp1 = new Point(40, 40)
points.aCp2 = new Point(70, -20) points.aCp2 = new Point(70, -20)
points.aTo = new Point(100, 10) points.aTo = new Point(100, 10)
points.bTo = new Point(10,50) points.bTo = new Point(10,50)
paths.smurve = new Path() paths.smurve = new Path()
.move(points.aFrom) .move(points.aFrom)
.curve(points.aCp1, points.aCp2,points.aTo) .curve(points.aCp1, points.aCp2,points.aTo)
.smurve_(points.bTo) .smurve\_(points.bTo)
.reverse() // Puts text at the end .reverse() // Puts text at the end
.setText('Path.smurve()') .setText('Path.smurve()')
return part return part
} }
``` ```
</Example> </Example>
```

View file

@ -10,7 +10,9 @@ The `Path.start()` method returns the Point object at the start of the path.
Point path.start() Point path.start()
``` ```
:::tipThis method is chainable as it returns the `Path` object::: :::tip
This method is chainable as it returns the `Path` object
:::
## Example ## Example
@ -18,20 +20,22 @@ Point path.start()
```js ```js
({ Point, points, Path, paths, snippets, Snippet, part }) => { ({ Point, points, Path, paths, snippets, Snippet, part }) => {
points.A = new Point(45, 60) points.A = new Point(45, 60)
points.B = new Point(10, 30) points.B = new Point(10, 30)
points.BCp2 = new Point(40, 20) points.BCp2 = new Point(40, 20)
points.C = new Point(90, 30) points.C = new Point(90, 30)
points.CCp1 = new Point(50, -30) points.CCp1 = new Point(50, -30)
paths.demo = new Path() paths.demo = new Path()
.move(points.A) .move(points.A)
.line(points.B) .line(points.B)
.curve(points.BCp2, points.CCp1, points.C) .curve(points.BCp2, points.CCp1, points.C)
snippets.end = new Snippet("notch", paths.demo.start()) snippets.end = new Snippet("notch", paths.demo.start())
return part return part
} }
``` ```
</Example> </Example>
```

View file

@ -2,7 +2,7 @@
title: Path.unhide() title: Path.unhide()
--- ---
The `Path.unhide()` method unhides the path so it appears in the output. By The `Path.unhide()` method unhides the path so it appears in the output. By
default, paths are not hidden. So you should only call this on path previously default, paths are not hidden. So you should only call this on path previously
hidden via `Path.hide()`. hidden via `Path.hide()`.
@ -12,7 +12,9 @@ hidden via `Path.hide()`.
Path path.unhide() Path path.unhide()
``` ```
:::tipThis method is chainable as it returns the `Path` object::: :::tip
This method is chainable as it returns the `Path` object
:::
## Example ## Example
@ -20,15 +22,17 @@ Path path.unhide()
```js ```js
({ Point, points, Path, paths, part }) => { ({ Point, points, Path, paths, part }) => {
points.top = new Point(50, 0) points.top = new Point(50, 0)
points.left = new Point (20,50) points.left = new Point (20,50)
points.right = new Point (80,50) points.right = new Point (80,50)
paths.a = new Path().move(points.top).line(points.right).setText('a') paths.a = new Path().move(points.top).line(points.right).setText('a')
paths.b = new Path().move(points.right).line(points.left).setText('b').hide().unhide() paths.b = new Path().move(points.right).line(points.left).setText('b').hide().unhide()
paths.c = new Path().move(points.left).line(points.top).setText('c') paths.c = new Path().move(points.left).line(points.top).setText('c')
return part return part
} }
``` ```
</Example> </Example>
```

View file

@ -5,7 +5,9 @@ title: Pattern.addPart()
The `Pattern.addPart()` method allows you to add a part to a pattern. The `Pattern.addPart()` method allows you to add a part to a pattern.
It has the same effect as passing a part to the Design constructor. It has the same effect as passing a part to the Design constructor.
:::noteThis method is chainable as it returns the Pattern object::: :::note
This method is chainable as it returns the Pattern object
:::
## Pattern.addPart() signature ## Pattern.addPart() signature
@ -16,30 +18,27 @@ Pattern pattern.addPart(object part)
## Pattern.addPart() example ## Pattern.addPart() example
```js ```js
import { Aaron } from "@freesewing/aaron" import { Aaron } from '@freesewing/aaron'
const extra = { const extra = {
name: 'aaron.extra', name: 'aaron.extra',
draft: ({ points, Point, paths, Path, part }) => { draft: ({ points, Point, paths, Path, part }) => {
points.msg = new Point(50,15) points.msg = new Point(50, 15).attr('data-text', 'I am an extra part')
.attr('data-text', "I am an extra part")
paths.box = new Path() paths.box = new Path()
.move(new Point(0,0)) .move(new Point(0, 0))
.line(new Point(0,30)) .line(new Point(0, 30))
.line(new Point(100,30)) .line(new Point(100, 30))
.line(new Point(100,0)) .line(new Point(100, 0))
.close(new Point(100,0)) .close(new Point(100, 0))
.addClass('note') .addClass('note')
return part return part
} },
} }
// Load some public test measurements from the FreeSewing backend // Load some public test measurements from the FreeSewing backend
const measurements = ( const measurements = (
await ( await (await fetch('https://backend3.freesewing.org/curated-sets/1.json')).json()
await fetch("https://backend3.freesewing.org/curated-sets/1.json")
).json()
).measurements ).measurements
const pattern = new Aaron({ measurements }).addPart(extra) const pattern = new Aaron({ measurements }).addPart(extra)

View file

@ -7,7 +7,9 @@ making sure to do so in the right order, handle dependencies, resolve
options to their absolute values and a number of other housekeeping things options to their absolute values and a number of other housekeeping things
that are required for the pattern to be drafted. that are required for the pattern to be drafted.
:::noteThis method is chainable as it returns the Pattern object::: :::note
This method is chainable as it returns the Pattern object
:::
## Pattern.draft() signature ## Pattern.draft() signature
@ -18,13 +20,11 @@ Pattern pattern.draft()
## Pattern.draft() example ## Pattern.draft() example
```js ```js
import { Aaron } from "@freesewing/aaron" import { Aaron } from '@freesewing/aaron'
// Load some public test measurements from the FreeSewing backend // Load some public test measurements from the FreeSewing backend
const measurements = ( const measurements = (
await ( await (await fetch('https://backend3.freesewing.org/curated-sets/1.json')).json()
await fetch("https://backend3.freesewing.org/curated-sets/1.json")
).json()
).measurements ).measurements
const pattern = new Aaron({ measurements }) const pattern = new Aaron({ measurements })

View file

@ -5,7 +5,9 @@ title: Pattern.draftPartForSet()
A pattern's `draftPartForSet()` method will draft a part using a A pattern's `draftPartForSet()` method will draft a part using a
given set of settings. given set of settings.
:::noteThis method is chainable as it returns the Pattern object::: :::note
This method is chainable as it returns the Pattern object
:::
## Pattern.draftPartForSet() signature ## Pattern.draftPartForSet() signature
@ -16,14 +18,10 @@ Pattern pattern.draftPartForSet(part, set)
## Pattern.draftPartForSet() example ## Pattern.draftPartForSet() example
```js ```js
import { Aaron } from "@freesewing/aaron" import { Aaron } from '@freesewing/aaron'
// Load a public test settings set from the FreeSewing backend // Load a public test settings set from the FreeSewing backend
const set = ( const set = await (await fetch('https://backend3.freesewing.org/curated-sets/1.json')).json()
await (
await fetch("https://backend3.freesewing.org/curated-sets/1.json")
).json()
)
const pattern = new Aaron() const pattern = new Aaron()

View file

@ -7,7 +7,9 @@ pattern's [lifecycle hooks](/reference/hooks/). It takes the
lifecycle hook's name as the first argument and the function as the second. lifecycle hook's name as the first argument and the function as the second.
This method will then be triggered by the lifecycle hook. This method will then be triggered by the lifecycle hook.
:::noteThis method is chainable as it returns the Pattern object::: :::note
This method is chainable as it returns the Pattern object
:::
## Pattern.on() signature ## Pattern.on() signature
@ -26,8 +28,8 @@ should pass it.
## Pattern.on() example ## Pattern.on() example
```js ```js
pattern.on('preRender', function(svg) { pattern.on('preRender', function (svg) {
svg.style += "svg { background: yellow;}"; svg.style += 'svg { background: yellow;}'
}) })
``` ```

View file

@ -6,7 +6,9 @@ The `Pattern.sample()` method will _sample_ the pattern which means
to draft multiple variants of the same pattern, and stack them on to draft multiple variants of the same pattern, and stack them on
top of each other. top of each other.
:::noteThis method is chainable as it returns the Pattern object::: :::note
This method is chainable as it returns the Pattern object
:::
Under the hood, this method will call one of Under the hood, this method will call one of
[Pattern.sampleOption()](/reference/api/pattern/sampleoption), [Pattern.sampleOption()](/reference/api/pattern/sampleoption),
@ -34,19 +36,17 @@ Pattern pattern.sample()
## Pattern.sample() example ## Pattern.sample() example
```js ```js
import { Aaron } from "@freesewing/aaron" import { Aaron } from '@freesewing/aaron'
// Load some public test measurements from the FreeSewing backend // Load some public test measurements from the FreeSewing backend
const measurements = ( const measurements = (
await ( await (await fetch('https://backend3.freesewing.org/curated-sets/1.json')).json()
await fetch("https://backend3.freesewing.org/curated-sets/1.json")
).json()
).measurements ).measurements
const pattern = new Aaron({ const pattern = new Aaron({
sample: { sample: {
models: measurements models: measurements,
} },
}) })
const svg = pattern.sample().render() const svg = pattern.sample().render()

View file

@ -13,7 +13,9 @@ the measurement of your choice between 90% and 110% if the value in the settings
The goal of measurement sampling is to understand the impact of a given measurement on a pattern. The goal of measurement sampling is to understand the impact of a given measurement on a pattern.
::: :::
:::noteThis method is chainable as it returns the Pattern object::: :::note
This method is chainable as it returns the Pattern object
:::
## Pattern.sampleMeasurement() signature ## Pattern.sampleMeasurement() signature
@ -24,13 +26,11 @@ Pattern pattern.sampleMeasurement(string measurement)
## Pattern.sampleMeasurement() example ## Pattern.sampleMeasurement() example
```js ```js
import { Aaron } from "@freesewing/aaron" import { Aaron } from '@freesewing/aaron'
// Load some public test measurements from the FreeSewing backend // Load some public test measurements from the FreeSewing backend
const measurements = ( const measurements = (
await ( await (await fetch('https://backend3.freesewing.org/curated-sets/1.json')).json()
await fetch("https://backend3.freesewing.org/curated-sets/1.json")
).json()
).measurements ).measurements
const pattern = new Aaron({ measurements }) const pattern = new Aaron({ measurements })

View file

@ -12,7 +12,9 @@ In this particular case, it will draft a variants for each of the models you pas
The goal of model sampling is to verify that a pattern grades correctly up and down as sizes change. The goal of model sampling is to verify that a pattern grades correctly up and down as sizes change.
::: :::
:::noteThis method is chainable as it returns the Pattern object::: :::note
This method is chainable as it returns the Pattern object
:::
## Pattern.sampleModels() signature ## Pattern.sampleModels() signature
@ -52,16 +54,14 @@ identifying your model in the models object.
## Pattern.sampleModels() example ## Pattern.sampleModels() example
```js ```js
import { Aaron } from "@freesewing/aaron" import { Aaron } from '@freesewing/aaron'
const Aaron = new Aaron() const Aaron = new Aaron()
// Load some public test measurements from the FreeSewing backend // Load some public test measurements from the FreeSewing backend
const measurements = ( const measurements = (
await ( await (await fetch('https://backend3.freesewing.org/curated-sets/1.json')).json()
await fetch("https://backend3.freesewing.org/curated-sets/1.json")
).json()
).measurements ).measurements
const svg = aaron.sampleModels(measurements, "34").render() const svg = aaron.sampleModels(measurements, '34').render()
``` ```

View file

@ -7,7 +7,7 @@ to draft multiple variants of the same pattern, and stack them on
top of each other. top of each other.
In this particular case, the variants it drafts depend In this particular case, the variants it drafts depend
on [the type of option](/reference/api/part/config/options/): on [the type of option](/reference/api/part/config/options/):
- For a Percentage or Degree option, 10 steps will be sampled, between min and max - For a Percentage or Degree option, 10 steps will be sampled, between min and max
- For a Counter or Millimeter option, a maximum of 10 steps will be sampled, between min and max - For a Counter or Millimeter option, a maximum of 10 steps will be sampled, between min and max
@ -20,7 +20,9 @@ The goal of option sampling is to verify the impact of an option on the pattern,
its min and max boundaries are correct and its default value is sensible. its min and max boundaries are correct and its default value is sensible.
::: :::
:::noteThis method is chainable as it returns the Pattern object::: :::note
This method is chainable as it returns the Pattern object
:::
## Pattern.sampleOption() signature ## Pattern.sampleOption() signature
@ -31,13 +33,11 @@ Pattern pattern.sampleOption(string option)
## Pattern.sampleOption() example ## Pattern.sampleOption() example
```js ```js
import { Aaron } from "@freesewing/aaron" import { Aaron } from '@freesewing/aaron'
// Load some public test measurements from the FreeSewing backend // Load some public test measurements from the FreeSewing backend
const measurements = ( const measurements = (
await ( await (await fetch('https://backend3.freesewing.org/curated-sets/1.json')).json()
await fetch("https://backend3.freesewing.org/curated-sets/1.json")
).json()
).measurements ).measurements
const pattern = new Aaron({ measurements }) const pattern = new Aaron({ measurements })

View file

@ -6,7 +6,9 @@ The `Pattern.use()` method will load a FreeSewing plugin.
Plugins are a way to extend a pattern's functionality. Plugins are a way to extend a pattern's functionality.
For more details, refer to [the plugin guide](/guides/plugins/). For more details, refer to [the plugin guide](/guides/plugins/).
:::noteThis method is chainable as it returns the Pattern object::: :::note
This method is chainable as it returns the Pattern object
:::
## Pattern.use() signature ## Pattern.use() signature
@ -22,14 +24,12 @@ you plugin object.
## Pattern.use() example ## Pattern.use() example
```js ```js
import { Aaron } from "@freesewing/aaron" import { Aaron } from '@freesewing/aaron'
import { pluginTheme } from "@freesewing/plugin-theme" import { pluginTheme } from '@freesewing/plugin-theme'
// Load some public test measurements from the FreeSewing backend // Load some public test measurements from the FreeSewing backend
const measurements = ( const measurements = (
await ( await (await fetch('https://backend3.freesewing.org/curated-sets/1.json')).json()
await fetch("https://backend3.freesewing.org/curated-sets/1.json")
).json()
).measurements ).measurements
const pattern = new Aaron({ measurements }).use(pluginTheme) const pattern = new Aaron({ measurements }).use(pluginTheme)

View file

@ -15,7 +15,9 @@ Point point.addCircle(
) )
``` ```
:::tipThis method is chainable as it returns the `Point` object::: :::tip
This method is chainable as it returns the `Point` object
:::
## Example ## Example
@ -26,18 +28,20 @@ Point point.addCircle(
.addCircle(3, 'lining dashed') .addCircle(3, 'lining dashed')
.addCircle(7, 'mark dashed') .addCircle(7, 'mark dashed')
points.b = new Point(50, 10) points.b = new Point(50, 10)
.addCircle(1, 'interfacing') .addCircle(1, 'interfacing')
.addCircle(3, 'fabric') .addCircle(3, 'fabric')
.addCircle(5, 'lining') .addCircle(5, 'lining')
.addCircle(7, 'mark') .addCircle(7, 'mark')
.addCircle(9, 'note') .addCircle(9, 'note')
points.c = new Point(70, 10) points.c = new Point(70, 10)
.addCircle(3, 'interfacing') .addCircle(3, 'interfacing')
.addCircle(7, 'mark lashed') .addCircle(7, 'mark lashed')
return part return part
} }
``` ```
</Example> </Example>
```

View file

@ -15,7 +15,9 @@ Point point.addText(
) )
``` ```
:::tipThis method is chainable as it returns the `Point` object::: :::tip
This method is chainable as it returns the `Point` object
:::
## Example ## Example
@ -26,18 +28,19 @@ Point point.addText(
.addText('FreeSewing') .addText('FreeSewing')
.addText('rocks') .addText('rocks')
// Avoid the text getting cropped // Avoid the text getting cropped
paths.hidden = new Path() paths.hidden = new Path()
.move(points.anchor) .move(points.anchor)
.line(points.anchor.shift(0, 80)) .line(points.anchor.shift(0, 80))
.addClass('hidden') .addClass('hidden')
return part
return part
} }
``` ```
</Example> </Example>
## Notes ## Notes
Remember to [use translation keys, not text](/guides/best-practices#use-translation-keys) Remember to [use translation keys, not text](/guides/best-practices#use-translation-keys)
```

View file

@ -18,8 +18,9 @@ Point point.attr(
If the third parameter is set to `true` it will call [`this.attributes.set()`](/reference/api/attributes/set/) instead, thereby overwriting the value of the attribute. If the third parameter is set to `true` it will call [`this.attributes.set()`](/reference/api/attributes/set/) instead, thereby overwriting the value of the attribute.
:::tip
:::tipThis method is chainable as it returns the `Point` object::: This method is chainable as it returns the `Point` object
:::
## Example ## Example
@ -27,18 +28,19 @@ If the third parameter is set to `true` it will call [`this.attributes.set()`](/
```js ```js
({ Point, points, Path, paths, part }) => { ({ Point, points, Path, paths, part }) => {
points.anchor = new Point(100, 25) points.anchor = new Point(100, 25)
.attr('data-text', 'FreeSewing') .attr('data-text', 'FreeSewing')
.attr('data-text', 'rocks') .attr('data-text', 'rocks')
// Avoid the text getting cropped // Avoid the text getting cropped
paths.hidden = new Path() paths.hidden = new Path()
.move(points.anchor) .move(points.anchor)
.line(points.anchor.shift(0, 80)) .line(points.anchor.shift(0, 80))
.addClass('hidden') .addClass('hidden')
return part return part
} }
``` ```
</Example> </Example>
@ -46,3 +48,4 @@ If the third parameter is set to `true` it will call [`this.attributes.set()`](/
See [Using Attributes](/howtos/code/attributes) See [Using Attributes](/howtos/code/attributes)
for information about custom Attributes that can be used with Points. for information about custom Attributes that can be used with Points.
```

View file

@ -11,7 +11,9 @@ attributes as the original point.
Point point.clone() Point point.clone()
``` ```
:::tipThis method is chainable as it returns the `Point` object::: :::tip
This method is chainable as it returns the `Point` object
:::
## Example ## Example
@ -19,21 +21,22 @@ Point point.clone()
```js ```js
({ Point, points, Path, paths, Snippet, snippets, part }) => { ({ Point, points, Path, paths, Snippet, snippets, part }) => {
points.A = new Point(25, 25) points.A = new Point(25, 25)
.setText("Point A", "text-xl") .setText("Point A", "text-xl")
.attr("data-text-fill-opacity", "0.5") .attr("data-text-fill-opacity", "0.5")
points.B = points.A.clone().setText("Point B") points.B = points.A.clone().setText("Point B")
snippets.x = new Snippet("notch", points.A) snippets.x = new Snippet("notch", points.A)
// Avoid the text getting cropped // Avoid the text getting cropped
paths.hidden = new Path() paths.hidden = new Path()
.move(new Point(20,10)) .move(new Point(20,10))
.move(new Point(75,30)) .move(new Point(75,30))
.addClass('hidden') .addClass('hidden')
return part return part
} }
``` ```
</Example> </Example>
@ -43,3 +46,4 @@ Point point.clone()
The [`Point.copy()`](/reference/api/point/copy/) method will only copy the The [`Point.copy()`](/reference/api/point/copy/) method will only copy the
point's coordinates, whereas this `Point.clone()` method will also copy its point's coordinates, whereas this `Point.clone()` method will also copy its
attributes. attributes.
```

View file

@ -21,7 +21,9 @@ Point point.setCircle(
) )
``` ```
:::tipThis method is chainable as it returns the `Point` object::: :::tip
This method is chainable as it returns the `Point` object
:::
## Example ## Example
@ -29,22 +31,24 @@ Point point.setCircle(
```js ```js
({ Point, points, part }) => { ({ Point, points, part }) => {
points.a = new Point(30, 10) points.a = new Point(30, 10)
.setCircle(3, 'lining dashed') .setCircle(3, 'lining dashed')
.setCircle(7, 'mark dashed') .setCircle(7, 'mark dashed')
points.b = new Point(50, 10) points.b = new Point(50, 10)
.setCircle(1, 'interfacing') .setCircle(1, 'interfacing')
.setCircle(3, 'fabric') .setCircle(3, 'fabric')
.setCircle(5, 'lining') .setCircle(5, 'lining')
.setCircle(7, 'mark') .setCircle(7, 'mark')
.setCircle(9, 'note') .setCircle(9, 'note')
points.c = new Point(70, 10) points.c = new Point(70, 10)
.setCircle(3, 'interfacing') .setCircle(3, 'interfacing')
.setCircle(7, 'mark lashed') .setCircle(7, 'mark lashed')
return part return part
} }
``` ```
</Example> </Example>
```

View file

@ -15,7 +15,9 @@ Point point.setText(
) )
``` ```
:::tipThis method is chainable as it returns the `Point` object::: :::tip
This method is chainable as it returns the `Point` object
:::
## Example ## Example
@ -23,21 +25,23 @@ Point point.setText(
```js ```js
({ Point, points, Path, paths, part }) => { ({ Point, points, Path, paths, part }) => {
points.anchor = new Point(100, 25) points.anchor = new Point(100, 25)
.setText('FreeSewing') .setText('FreeSewing')
.setText('rocks') .setText('rocks')
// Avoid the text getting cropped // Avoid the text getting cropped
paths.hidden = new Path() paths.hidden = new Path()
.move(points.anchor) .move(points.anchor)
.line(points.anchor.shift(0, 80)) .line(points.anchor.shift(0, 80))
.addClass('hidden') .addClass('hidden')
return part return part
} }
``` ```
</Example> </Example>
## Notes ## Notes
Remember to [use translation keys, not text](/guides/best-practices#use-translation-keys) Remember to [use translation keys, not text](/guides/best-practices#use-translation-keys)
```

View file

@ -3,7 +3,7 @@ title: Snippet.attr()
--- ---
The `Snippet.attr()` method can be used to add attributes to the Snippet The `Snippet.attr()` method can be used to add attributes to the Snippet
object. It calls `this.attributes.add()` under the hood, and returns the object. It calls `this.attributes.add()` under the hood, and returns the
Snippet object. Snippet object.
If the third parameter is set to `true` it will call `this.attributes.set()` If the third parameter is set to `true` it will call `this.attributes.set()`
@ -13,13 +13,15 @@ instead, thereby overwriting the value of the attribute.
```js ```js
Snippet snippet.attr( Snippet snippet.attr(
string name, string name,
mixed value, mixed value,
bool overwrite = false bool overwrite = false
) )
``` ```
:::tipThis method is chainable as it returns the `Snippet` object::: :::tip
This method is chainable as it returns the `Snippet` object
:::
## Example ## Example
@ -27,17 +29,18 @@ Snippet snippet.attr(
```js ```js
({ Point, points, Path, paths, Snippet, snippets, part }) => { ({ Point, points, Path, paths, Snippet, snippets, part }) => {
snippets.logo = new Snippet('logo', new Point(0,0)) snippets.logo = new Snippet('logo', new Point(0,0))
.attr("data-scale", 0.75) .attr("data-scale", 0.75)
.attr("data-rotate", 180) .attr("data-rotate", 180)
// Prevent clipping // Prevent clipping
paths.diag = new Path() paths.diag = new Path()
.move(new Point(-25,-10)) .move(new Point(-25,-10))
.move(new Point(25,35)) .move(new Point(25,35))
return part return part
} }
``` ```
</Example> </Example>
@ -45,3 +48,4 @@ Snippet snippet.attr(
See [Using Attributes](/howtos/code/attributes) See [Using Attributes](/howtos/code/attributes)
for information about what Attributes can be used with Snippets. for information about what Attributes can be used with Snippets.
::: :::
```

View file

@ -11,7 +11,9 @@ sets the `data-rotate` property.
Snippet snippet.rotate(rotation, overwrite=true) Snippet snippet.rotate(rotation, overwrite=true)
``` ```
:::tipThis method is chainable as it returns the `Snippet` object::: :::tip
This method is chainable as it returns the `Snippet` object
:::
## Example ## Example
@ -19,20 +21,22 @@ Snippet snippet.rotate(rotation, overwrite=true)
```js ```js
({ Point, Path, paths, Snippet, snippets, part }) => { ({ Point, Path, paths, Snippet, snippets, part }) => {
for (const i of [0,1,2,3,4,5,6]) { for (const i of [0,1,2,3,4,5,6]) {
snippets[`demo${i}`] = new Snippet( snippets[`demo${i}`] = new Snippet(
"logo", "logo",
new Point(60*i, 0) new Point(60*i, 0)
).rotate(60 * i) ).rotate(60 * i)
}
// Prevent clipping
paths.diag = new Path()
.move(new Point(-30,-50))
.move(new Point(400,50))
return part
} }
// Prevent clipping
paths.diag = new Path()
.move(new Point(-30,-50))
.move(new Point(400,50))
return part
}
``` ```
</Example> </Example>
```

View file

@ -11,7 +11,9 @@ sets the `data-scale` property.
Snippet snippet.scale(scale, overwrite=true) Snippet snippet.scale(scale, overwrite=true)
``` ```
:::tipThis method is chainable as it returns the `Snippet` object::: :::tip
This method is chainable as it returns the `Snippet` object
:::
## Example ## Example
@ -19,20 +21,22 @@ Snippet snippet.scale(scale, overwrite=true)
```js ```js
({ Point, Path, paths, Snippet, snippets, part }) => { ({ Point, Path, paths, Snippet, snippets, part }) => {
for (const i of [1,2,3,4,5,6]) { for (const i of [1,2,3,4,5,6]) {
snippets[`demo${i}`] = new Snippet( snippets[`demo${i}`] = new Snippet(
"logo", "logo",
new Point(30*i, 0) new Point(30\*i, 0)
).scale(i/10) ).scale(i/10)
}
// Prevent clipping
paths.diag = new Path()
.move(new Point(0,-30))
.move(new Point(200,20))
return part
} }
// Prevent clipping
paths.diag = new Path()
.move(new Point(0,-30))
.move(new Point(200,20))
return part
}
``` ```
</Example> </Example>
```

View file

@ -11,4 +11,6 @@ original stack.
Stack stack.addPart(Part part) Stack stack.addPart(Part part)
``` ```
:::noteThis method is chainable as it returns the Stack object::: :::note
This method is chainable as it returns the Stack object
:::

View file

@ -20,4 +20,6 @@ If the third parameter is set to `true` it will call
`this.attributes.set()` instead, `this.attributes.set()` instead,
thereby overwriting the value of the attribute. thereby overwriting the value of the attribute.
:::noteThis method is chainable as it returns the Stack object::: :::note
This method is chainable as it returns the Stack object
:::

View file

@ -5,7 +5,6 @@ title: Stack.generateTransform()
The `Stack.generateTransform()` method generates SVG transforms for the stack, The `Stack.generateTransform()` method generates SVG transforms for the stack,
sets them as attributes, and returns the original stack. sets them as attributes, and returns the original stack.
## Stack.generateTransform() signature ## Stack.generateTransform() signature
```js ```js
@ -16,11 +15,13 @@ The `Stack.generateTransforms()` method takes a single argument,
an object with the following properties containing the transforms an object with the following properties containing the transforms
to apply: to apply:
| Property | Type |Description | | Property | Type | Description |
|----------|------|------------| | -------- | ------- | ----------------------------------------------------------------------------- |
| `move` | Object | `move.x` and `move.y` are coordinates to which the stack should be translated | `move` | Object | `move.x` and `move.y` are coordinates to which the stack should be translated |
| `rotate` | Number | The number of degrees to rate the stack around its center | | `rotate` | Number | The number of degrees to rate the stack around its center |
| `flipX` | Boolean | Whether to flip the stack along the X axis | | `flipX` | Boolean | Whether to flip the stack along the X axis |
| `flipY` | Boolean | Whether to flip the stack along the Y axis | | `flipY` | Boolean | Whether to flip the stack along the Y axis |
:::noteThis method is chainable as it returns the Stack object::: :::note
This method is chainable as it returns the Stack object
:::

View file

@ -11,7 +11,10 @@ and returns the original stack.
```js ```js
Stack stack.home() Stack stack.home()
``` ```
:::noteThis method is chainable as it returns the Stack object:::
:::note
This method is chainable as it returns the Stack object
:::
## Notes ## Notes

View file

@ -13,7 +13,9 @@ rather through a plugin.
Store Store.extend(Array methods=[]) Store Store.extend(Array methods=[])
``` ```
:::tipThis method is chainable as it returns the `Store` object::: :::tip
This method is chainable as it returns the `Store` object
:::
The single argument should be an Array of methods to add to the The single argument should be an Array of methods to add to the
store. Each entry in the array should be an array itself holding a path in store. Each entry in the array should be an array itself holding a path in
@ -23,13 +25,11 @@ The expected first parameter for the method is the `Store` instance.
```js ```js
function myCustomMethod(store, ...otherArguments) { function myCustomMethod(store, ...otherArguments) {
// Do something clever // Do something clever
} }
const store = new Store([ const store = new Store([['path.to.the.method', myCustomMethod]])
["path.to.the.method", myCustomMethod ] ```
])
```
With the configuration above, you can call `store.path.to.the.method()` and it With the configuration above, you can call `store.path.to.the.method()` and it
will run `myCustomMethod()`. will run `myCustomMethod()`.
@ -46,5 +46,3 @@ The Store will not allow you to extend any of the following keys:
- `unset` - `unset`
- `get` - `get`
- `extend` - `extend`

View file

@ -12,18 +12,18 @@ If `key` does not hold and Array, the Store will log a warning, but nothing will
Store store.push(mixed value1, mixed value2, ...) Store store.push(mixed value1, mixed value2, ...)
``` ```
:::noteThis method is [variadic](https://en.wikipedia.org/wiki/Variadic_function)::: :::note
This method is [variadic](https://en.wikipedia.org/wiki/Variadic_function)
:::
:::tipThis method is chainable as it returns the `Store` object::: :::tip
This method is chainable as it returns the `Store` object
:::
## Example ## Example
```js ```js
const store = new Store() const store = new Store()
store.set('example', ['Hi there']) store.set('example', ['Hi there'])
store.push( store.push('How are you doing', 'How are YOU doing')
'How are you doing',
'How are YOU doing'
)
``` ```

View file

@ -11,7 +11,9 @@ The `Store.set()` method stores the value of `value` in the store under key
Store store.set(mixed key, mixed value) Store store.set(mixed key, mixed value)
``` ```
:::tipThis method is chainable as it returns the `Store` object::: :::tip
This method is chainable as it returns the `Store` object
:::
## Example ## Example
@ -42,4 +44,3 @@ value = store.get(['my', 'other', 'nested', 'example']) // works
value = store.my.nested.example // Also works value = store.my.nested.example // Also works
value = store.my.other.nested.example // Also works value = store.my.other.nested.example // Also works
``` ```

View file

@ -11,7 +11,9 @@ The `Store.set()` method stores the value of `value` in the store under key
Store store.set(mixed key, mixed value) Store store.set(mixed key, mixed value)
``` ```
:::tipThis method is chainable as it returns the `Store` object::: :::tip
This method is chainable as it returns the `Store` object
:::
## Example ## Example
@ -20,4 +22,3 @@ const store = new Store()
store.set('example', 'Hi there') store.set('example', 'Hi there')
store.setIfUnset('example', 'Hi again') // This has no effect store.setIfUnset('example', 'Hi again') // This has no effect
``` ```

View file

@ -10,12 +10,12 @@ The `Store.unset()` value removes a `key` from the store.
Store store.unset(string key) Store store.unset(string key)
``` ```
:::tipThis method is chainable as it returns the `Store` object::: :::tip
This method is chainable as it returns the `Store` object
:::
## Example ## Example
```js ```js
const store = new Store() const store = new Store().set('example', 'I will be gone before you know it').unset('example')
.set('example', 'I will be gone before you know it')
.unset('example')
``` ```

View file

@ -36,6 +36,7 @@ git clone https://github.com/your-username/freesewing
cd freesewing cd freesewing
yarn kickstart yarn kickstart
``` ```
::: :::
This sets up the monorepo. If you would like to create a new design, run the This sets up the monorepo. If you would like to create a new design, run the
@ -135,13 +136,15 @@ npx @freesewing/new-design
``` ```
After you've answered [some questions](#questions), it will take a while to set After you've answered [some questions](#questions), it will take a while to set
everything up. When it's done, you will have a new folder with the development everything up. When it's done, you will have a new folder with the development
environment inside. environment inside.
Now you're ready to [start the development Now you're ready to [start the development
environment](/tutorials/getting-started-linux/dev-start). environment](/tutorials/getting-started-linux/dev-start).
:::tipThe folder will have the name you chose above.::: :::tip
The folder will have the name you chose above.
:::
:::note :::note

View file

@ -10,4 +10,6 @@ We'll cover the following steps:
<ReadMore /> <ReadMore />
:::tipThese instructions are also valid for BSD or other Unix systems::: :::tip
These instructions are also valid for BSD or other Unix systems
:::

View file

@ -36,6 +36,7 @@ git clone https://github.com/your-username/freesewing
cd freesewing cd freesewing
yarn kickstart yarn kickstart
``` ```
::: :::
This sets up the monorepo. If you would like to create a new design, run the This sets up the monorepo. If you would like to create a new design, run the
@ -120,13 +121,15 @@ npx @freesewing/new-design
``` ```
After you've answered [some questions](#questions), it will take a while to set After you've answered [some questions](#questions), it will take a while to set
everything up. When it's done, you will have a new folder with the development everything up. When it's done, you will have a new folder with the development
environment inside. environment inside.
Now you're ready to [start the development Now you're ready to [start the development
environment](/tutorials/getting-started-linux/dev-start). environment](/tutorials/getting-started-linux/dev-start).
:::tipThe folder will have the name you chose above.::: :::tip
The folder will have the name you chose above.
:::
:::note :::note

View file

@ -35,11 +35,13 @@ FreeSewing project.
### Install WSL ### Install WSL
:::warning This guide uses WSL version 2, which requires installing the Hyper-V :::warning
This guide uses WSL version 2, which requires installing the Hyper-V
virtualisation system. If you have another virtualisation system installed (such virtualisation system. If you have another virtualisation system installed (such
as VirtualBox or VMWare) you may run into conflicts which require either as VirtualBox or VMWare) you may run into conflicts which require either
updating that system to a version which can use the HyperV backend or porting updating that system to a version which can use the HyperV backend or porting
your existing machines to use HyperV. ::: your existing machines to use HyperV.
:::
Follow the [Windows Subsystem for Linux Installation Guide for Windows Follow the [Windows Subsystem for Linux Installation Guide for Windows
10](https://docs.microsoft.com/en-gb/windows/wsl/install-win10) (requires a 10](https://docs.microsoft.com/en-gb/windows/wsl/install-win10) (requires a
@ -48,8 +50,8 @@ recent version of Windows 10).
#### Install NVM #### Install NVM
Open a new WSL terminal from the shortcuts created or by searching for "WSL Open a new WSL terminal from the shortcuts created or by searching for "WSL
Terminal" in the start menu. [Install NVM by following the NVM setup Terminal" in the start menu. [Install NVM by following the NVM setup
guide](https://github.com/nvm-sh/nvm#install--update-script). Once installed guide](https://github.com/nvm-sh/nvm#install--update-script). Once installed
you will need to activate NVM by either following the instructions printed to you will need to activate NVM by either following the instructions printed to
the screen or opening a new terminal. the screen or opening a new terminal.
@ -63,10 +65,12 @@ then activate using `nvm use <version>`. You can determine what version the
FreeSewing project uses by checking FreeSewing project uses by checking
[freesewing/freesewing/.nvmrc](https://github.com/freesewing/freesewing/blob/develop/.nvmrc). [freesewing/freesewing/.nvmrc](https://github.com/freesewing/freesewing/blob/develop/.nvmrc).
:::warning At the time this guide was written the latest version of Node.js/npm has :::warning
At the time this guide was written the latest version of Node.js/npm has
a bug in the dependency resolution process which causes the freesewing project a bug in the dependency resolution process which causes the freesewing project
to fail to build. Use the latest LTS version (currently 18.17.0) or the specific to fail to build. Use the latest LTS version (currently 18.17.0) or the specific
version used by the main project to avoid this issue. ::: version used by the main project to avoid this issue.
:::
Node.js comes with the Node Package Manager (npm) by default which can be used to Node.js comes with the Node Package Manager (npm) by default which can be used to
set up the project. The default package manager uses a fairly simplistic approach set up the project. The default package manager uses a fairly simplistic approach
@ -122,7 +126,6 @@ this guide you have already done steps 1 and 2, you will only need to install
the [remote development the [remote development
extension](https://aka.ms/vscode-remote/download/extension)) extension](https://aka.ms/vscode-remote/download/extension))
## Setting up a development environment in Windows. ## Setting up a development environment in Windows.
### Install NVM ### Install NVM
@ -165,9 +168,12 @@ In VSCode or in a terminal, navigate to the folder you wish to contain your new
After you've answered [some questions](#questions), it will take a while to set everything up. After you've answered [some questions](#questions), it will take a while to set everything up.
When it's done, you will have a new folder with the development environment inside. When it's done, you will have a new folder with the development environment inside.
:::tipThe folder will have the name you chose above.::: :::tip
The folder will have the name you chose above.
:::
:::note :::note
### Questions ### Questions
#### What template to use #### What template to use

View file

@ -17,10 +17,12 @@ tedious. There are macros to add titles to our pattern, or grainline
indicators, a scalebox, and there's a macro to round corners. The `round` indicators, a scalebox, and there's a macro to round corners. The `round`
macro. macro.
:::note You can find more information on the `round` macro in [the macros docs](/reference/macros/round/).::: :::note
You can find more information on the `round` macro in [the macros docs](/reference/macros/round/).
:::
We need a half circle here, but the `round` macro works on 90° angles, so We need a half circle here, but the `round` macro works on 90° angles, so
we'll use it twice. As such, we'll add some points to guide the macro, and we'll use it twice. As such, we'll add some points to guide the macro, and
then put it to work. then put it to work.
Like our neck opening, we've only drawn half since we can simply copy the Like our neck opening, we've only drawn half since we can simply copy the
@ -41,36 +43,38 @@ function draftBib({
part, part,
}) { }) {
/* /\*
* Construct the quarter neck opening
*/ - Construct the quarter neck opening
_/
let tweak = 1 let tweak = 1
let target = (measurements.head * options.neckRatio) /4 let target = (measurements.head _ options.neckRatio) /4
let delta let delta
do { do {
points.right = new Point( points.right = new Point(
tweak * measurements.head / 10, tweak _ measurements.head / 10,
0 0
) )
points.bottom = new Point( points.bottom = new Point(
0, 0,
tweak * measurements.head / 12 tweak _ measurements.head / 12
) )
points.rightCp1 = points.right.shift( points.rightCp1 = points.right.shift(
90, 90,
points.bottom.dy(points.right) / 2 points.bottom.dy(points.right) / 2
) )
points.bottomCp2 = points.bottom.shift( points.bottomCp2 = points.bottom.shift(
0, 0,
points.bottom.dx(points.right) / 2 points.bottom.dx(points.right) / 2
) )
paths.quarterNeck = new Path() paths.quarterNeck = new Path()
.move(points.right) .move(points.right)
.curve( .curve(
points.rightCp1, points.rightCp1,
points.bottomCp2, points.bottomCp2,
points.bottom points.bottom
) )
.hide() .hide()
@ -78,11 +82,13 @@ function draftBib({
delta = paths.quarterNeck.length() - target delta = paths.quarterNeck.length() - target
if (delta > 0) tweak = tweak * 0.99 if (delta > 0) tweak = tweak * 0.99
else tweak = tweak * 1.02 else tweak = tweak * 1.02
} while (Math.abs(delta) > 1)
/* } while (Math.abs(delta) > 1)
* Construct the complete neck opening
*/ /\*
- Construct the complete neck opening
\*/
points.rightCp2 = points.rightCp1.flipY() points.rightCp2 = points.rightCp1.flipY()
points.bottomCp1 = points.bottomCp2.flipX() points.bottomCp1 = points.bottomCp2.flipX()
points.left = points.right.flipX() points.left = points.right.flipX()
@ -92,83 +98,88 @@ function draftBib({
points.topCp1 = points.bottomCp2.flipY() points.topCp1 = points.bottomCp2.flipY()
points.topCp2 = points.bottomCp1.flipY() points.topCp2 = points.bottomCp1.flipY()
paths.neck = new Path() paths.neck = new Path()
.move(points.top) .move(points.top)
.curve(points.topCp2, points.leftCp1, points.left) .curve(points.topCp2, points.leftCp1, points.left)
.curve(points.leftCp2, points.bottomCp1, points.bottom) .curve(points.leftCp2, points.bottomCp1, points.bottom)
.curve(points.bottomCp2, points.rightCp1, points.right) .curve(points.bottomCp2, points.rightCp1, points.right)
.curve(points.rightCp2, points.topCp1, points.top) .curve(points.rightCp2, points.topCp1, points.top)
.close() .close()
.addClass('fabric') .addClass('fabric')
/* /\*
* Drawing the bib outline
*/
const width = measurements.head * options.widthRatio
const length = measurements.head * options.lengthRatio
points.topLeft = new Point( - Drawing the bib outline
width / -2, _/
points.top.y - (width / 2 - points.right.x) const width = measurements.head _ options.widthRatio
) const length = measurements.head \* options.lengthRatio
points.topRight = points.topLeft.shift(0, width)
points.bottomLeft = points.topLeft.shift(-90, length)
points.bottomRight = points.topRight.shift(-90, length)
/* points.topLeft = new Point(
* Shape the straps 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.edgeLeft = new Point(points.topLeft.x, points.left.y)
points.edgeRight = new Point(points.topRight.x, points.right.y) points.edgeRight = new Point(points.topRight.x, points.right.y)
points.edgeTop = new Point(0, points.topLeft.y) points.edgeTop = new Point(0, points.topLeft.y)
points.edgeLeftCp = points.edgeLeft.shiftFractionTowards(points.topLeft, 0.5) points.edgeLeftCp = points.edgeLeft.shiftFractionTowards(points.topLeft, 0.5)
points.edgeRightCp = points.edgeLeftCp.flipX() points.edgeRightCp = points.edgeLeftCp.flipX()
points.edgeTopLeftCp = points.edgeTop.shiftFractionTowards( points.edgeTopLeftCp = points.edgeTop.shiftFractionTowards(
points.topLeft, points.topLeft,
0.5 0.5
) )
points.edgeTopRightCp = points.edgeTopLeftCp.flipX() points.edgeTopRightCp = points.edgeTopLeftCp.flipX()
// highlight-start // highlight-start
// Round the straps // Round the straps
const strap = points.edgeTop.dy(points.top) const strap = points.edgeTop.dy(points.top)
points.tipRight = points.edgeTop.translate(strap / 2, strap / 2) points.tipRight = points.edgeTop.translate(strap / 2, strap / 2)
points.tipRightTop = new Point(points.tipRight.x, points.edgeTop.y) points.tipRightTop = new Point(points.tipRight.x, points.edgeTop.y)
points.tipRightBottom = new Point(points.tipRight.x, points.top.y) points.tipRightBottom = new Point(points.tipRight.x, points.top.y)
macro("round", { macro("round", {
id: "tipRightTop", id: "tipRightTop",
from: points.edgeTop, from: points.edgeTop,
to: points.tipRight, to: points.tipRight,
via: points.tipRightTop, via: points.tipRightTop,
hide: false hide: false
}) })
macro("round", { macro("round", {
id: "tipRightBottom", id: "tipRightBottom",
from: points.tipRight, from: points.tipRight,
to: points.top, to: points.top,
via: points.tipRightBottom, via: points.tipRightBottom,
hide: false hide: false
}) })
// highlight-end // highlight-end
/* /*
* Now, adapt our `rect` path so it's no longer a rectangle:
*/
paths.rect = new Path()
.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()
return part - Now, adapt our `rect` path so it's no longer a rectangle:
\*/
paths.rect = new Path()
.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()
return part
} }
``` ```
</Example> </Example>
Notice that we always draw our path at the end after we've manipulated our points. Notice that we always draw our path at the end after we've manipulated our points.
```

View file

@ -19,12 +19,12 @@ does.
## Destructuring the function parameter ## Destructuring the function parameter
If you're not familiar with the `({ part })` syntax you see above, this is a If you're not familiar with the `({ part })` syntax you see above, this is a
technique called *parameter destructuring* or more generally, [object technique called _parameter destructuring_ or more generally, [object
destructuring](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment). destructuring](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment).
The draft method receives only 1 parameter: An object that holds everything we The draft method receives only 1 parameter: An object that holds everything we
need to draft our method. Destructuring is a way to *pull things out of the need to draft our 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>
@ -53,7 +53,7 @@ function draftBib({ 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
*destructuring*. _destructuring_.
:::note :::note
@ -92,7 +92,9 @@ Here's a brief summary of the things we've added above:
- `points`: A container object to hold the part's points - `points`: A container object to hold the part's points
- `paths`: A container object to hold the part's paths - `paths`: A container object to hold the part's paths
:::tipRemember: Constructors start with a **C**apital letter::: :::tip
Remember: Constructors start with a **C**apital letter
:::
Long story short: These will make it possible for us to draw points and paths easily. Long story short: These will make it possible for us to draw points and paths easily.

View file

@ -3,5 +3,6 @@ title: Supporting translation
order: 80 order: 80
--- ---
:::note [FIXME]Write this section for v3::: :::note [FIXME]
Write this section for v3
:::

View file

@ -42,6 +42,7 @@ If you set a `menu` property on your option, the FreeSewing frontend will use
this to organize your various options in a menu structure. this to organize your various options in a menu structure.
### Sub menus ### Sub menus
You can a nested menu structure with dot-notation. So `style.pockets` will You can a nested menu structure with dot-notation. So `style.pockets` will
create a `pockets` submenu under the `style` menu and put your option there. create a `pockets` submenu under the `style` menu and put your option there.
@ -65,4 +66,6 @@ function(
This is typically used to hide options conditionally. This is typically used to hide options conditionally.
:::note [FIXME]Include example::: :::note [FIXME]
Include example
:::

View file

@ -3,13 +3,13 @@ title: Testing your designs
order: 70 order: 70
--- ---
:::note [FIXME] Update this for v3 :::
With the basic outline of our pattern ready, now would be a good time With the basic outline of our pattern ready, now would be a good time
to test it to see how well it adapts to different measurements, to test it to see how well it adapts to different measurements,
and the range of options we provided. and the range of options we provided.
:::note [FIXME] :::note [FIXME]
Update this for v3
This page needs to be updated with screenshots from the v3 development This page needs to be updated with screenshots from the v3 development
environment environment
::: :::
@ -40,7 +40,7 @@ these.
## Testing pattern options ## Testing pattern options
We used percentage options, which can vary between their minimum and maximum We used percentage options, which can vary between their minimum and maximum
value. For these tests, FreeSewing will divide that range into 10 steps and value. For these tests, FreeSewing will divide that range into 10 steps and
draft our pattern for each step. draft our pattern for each step.
Click on any of the options we've added to our pattern, and our bib will be Click on any of the options we've added to our pattern, and our bib will be
@ -54,11 +54,13 @@ that it only influences the length:
![This is what it should look like when we test the `lengthRatio` ![This is what it should look like when we test the `lengthRatio`
option](test-option-lengthratio.png) option](test-option-lengthratio.png)
:::note [FIXME]Update screenshot for v3::: :::note [FIXME]
Update screenshot for v3
:::
### neckRatio ### neckRatio
The `neckRatio` option will determine the size of the neck opening. For the The `neckRatio` option will determine the size of the neck opening. For the
same `head` measurement, varying this option should result in bibs with same `head` measurement, varying this option should result in bibs with
increasingly larger neck opening. increasingly larger neck opening.
@ -68,11 +70,13 @@ smaller, we will rotate the straps further out of the way to avoid overlap:
![This is what it should look like when we test the `neckRatio` ![This is what it should look like when we test the `neckRatio`
option](test-option-neckratio.png) option](test-option-neckratio.png)
:::note [FIXME]Update screenshot for v3::: :::note [FIXME]
Update screenshot for v3
:::
### widthRatio ### widthRatio
The `widthRatio` option will determine the width of our bib. For the same The `widthRatio` option will determine the width of our bib. For the same
`head` measurement, varying this option should result in increasingly wider `head` measurement, varying this option should result in increasingly wider
bibs. bibs.
@ -84,7 +88,9 @@ bib shorter when it's worn.
![This is what it should look like when we test the `widthRatio` ![This is what it should look like when we test the `widthRatio`
option](test-option-widthratio.png) option](test-option-widthratio.png)
:::note [FIXME]Update screenshot for v3::: :::note [FIXME]
Update screenshot for v3
:::
:::note :::note
@ -101,12 +107,14 @@ to the reader_.
## Testing measurements ## Testing measurements
Testing a measurement will vary that measurement 10% up or down while leaving Testing a measurement will vary that measurement 10% up or down while leaving
everything else the same. This gives us the option to determine how any given everything else the same. This gives us the option to determine how any given
measurement is influencing the pattern. measurement is influencing the pattern.
For our bib, we only use one measurement, so it influences the entire pattern. For our bib, we only use one measurement, so it influences the entire pattern.
:::note [FIXME]Add screenshot::: :::note [FIXME]
Add screenshot
:::
## Testing measurments sets ## Testing measurments sets
@ -121,27 +129,31 @@ ends up being the same as testing a complete set of measurements.
But most patterns use multiple measurements, and we'll find this test gives But most patterns use multiple measurements, and we'll find this test gives
us insight into how our pattern will adapt to differently sized bodies. us insight into how our pattern will adapt to differently sized bodies.
:::note [FIXME]Add screenshot::: :::note [FIXME]
Add screenshot
:::
## The antperson test ## The antperson test
A special case of model testing is the so-called _antperson test_. It drafts A special case of model testing is the so-called _antperson test_. It drafts
our pattern with a set of _typical_ measurements , and then drafts it again our pattern with a set of _typical_ measurements , and then drafts it again
with measurements that are 1/10th of those _typical_ measurements. with measurements that are 1/10th of those _typical_ measurements.
It is named after [the cartoon It is named after [the cartoon
character](https://en.wikipedia.org/wiki/Ant-Man_\(film\)) who can shrink, yet character](<https://en.wikipedia.org/wiki/Ant-Man_(film)>) who can shrink, yet
somehow his suit still fits. somehow his suit still fits.
The purpose of the antperson test is to bring out areas in our pattern where The purpose of the antperson test is to bring out areas in our pattern where
we made assumptions that will not properly scale. Many drafting books will we made assumptions that will not properly scale. Many drafting books will
tell us to _add 3 cm there_ or _measure 2 inch to the right_. Those tell us to _add 3 cm there_ or _measure 2 inch to the right_. Those
instructions don't scale, and we should avoid them. instructions don't scale, and we should avoid them.
The best patterns will pass the antperson test with 2 patterns exactly the 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. same, where one will simply be 1/10th the scale of the other.
:::note [FIXME]Add screenshot::: :::note [FIXME]
Add screenshot
:::
When we're happy with how our pattern passes these tests, it's time to When we're happy with how our pattern passes these tests, it's time to
complete our design. complete our design.