feat(markdown): Ported code howtos to v3
This commit is contained in:
parent
d1edf93750
commit
af99d3e8c0
25 changed files with 451 additions and 636 deletions
|
@ -1,18 +1,22 @@
|
||||||
---
|
---
|
||||||
title: Accessing measurements
|
title: Accessing measurements
|
||||||
for: developers
|
|
||||||
about: Shows you how to access user measurements from inside your pattern
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Measurements are stored in `pattern.settings.measurements`.
|
Measurements are available on the `measurements` key of from the object passed
|
||||||
|
to your part's draft method. You can destructure them for easy access.
|
||||||
|
|
||||||
You can pull them out of there with
|
```design/src/part.mjs
|
||||||
the [shorthand](/howtos/code/shorthand/) call:
|
function draftPart = ({
|
||||||
|
// highlight-start
|
||||||
|
measurements,
|
||||||
|
// highlight-end
|
||||||
|
part
|
||||||
|
}) {
|
||||||
|
|
||||||
```js
|
// Do something here
|
||||||
const { measurements, options } = part.shorthand()
|
|
||||||
|
|
||||||
let sleeveBonus = measurements.shoulderToWrist * (1 + options.sleeveLengthBonus);
|
return part
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
<Note>
|
<Note>
|
||||||
|
|
|
@ -1,16 +1,26 @@
|
||||||
---
|
---
|
||||||
title: Accessing user options
|
title: Accessing options
|
||||||
for: developers
|
|
||||||
about: Shows you how to access user options from inside your pattern
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Options are stored in `pattern.settings.options`.
|
(the value of) Options are available on the `options` key of from the object
|
||||||
|
passed to your part's draft method. You can destructure them for easy access.
|
||||||
|
|
||||||
You can pull them out of there with
|
```design/src/part.mjs
|
||||||
the [shorthand](/howtos/code/shorthand/) call:
|
function draftPart = ({
|
||||||
|
// highlight-start
|
||||||
|
options,
|
||||||
|
// highlight-end
|
||||||
|
part
|
||||||
|
}) {
|
||||||
|
|
||||||
```js
|
// Do something here
|
||||||
const { measurements, options } = part.shorthand()
|
|
||||||
|
|
||||||
let sleeveBonus = measurements.shoulderToWrist * (1 + options.sleeveLengthBonus);
|
return part
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<Note>
|
||||||
|
|
||||||
|
Unlike measurements, options come with default values.
|
||||||
|
|
||||||
|
</Note>
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
---
|
|
||||||
title: Add instructions to your design
|
|
||||||
for: developers
|
|
||||||
about: While documentation is good, sometimes you want to add some instructions to your design itself
|
|
||||||
---
|
|
||||||
|
|
||||||
<Note>
|
|
||||||
|
|
||||||
##### See this example in our source code
|
|
||||||
|
|
||||||
- [designs/aaron/src/back.js](https://github.com/freesewing/freesewing/blob/3ca5d0edfe54c7ac20aaf3af2f3544aee72f9b99/designs/aaron/src/back.js#L66)
|
|
||||||
|
|
||||||
</Note>
|
|
||||||
|
|
||||||
Adding instructions to your pattern is _just_ a matter of adding text.
|
|
||||||
The tricky part is to make sure your text can be translated.
|
|
||||||
|
|
||||||
Below is a rather involved example from Aaron:
|
|
||||||
|
|
||||||
```js
|
|
||||||
points.bindingAnchor = new Point(points.armhole.x / 4, points.armhole.y)
|
|
||||||
.attr('data-text', 'cutTwoStripsToFinishTheArmholes')
|
|
||||||
.attr('data-text', ':\n')
|
|
||||||
.attr('data-text', `2x: ${units(sa * 6 || 60)} x ${units(armholeLength * 0.95 + 2 * sa)}`)
|
|
||||||
.attr('data-text', '\n \n')
|
|
||||||
.attr('data-text', 'cutOneStripToFinishTheNeckOpening')
|
|
||||||
.attr('data-text', ':\n')
|
|
||||||
.attr('data-text', 'width')
|
|
||||||
.attr('data-text', ':')
|
|
||||||
.attr(
|
|
||||||
'data-text',
|
|
||||||
`${units((sa || 10) * 6)} x ${units(neckOpeningLength * 2 * 0.95 + 2 * sa)}`
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
If you want to add text along a path, you can do that too:
|
|
||||||
|
|
||||||
```js
|
|
||||||
paths.breakLine.attr('data-text', 'breakLine').attr('data-text-class', 'center')
|
|
||||||
paths.flb.attr('data-text', 'facingLiningBoundary')
|
|
||||||
```
|
|
||||||
|
|
||||||
<Tip>
|
|
||||||
|
|
||||||
Refer to [the sprinkle macro documentation](/reference/api/macros/sprinkle/) for details on how
|
|
||||||
to use this macro
|
|
||||||
|
|
||||||
</Tip>
|
|
|
@ -1,42 +1,29 @@
|
||||||
---
|
---
|
||||||
title: Adding pattern parts
|
title: Adding pattern parts
|
||||||
for: developers
|
|
||||||
about: Shows you how to add new parts to your pattern
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Since the patterns parts are listed
|
Parts can be added to the design add build time, by passing them to [the Design
|
||||||
in [the configuration file](/reference/api/config/), freesewing knows about
|
constructor](/reference/api/design), or at runtime by calling
|
||||||
all the parts that belong to your pattern.
|
[Pattern.addPart()](/reference/api/pattern/addpart). The latter approach is
|
||||||
|
rarely used, but it's there if you need it.
|
||||||
|
|
||||||
It expects that each pattern has its own draft method, that is called `draft`
|
## At build time
|
||||||
followed by the capitalized name of the pattern part.
|
|
||||||
|
|
||||||
For example, if our pattern `Sorcha` has a part called `back`, you should
|
```mjs
|
||||||
have a `draftBack` method. It's good practice to keep each part in its own
|
import { Design } from '@freesewing/core'
|
||||||
file, so create a file called `back.js`. Inside, you export your method
|
import { myPart } from './mypart.mjs'
|
||||||
to draft this part:
|
|
||||||
|
|
||||||
```js
|
const Sorcha = new Design({
|
||||||
export default part => {
|
parts: [ myPart ]
|
||||||
// Your part code here
|
})
|
||||||
|
|
||||||
return part
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Then, in your `index.js` file, you import this file, and attach the
|
## At run time
|
||||||
method to your pattern's prototype:
|
|
||||||
|
|
||||||
```js
|
```mjs
|
||||||
import freesewing from "freesewing"
|
import { Aaron } from '@freesewing/aaron'
|
||||||
import plugins from "@freesewing/plugin-bundle"
|
import { myRuntimePart } from './mypart.mjs'
|
||||||
import config from "../config"
|
|
||||||
// Parts
|
|
||||||
import draftBack from "./back"
|
|
||||||
|
|
||||||
// Create new design
|
const pattern = new Aaron()
|
||||||
const Sorcha = new freesewing.Design(config, plugins)
|
pattern.addPart(myRuntimePart)
|
||||||
|
|
||||||
// Attach to pattern prototype
|
|
||||||
Sorcha.prototype.draftBack = part => draftBack(part)
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,22 +1,30 @@
|
||||||
---
|
---
|
||||||
title: Adding paths
|
title: Adding paths
|
||||||
for: developers
|
|
||||||
icon: pattern
|
|
||||||
about: Shows you how to add paths to your pattern
|
|
||||||
---
|
---
|
||||||
|
|
||||||
After using the [shorthand](/howtos/code/shorthand/) call,
|
Paths should be stored in the `paths` key of the object passed to your part's
|
||||||
`Path` contains the path constructor, while `paths` is a reference to `part.paths`,
|
draft method. The contructor for paths is available in the `Path` key. You can
|
||||||
which is where you should store your paths.
|
destructure them for easy access.
|
||||||
|
|
||||||
Things will now _just work_ when you do this:
|
<Example caption="An example of adding a path" tutorial>
|
||||||
|
```design/src/part.mjs
|
||||||
|
function draftPart = ({
|
||||||
|
Point,
|
||||||
|
// highlight-start
|
||||||
|
Path,
|
||||||
|
paths,
|
||||||
|
// highlight-end
|
||||||
|
part
|
||||||
|
}) {
|
||||||
|
|
||||||
```js
|
// highlight-start
|
||||||
paths.example = new Path()
|
paths.demo = new Path()
|
||||||
|
.move(new Point(0,0))
|
||||||
|
.line(new Point(100,20))
|
||||||
|
.addClass('lining lashed')
|
||||||
|
// highlight-end
|
||||||
|
|
||||||
|
return part
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
</Example>
|
||||||
<Tip>
|
|
||||||
|
|
||||||
The [Path API docs](/reference/api/path) list all the things you can do with a path object.
|
|
||||||
|
|
||||||
</Tip>
|
|
||||||
|
|
|
@ -1,21 +1,26 @@
|
||||||
---
|
---
|
||||||
title: Adding points
|
title: Adding points
|
||||||
for: developers
|
|
||||||
about: Shows you how to add points to your pattern
|
|
||||||
---
|
---
|
||||||
|
|
||||||
After using the [shorthand](/howtos/code/shorthand/) call,
|
Points should be stored in the `points` key of the object passed to your part's
|
||||||
`Point` contains the point constructor, while `points` is a reference to `part.points`,
|
draft method. The contructor for points is available in the `Point` key. You
|
||||||
which is where you should store your points.
|
can destructure them for easy access.
|
||||||
|
|
||||||
Things will now _just work_ when you do this:
|
<Example caption="An example of adding a point" tutorial>
|
||||||
|
```design/src/part.mjs
|
||||||
|
function draftPart = ({
|
||||||
|
// highlight-start
|
||||||
|
Point,
|
||||||
|
points,
|
||||||
|
// highlight-end
|
||||||
|
part
|
||||||
|
}) {
|
||||||
|
|
||||||
```js
|
// highlight-start
|
||||||
points.centerBack = new Point(0,0);
|
points.demo = new Point(0,0).addText('hi')
|
||||||
|
// highlight-end
|
||||||
|
|
||||||
|
return part
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
</Example>
|
||||||
<Tip>
|
|
||||||
|
|
||||||
The [Point API docs](/reference/api/point/) list many ways to create a point.
|
|
||||||
|
|
||||||
</Tip>
|
|
||||||
|
|
|
@ -1,32 +1,51 @@
|
||||||
---
|
---
|
||||||
title: Adding snippets
|
title: Adding snippets
|
||||||
for: developers
|
|
||||||
about: Shows you how to add snippets to your pattern
|
|
||||||
---
|
---
|
||||||
|
|
||||||
After using the [shorthand](/howtos/code/shorthand/) call,
|
Snippets should be stored in the `snippets` key of the object passed to your part's
|
||||||
`Snippet` contains the path constructor, while `snippets` is a reference to `part.snippets`,
|
draft method. The contructor for snippets is available in the `Snippets` key. You can
|
||||||
which is where you should store your paths.
|
destructure them for easy access.
|
||||||
|
|
||||||
Things will now _just work_ when you do this:
|
<Example caption="An example of adding a snippet" tutorial>
|
||||||
|
```design/src/part.mjs
|
||||||
|
function draftPart = ({
|
||||||
|
Point,
|
||||||
|
Path,
|
||||||
|
paths,
|
||||||
|
// highlight-start
|
||||||
|
Snippet,
|
||||||
|
snippets,
|
||||||
|
// highlight-end
|
||||||
|
part
|
||||||
|
}) {
|
||||||
|
|
||||||
```js
|
// highlight-start
|
||||||
snippets.logo = new Snippet('logo', points.logoAnchor);
|
snippets.logo = new Snippet('logo', new Point(50,50))
|
||||||
|
.attr('data-scale', 0.5)
|
||||||
|
.attr('data-rotate', 180)
|
||||||
|
// highlight-end
|
||||||
|
|
||||||
|
// prevent clipping
|
||||||
|
paths.demo = new Path()
|
||||||
|
.move(new Point(0,0))
|
||||||
|
.move(new Point(100,100))
|
||||||
|
|
||||||
|
return part
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
</Example>
|
||||||
|
|
||||||
You can scale and rotate a snippet by setting the `data-scale` and `data-rotate` attributes respectively.
|
You can scale and rotate a snippet by setting the `data-scale` and `data-rotate` attributes respectively.
|
||||||
|
|
||||||
- **data-scale** : Either a single scale factor, or a set of 2 scale factors for the X and Y axis respectively. See [the SVG scale transform](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform#Scale) for details.
|
- **data-scale** : Either a single scale factor, or a set of 2 scale factors
|
||||||
- **data-rotate**: A rotation in degrees. The center of the rotation will be the snippet's anchor point
|
for the X and Y axis respectively. See [the SVG scale
|
||||||
|
transform](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform#Scale)
|
||||||
|
for details.
|
||||||
|
- **data-rotate**: A rotation in degrees. The center of the rotation will be
|
||||||
|
the snippet's anchor point
|
||||||
|
|
||||||
<Tip>
|
<Tip>
|
||||||
|
|
||||||
See [Using attributes](/howtos/code/attributes/) for details on how to set attributes.
|
See [Using attributes](/howtos/code/attributes/) for details on how to set attributes.
|
||||||
|
|
||||||
</Tip>
|
</Tip>
|
||||||
|
|
||||||
Below is an example of the available snippets, and the use of the `data-scale` and `data-rotate` attributes:
|
|
||||||
|
|
||||||
<Example pattern="rendertest" options_only="snippets">
|
|
||||||
Overview of available snippets
|
|
||||||
</Example>
|
|
||||||
|
|
|
@ -4,45 +4,37 @@ title: Adding text
|
||||||
|
|
||||||
SVG is pretty great, but its text handling leaves much to be desired.
|
SVG is pretty great, but its text handling leaves much to be desired.
|
||||||
|
|
||||||
To abstract away the intricacies of adding text to an SVG document,
|
To abstract away the intricacies of adding text to an SVG document, FreeSewing
|
||||||
FreeSewing lets you add text to patterns by adding it to the attributes
|
provides the [Point.addText()](/reference/api/point/addtext) and
|
||||||
of points and paths.
|
[Path.addText()](/reference/api/path/addtext) methods to let you add text to
|
||||||
|
points and paths.
|
||||||
|
|
||||||
All you have to do is set the `data-text` attribute to the text you want to add to the pattern:
|
<Example caption="An example of adding text" tutorial>
|
||||||
|
```design/src/part.mjs
|
||||||
|
function draftPart = ({
|
||||||
|
Point,
|
||||||
|
points,
|
||||||
|
Path,
|
||||||
|
paths,
|
||||||
|
part
|
||||||
|
}) {
|
||||||
|
|
||||||
```js
|
points.demo = new Point(70,10)
|
||||||
points.anchor = new Point(100, 25)
|
// highlight-start
|
||||||
.attr("data-text", "freesewingIsMadeByJoostDeCockAndContributors")
|
.addText('Text on a point', 'center')
|
||||||
.attr("data-text-class", "center");
|
// highlight-end
|
||||||
|
|
||||||
|
paths.demo = new Path()
|
||||||
|
.move(new Point(0,0))
|
||||||
|
.line(new Point(100, 40))
|
||||||
|
.addClass('note dotted stroke-sm')
|
||||||
|
// highlight-start
|
||||||
|
.addText('Text on a path', 'center')
|
||||||
|
// highlight-end
|
||||||
|
|
||||||
|
|
||||||
|
return part
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
<Example part="point_attr">Text inserted in a FreeSewing pattern</Example>
|
|
||||||
|
|
||||||
<Note>
|
|
||||||
|
|
||||||
You may have noticed that the text we inserted isn't the text that's shown.
|
|
||||||
That is because, in line with our [best practices](/guides/best-practices) we allow translation of
|
|
||||||
our pattern by inserting a key that is used to lookup the string in the language
|
|
||||||
of the pattern, using [the i18n plugin](/reference/plugins/i18n).
|
|
||||||
|
|
||||||
</Note>
|
|
||||||
|
|
||||||
You can use the same approach to add text to a path:
|
|
||||||
|
|
||||||
```js
|
|
||||||
points.B = new Point(10, 50);
|
|
||||||
points.BCp2 = new Point(40, 10);
|
|
||||||
points.C = new Point(90, 30);
|
|
||||||
points.CCp1 = new Point(50, 90);
|
|
||||||
|
|
||||||
paths.example = new Path()
|
|
||||||
.move(points.B)
|
|
||||||
.curve(points.BCp2, points.CCp1, points.C)
|
|
||||||
.attr("class", "canvas")
|
|
||||||
.attr("data-text", "freesewingIsMadeByJoostDeCockAndContributors")
|
|
||||||
.attr("data-text-class", "text-xs center");
|
|
||||||
```
|
|
||||||
|
|
||||||
<Example part="path_attr">
|
|
||||||
Text on a path
|
|
||||||
</Example>
|
</Example>
|
||||||
|
```
|
||||||
|
|
37
markdown/dev/howtos/code/after/en.md
Normal file
37
markdown/dev/howtos/code/after/en.md
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
---
|
||||||
|
title: Part dependencies
|
||||||
|
---
|
||||||
|
|
||||||
|
Part dependencies control the order in which parts are drafted. FreeSewing will
|
||||||
|
make sure to draft all of a part's dependencies before drafting the part
|
||||||
|
itself.
|
||||||
|
|
||||||
|
<Warning compact>
|
||||||
|
Do not confuse this with [part inheritance](/howtos/code/from).
|
||||||
|
</Warning>
|
||||||
|
|
||||||
|
Part dependencies are configured with [the `after`
|
||||||
|
keyword](/reference/api/part/config/dependencies#after). Let's look at an
|
||||||
|
example:
|
||||||
|
|
||||||
|
```js
|
||||||
|
// highlight-start
|
||||||
|
import { otherPart } from './otherpart.mjs'
|
||||||
|
// highlight-end
|
||||||
|
|
||||||
|
export const myPart = {
|
||||||
|
name: 'example.myPart',
|
||||||
|
// highlight-start
|
||||||
|
after: otherPart,
|
||||||
|
// highlight-end
|
||||||
|
draft: function ({ part }) {
|
||||||
|
// Design part here
|
||||||
|
return part
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
<Tip>
|
||||||
|
Refer to [the part documentation on
|
||||||
|
dependencies](/reference/api/part/config/dependencies) for all details.
|
||||||
|
</Tip>
|
|
@ -1,11 +1,51 @@
|
||||||
---
|
---
|
||||||
title: Using attributes
|
title: Using attributes
|
||||||
for: developers
|
|
||||||
about: Show s you have to use attributes on points, paths, and snippets
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Points, Paths, and Snippets all have [attributes](/reference/api/attributes/) that you can use to
|
Points, Paths, and Snippets all have [attributes](/reference/api/attributes/)
|
||||||
influence how they behave.
|
that you can use to influence how they behave.
|
||||||
|
|
||||||
|
Under the hood, text, css classes, and even circles are all set in attributes.
|
||||||
|
There are plenty of higher-level helper methods available, but knowing how to
|
||||||
|
manipulate attributes is useful in case you want to accomplish something for
|
||||||
|
which there is no higher-level helper method.
|
||||||
|
|
||||||
|
Let's use an example to see the different ways we can assign a css class:
|
||||||
|
|
||||||
|
<Example caption="Various ways to set attributes on a point">
|
||||||
|
```mjs
|
||||||
|
({ points, Point, paths, Path, part }) => {
|
||||||
|
/*
|
||||||
|
* Via the high-level Point.addText method
|
||||||
|
*/
|
||||||
|
points.a = new Point(0,0)
|
||||||
|
.addText('I am bold and colorful', 'bold fill-note')
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Via the lower-level Point.attr method
|
||||||
|
*/
|
||||||
|
points.b = new Point(0,10)
|
||||||
|
.attr('data-text', 'I am bold and colorful')
|
||||||
|
.attr('data-text-class', 'bold fill-lining')
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Via low-level access to the attributes property
|
||||||
|
*/
|
||||||
|
points.c = new Point(0,20)
|
||||||
|
points.c.attributes.add('data-text', 'I am bold and colorful')
|
||||||
|
points.c.attributes.add('data-text-class', 'bold fill-contrast')
|
||||||
|
|
||||||
|
// Prevent clipping
|
||||||
|
paths.diag = new Path()
|
||||||
|
.move(new Point(-10,-5))
|
||||||
|
.move(new Point(80,25))
|
||||||
|
|
||||||
|
return part
|
||||||
|
}
|
||||||
|
```
|
||||||
|
</Example>
|
||||||
|
|
||||||
|
kEven though there are helpers methods available for them.
|
||||||
|
|
||||||
A common scenario is to apply CSS classes to style a path:
|
A common scenario is to apply CSS classes to style a path:
|
||||||
|
|
||||||
|
|
|
@ -4,39 +4,40 @@ for: developers
|
||||||
about: Shows you how to create a new design
|
about: Shows you how to create a new design
|
||||||
---
|
---
|
||||||
|
|
||||||
To create a new pattern, call `new freesewing.Design()`.
|
When creating a new design, you have two options:
|
||||||
It takes your pattern configuration,
|
|
||||||
and any plugins you want to load as parameters.
|
|
||||||
|
|
||||||
For example, if we were creating a new pattern called `Sorcha`:
|
- Create it in a stand-along development environment
|
||||||
|
- Create it inside (your fork of ) the FreeSewing monorepo
|
||||||
|
|
||||||
```js
|
If you are unsure what to pick, go with the standalong development environment.
|
||||||
import freesewing from "@freesewing/core"
|
It is the best choice for people new to FreeSewing.
|
||||||
import plugins from "@freesewing/plugin-bundle"
|
|
||||||
import config from "../config"
|
|
||||||
|
|
||||||
// Create new design
|
Working inside the monorepo is the preferred way of regular contributors, but
|
||||||
const Sorcha = new freesewing.Design(config, plugins)
|
if you were a regular contributor, you would probably already know this. So
|
||||||
|
when in doubt, go stand-alone. You can always change track later.
|
||||||
|
|
||||||
|
## Stand-alone
|
||||||
|
|
||||||
|
To setup the standalong development environment, you need NodeJS 16 or higher.
|
||||||
|
Then run:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npx @freesewing/new-design@next
|
||||||
```
|
```
|
||||||
|
|
||||||
This method does not return a `Design` object. Instead it returns
|
This command will setup FreeSewing's stand-alone development environment.
|
||||||
a constructor method for your pattern.
|
|
||||||
|
|
||||||
When importing your pattern, it is itself a constructor:
|
## Work inside the monorepo
|
||||||
|
|
||||||
```js
|
First, [fork our monorepo](https://github.com/freesewing/freesewing/fork). Then run:
|
||||||
import Sorcha from "@freesewing/sorcha"
|
|
||||||
|
|
||||||
// Sorcha is a constructor for your pattern.
|
```sh
|
||||||
let pattern = new Sorcha()
|
git clone <url to your fork>
|
||||||
|
cd freesewing
|
||||||
|
yarn kickstart
|
||||||
|
yarn new design
|
||||||
```
|
```
|
||||||
|
|
||||||
<Tip>
|
These commands will clone your fork of the
|
||||||
|
[freesewing/freesewing](https://github.com/freesewing/freesewing) repository on
|
||||||
##### Design() is a super-constructor
|
Github and set it up for development.
|
||||||
|
|
||||||
Constructors are functions you can call with `new` to create an object.
|
|
||||||
As `freesewing.Design()` returns a constructor, you can think of it
|
|
||||||
as a super-constructor.
|
|
||||||
|
|
||||||
</Tip>
|
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
---
|
|
||||||
title: Part dependencies
|
|
||||||
for: developers
|
|
||||||
about: Shows you how to create dependencies between pattern parts
|
|
||||||
---
|
|
||||||
|
|
||||||
Part dependencies are set in the [pattern configuration](/reference/api/config), and
|
|
||||||
control the order in which parts are drawn. FreeSewing will make sure
|
|
||||||
that before drafting a part, it will first draft all its dependencies.
|
|
||||||
|
|
||||||
Let's look at an example:
|
|
||||||
|
|
||||||
```js
|
|
||||||
dependencies: {
|
|
||||||
front: "base",
|
|
||||||
back: "base",
|
|
||||||
sleeve: ["front", "back"]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
This could be from a T-shirt pattern where the `front` and `back` patterns are very similar,
|
|
||||||
so they both are inheriting a `base` part.
|
|
||||||
In addition, the `sleeve` part needs to be drafted after the `front` and `back` part because
|
|
||||||
in `front` and `back` we store the length of the armhole seam in the [store](/reference/api/store) and
|
|
||||||
we need that info to fit the sleevecap to the armhole.
|
|
||||||
|
|
||||||
Now if a user requests to draft only the `sleeve` part, FreeSewing will still draft:
|
|
||||||
|
|
||||||
- First the `base` part
|
|
||||||
- Then the `front` and `back` parts
|
|
||||||
- Finally the `sleeve` part
|
|
||||||
|
|
||||||
but it will only render the `sleeve` part, as that's the only thing the user requested.
|
|
||||||
|
|
||||||
<Note>
|
|
||||||
|
|
||||||
For inheriting parts, please refer to [part inheritance](/howtos/code/inject/).
|
|
||||||
|
|
||||||
</Note>
|
|
|
@ -2,21 +2,44 @@
|
||||||
title: Drawing circles
|
title: Drawing circles
|
||||||
---
|
---
|
||||||
|
|
||||||
Real circles are rarely used in pattern design, and they are not part of the SVG path specification,
|
Real circles are rarely used in pattern design, and they are not part of the
|
||||||
but rather a different SVG element.
|
SVG path specification, but rather a different SVG element.
|
||||||
|
|
||||||
Still, if you want a circle, you can draw one by setting a Point's `data-circle` attribute
|
Still, if you want a circle, you can draw one by calling
|
||||||
to the radius of the circle you want to draw.
|
[`Point.addCircle()`](/reference/api/point/addcircle):
|
||||||
|
|
||||||
In addition, all attributes that have a `data-circle-` prefix will apply to the circle, rather than the point.
|
<Example caption="An example of adding a path" tutorial>
|
||||||
|
```design/src/part.mjs
|
||||||
|
function draftPart = ({
|
||||||
|
Point,
|
||||||
|
points,
|
||||||
|
Path,
|
||||||
|
paths,
|
||||||
|
part
|
||||||
|
}) {
|
||||||
|
|
||||||
Practically, you will probably want to use
|
points.anchor = new Point(0,0)
|
||||||
the [Point.addCircle()](/reference/api/point/adcircle) which does all of this for you behind the scenes:
|
// highlight-start
|
||||||
|
.addCircle(5, 'lining dotted')
|
||||||
|
.addCircle(10, 'note dashed ')
|
||||||
|
.addCircle(15, 'facing lashed')
|
||||||
|
.addCircle(20, 'interfacing')
|
||||||
|
// highlight-end
|
||||||
|
|
||||||
<Example part="point_addcircle">
|
// Prevent clipping
|
||||||
Examples of circles drawn on a pattern
|
paths.demo = new Path()
|
||||||
|
.move(new Point(-20,-20))
|
||||||
|
.move(new Point(20,20))
|
||||||
|
|
||||||
|
return part
|
||||||
|
}
|
||||||
|
```
|
||||||
</Example>
|
</Example>
|
||||||
|
|
||||||
|
<Warning>
|
||||||
|
Circles are not taken into account when calculating the part's boundary.
|
||||||
|
</Warning>
|
||||||
|
|
||||||
<Comment by="joost">
|
<Comment by="joost">
|
||||||
##### How multiple circles are implemented
|
##### How multiple circles are implemented
|
||||||
|
|
||||||
|
@ -45,3 +68,4 @@ While this is probably what you'd intuitively expect, it is somewhat inconsisten
|
||||||
other attributes are rendered, so I felt it was best to point it out explicitly.
|
other attributes are rendered, so I felt it was best to point it out explicitly.
|
||||||
|
|
||||||
</Comment>
|
</Comment>
|
||||||
|
|
||||||
|
|
|
@ -1,147 +0,0 @@
|
||||||
---
|
|
||||||
title: Create a new design based on an existing design
|
|
||||||
---
|
|
||||||
|
|
||||||
<Note>
|
|
||||||
|
|
||||||
##### See this example in our source code
|
|
||||||
|
|
||||||
- [designs/aaron/config/index.js](https://github.com/freesewing/freesewing/blob/3ca5d0edfe54c7ac20aaf3af2f3544aee72f9b99/designs/aaron/config/index.js#L36)
|
|
||||||
- [designs/aaron/src/index.js](https://github.com/freesewing/freesewing/blob/3ca5d0edfe54c7ac20aaf3af2f3544aee72f9b99/designs/aaron/src/index.js#L2)
|
|
||||||
- [designs/carlita/src/index.js](https://github.com/freesewing/freesewing/blob/3ca5d0edfe54c7ac20aaf3af2f3544aee72f9b99/designs/carlita/src/index.js#L25)
|
|
||||||
|
|
||||||
</Note>
|
|
||||||
|
|
||||||
## Setup
|
|
||||||
|
|
||||||
To be able to extend existing patterns, you will have to access them on your local machine. There are two ways to do this:
|
|
||||||
|
|
||||||
- add needed dependencies when using `npx @freesewing/new-design`
|
|
||||||
- create your new pattern in a clone of the [freesewing monorepo](https://github.com/freesewing/freesewing)
|
|
||||||
|
|
||||||
### When using `npx @freesewing/new-design`
|
|
||||||
|
|
||||||
If you want to use one of our blocks, you can simply pick that option when you run `npx @freesewing/new-design`.
|
|
||||||
Doing so will set everything up for you, so you won't have to worry about a thing.
|
|
||||||
|
|
||||||
If you want to extend an existing design, you'll have to do some work yourself.
|
|
||||||
|
|
||||||
#### Start from scratch
|
|
||||||
|
|
||||||
First step is to spin up the development environment. Pick _from scratch_ when prompted:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx @freesewing/new-design
|
|
||||||
```
|
|
||||||
|
|
||||||
### Install dependencies
|
|
||||||
|
|
||||||
Let's assume you want to extend **Simon**. You will first need to install it as a dependency.
|
|
||||||
We also need to install **Brian** since Simon is based on Brian:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm install --save @freesewing/simon @freesewing/brian
|
|
||||||
```
|
|
||||||
|
|
||||||
This will install both Simon and Brian as a dependency, which you can then access in your pattern.
|
|
||||||
|
|
||||||
<Tip>
|
|
||||||
If the design you extend relies on a design you did not install, error messages will tell you what you are missing
|
|
||||||
</Tip>
|
|
||||||
|
|
||||||
### Import your dependencies
|
|
||||||
|
|
||||||
<Fixme>Complete this documentation</Fixme>
|
|
||||||
|
|
||||||
### Using the freesewing monorepo
|
|
||||||
|
|
||||||
You can use the power of robots to install the needed dependencies if you work in a clone of the [freesewing monorepo](https://github.com/freesewing/freesewing).
|
|
||||||
|
|
||||||
- First, clone the monorepo (or your fork of it) to your local machine.
|
|
||||||
- If you haven't already, now is also a good time to create a feature branch so that you don't work directly in the `develop`-branch of the git-repository: `git checkout -b mycoolnewpattern` (adjust name accordingly).
|
|
||||||
- Go to the root and run `yarn kickstart`. This will take a while, so grab a coffee and come back later.
|
|
||||||
- Once that is done, edit the file `config/descriptions.yaml` to include the name and description of your new pattern (take care to start the description with `A FreeSewing pattern`).
|
|
||||||
- Create a folder for your new pattern in `packages`.
|
|
||||||
- Run `yarn reconfigure`. This will read the changes in `config/descriptions.yaml` and create the needed files in your new folder.
|
|
||||||
- You can now start the actual pattern design work (i.e. editing and adding `src` and `config` files for your pattern.
|
|
||||||
- For dependencies, configure them in `config/dependencies.yaml`.
|
|
||||||
- Run `yarn reconfigure` again, and the magic will make sure that your `package.json` is updated accordingly.
|
|
||||||
- You can set yourself as an author in `config/exceptions.yaml`, and - you guessed it - run `yarn reconfigure` again.
|
|
||||||
- To spin up the development environment, you also need to run `npm install` (or `yarn install`) in the `example`-folder of any pattern you want to work on. (This is because the neccessary `node_modules`-folder is excluded from the git-repository.)
|
|
||||||
|
|
||||||
Now you can work on extending existing patterns into something new and exciting. And the best part about using this method is that making a pull request will be much easier once you're done developing your new pattern.
|
|
||||||
|
|
||||||
## Examples
|
|
||||||
|
|
||||||
The example below is from Aaron, which is based on Brian.
|
|
||||||
|
|
||||||
Brian has a part called `base` that is hidden by default.
|
|
||||||
We will use this part as a dependency, and also hide it.
|
|
||||||
|
|
||||||
This is what it looks like in the Aaron config file:
|
|
||||||
|
|
||||||
```js
|
|
||||||
dependencies: {
|
|
||||||
front: 'base',
|
|
||||||
back: 'front'
|
|
||||||
},
|
|
||||||
inject: {
|
|
||||||
front: 'base',
|
|
||||||
back: 'front'
|
|
||||||
},
|
|
||||||
hide: ['base'],
|
|
||||||
```
|
|
||||||
|
|
||||||
And here is the code:
|
|
||||||
|
|
||||||
```js
|
|
||||||
import freesewing from '@freesewing/core'
|
|
||||||
import Brian from '@freesewing/brian'
|
|
||||||
import plugins from '@freesewing/plugin-bundle'
|
|
||||||
import config from '../config'
|
|
||||||
// Parts
|
|
||||||
import draftBack from './back'
|
|
||||||
import draftFront from './front'
|
|
||||||
|
|
||||||
// Create design
|
|
||||||
const Pattern = new freesewing.Design(config, plugins)
|
|
||||||
|
|
||||||
// Attach draft methods to prototype
|
|
||||||
Pattern.prototype.draftBase = function(part) {
|
|
||||||
// Getting the base part from Brian
|
|
||||||
return new Brian(this.settings).draftBase(part)
|
|
||||||
}
|
|
||||||
Pattern.prototype.draftFront = part => draftFront(part)
|
|
||||||
Pattern.prototype.draftBack = part => draftBack(part)
|
|
||||||
|
|
||||||
export default Pattern
|
|
||||||
```
|
|
||||||
|
|
||||||
If you have a lot of parts to inherit, you can create a loop like in this
|
|
||||||
example from Carlita:
|
|
||||||
|
|
||||||
```js
|
|
||||||
// Attach draft methods from Carlton to prototype
|
|
||||||
for (let m of [
|
|
||||||
'draftBack',
|
|
||||||
'draftTail',
|
|
||||||
'draftTopSleeve',
|
|
||||||
'draftUnderSleeve',
|
|
||||||
'draftBelt',
|
|
||||||
'draftCollarStand',
|
|
||||||
'draftCollar',
|
|
||||||
'draftCuffFacing',
|
|
||||||
'draftPocket',
|
|
||||||
'draftPocketFlap',
|
|
||||||
'draftPocketLining',
|
|
||||||
'draftChestPocketWelt',
|
|
||||||
'draftChestPocketBag',
|
|
||||||
'draftInnerPocketWelt',
|
|
||||||
'draftInnerPocketBag',
|
|
||||||
'draftInnerPocketTab'
|
|
||||||
]) {
|
|
||||||
Pattern.prototype[m] = function(part) {
|
|
||||||
return new Carlton(this.settings)[m](part)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
36
markdown/dev/howtos/code/from/en.md
Normal file
36
markdown/dev/howtos/code/from/en.md
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
---
|
||||||
|
title: Part inheritance
|
||||||
|
---
|
||||||
|
|
||||||
|
Part inheritance means that rather than start your part from a blank slate, your starting point is another part.
|
||||||
|
You will _inherit_ all its points, paths, and snippets, hence the name.
|
||||||
|
|
||||||
|
<Warning compact>
|
||||||
|
Do not confuse this with [part dependencies](/howtos/code/after).
|
||||||
|
</Warning>
|
||||||
|
|
||||||
|
Part inheritance is configured with [the `from`
|
||||||
|
keyword](/reference/api/part/config/dependencies#from). Let's look at an
|
||||||
|
example:
|
||||||
|
|
||||||
|
```js
|
||||||
|
// highlight-start
|
||||||
|
import { front as brianFront } from '@freesewing/brian'
|
||||||
|
// highlight-end
|
||||||
|
|
||||||
|
export const front = {
|
||||||
|
name: 'example.front',
|
||||||
|
// highlight-start
|
||||||
|
from: brianFront,
|
||||||
|
// highlight-end
|
||||||
|
draft: function ({ part }) {
|
||||||
|
// Design part here
|
||||||
|
return part
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
<Tip>
|
||||||
|
Refer to [the part documentation on
|
||||||
|
dependencies](/reference/api/part/config/dependencies) for all details.
|
||||||
|
</Tip>
|
|
@ -1,22 +1,30 @@
|
||||||
---
|
---
|
||||||
title: Hide paths from an inherited part
|
title: Hide ore remove paths from an inherited part
|
||||||
for: developers
|
|
||||||
about: When you inherit a part, it comes with a bunch of paths. Here'show to hide them
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<Note>
|
To hide remove paths from an inherited part, iterate over the `paths` object
|
||||||
|
and call `Path.hide()` on all entries:
|
||||||
|
|
||||||
##### See this example in our source code
|
```mjs
|
||||||
|
for (const i in paths) paths[i].hide()
|
||||||
- [designs/aaron/src/front.js](https://github.com/freesewing/freesewing/blob/3ca5d0edfe54c7ac20aaf3af2f3544aee72f9b99/designs/aaron/src/front.js#L22)
|
|
||||||
|
|
||||||
</Note>
|
|
||||||
|
|
||||||
The example below is from Aaron which inherits from Brian.
|
|
||||||
|
|
||||||
We iterate over the paths and set their render property to false.
|
|
||||||
|
|
||||||
```js
|
|
||||||
// Hide Brian paths
|
|
||||||
for (let key of Object.keys(paths)) paths[key].render = false
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
To outright remove the paths all together, delete them:
|
||||||
|
|
||||||
|
```mjs
|
||||||
|
for (const i in paths) delete paths[i]
|
||||||
|
```
|
||||||
|
|
||||||
|
<Warning>
|
||||||
|
Do __not__ replace the `path` object:
|
||||||
|
|
||||||
|
```mjs
|
||||||
|
paths = {}
|
||||||
|
```
|
||||||
|
|
||||||
|
as the `paths` object is more than a pojo (plain old javascript object)
|
||||||
|
</Warning>
|
||||||
|
|
||||||
|
<Tip>
|
||||||
|
You can use the same strategy for hiding or removing points or snippets.
|
||||||
|
</Tip>
|
||||||
|
|
|
@ -1,52 +0,0 @@
|
||||||
---
|
|
||||||
title: Design inheritance
|
|
||||||
for: developers
|
|
||||||
about: Shows how you can use one design as the basis for another
|
|
||||||
---
|
|
||||||
|
|
||||||
If your pattern is based on, or extending, another pattern (some of) your
|
|
||||||
pattern parts will need to be drafted by the parent pattern.
|
|
||||||
|
|
||||||
In such a case, rather than return our own draft method for the part, you
|
|
||||||
should instantiate the parent pattern, and return its part draft method:
|
|
||||||
|
|
||||||
```js
|
|
||||||
import freesewing from "@freesewing/core";
|
|
||||||
import Brian from "@freesewing/brian";
|
|
||||||
import plugins from "@freesewing/plugin-bundle";
|
|
||||||
import config from "../config";
|
|
||||||
// Parts
|
|
||||||
import draftBack from "./back";
|
|
||||||
|
|
||||||
// Create new design
|
|
||||||
const Sorcha = new freesewing.Design(config, plugins);
|
|
||||||
|
|
||||||
// Attach our own draft method to the prototype
|
|
||||||
Sorcha.prototype.draftBack = part => draftBack(part);
|
|
||||||
|
|
||||||
// Attach the inherited draft method to the prototype
|
|
||||||
Sorcha.prototype.draftBase = function(part) {
|
|
||||||
// Getting the base part from Brian
|
|
||||||
return new Brian(this.settings).draftBase(part);
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
<Warning>
|
|
||||||
|
|
||||||
Because we're using the `this` keyword here, you cannot use the arrow notation.
|
|
||||||
|
|
||||||
</Warning>
|
|
||||||
|
|
||||||
## Configuration
|
|
||||||
|
|
||||||
The inherited pattern parts will use the configuration of your pattern.
|
|
||||||
You must take care to make sure that
|
|
||||||
your pattern has all the options the parent pattern requires.
|
|
||||||
|
|
||||||
For example, if you inherit from a pattern that has a `chestEase` option, you will
|
|
||||||
need to add that option to your own patter, because the inherited parts will depend on it.
|
|
||||||
|
|
||||||
## Dependencies
|
|
||||||
|
|
||||||
When extending a pattern, you should add it as a peer dependency, rather than a regular dependency.
|
|
||||||
Doing so will avoid that the parent pattern will get bundled with your own pattern.
|
|
|
@ -1,34 +0,0 @@
|
||||||
---
|
|
||||||
title: Part inheritance
|
|
||||||
for: developers
|
|
||||||
about: Shows how you can use one part of your pattern as the basis for another
|
|
||||||
---
|
|
||||||
|
|
||||||
Part inheritance within your own pattern is handled via the `inject` settings in
|
|
||||||
the [pattern configuration](/reference/api/config/). Here is a simple example:
|
|
||||||
|
|
||||||
```js
|
|
||||||
inject: {
|
|
||||||
front: "base",
|
|
||||||
back: "base",
|
|
||||||
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The `front` and `back` parts will be _injected_ with the `base` part. As a result, both
|
|
||||||
the `front` and `back` parts will be instantiated with a cloned copy of all the points, paths,
|
|
||||||
and snippets of the `base` part.
|
|
||||||
|
|
||||||
This is a common design pattern where one part builds on another. In our example, we can imagine
|
|
||||||
a T-shirt pattern where the front and back are rather similar, apart from the neckline.
|
|
||||||
So rather than repeating ourselves, we draft a `base` part and inject that in the `front` and
|
|
||||||
`back` parts.
|
|
||||||
|
|
||||||
Using `inject` will cause FreeSewing to always draft the injected part prior to
|
|
||||||
drafting the part it gets injected to. It will, in other words, influece the draft order.
|
|
||||||
|
|
||||||
<Note>
|
|
||||||
|
|
||||||
For inheriting parts from other patterns, please refer to [Design inheritance](/howtos/code/inheritance/).
|
|
||||||
|
|
||||||
</Note>
|
|
|
@ -5,13 +5,7 @@ about: Shows how you can use macros within your pattern
|
||||||
---
|
---
|
||||||
|
|
||||||
Macros are a way to facilitate pattern design by bundling a bunch of individual actions
|
Macros are a way to facilitate pattern design by bundling a bunch of individual actions
|
||||||
into a little routine.
|
into a little routine. Macros are provided by [plugins](/reference/plugins/).
|
||||||
|
|
||||||
Macros are provided by [plugins](/reference/plugins/). Here are some examples:
|
|
||||||
|
|
||||||
<Example pattern="rendertest" options_only="macros">
|
|
||||||
Some examples of macros
|
|
||||||
</Example>
|
|
||||||
|
|
||||||
Refer to the [macros documentation](/reference/api/macros/) for details on how to use macros,
|
Refer to the [macros documentation](/reference/api/macros/) for details on how to use macros,
|
||||||
and the [plugins](/reference/plugins/) documentation for info on how to create your
|
and the [plugins](/reference/plugins/) documentation for info on how to create your
|
||||||
|
|
|
@ -1,18 +1,7 @@
|
||||||
---
|
---
|
||||||
title: Share dimensions between pattern parts
|
title: Share dimensions between pattern parts
|
||||||
for: developers
|
|
||||||
about: Shows how to share dimensions between similar pattern parts
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<Note>
|
|
||||||
|
|
||||||
##### See this example in our source code
|
|
||||||
|
|
||||||
- [designs/aaron/src/shared.js](https://github.com/freesewing/freesewing/blob/3ca5d0edfe54c7ac20aaf3af2f3544aee72f9b99/designs/aaron/src/shared.js)
|
|
||||||
- [designs/aaron/src/front.js](https://github.com/freesewing/freesewing/blob/3ca5d0edfe54c7ac20aaf3af2f3544aee72f9b99/designs/aaron/src/front.js#L160)
|
|
||||||
|
|
||||||
</Note>
|
|
||||||
|
|
||||||
When you have different pattern parts that look similar -- like the front
|
When you have different pattern parts that look similar -- like the front
|
||||||
and back of a garment -- you may find that there's a lot of dimensions
|
and back of a garment -- you may find that there's a lot of dimensions
|
||||||
shared between them.
|
shared between them.
|
||||||
|
@ -20,7 +9,7 @@ shared between them.
|
||||||
The example below is from Aaron where dimensions are shared between
|
The example below is from Aaron where dimensions are shared between
|
||||||
the back and front part.
|
the back and front part.
|
||||||
|
|
||||||
Aaron has a file called `shared.js` that looks like this:
|
Aaron has a file called `shared.mjs` that looks like this:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
export function dimensions(macro, points, sa) {
|
export function dimensions(macro, points, sa) {
|
||||||
|
@ -33,7 +22,8 @@ export function dimensions(macro, points, sa) {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
In both `front.js` and `back.js` we use this code to add these shared dimensions:
|
In both `front.mjs` and `back.mjs` we use this code to add these shared
|
||||||
|
dimensions:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import { dimensions } from './shared'
|
import { dimensions } from './shared'
|
||||||
|
@ -42,13 +32,6 @@ import { dimensions } from './shared'
|
||||||
|
|
||||||
if (paperless) {
|
if (paperless) {
|
||||||
dimensions(macro, points, sa)
|
dimensions(macro, points, sa)
|
||||||
// ... specific dimensions
|
// ... dimensions specific to this part
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
<Note>
|
|
||||||
|
|
||||||
Since our shared dimension method is a so-called _named export_ we need to
|
|
||||||
import it with the syntax you see above.
|
|
||||||
|
|
||||||
</Note>
|
|
||||||
|
|
|
@ -1,40 +0,0 @@
|
||||||
---
|
|
||||||
title: Using shorthand
|
|
||||||
for: developers
|
|
||||||
about: Shows you how to use our shorthand method and notation
|
|
||||||
---
|
|
||||||
|
|
||||||
The [Part.shorthand()](/reference/api/part/shorthand) method will become your best friend.
|
|
||||||
|
|
||||||
By using [object destructuring](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Object_destructuring) you'll get access to a bunch
|
|
||||||
of handy variables to make your code more concise and readable.
|
|
||||||
|
|
||||||
[Part.shorthand()](/reference/api/part/shorthand) provides a lot of things, and you typically
|
|
||||||
don't need all of them, but here's everything it has to offer:
|
|
||||||
|
|
||||||
```js
|
|
||||||
const {
|
|
||||||
options, // Pattern options
|
|
||||||
measurements, // Model measurements
|
|
||||||
Point, // Point constructor
|
|
||||||
Path, // Path constructor
|
|
||||||
Snippet, // Snippet constructor
|
|
||||||
points, // Holds part points
|
|
||||||
paths, // Holds part paths
|
|
||||||
snippets, // Holds part snippets
|
|
||||||
store, // The store allows you to share data between parts
|
|
||||||
utils, // A collection of utilities
|
|
||||||
macro, // Method to call a macro
|
|
||||||
debug, // Method to log debug info
|
|
||||||
sa, // Requested seam allowance
|
|
||||||
final, // Whether to draft a complete pattern or not
|
|
||||||
paperless, // Whether to draft a paperless pattern or not
|
|
||||||
units, // Requested units
|
|
||||||
} = part.shorthand();
|
|
||||||
```
|
|
||||||
|
|
||||||
<Note>
|
|
||||||
|
|
||||||
Many examples throughout our documentation use shorthand notation.
|
|
||||||
|
|
||||||
</Note>
|
|
|
@ -1,33 +1,49 @@
|
||||||
---
|
---
|
||||||
title: Sharing data between parts
|
title: Sharing data between parts
|
||||||
for: developers
|
|
||||||
about: Shows how you use the pattern store to share data between parts
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Sometimes, you'll want to access data from one part into another part.
|
Sometimes, you'll want to access data from one part into another part. For
|
||||||
For example, you may store the length of the armhole in your front and back parts,
|
example, you may store the length of the armhole in your front and back parts,
|
||||||
and then read that value when drafting the sleeve so you can verify the sleeve fits the armhole.
|
and then read that value when drafting the sleeve so you can verify the sleeve
|
||||||
|
fits the armhole.
|
||||||
|
|
||||||
For this, you should use the [Store](/reference/api/store/), which is available via
|
For this, you should use the [Store](/reference/api/store/), which is available
|
||||||
the [shorthand](/howtos/code/shorthand/) call:
|
via _destructuring_ in your part's draft method.
|
||||||
|
|
||||||
```js
|
Setting a value in one part:
|
||||||
export default function(part) {
|
|
||||||
let { store } = part.shorthand();
|
|
||||||
store.set('hello', 'world');
|
|
||||||
|
|
||||||
return part();
|
```mjs
|
||||||
|
function draftPartA({
|
||||||
|
// highlight-start
|
||||||
|
store,
|
||||||
|
// highlight-end
|
||||||
|
part,
|
||||||
|
}) {
|
||||||
|
// highlight-start
|
||||||
|
store.set('hello', 'world')
|
||||||
|
// highlight-end
|
||||||
|
|
||||||
|
return part()
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
```js
|
Reading a value in another part:
|
||||||
export default function(part) {
|
|
||||||
let { store } = part.shorthand();
|
|
||||||
store.get('hello'); // Returns 'world'
|
|
||||||
|
|
||||||
return part();
|
```mjs
|
||||||
|
function draftPartB({
|
||||||
|
// highlight-start
|
||||||
|
store,
|
||||||
|
// highlight-end
|
||||||
|
part,
|
||||||
|
}) {
|
||||||
|
// highlight-start
|
||||||
|
const value = store.get('hello')
|
||||||
|
// value now contains 'world'
|
||||||
|
// highlight-end
|
||||||
|
|
||||||
|
return part()
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
In a case like this, the order in which parts are drafted becomes important, so you
|
In a case like this, the order in which parts are drafted becomes important, so you
|
||||||
should reflect that in the [pattern configuration](/reference/api/config/).
|
should reflect that in the [part dependencies](/howtos/code/after).
|
||||||
|
|
|
@ -1,29 +1,21 @@
|
||||||
---
|
---
|
||||||
title: Storing the seam length to use in another part
|
title: Storing the seam length to use in another part
|
||||||
for: developers
|
|
||||||
about: Shows how to store a seam length so you can true the seam of another part
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<Note>
|
|
||||||
|
|
||||||
##### See this example in our source code
|
|
||||||
|
|
||||||
- [designs/aaron/src/front.js](https://github.com/freesewing/freesewing/blob/3ca5d0edfe54c7ac20aaf3af2f3544aee72f9b99/designs/aaron/src/front.js#L103)
|
|
||||||
|
|
||||||
</Note>
|
|
||||||
|
|
||||||
Often when designing patterns, we need to _true a seam_ which means to make sure
|
Often when designing patterns, we need to _true a seam_ which means to make sure
|
||||||
that two parts that need to be joined together are the same distance.
|
that two parts that need to be joined together are the same distance.
|
||||||
|
|
||||||
The example below is from Aaron and stores the length of the armhole seam:
|
The example below is from Aaron and stores the length of the armhole seam:
|
||||||
|
|
||||||
```js
|
```mjs
|
||||||
// Store length of armhole and neck opening
|
// Store length of armhole and neck opening
|
||||||
store.set(
|
store.set(
|
||||||
'frontArmholeLength',
|
'frontArmholeLength',
|
||||||
new Path()
|
new Path()
|
||||||
.move(points.armhole)
|
.move(points.armhole)
|
||||||
.curve(points.armholeCp2, points.strapRightCp1, points.strapRight)
|
.curve(points.armholeCp2, points.strapRightCp1, points.strapRight)
|
||||||
.length()
|
.length()
|
||||||
)
|
)
|
||||||
|
// Seam length is now available in other parts via:
|
||||||
|
store.get('frontArmholeLength')
|
||||||
```
|
```
|
||||||
|
|
|
@ -14,41 +14,59 @@ To add linebreaks to text, you merely have to include them in your text.
|
||||||
When doing so, keep in mind that single-quoted strings in Javascript
|
When doing so, keep in mind that single-quoted strings in Javascript
|
||||||
will **not** pick up linebreaks.
|
will **not** pick up linebreaks.
|
||||||
|
|
||||||
```js
|
<Example caption="An example of whitespace in text">
|
||||||
points.example1.attr('data-text', 'this\nwill\nnot\nwork')
|
```design/src/part.mjs
|
||||||
points.example2.attr('data-text', "this\nwill\nwork")
|
function draftPart = ({
|
||||||
points.example2.attr('data-text', `this
|
Point,
|
||||||
will
|
points,
|
||||||
also
|
Path,
|
||||||
work`)
|
paths,
|
||||||
|
part
|
||||||
|
}) {
|
||||||
|
points.demo1 = new Point(10,20)
|
||||||
|
// highlight-start
|
||||||
|
.addText('this\nwill\nwork')
|
||||||
|
// highlight-end
|
||||||
|
points.demo2 = new Point(40,20)
|
||||||
|
// highlight-start
|
||||||
|
.addText("this\nwill\nalso\nwork")
|
||||||
|
// highlight-end
|
||||||
|
points.demo3 = new Point(70,20)
|
||||||
|
// highlight-start
|
||||||
|
.addText(`And
|
||||||
|
this
|
||||||
|
will
|
||||||
|
also
|
||||||
|
work`).attr('data-text-lineheight', 7)
|
||||||
|
// highlight-end
|
||||||
|
|
||||||
|
// Prevent clipping
|
||||||
|
paths.diag = new Path()
|
||||||
|
.move(new Point(0,10))
|
||||||
|
.move(new Point(90, 70))
|
||||||
|
|
||||||
|
return part
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
</Example>
|
||||||
|
|
||||||
<Tip>
|
<Tip>
|
||||||
|
You can control the lineheight by setting the `data-text-lineheight` attribute.
|
||||||
You can control the lineheight by setting the `data-text-lineheight` attribute:
|
|
||||||
|
|
||||||
```js
|
|
||||||
points.example2
|
|
||||||
.attr('data-text', "this\nwill\nwork")
|
|
||||||
.attr('data-text-lineheight', settings.scale * 8)
|
|
||||||
```
|
|
||||||
|
|
||||||
</Tip>
|
</Tip>
|
||||||
|
|
||||||
## Adding spaces to text
|
## Adding consecutive spaces to text
|
||||||
|
|
||||||
Adding a single space between two words is not a problem.
|
Adding a single space between two words is not a problem.
|
||||||
But what if you want to add a couple of spaces in a row?
|
But what if you want to add a couple of spaces in a row?
|
||||||
Both in HTML and SVG they will get collapsed into a single space.
|
Both in HTML and SVG they will get collapsed into a single space.
|
||||||
|
|
||||||
To get around that, use ` ` for space:
|
To get around that, use ` ` for space.
|
||||||
|
|
||||||
```js
|
```mjs
|
||||||
points.example.attr(
|
points.demo = new Point(0, 0)
|
||||||
'data-text',
|
// highlight-start
|
||||||
"far      apart"
|
.addText('far      apart')
|
||||||
)
|
// highlight-end
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Whether you're rendering to SVG or React, by using ` ` your spaces
|
|
||||||
will be properly rendered in both environments.
|
|
||||||
|
|
|
@ -74,6 +74,7 @@ const mdxLoader = async (language, site, slug, jargon) => {
|
||||||
aliases: {
|
aliases: {
|
||||||
javascript: [
|
javascript: [
|
||||||
'design/src/index.mjs',
|
'design/src/index.mjs',
|
||||||
|
'design/src/part.mjs',
|
||||||
'design/src/bib.mjs',
|
'design/src/bib.mjs',
|
||||||
'index.mjs',
|
'index.mjs',
|
||||||
'part.mjs',
|
'part.mjs',
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue