diff --git a/markdown/dev/howtos/code/accessing-measurements/en.md b/markdown/dev/howtos/code/accessing-measurements/en.md index dc6b0f5d2b1..cb480db37ad 100644 --- a/markdown/dev/howtos/code/accessing-measurements/en.md +++ b/markdown/dev/howtos/code/accessing-measurements/en.md @@ -1,18 +1,22 @@ --- 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 -the [shorthand](/howtos/code/shorthand/) call: +```design/src/part.mjs +function draftPart = ({ + // highlight-start + measurements, + // highlight-end + part +}) { -```js -const { measurements, options } = part.shorthand() + // Do something here -let sleeveBonus = measurements.shoulderToWrist * (1 + options.sleeveLengthBonus); + return part +} ``` diff --git a/markdown/dev/howtos/code/accessing-options/en.md b/markdown/dev/howtos/code/accessing-options/en.md index 0e2cf55070c..409b7ed2165 100644 --- a/markdown/dev/howtos/code/accessing-options/en.md +++ b/markdown/dev/howtos/code/accessing-options/en.md @@ -1,16 +1,26 @@ --- -title: Accessing user options -for: developers -about: Shows you how to access user options from inside your pattern +title: Accessing options --- -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 -the [shorthand](/howtos/code/shorthand/) call: +```design/src/part.mjs +function draftPart = ({ + // highlight-start + options, + // highlight-end + part +}) { -```js -const { measurements, options } = part.shorthand() + // Do something here -let sleeveBonus = measurements.shoulderToWrist * (1 + options.sleeveLengthBonus); + return part +} ``` + + + +Unlike measurements, options come with default values. + + diff --git a/markdown/dev/howtos/code/adding-instructions/en.md b/markdown/dev/howtos/code/adding-instructions/en.md deleted file mode 100644 index 0df0ce5a506..00000000000 --- a/markdown/dev/howtos/code/adding-instructions/en.md +++ /dev/null @@ -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 ---- - - - -##### 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) - - - -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') -``` - - - -Refer to [the sprinkle macro documentation](/reference/api/macros/sprinkle/) for details on how -to use this macro - - diff --git a/markdown/dev/howtos/code/adding-parts/en.md b/markdown/dev/howtos/code/adding-parts/en.md index 4016c48869f..aa3ef144cc4 100644 --- a/markdown/dev/howtos/code/adding-parts/en.md +++ b/markdown/dev/howtos/code/adding-parts/en.md @@ -1,42 +1,29 @@ --- title: Adding pattern parts -for: developers -about: Shows you how to add new parts to your pattern --- -Since the patterns parts are listed -in [the configuration file](/reference/api/config/), freesewing knows about -all the parts that belong to your pattern. +Parts can be added to the design add build time, by passing them to [the Design +constructor](/reference/api/design), or at runtime by calling +[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` -followed by the capitalized name of the pattern part. +## At build time -For example, if our pattern `Sorcha` has a part called `back`, you should -have a `draftBack` method. It's good practice to keep each part in its own -file, so create a file called `back.js`. Inside, you export your method -to draft this part: +```mjs +import { Design } from '@freesewing/core' +import { myPart } from './mypart.mjs' -```js -export default part => { - // Your part code here - - return part -} +const Sorcha = new Design({ + parts: [ myPart ] +}) ``` -Then, in your `index.js` file, you import this file, and attach the -method to your pattern's prototype: +## At run time -```js -import freesewing from "freesewing" -import plugins from "@freesewing/plugin-bundle" -import config from "../config" -// Parts -import draftBack from "./back" +```mjs +import { Aaron } from '@freesewing/aaron' +import { myRuntimePart } from './mypart.mjs' -// Create new design -const Sorcha = new freesewing.Design(config, plugins) - -// Attach to pattern prototype -Sorcha.prototype.draftBack = part => draftBack(part) +const pattern = new Aaron() +pattern.addPart(myRuntimePart) ``` diff --git a/markdown/dev/howtos/code/adding-paths/en.md b/markdown/dev/howtos/code/adding-paths/en.md index 07907710492..41e84cb75a7 100644 --- a/markdown/dev/howtos/code/adding-paths/en.md +++ b/markdown/dev/howtos/code/adding-paths/en.md @@ -1,22 +1,30 @@ --- 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, -`Path` contains the path constructor, while `paths` is a reference to `part.paths`, -which is where you should store your paths. +Paths should be stored in the `paths` key of the object passed to your part's +draft method. The contructor for paths is available in the `Path` key. You can +destructure them for easy access. -Things will now _just work_ when you do this: + +```design/src/part.mjs +function draftPart = ({ + Point, + // highlight-start + Path, + paths, + // highlight-end + part +}) { -```js -paths.example = new Path() + // highlight-start + paths.demo = new Path() + .move(new Point(0,0)) + .line(new Point(100,20)) + .addClass('lining lashed') + // highlight-end + + return part +} ``` - - - -The [Path API docs](/reference/api/path) list all the things you can do with a path object. - - + diff --git a/markdown/dev/howtos/code/adding-points/en.md b/markdown/dev/howtos/code/adding-points/en.md index 396f0a30848..dbf8f31df7d 100644 --- a/markdown/dev/howtos/code/adding-points/en.md +++ b/markdown/dev/howtos/code/adding-points/en.md @@ -1,21 +1,26 @@ --- title: Adding points -for: developers -about: Shows you how to add points to your pattern --- -After using the [shorthand](/howtos/code/shorthand/) call, -`Point` contains the point constructor, while `points` is a reference to `part.points`, -which is where you should store your points. +Points should be stored in the `points` key of the object passed to your part's +draft method. The contructor for points is available in the `Point` key. You +can destructure them for easy access. -Things will now _just work_ when you do this: + +```design/src/part.mjs +function draftPart = ({ + // highlight-start + Point, + points, + // highlight-end + part +}) { -```js -points.centerBack = new Point(0,0); + // highlight-start + points.demo = new Point(0,0).addText('hi') + // highlight-end + + return part +} ``` - - - -The [Point API docs](/reference/api/point/) list many ways to create a point. - - + diff --git a/markdown/dev/howtos/code/adding-snippets/en.md b/markdown/dev/howtos/code/adding-snippets/en.md index 46e882bef02..d6cadb9edd1 100644 --- a/markdown/dev/howtos/code/adding-snippets/en.md +++ b/markdown/dev/howtos/code/adding-snippets/en.md @@ -1,32 +1,51 @@ --- title: Adding snippets -for: developers -about: Shows you how to add snippets to your pattern --- -After using the [shorthand](/howtos/code/shorthand/) call, -`Snippet` contains the path constructor, while `snippets` is a reference to `part.snippets`, -which is where you should store your paths. +Snippets should be stored in the `snippets` key of the object passed to your part's +draft method. The contructor for snippets is available in the `Snippets` key. You can +destructure them for easy access. -Things will now _just work_ when you do this: + +```design/src/part.mjs +function draftPart = ({ + Point, + Path, + paths, + // highlight-start + Snippet, + snippets, + // highlight-end + part +}) { -```js -snippets.logo = new Snippet('logo', points.logoAnchor); + // highlight-start + 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 +} ``` + 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-rotate**: A rotation in degrees. The center of the rotation will be the snippet's anchor point +- **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-rotate**: A rotation in degrees. The center of the rotation will be + the snippet's anchor point See [Using attributes](/howtos/code/attributes/) for details on how to set attributes. - -Below is an example of the available snippets, and the use of the `data-scale` and `data-rotate` attributes: - - -Overview of available snippets - diff --git a/markdown/dev/howtos/code/adding-text/en.md b/markdown/dev/howtos/code/adding-text/en.md index cee40a90a52..a5a69308a10 100644 --- a/markdown/dev/howtos/code/adding-text/en.md +++ b/markdown/dev/howtos/code/adding-text/en.md @@ -4,45 +4,37 @@ title: Adding text 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, -FreeSewing lets you add text to patterns by adding it to the attributes -of points and paths. +To abstract away the intricacies of adding text to an SVG document, FreeSewing +provides the [Point.addText()](/reference/api/point/addtext) and +[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: + +```design/src/part.mjs +function draftPart = ({ + Point, + points, + Path, + paths, + part +}) { -```js -points.anchor = new Point(100, 25) - .attr("data-text", "freesewingIsMadeByJoostDeCockAndContributors") - .attr("data-text-class", "center"); + points.demo = new Point(70,10) + // highlight-start + .addText('Text on a point', '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 +} ``` - -Text inserted in a FreeSewing pattern - - - -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). - - - -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"); -``` - - -Text on a path +``` diff --git a/markdown/dev/howtos/code/after/en.md b/markdown/dev/howtos/code/after/en.md new file mode 100644 index 00000000000..551ab521f9b --- /dev/null +++ b/markdown/dev/howtos/code/after/en.md @@ -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. + + +Do not confuse this with [part inheritance](/howtos/code/from). + + +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 + } +} +``` + + +Refer to [the part documentation on +dependencies](/reference/api/part/config/dependencies) for all details. + diff --git a/markdown/dev/howtos/code/attributes/en.md b/markdown/dev/howtos/code/attributes/en.md index edcc753e528..2fe77bbbc73 100644 --- a/markdown/dev/howtos/code/attributes/en.md +++ b/markdown/dev/howtos/code/attributes/en.md @@ -1,11 +1,51 @@ --- 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 -influence how they behave. +Points, Paths, and Snippets all have [attributes](/reference/api/attributes/) +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: + + +```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 + } +``` + + +kEven though there are helpers methods available for them. A common scenario is to apply CSS classes to style a path: diff --git a/markdown/dev/howtos/code/create-new-design/en.md b/markdown/dev/howtos/code/create-new-design/en.md index 79e25926ac2..19d1027fa8d 100644 --- a/markdown/dev/howtos/code/create-new-design/en.md +++ b/markdown/dev/howtos/code/create-new-design/en.md @@ -4,39 +4,40 @@ for: developers about: Shows you how to create a new design --- -To create a new pattern, call `new freesewing.Design()`. -It takes your pattern configuration, -and any plugins you want to load as parameters. +When creating a new design, you have two options: -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 -import freesewing from "@freesewing/core" -import plugins from "@freesewing/plugin-bundle" -import config from "../config" +If you are unsure what to pick, go with the standalong development environment. +It is the best choice for people new to FreeSewing. -// Create new design -const Sorcha = new freesewing.Design(config, plugins) +Working inside the monorepo is the preferred way of regular contributors, but +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 -a constructor method for your pattern. +This command will setup FreeSewing's stand-alone development environment. -When importing your pattern, it is itself a constructor: +## Work inside the monorepo -```js -import Sorcha from "@freesewing/sorcha" +First, [fork our monorepo](https://github.com/freesewing/freesewing/fork). Then run: -// Sorcha is a constructor for your pattern. -let pattern = new Sorcha() +```sh +git clone +cd freesewing +yarn kickstart +yarn new design ``` - - -##### Design() is a super-constructor - -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. - - +These commands will clone your fork of the +[freesewing/freesewing](https://github.com/freesewing/freesewing) repository on +Github and set it up for development. diff --git a/markdown/dev/howtos/code/dependencies/en.md b/markdown/dev/howtos/code/dependencies/en.md deleted file mode 100644 index d5f0498e58b..00000000000 --- a/markdown/dev/howtos/code/dependencies/en.md +++ /dev/null @@ -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. - - - -For inheriting parts, please refer to [part inheritance](/howtos/code/inject/). - - diff --git a/markdown/dev/howtos/code/drawing-circles/en.md b/markdown/dev/howtos/code/drawing-circles/en.md index f75b14cc1c2..f2045e7641e 100644 --- a/markdown/dev/howtos/code/drawing-circles/en.md +++ b/markdown/dev/howtos/code/drawing-circles/en.md @@ -2,21 +2,44 @@ title: Drawing circles --- -Real circles are rarely used in pattern design, and they are not part of the SVG path specification, -but rather a different SVG element. +Real circles are rarely used in pattern design, and they are not part of the +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 -to the radius of the circle you want to draw. +Still, if you want a circle, you can draw one by calling +[`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. + +```design/src/part.mjs +function draftPart = ({ + Point, + points, + Path, + paths, + part +}) { -Practically, you will probably want to use -the [Point.addCircle()](/reference/api/point/adcircle) which does all of this for you behind the scenes: + points.anchor = new Point(0,0) + // highlight-start + .addCircle(5, 'lining dotted') + .addCircle(10, 'note dashed ') + .addCircle(15, 'facing lashed') + .addCircle(20, 'interfacing') + // highlight-end - -Examples of circles drawn on a pattern + // Prevent clipping + paths.demo = new Path() + .move(new Point(-20,-20)) + .move(new Point(20,20)) + + return part +} +``` + +Circles are not taken into account when calculating the part's boundary. + + ##### 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. + diff --git a/markdown/dev/howtos/code/extend-pattern/en.md b/markdown/dev/howtos/code/extend-pattern/en.md deleted file mode 100644 index 595b0a4b831..00000000000 --- a/markdown/dev/howtos/code/extend-pattern/en.md +++ /dev/null @@ -1,147 +0,0 @@ ---- -title: Create a new design based on an existing design ---- - - - -##### 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) - - - -## 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. - - -If the design you extend relies on a design you did not install, error messages will tell you what you are missing - - -### Import your dependencies - -Complete this documentation - -### 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) - } -} -``` diff --git a/markdown/dev/howtos/code/from/en.md b/markdown/dev/howtos/code/from/en.md new file mode 100644 index 00000000000..22688bfe4a8 --- /dev/null +++ b/markdown/dev/howtos/code/from/en.md @@ -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. + + +Do not confuse this with [part dependencies](/howtos/code/after). + + +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 + } +} +``` + + +Refer to [the part documentation on +dependencies](/reference/api/part/config/dependencies) for all details. + diff --git a/markdown/dev/howtos/code/hide-paths/en.md b/markdown/dev/howtos/code/hide-paths/en.md index 2a8c07b761a..9f3c2bcdb1f 100644 --- a/markdown/dev/howtos/code/hide-paths/en.md +++ b/markdown/dev/howtos/code/hide-paths/en.md @@ -1,22 +1,30 @@ --- -title: Hide 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 +title: Hide ore remove paths from an inherited part --- - +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 - -- [designs/aaron/src/front.js](https://github.com/freesewing/freesewing/blob/3ca5d0edfe54c7ac20aaf3af2f3544aee72f9b99/designs/aaron/src/front.js#L22) - - - -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 +```mjs +for (const i in paths) paths[i].hide() ``` + +To outright remove the paths all together, delete them: + +```mjs +for (const i in paths) delete paths[i] +``` + + +Do __not__ replace the `path` object: + +```mjs +paths = {} +``` + +as the `paths` object is more than a pojo (plain old javascript object) + + + +You can use the same strategy for hiding or removing points or snippets. + diff --git a/markdown/dev/howtos/code/inheritance/en.md b/markdown/dev/howtos/code/inheritance/en.md deleted file mode 100644 index 62df1f88824..00000000000 --- a/markdown/dev/howtos/code/inheritance/en.md +++ /dev/null @@ -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); -}; -``` - - - -Because we're using the `this` keyword here, you cannot use the arrow notation. - - - -## 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. diff --git a/markdown/dev/howtos/code/inject/en.md b/markdown/dev/howtos/code/inject/en.md deleted file mode 100644 index de84aa34b5d..00000000000 --- a/markdown/dev/howtos/code/inject/en.md +++ /dev/null @@ -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. - - - -For inheriting parts from other patterns, please refer to [Design inheritance](/howtos/code/inheritance/). - - diff --git a/markdown/dev/howtos/code/macros/en.md b/markdown/dev/howtos/code/macros/en.md index 067b54f3b86..83d0e9bde02 100644 --- a/markdown/dev/howtos/code/macros/en.md +++ b/markdown/dev/howtos/code/macros/en.md @@ -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 -into a little routine. - -Macros are provided by [plugins](/reference/plugins/). Here are some examples: - - -Some examples of macros - +into a little routine. Macros are provided by [plugins](/reference/plugins/). 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 diff --git a/markdown/dev/howtos/code/shared-dimensions/en.md b/markdown/dev/howtos/code/shared-dimensions/en.md index e3401fe80b3..de3e12b1206 100644 --- a/markdown/dev/howtos/code/shared-dimensions/en.md +++ b/markdown/dev/howtos/code/shared-dimensions/en.md @@ -1,18 +1,7 @@ --- title: Share dimensions between pattern parts -for: developers -about: Shows how to share dimensions between similar pattern parts --- - - -##### 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) - - - 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 shared between them. @@ -20,7 +9,7 @@ shared between them. The example below is from Aaron where dimensions are shared between 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 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 import { dimensions } from './shared' @@ -42,13 +32,6 @@ import { dimensions } from './shared' if (paperless) { dimensions(macro, points, sa) - // ... specific dimensions + // ... dimensions specific to this part } ``` - - - -Since our shared dimension method is a so-called _named export_ we need to -import it with the syntax you see above. - - diff --git a/markdown/dev/howtos/code/shorthand/en.md b/markdown/dev/howtos/code/shorthand/en.md deleted file mode 100644 index 0a20bf3f3e0..00000000000 --- a/markdown/dev/howtos/code/shorthand/en.md +++ /dev/null @@ -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(); -``` - - - -Many examples throughout our documentation use shorthand notation. - - diff --git a/markdown/dev/howtos/code/store/en.md b/markdown/dev/howtos/code/store/en.md index 6192b6285c4..06ad0a03724 100644 --- a/markdown/dev/howtos/code/store/en.md +++ b/markdown/dev/howtos/code/store/en.md @@ -1,33 +1,49 @@ --- 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. -For 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. +Sometimes, you'll want to access data from one part into another part. For +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. -For this, you should use the [Store](/reference/api/store/), which is available via -the [shorthand](/howtos/code/shorthand/) call: +For this, you should use the [Store](/reference/api/store/), which is available +via _destructuring_ in your part's draft method. -```js -export default function(part) { - let { store } = part.shorthand(); - store.set('hello', 'world'); +Setting a value in one part: - return part(); +```mjs +function draftPartA({ + // highlight-start + store, + // highlight-end + part, +}) { + // highlight-start + store.set('hello', 'world') + // highlight-end + + return part() } ``` -```js -export default function(part) { - let { store } = part.shorthand(); - store.get('hello'); // Returns 'world' +Reading a value in another part: - 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 -should reflect that in the [pattern configuration](/reference/api/config/). +should reflect that in the [part dependencies](/howtos/code/after). diff --git a/markdown/dev/howtos/code/storing-path-length/en.md b/markdown/dev/howtos/code/storing-path-length/en.md index ec0cf1d729e..0e259e7b038 100644 --- a/markdown/dev/howtos/code/storing-path-length/en.md +++ b/markdown/dev/howtos/code/storing-path-length/en.md @@ -1,29 +1,21 @@ --- 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 --- - - -##### 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) - - - 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. The example below is from Aaron and stores the length of the armhole seam: -```js - // Store length of armhole and neck opening - store.set( - 'frontArmholeLength', - new Path() - .move(points.armhole) - .curve(points.armholeCp2, points.strapRightCp1, points.strapRight) - .length() - ) +```mjs +// Store length of armhole and neck opening +store.set( + 'frontArmholeLength', + new Path() + .move(points.armhole) + .curve(points.armholeCp2, points.strapRightCp1, points.strapRight) + .length() +) +// Seam length is now available in other parts via: +store.get('frontArmholeLength') ``` diff --git a/markdown/dev/howtos/code/text-whitespace/en.md b/markdown/dev/howtos/code/text-whitespace/en.md index 56515eb9a7f..cb46fec8d7e 100644 --- a/markdown/dev/howtos/code/text-whitespace/en.md +++ b/markdown/dev/howtos/code/text-whitespace/en.md @@ -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 will **not** pick up linebreaks. -```js -points.example1.attr('data-text', 'this\nwill\nnot\nwork') -points.example2.attr('data-text', "this\nwill\nwork") -points.example2.attr('data-text', `this -will -also -work`) + +```design/src/part.mjs +function draftPart = ({ + Point, + points, + Path, + 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 +} ``` + - -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) -``` - +You can control the lineheight by setting the `data-text-lineheight` attribute. -## Adding spaces to text +## Adding consecutive spaces to text 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? 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 -points.example.attr( - 'data-text', - "far      apart" -) +```mjs + points.demo = new Point(0, 0) + // highlight-start + .addText('far      apart') + // highlight-end +} ``` -Whether you're rendering to SVG or React, by using ` ` your spaces -will be properly rendered in both environments. diff --git a/sites/shared/mdx/loader.js b/sites/shared/mdx/loader.js index e973db78f62..aa73d9bce28 100644 --- a/sites/shared/mdx/loader.js +++ b/sites/shared/mdx/loader.js @@ -74,6 +74,7 @@ const mdxLoader = async (language, site, slug, jargon) => { aliases: { javascript: [ 'design/src/index.mjs', + 'design/src/part.mjs', 'design/src/bib.mjs', 'index.mjs', 'part.mjs',