From 38218b198684dd6b309670d34257158951ce5530 Mon Sep 17 00:00:00 2001 From: Josh Munic Date: Sun, 4 May 2025 18:02:39 -0700 Subject: [PATCH 01/46] Fix Simon Cuffs cutting instructions Add "Cut 2 from interfacing" to the cutting instructions on the Simon shirt cuffs pattern. The cutting instructions in the documentation say to cut 2 from interfacing. --- designs/simon/src/shared.mjs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/designs/simon/src/shared.mjs b/designs/simon/src/shared.mjs index 3a1b5388f4b..e09f459b591 100644 --- a/designs/simon/src/shared.mjs +++ b/designs/simon/src/shared.mjs @@ -129,7 +129,10 @@ export const draftBarrelCuff = (part) => { export const decorateBarrelCuff = (part) => { const { macro, store, snippets, Snippet, points, measurements, options, Point } = part.shorthand() // Cutlist - store.cutlist.setCut({ cut: 4, from: 'fabric' }) + store.cutlist.setCut([ + { cut: 4, from: 'fabric' }, + { cut: 2, from: 'interfacing' }, + ]) // Title points.title = new Point(points.bottomRight.x / 2, points.bottomRight.y / 2) @@ -188,7 +191,10 @@ export const draftFrenchCuff = (part) => { export const decorateFrenchCuff = (part) => { const { macro, store, snippets, Snippet, points, measurements, options, Point } = part.shorthand() // Cutlist - store.cutlist.setCut({ cut: 4, from: 'fabric' }) + store.cutlist.setCut([ + { cut: 4, from: 'fabric' }, + { cut: 2, from: 'interfacing' }, + ]) // Title points.title = new Point(points.bottomRight.x / 2, points.bottomRight.y / 2) From 33308e846ac372fff0a65854a68c225a3947cd19 Mon Sep 17 00:00:00 2001 From: Jared Johnston Date: Mon, 5 May 2025 21:45:58 +1000 Subject: [PATCH 02/46] Change github links to codeberg --- .../getting-started-linux/dev-setup/readme.mdx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sites/dev/docs/tutorials/getting-started-linux/dev-setup/readme.mdx b/sites/dev/docs/tutorials/getting-started-linux/dev-setup/readme.mdx index 17933a6063e..9e4bff43dcf 100644 --- a/sites/dev/docs/tutorials/getting-started-linux/dev-setup/readme.mdx +++ b/sites/dev/docs/tutorials/getting-started-linux/dev-setup/readme.mdx @@ -22,17 +22,17 @@ This is the recommended way for (aspiring) FreeSewing contributors ### TL;DR ```bash -git clone https://github.com/freesewing/freesewing +git clone https://codeberg.org/freesewing/freesewing.git cd freesewing yarn kickstart ``` :::tip Even better: [clone your own -fork](https://github.com/freesewing/freesewing/fork) +fork](https://codeberg.org/freesewing/freesewing/fork) ```bash -git clone https://github.com/your-username/freesewing +git clone https://codeberg.org/your-username/freesewing.git cd freesewing yarn kickstart ``` @@ -72,7 +72,7 @@ npm install yarn --global #### Fork our repository You'll want to fork our repository. This way you have your own copy where you can make -all the changes you want. To do so, visit https://github.com/freesewing/freesewing/fork +all the changes you want. To do so, visit https://codeberg.org/freesewing/freesewing/fork #### Clone the forked repository @@ -82,7 +82,7 @@ Now that you have your very own fork, it's time to clone it locally. git clone ``` -Make sure to use the URL to your own fork, typically `https://github.com/your-username/freesewing` but +Make sure to use the URL to your own fork, typically `https://codeberg.org/your-username/freesewing.git` but obviously with your real username rather than `your-username`. #### Install dependencies From dcf7c0412b6dd1285a2480f08a11695e54fa6af6 Mon Sep 17 00:00:00 2001 From: Benjamin Fan Date: Sun, 18 May 2025 09:32:33 +0000 Subject: [PATCH 03/46] fix(dev): v4 tutorial setup changes (#278) Changes to tutorial documentation: 1. Changed instances of `yarn` to `npm`. Remove references to installing `yarn`. 2. Changed instances of `@freesewing/new-design` to `@freesewing/studio`. 3. Changed instances of "lab" to "development environment" and `npm run lab` to `npm run org`. 4. Changed instances of Node v18.17.0 to v20.19.1. ~(I think I might have missed it in one spot. I'll submit a future PR for it.)~ I did not touch the Getting "Started with Vercel" and "Getting Started with Codespaces" tutorials. I need to take a closer look at these to see if they are still relevant or if we might want to remove them. Co-authored-by: Benjamin Fan Reviewed-on: https://codeberg.org/freesewing/freesewing/pulls/278 Reviewed-by: Joost De Cock Co-authored-by: Benjamin Fan Co-committed-by: Benjamin Fan --- .../dev-setup/readme.mdx | 117 ++++++------------ .../dev-start/readme.mdx | 55 +++++--- .../installing-node/readme.mdx | 4 +- .../node-versions/readme.mdx | 2 +- .../getting-started-mac/dev-setup/readme.mdx | 116 +++++++---------- .../getting-started-mac/dev-start/readme.mdx | 55 +++++--- .../installing-node/readme.mdx | 4 +- .../node-versions/readme.mdx | 2 +- .../getting-started-windows/readme.mdx | 40 ++---- .../part1/new-design/readme.mdx | 83 ++++++++----- .../pattern-design/part1/nodejs/readme.mdx | 2 +- .../tutorials/pattern-design/part1/readme.mdx | 13 +- .../pattern-design/part1/sde/readme.mdx | 2 +- .../docs/tutorials/pattern-design/readme.mdx | 13 +- 14 files changed, 242 insertions(+), 266 deletions(-) diff --git a/sites/dev/docs/tutorials/getting-started-linux/dev-setup/readme.mdx b/sites/dev/docs/tutorials/getting-started-linux/dev-setup/readme.mdx index 9e4bff43dcf..ed9ff47eeac 100644 --- a/sites/dev/docs/tutorials/getting-started-linux/dev-setup/readme.mdx +++ b/sites/dev/docs/tutorials/getting-started-linux/dev-setup/readme.mdx @@ -3,17 +3,16 @@ title: Setting up the FreeSewing development environment sidebar_position: 40 --- -FreeSewing provides a development environment to help you design and develop -patterns. +FreeSewing provides the studio, a development environment to help you design and develop patterns. -There are two ways to run this development environment: +There are two ways to run this studio: -- [**Monorepo development**](#monorepo-development): Use this if you intend to +- [**Repository studio**](#monorepo-studio): Use this if you intend to contribute your work to FreeSewing -- [**Stand-alone development**](#stand-alone-development): Use this if you want +- [**Stand-alone studio**](#stand-alone-studio): Use this if you want to do your own thing, and not contribute to FreeSewing -## Monorepo development +## Repository studio :::note This is the recommended way for (aspiring) FreeSewing contributors @@ -24,7 +23,7 @@ This is the recommended way for (aspiring) FreeSewing contributors ```bash git clone https://codeberg.org/freesewing/freesewing.git cd freesewing -yarn kickstart +npm run kickstart ``` :::tip @@ -34,22 +33,16 @@ fork](https://codeberg.org/freesewing/freesewing/fork) ```bash git clone https://codeberg.org/your-username/freesewing.git cd freesewing -yarn kickstart +npm run kickstart ``` ::: -This sets up the monorepo. If you would like to create a new design, run the +This sets up the monorepo. If you would like to create a new design or plugin, run the following command: ```sh -yarn new design -``` - -If you'd like to create a new plugin, run this variant instead: - -```sh -yarn new plugin +npm run add ``` ### Step by step @@ -59,16 +52,6 @@ These docs assume you have git installed. But if you're running Linux, you have git, right? ::: -#### Install yarn - -Our repository uses yarn workspaces. So you'll need `yarn` to work with it. - -To install it run: - -```bash -npm install yarn --global -``` - #### Fork our repository You'll want to fork our repository. This way you have your own copy where you can make @@ -87,91 +70,71 @@ obviously with your real username rather than `your-username`. #### Install dependencies -Enter the directory that was created, and run the `yarn kickstart` command: +Enter the directory that was created, and run the `npm run kickstart` command: ```bash cd freesewing -yarn kickstart +npm run kickstart ``` Now you're ready to [start the development environment](/tutorials/getting-started-linux/dev-start). -:::note +### Creating a new design or plugin -There is another `yarn` command that comes with some Linux distributions, -installed as part of the `cmdtest` package and used for command line -scenario testing. -If you get an `ERROR: There are no scenarios; must have at least one.` -message when trying to run the `yarn` command, it may be because the wrong -`yarn` is being used. - -Possible workarounds for this include uninstalling the `cmdtest` package -or making sure that npm `yarn` is installed and comes first in your `PATH` -environment variable. - -::: - -## Creating a new design - -If you would like to create a new design, run the following command: +If you would like to create a new design or plugin, run the following command: ```sh -yarn new design +npm run add ``` -## Creating a new plugin +After you've answered [some questions](#questions), it create a new +sub-folder for your design in the `designs` folder. -If you'd like to create a new plugin, run the following command: - -```sh -yarn new plugin -``` +Now you're ready to [start the development +environment](/tutorials/getting-started-linux/dev-start). ## Stand-alone development With Node.js installed, all you need to do to setup the stand-alone development environment is run this command: ```bash -npx @freesewing/new-design +npx @freesewing/studio ``` -After you've answered [some questions](#questions), it will take a while to set +After you enter the folder name to create, it will take a while to set everything up. When it's done, you will have a new folder with the development environment inside. +### Creating a new design + +If you would like to create a new design, enter the folder that was just created and run the following command: + +```sh +npm run add +``` + +After you've answered [some questions](#questions), it create a new +sub-folder for your design in the `designs` folder. + Now you're ready to [start the development environment](/tutorials/getting-started-linux/dev-start). -:::tip -The folder will have the name you chose above. -::: - :::note ### Questions +#### What design name to use + +Please stick to a single word name using \[a-z] to avoid problems. + #### What template to use Use `From scratch` unless you want to start from our of our blocks: -- Use `Extend Brian` to start from [Brian](https://freesewing.org/designs/brian) -- Use `Extend Bent` to start from [Bent](https://freesewing.org/designs/bent) -- Use `Extend Bella` to start from [Bella](https://freesewing.org/designs/bella) -- Use `Extend Breanna` to start from [Breanna](https://freesewing.org/designs/breanna) -- Use `Extend Titan` to start from [Titan](https://freesewing.org/designs/titan) - -#### What name to use - -This will become the name of your design. Stick to \[a-z] here to avoid problems. - -If you're not certain what to pick, just mash some keys, it doesn't matter. - -#### What package manager to use - -You may wish to choose `yarn` since that is the package manager -that we use when doing work in the monorepo, -and many of our tutorials are written to use `yarn`. -However, it doesn't really matter. -You can choose either `yarn` or `npm` as you wish. +- Use `Extend Brian` to start from [Brian](https://freesewing.eu/designs/brian) +- Use `Extend Bent` to start from [Bent](https://freesewing.eu/designs/bent) +- Use `Extend Bella` to start from [Bella](https://freesewing.eu/designs/bella) +- Use `Extend Breanna` to start from [Breanna](https://freesewing.eu/designs/breanna) +- Use `Extend Titan` to start from [Titan](https://freesewing.eu/designs/titan) ::: diff --git a/sites/dev/docs/tutorials/getting-started-linux/dev-start/readme.mdx b/sites/dev/docs/tutorials/getting-started-linux/dev-start/readme.mdx index 1577a04548d..4a25e735e5c 100644 --- a/sites/dev/docs/tutorials/getting-started-linux/dev-start/readme.mdx +++ b/sites/dev/docs/tutorials/getting-started-linux/dev-start/readme.mdx @@ -3,55 +3,70 @@ title: Start the development environment sidebar_position: 50 --- -FreeSewing provides a development environment to help you design and develop patterns. +FreeSewing provides the studio, a development environment to help you design and develop patterns. -There are two ways to run this development environment: +There are two ways to run this studio: -- [**Monorepo development**](#monorepo-development): Use this if you intend to contribute your work to FreeSewing -- [**Stand-alone development**](#stand-alone-development): Use this if you want to do your own thing, and not contribute to FreeSewing +- [**Repository studio**](#repository-studio): Use this if you intend to contribute your work to FreeSewing +- [**Stand-alone studio**](#stand-alone-studio): Use this if you want to do your own thing, and not contribute to FreeSewing -## Monorepo development +## Repository Studio -Run `yarn lab` to start the development environment: +Run `npm run studio` to start the repository studio development environment: ```bash -yarn lab +npm run studio ``` -Then point your browser to http://localhost:8000 +Then point your browser to http://localhost:3000 + +Your new design will appear in the Local Designs page. :::tip -### Adding a new design +### Adding another new design -This is all you need to work on existing designs. If you'd like to add a new design, run: +This is all you need to work on existing designs. If you'd like to add another new design, run: ```bash -yarn new design +npm run add ``` -Just make sure to re-start the lab afterwards with `yarn lab` +Just make sure to re-start the repository studio afterwards with `npm run studio` + ::: -## Stand-alone development +## Stand-alone studio -You will have a new folder that has the name you picked for your design. -If you chose `test`, you will have a folder named `test`. -If you chose `banana`, you'll have a folder named `banana`. -(Within this new folder, the `design` subfolder holds your design's configuration file and source code. +You will have a new folder that contains the stand-alone studio development environment. +(Within this new folder, the `design` subfolder holds your design's configuration files and source code. You can ignore all other subfolders and files; they are part of the development environment.) To start the development environment, enter the folder that was created -and run `yarn dev` (or `npm run dev` if you're using npm as a package manager). +and run `npm run start`. -Then open your browser and go to http://localhost:8000 +```bash +npm run start +``` + +Then open your browser and go to http://localhost:3000 :::tip The development environment will watch for any changes you make to the pattern's source code or configuration. -When you do, it will update automatically in your browser. +When you do, the pattern will update automatically in your browser. ::: +### Adding another new design + +This is all you need to work on existing designs. If you'd like to add another new design, run: + +```bash +npm run add +``` + +Just make sure to re-start the stand-alone studio afterwards with `npm run start`. + :::note ##### Yay, you're done! diff --git a/sites/dev/docs/tutorials/getting-started-linux/installing-node/readme.mdx b/sites/dev/docs/tutorials/getting-started-linux/installing-node/readme.mdx index d506696a944..eed39beba8d 100644 --- a/sites/dev/docs/tutorials/getting-started-linux/installing-node/readme.mdx +++ b/sites/dev/docs/tutorials/getting-started-linux/installing-node/readme.mdx @@ -6,10 +6,10 @@ sidebar_position: 20 Now we will use `nvm` to install Node.js. Run the following command: ```bash -nvm install lts/hydrogen +nvm install lts/iron ``` -This will install the so-called LTS version of Node.js 18 on your system. +This will install the so-called LTS version of Node.js 20 on your system. LTS versions -- short for Long Term Support -- are good Node.js versions to use because they are stable and supported for a long time. diff --git a/sites/dev/docs/tutorials/getting-started-linux/node-versions/readme.mdx b/sites/dev/docs/tutorials/getting-started-linux/node-versions/readme.mdx index 8e9de71159d..208d4501004 100644 --- a/sites/dev/docs/tutorials/getting-started-linux/node-versions/readme.mdx +++ b/sites/dev/docs/tutorials/getting-started-linux/node-versions/readme.mdx @@ -47,7 +47,7 @@ With multiple Node.js versions installed, `nvm` allows you to switch between dif versions. Just tell it which version you want to use: ```bash -nvm use lts/hydrogen +nvm use lts/iron ``` If you picked a version that is not installed, `nvm` will simply tell you diff --git a/sites/dev/docs/tutorials/getting-started-mac/dev-setup/readme.mdx b/sites/dev/docs/tutorials/getting-started-mac/dev-setup/readme.mdx index c79874869af..96ef4a30c44 100644 --- a/sites/dev/docs/tutorials/getting-started-mac/dev-setup/readme.mdx +++ b/sites/dev/docs/tutorials/getting-started-mac/dev-setup/readme.mdx @@ -3,17 +3,16 @@ title: Setting up the FreeSewing development environment sidebar_position: 40 --- -FreeSewing provides a development environment to help you design and develop -patterns. +FreeSewing provides the studio, a development environment to help you design and develop patterns. -There are two ways to run this development environment: +There are two ways to run this studio: -- [**Monorepo development**](#monorepo-development): Use this if you intend to +- [**Repository studio**](#monorepo-studio): Use this if you intend to contribute your work to FreeSewing -- [**Stand-alone development**](#stand-alone-development): Use this if you want +- [**Stand-alone studio**](#stand-alone-studio): Use this if you want to do your own thing, and not contribute to FreeSewing -## Monorepo development +## Repository studio :::note This is the recommended way for (aspiring) FreeSewing contributors @@ -22,57 +21,41 @@ This is the recommended way for (aspiring) FreeSewing contributors ### TL;DR ```bash -git clone https://github.com/freesewing/freesewing +git clone https://codeberg.org/freesewing/freesewing.git cd freesewing -yarn kickstart +npm run kickstart ``` :::tip Even better: [clone your own -fork](https://github.com/freesewing/freesewing/fork) +fork](https://codeberg.org/freesewing/freesewing/fork) ```bash -git clone https://github.com/your-username/freesewing +git clone https://codeberg.org/your-username/freesewing.git cd freesewing -yarn kickstart +npm run kickstart ``` ::: -This sets up the monorepo. If you would like to create a new design, run the +This sets up the monorepo. If you would like to create a new design or plugin, run the following command: ```sh -yarn new design -``` - -If you'd like to create a new plugin, run this variant instead: - -```sh -yarn new plugin +npm run add ``` ### Step by step :::note These docs assume you have git installed. -But if you're running macOS, you have git, right? +But if you're running on a Mac system, you have git, right? ::: -#### Install yarn - -Our repository uses yarn workspaces. So you'll need `yarn` to work with it. - -To install it run: - -```bash -npm install yarn --global -``` - #### Fork our repository You'll want to fork our repository. This way you have your own copy where you can make -all the changes you want. To do so, visit https://github.com/freesewing/freesewing/fork +all the changes you want. To do so, visit https://codeberg.org/freesewing/freesewing/fork #### Clone the forked repository @@ -82,81 +65,76 @@ Now that you have your very own fork, it's time to clone it locally. git clone ``` -Make sure to use the URL to your own fork, typically `https://github.com/your-username/freesewing` but +Make sure to use the URL to your own fork, typically `https://codeberg.org/your-username/freesewing.git` but obviously with your real username rather than `your-username`. #### Install dependencies -Enter the directory that was created, and run the `yarn kickstart` command: +Enter the directory that was created, and run the `npm run kickstart` command: ```bash cd freesewing -yarn kickstart +npm run kickstart ``` Now you're ready to [start the development environment](/tutorials/getting-started-linux/dev-start). -## Creating a new design +### Creating a new design or plugin -If you would like to create a new design, run the following command: +If you would like to create a new design or plugin, run the following command: ```sh -yarn new design +npm run add ``` -## Creating a new plugin +After you've answered [some questions](#questions), it create a new +sub-folder for your design in the `designs` folder. -If you'd like to create a new plugin, run the following command: - -```sh -yarn new plugin -``` +Now you're ready to [start the development +environment](/tutorials/getting-started-mac/dev-start). ## Stand-alone development With Node.js installed, all you need to do to setup the stand-alone development environment is run this command: ```bash -npx @freesewing/new-design +npx @freesewing/studio ``` -After you've answered [some questions](#questions), it will take a while to set +After you enter the folder name to create, it will take a while to set everything up. When it's done, you will have a new folder with the development environment inside. -Now you're ready to [start the development -environment](/tutorials/getting-started-linux/dev-start). +### Creating a new design -:::tip -The folder will have the name you chose above. -::: +If you would like to create a new design, enter the folder that was just created and run the following command: + +```sh +npm run add +``` + +After you've answered [some questions](#questions), it create a new +sub-folder for your design in the `designs` folder. + +Now you're ready to [start the development +environment](/tutorials/getting-started-mac/dev-start). :::note ### Questions +#### What design name to use + +Please stick to a single word name using \[a-z] to avoid problems. + #### What template to use Use `From scratch` unless you want to start from our of our blocks: -- Use `Extend Brian` to start from [Brian](https://freesewing.org/designs/brian) -- Use `Extend Bent` to start from [Bent](https://freesewing.org/designs/bent) -- Use `Extend Bella` to start from [Bella](https://freesewing.org/designs/bella) -- Use `Extend Breanna` to start from [Breanna](https://freesewing.org/designs/breanna) -- Use `Extend Titan` to start from [Titan](https://freesewing.org/designs/titan) - -#### What name to use - -This will become the name of your design. Stick to \[a-z] here to avoid problems. - -If you're not certain what to pick, just mash some keys, it doesn't matter. - -#### What package manager to use - -You may wish to choose `yarn` since that is the package manager -that we use when doing work in the monorepo, -and many of our tutorials are written to use `yarn`. -However, it doesn't really matter. -You can choose either `yarn` or `npm` as you wish. +- Use `Extend Brian` to start from [Brian](https://freesewing.eu/designs/brian) +- Use `Extend Bent` to start from [Bent](https://freesewing.eu/designs/bent) +- Use `Extend Bella` to start from [Bella](https://freesewing.eu/designs/bella) +- Use `Extend Breanna` to start from [Breanna](https://freesewing.eu/designs/breanna) +- Use `Extend Titan` to start from [Titan](https://freesewing.eu/designs/titan) ::: diff --git a/sites/dev/docs/tutorials/getting-started-mac/dev-start/readme.mdx b/sites/dev/docs/tutorials/getting-started-mac/dev-start/readme.mdx index 1577a04548d..4a25e735e5c 100644 --- a/sites/dev/docs/tutorials/getting-started-mac/dev-start/readme.mdx +++ b/sites/dev/docs/tutorials/getting-started-mac/dev-start/readme.mdx @@ -3,55 +3,70 @@ title: Start the development environment sidebar_position: 50 --- -FreeSewing provides a development environment to help you design and develop patterns. +FreeSewing provides the studio, a development environment to help you design and develop patterns. -There are two ways to run this development environment: +There are two ways to run this studio: -- [**Monorepo development**](#monorepo-development): Use this if you intend to contribute your work to FreeSewing -- [**Stand-alone development**](#stand-alone-development): Use this if you want to do your own thing, and not contribute to FreeSewing +- [**Repository studio**](#repository-studio): Use this if you intend to contribute your work to FreeSewing +- [**Stand-alone studio**](#stand-alone-studio): Use this if you want to do your own thing, and not contribute to FreeSewing -## Monorepo development +## Repository Studio -Run `yarn lab` to start the development environment: +Run `npm run studio` to start the repository studio development environment: ```bash -yarn lab +npm run studio ``` -Then point your browser to http://localhost:8000 +Then point your browser to http://localhost:3000 + +Your new design will appear in the Local Designs page. :::tip -### Adding a new design +### Adding another new design -This is all you need to work on existing designs. If you'd like to add a new design, run: +This is all you need to work on existing designs. If you'd like to add another new design, run: ```bash -yarn new design +npm run add ``` -Just make sure to re-start the lab afterwards with `yarn lab` +Just make sure to re-start the repository studio afterwards with `npm run studio` + ::: -## Stand-alone development +## Stand-alone studio -You will have a new folder that has the name you picked for your design. -If you chose `test`, you will have a folder named `test`. -If you chose `banana`, you'll have a folder named `banana`. -(Within this new folder, the `design` subfolder holds your design's configuration file and source code. +You will have a new folder that contains the stand-alone studio development environment. +(Within this new folder, the `design` subfolder holds your design's configuration files and source code. You can ignore all other subfolders and files; they are part of the development environment.) To start the development environment, enter the folder that was created -and run `yarn dev` (or `npm run dev` if you're using npm as a package manager). +and run `npm run start`. -Then open your browser and go to http://localhost:8000 +```bash +npm run start +``` + +Then open your browser and go to http://localhost:3000 :::tip The development environment will watch for any changes you make to the pattern's source code or configuration. -When you do, it will update automatically in your browser. +When you do, the pattern will update automatically in your browser. ::: +### Adding another new design + +This is all you need to work on existing designs. If you'd like to add another new design, run: + +```bash +npm run add +``` + +Just make sure to re-start the stand-alone studio afterwards with `npm run start`. + :::note ##### Yay, you're done! diff --git a/sites/dev/docs/tutorials/getting-started-mac/installing-node/readme.mdx b/sites/dev/docs/tutorials/getting-started-mac/installing-node/readme.mdx index d506696a944..eed39beba8d 100644 --- a/sites/dev/docs/tutorials/getting-started-mac/installing-node/readme.mdx +++ b/sites/dev/docs/tutorials/getting-started-mac/installing-node/readme.mdx @@ -6,10 +6,10 @@ sidebar_position: 20 Now we will use `nvm` to install Node.js. Run the following command: ```bash -nvm install lts/hydrogen +nvm install lts/iron ``` -This will install the so-called LTS version of Node.js 18 on your system. +This will install the so-called LTS version of Node.js 20 on your system. LTS versions -- short for Long Term Support -- are good Node.js versions to use because they are stable and supported for a long time. diff --git a/sites/dev/docs/tutorials/getting-started-mac/node-versions/readme.mdx b/sites/dev/docs/tutorials/getting-started-mac/node-versions/readme.mdx index fa7409296c3..208d4501004 100644 --- a/sites/dev/docs/tutorials/getting-started-mac/node-versions/readme.mdx +++ b/sites/dev/docs/tutorials/getting-started-mac/node-versions/readme.mdx @@ -47,7 +47,7 @@ With multiple Node.js versions installed, `nvm` allows you to switch between dif versions. Just tell it which version you want to use: ```bash -nvm use v10.22.1 +nvm use lts/iron ``` If you picked a version that is not installed, `nvm` will simply tell you diff --git a/sites/dev/docs/tutorials/getting-started-windows/readme.mdx b/sites/dev/docs/tutorials/getting-started-windows/readme.mdx index e612048cb2e..65bb7d3479c 100644 --- a/sites/dev/docs/tutorials/getting-started-windows/readme.mdx +++ b/sites/dev/docs/tutorials/getting-started-windows/readme.mdx @@ -55,11 +55,11 @@ guide](https://github.com/nvm-sh/nvm#install--update-script). Once installed you will need to activate NVM by either following the instructions printed to the screen or opening a new terminal. -#### Install Node.js (and optionally Yarn) +#### Install Node.js Now that you have NVM installed, you can install Node.js. The latest version can be installed using `nvm install default`. You can also install a specific version -using `nvm install v18.17.0`. For the purposes of debugging it can be useful to +using `nvm install v20.19.1`. For the purposes of debugging it can be useful to have the same version of Node.js installed as the main project uses, which you can then activate using `nvm use `. You can determine what version the FreeSewing project uses by checking @@ -68,16 +68,12 @@ FreeSewing project uses by checking :::warning At the time this guide was written the latest version of Node.js/npm has a bug in the dependency resolution process which causes the freesewing project -to fail to build. Use the latest LTS version (currently 18.17.0) or the specific +to fail to build. Use the latest LTS version (currently 20.19.1) or the specific version used by the main project to avoid this issue. ::: -Node.js comes with the Node Package Manager (npm) by default which can be used to -set up the project. The default package manager uses a fairly simplistic approach -to dependency resolution which can make builds take a long time. Yarn is an -alternative package manager which makes builds faster, especially for monolithic -projects like FreeSewing. If you'd like to install yarn run `npm install yarn ---global` (optional, but recommended). +Node.js comes with the Node Package Manager (npm) by default which is used to +set up the project. #### Install and configure Git (recommended) @@ -137,12 +133,12 @@ will take you to the latest release which provides an installer you can download and run. Once nvm-windows is installed you will be able to continue with the rest of this process. -### Install Node.js (and optionally Yarn) +### Install Node.js Open a Powershell terminal or command prompt. Run `nvm ls available` to show versions that can be installed. Choose the appropriate version (you should use the same version as the freesewing project or latest LTS version) then run `nvm -install 18.17.0` and `nvm use 18.17.0` (where `18.17.0` is the full version +install 20.19.1` and `nvm use 20.19.1` (where `20.19.1` is the full version string of the version you wish to use) to activate the newly installed version. You will receive a prompt for elevated permissions and will need to accept it in order to activate the new version of Node.js. @@ -150,20 +146,16 @@ order to activate the new version of Node.js. :::warning At the time this guide was written the latest version of Node.js/npm has a bug in the dependency resolution process which causes the freesewing project -to fail to build. Use the latest LTS version (currently 18.17.0) or the specific +to fail to build. Use the latest LTS version (currently 20.19.1 or the specific version used by the main project to avoid this issue. ::: -Node.js comes with the Node Package Manager (npm) by default which can be used to -set up the project. The default package manager uses a fairly simplistic approach -to dependency resolution which can make builds take a long time. Yarn is an -alternative package manager which makes builds faster, especially for monolithic -projects like FreeSewing. If you'd like to install yarn run (`npm install yarn --g`) (optional). +Node.js comes with the Node Package Manager (npm) by default which is used to +set up the project. ## Setting up the FreeSewing development environment -In VSCode or in a terminal, navigate to the folder you wish to contain your new patterns (e.g. `D:\Documents\my-freesewing-patterns`). Inside this directory run `npx @freesewing/new-design`. +In VSCode or in a terminal, navigate to the folder you wish to contain your new patterns (e.g. `D:\Documents\my-freesewing-patterns`). Inside this directory run `npx @freesewing/studio`. After you've answered [some questions](#questions), it will take a while to set everything up. When it's done, you will have a new folder with the development environment inside. @@ -192,14 +184,6 @@ This will become the name of your design. Stick to \[a-z] here to avoid problems If you're not certain what to pick, just mash some keys, it doesn't matter. -#### What package manager to use - -You may wish to choose `yarn` since that is the package manager -that we use when doing work in the monorepo, -and many of our tutorials are written to use `yarn`. -However, it doesn't really matter. -You can choose either `yarn` or `npm` as you wish. - ::: ## Start the development environment @@ -211,7 +195,7 @@ If you chose `banana`, you'll have a folder named `banana`. You can ignore all other subfolders and files; they are part of the development environment.) To start the development environment, navigate to the folder that was created -and run `yarn dev` (or `npm run dev` if you're using npm as a package manager). +and run `npm run org`. Then open your browser and go to http://localhost:8000 diff --git a/sites/dev/docs/tutorials/pattern-design/part1/new-design/readme.mdx b/sites/dev/docs/tutorials/pattern-design/part1/new-design/readme.mdx index 0cfd2e1b3f0..b02b0793547 100644 --- a/sites/dev/docs/tutorials/pattern-design/part1/new-design/readme.mdx +++ b/sites/dev/docs/tutorials/pattern-design/part1/new-design/readme.mdx @@ -1,28 +1,22 @@ --- -title: Setting up the development environment +title: Setting up the FreeSewing development environment sidebar_position: 20 --- -FreeSewing provides a development environment that visualizes your design for -you. This tutorial is for the stand-alone development environment, not the -monorepo development environment (which you may have set up if you followed a +FreeSewing provides the studio, a development environment that visualizes your design for +you. This tutorial is for the stand-alone studio, not the +repository studio (which you may have set up if you followed a getting started tutorial). To set it up, I will open a terminal and enter the following command: ```sh -npx @freesewing/new-design +npx @freesewing/studio ``` -It will ask if it is ok to install the development environment in a new folder -named `freesewing`. You can accept the default, or pick a different folder name -if you prefer. - -It will also ask what package manager you would like to use. -Here too the default (`npm`) is fine., unless you are certain you have **yarn** installed. - -After answering these questions, files will be downloaded, dependencies installed, -and it will also initialize a git repository for you (if you have git on your system). +After you enter the folder name to create, it will take a while to set +everything up. When it's done, you will have a new folder with the development +environment inside. :::note @@ -31,29 +25,58 @@ of dependencies that need to be downloaded. ::: -When it's ready, you can enter the `freesewing` directory that was just created and run `npm run dev`: +You will have a new folder that contains the stand-alone studio development environment. +(Within this new folder, the `design` subfolder holds your design's configuration files and source code. +You can ignore all other subfolders and files; they are part of the development environment.) -```sh -cd freesewing -npm run dev +### Creating a new design + +If you would like to create a new design, enter the folder that was just +created and run the following command: + +```bash +npm run add ``` -Or if you want to use yarn as package manager: +After you've answered [some questions](#questions), it create a new +sub-folder for your design in the `designs` folder. -```sh -cd freesewing -yarn dev +:::note + +### Questions + +#### What design name to use + +Please stick to a single word name using \[a-z] to avoid problems. + +#### What template to use + +Use `From scratch` unless you want to start from our of our blocks: + +- Use `Extend Brian` to start from [Brian](https://freesewing.eu/designs/brian) +- Use `Extend Bent` to start from [Bent](https://freesewing.eu/designs/bent) +- Use `Extend Bella` to start from [Bella](https://freesewing.eu/designs/bella) +- Use `Extend Breanna` to start from [Breanna](https://freesewing.eu/designs/breanna) +- Use `Extend Titan` to start from [Titan](https://freesewing.eu/designs/titan) + +::: + +### Starting the development environment + +To start the development environment, enter the folder containing the +stand-alone studio and run `npm run start`. + +```bash +npm run start ``` -Now open a browser and go to http://localhost:8000 - -If all goes well, we'll should see this landing page: - -![The FreeSewing development environment](./nd.png) +Then open your browser and go to http://localhost:3000 :::tip - -##### More detailed setup tutorials are available +The development environment will watch for any changes you make to +the pattern's source code or configuration. +When you do, the pattern will update automatically in your browser. +::: This pattern design tutorial contains only an abbreviated overview of the setup process. @@ -69,7 +92,7 @@ For more detailed instructions, please refer to one of our setup tutorials: ##### Need help? -If you run into any issues, head over to [FreeSewing.org/support](https://next.freesewing.org/support) +If you run into any issues, head over to [FreeSewing.eu/support](https://freesewing.eu/support) which lists the various ways in which you can get help. ::: diff --git a/sites/dev/docs/tutorials/pattern-design/part1/nodejs/readme.mdx b/sites/dev/docs/tutorials/pattern-design/part1/nodejs/readme.mdx index 5600b135cb6..249def14c04 100644 --- a/sites/dev/docs/tutorials/pattern-design/part1/nodejs/readme.mdx +++ b/sites/dev/docs/tutorials/pattern-design/part1/nodejs/readme.mdx @@ -25,7 +25,7 @@ If you don't have NodeJS on your system, you can go to ##### NodeJS versions -You need Node.js 18 (lts/hydrogen) or higher to use FreeSewing +You need Node.js 20 (lts/iron) or higher to use FreeSewing If you're looking to use different versions, I can recommend using `nvm` which makes this very easy: https://github.com/nvm-sh/nvm diff --git a/sites/dev/docs/tutorials/pattern-design/part1/readme.mdx b/sites/dev/docs/tutorials/pattern-design/part1/readme.mdx index 03cb888bba4..1acc688f6dd 100644 --- a/sites/dev/docs/tutorials/pattern-design/part1/readme.mdx +++ b/sites/dev/docs/tutorials/pattern-design/part1/readme.mdx @@ -1,5 +1,5 @@ --- -title: "Part 1: Prerequisites" +title: 'Part 1: Prerequisites' --- In this first part, I will get your up and running with the FreeSewing @@ -10,24 +10,23 @@ this section. If not, I have good news and bad news (and then some more good news) for you. The good news is that JavaScript is an easy language to pick up. It is also a -very popular and versatile language and the skills you learn here will serve +very popular and versatile language and the skills you learn here will serve you well. -The bad news is that the JavaScript ecosystem is vast, and unfortunately +The bad news is that the JavaScript ecosystem is vast, and unfortunately somewhat fractured. Most of the problems people need help with are not so much in the code itself, but rather getting everything to work together. This is true not just for FreeSewing, but pretty much all modern JavaScript. -But, no need to despair, FreeSewing provides a development environment that +But, no need to despair, FreeSewing provides a development environment that will take care of all of this for you. So you can focus on designing patterns. -If you have NodeJS on your system, getting that development environment up +If you have NodeJS on your system, getting that development environment up and running takes only a single command: ```sh -npx @freesewing/new-design +npx @freesewing/studio ``` If you don't have NodeJS on your system --- or if you're not sure what NodeJS is to begin with --- read on to learn how to install it. - diff --git a/sites/dev/docs/tutorials/pattern-design/part1/sde/readme.mdx b/sites/dev/docs/tutorials/pattern-design/part1/sde/readme.mdx index 2ca7d18ff8c..2910a8cd869 100644 --- a/sites/dev/docs/tutorials/pattern-design/part1/sde/readme.mdx +++ b/sites/dev/docs/tutorials/pattern-design/part1/sde/readme.mdx @@ -3,7 +3,7 @@ title: The FreeSewing development environment sidebar_position: 30 --- -If you have been to FreeSewing.org the FreeSewing development environment will look familiar. +If you have been to FreeSewing.eu the FreeSewing development environment will look familiar. That's because under the hood, it re-uses the same building blocks. At the top of the page is the header with a row of icons that lay out what is available to you. diff --git a/sites/dev/docs/tutorials/pattern-design/readme.mdx b/sites/dev/docs/tutorials/pattern-design/readme.mdx index 9f5ca17253c..a11bc7de5d3 100644 --- a/sites/dev/docs/tutorials/pattern-design/readme.mdx +++ b/sites/dev/docs/tutorials/pattern-design/readme.mdx @@ -9,22 +9,22 @@ how to design a bespoke sewing pattern, start to finish. This tutorial is divided into three parts, allowing you to speedrun or entirely skip certain parts depending on your interests or prior experience: -## Part 1: Prerequisites +## Part 1: Prerequisites The first sections of this tutorial, [Part 1](/tutorials/pattern-design/part1), -deals with the prerequisites. Installing node, setting up the FreeSewing -development environment on your system, and so on. If you are familiar with +deals with the prerequisites. Installing node, setting up the FreeSewing +development environment on your system, and so on. If you are familiar with the JavaScript ecosystem, I can summarize that entire section in this one-liner that sets up the FreeSewing development environment on your system: ```sh -npx @freesewing/new-design +npx @freesewing/studio ``` ## Part 2: Parametric design In [Part 2](/tutorials/pattern-design/part2) I will show you how to design a -parametric sewing pattern with FreeSewing. We'll create a part, add a bunch of +parametric sewing pattern with FreeSewing. We'll create a part, add a bunch of points, draw lines and curves, and so on. All the basic skills required to create a sewing pattern in code. @@ -39,10 +39,9 @@ There is more to FreeSewing patterns than meets the eye, and in [Part further value to your designs. This includes things like translation, supporting laser cutters, avoiding the -need to printing with so-called *paperless patterns*, as well as how you can +need to printing with so-called _paperless patterns_, as well as how you can configure your pattern to integrate with FreeSewing.org, or your own frontend. - You can follow this tutorial start to finish, or skip ahead and back, the choice is yours. From 3390def67c619078fc19836de574624c95ecc02a Mon Sep 17 00:00:00 2001 From: Benjamin Fan Date: Sun, 18 May 2025 09:40:11 +0000 Subject: [PATCH 04/46] fix(react): Pattern Layout print settings UI fixes (#351) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #341 Fixes #342 ![Screenshot 2025-05-13 at 4.19.07 PM.png](/attachments/495b1a64-b7e6-40ca-b531-287cea0d29a1) ![Screenshot 2025-05-13 at 4.18.47 PM.png](/attachments/ce8f568e-537e-4f19-b0c1-893253966914) Co-authored-by: Benjamin Fan Reviewed-on: https://codeberg.org/freesewing/freesewing/pulls/351 Reviewed-by: Joost De Cock Co-authored-by: Benjamin Fan Co-committed-by: Benjamin Fan --- .../react/components/Editor/components/menus/Value.mjs | 2 +- packages/react/components/Editor/lib/layout-settings.mjs | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/react/components/Editor/components/menus/Value.mjs b/packages/react/components/Editor/components/menus/Value.mjs index 5a6cc2e8415..21c0fcc3509 100644 --- a/packages/react/components/Editor/components/menus/Value.mjs +++ b/packages/react/components/Editor/components/menus/Value.mjs @@ -119,7 +119,7 @@ export const MenuMmValue = ({ current, config, units, changed }) => ( * Displays the current percentage value, and the absolute value if configured */ export const MenuPctOptionValue = ({ config, current, settings, changed, patternConfig }) => { - const val = changed ? current : config.pct / 100 + const val = changed ? current : config.dflt return ( diff --git a/packages/react/components/Editor/lib/layout-settings.mjs b/packages/react/components/Editor/lib/layout-settings.mjs index e46751fa2a5..883282ce487 100644 --- a/packages/react/components/Editor/lib/layout-settings.mjs +++ b/packages/react/components/Editor/lib/layout-settings.mjs @@ -20,7 +20,8 @@ const defaultPrintSettings = (units) => ({ size: units === 'imperial' ? 'letter' : 'a4', orientation: 'portrait', margin: units === 'imperial' ? 12.7 : 10, - coverPage: true, + coverPage: 1, + iconSize: 0.5, }) export function menuLayoutSettingsStructure(units) { @@ -76,6 +77,7 @@ export function menuLayoutSettingsStructure(units) { ), }, icon: PageOrientationIcon, + dflt: defaults.orientation, }, margin: { dense: true, @@ -98,7 +100,7 @@ export function menuLayoutSettingsStructure(units) { 0: 'Do not include a cover page', 1: 'Include a cover page', }, - dflt: 0, + dflt: defaults.coverPage, }, iconSize: { dense: true, @@ -108,7 +110,7 @@ export function menuLayoutSettingsStructure(units) { about: 'Controls the size of the icons that allow you to rotate/flip individual pattern parts', min: 10, - dflt: 0.5, + dflt: defaults.iconSize, step: 1, max: 200, }, From 1896eba914d5712c0893dfe5a72977662cc180e8 Mon Sep 17 00:00:00 2001 From: Benjamin Fan Date: Sun, 18 May 2025 09:43:40 +0000 Subject: [PATCH 05/46] fix(wahid): Add new waist, hips, and pocket calculations (#352) This PR changes how the Wahid pattern is generated to improve widths at the waist and hips. It does so by using the actual waist and hips measurements to generate the waist and hips points, as opposed to the old method which used the chest circumference as the base to approximate the waist and hips points. The new method results in a pattern where the chest/waist/hips widths of the garment are exactly the values of chest/waist/hips measurements plus ease. The changes are controlled by a new Legacy Waist and Hips option. The option is disabled by default, but when it is enabled the Wahid pattern is generated the old way. So, users will be able to generate the same Wahid patterns as before, if desired. The PR also contains a fix for the front pocket angle. The waist and hips changes were tested by someone who reported that it fixed their sway back issue: https://discord.com/channels/698854858052075530/757631205804998759/1367899207553388556 discord://discord.com/channels/698854858052075530/757631205804998759/1367899207553388556 Fixes #302 Fixes #328 Co-authored-by: Benjamin Fan Reviewed-on: https://codeberg.org/freesewing/freesewing/pulls/352 Reviewed-by: Joost De Cock Co-authored-by: Benjamin Fan Co-committed-by: Benjamin Fan --- designs/wahid/i18n/en.json | 12 ++++++ designs/wahid/src/back.mjs | 17 ++++++++- designs/wahid/src/front.mjs | 38 +++++++++++++++++-- designs/wahid/src/options.mjs | 1 + designs/wahid/src/shared.mjs | 16 ++++++++ .../wahid/options/legacywaisthips/readme.mdx | 21 ++++++++++ 6 files changed, 100 insertions(+), 5 deletions(-) create mode 100644 sites/org/docs/docs/designs/wahid/options/legacywaisthips/readme.mdx diff --git a/designs/wahid/i18n/en.json b/designs/wahid/i18n/en.json index f5004a7674e..b15a033eea7 100644 --- a/designs/wahid/i18n/en.json +++ b/designs/wahid/i18n/en.json @@ -117,6 +117,18 @@ "centerBackDart": { "t": "Center back dart", "d": "Whether or not to include a center back dart to fit a rounded back." + }, + "legacyWaistHips": { + "t": "Legacy waist and hips widths", + "d": "Enable this option to use the legacy (v3) way to calculate the waist and hips widths (using chest circumference) rather than the new way (using the waist and hips measurements)." + }, + "legacyWaistHipsNo": { + "t": "Calculate waist and hips widths the new way", + "d": "Uses the waist and hips measurements to calculate the waist and hips widths" + }, + "legacyWaistHipsYes": { + "t": "Calculate waist and hips widths the legacy (v3) way", + "d": "Uses the chest measurement to approximate the waist and hips widths" } } } diff --git a/designs/wahid/src/back.mjs b/designs/wahid/src/back.mjs index 105c5e7fa83..00cb52344b9 100644 --- a/designs/wahid/src/back.mjs +++ b/designs/wahid/src/back.mjs @@ -1,6 +1,13 @@ import { constructMainDart, shapeSideSeam, dartPath } from './shared.mjs' import { back as brianBack } from '@freesewing/brian' -import { backInset, shoulderInset, neckInset, centerBackDart, backScyeDart } from './options.mjs' +import { + backInset, + shoulderInset, + neckInset, + centerBackDart, + backScyeDart, + legacyWaistHips, +} from './options.mjs' import { hidePresets } from '@freesewing/core' function wahidBack({ @@ -20,6 +27,13 @@ function wahidBack({ for (let i of Object.keys(paths)) delete paths[i] delete snippets.armholePitchNotch + if (!options.legacyWaistHips) { + // Use actual measurements to set waist and hips points + points.waist = new Point((measurements.waist * (1 + options.waistEase)) / 4, points.cbWaist.y) + points.hips = new Point((measurements.hips * (1 + options.hipsEase)) / 4, points.cbHips.y) + points.hem = new Point(points.hips.x, points.cbHem.y) + } + // Back inset let shoulderLen = points.shoulder.dist(points.neck) let backInset = shoulderLen * options.backInset @@ -279,6 +293,7 @@ export const back = { neckInset, centerBackDart, backScyeDart, + legacyWaistHips, }, draft: wahidBack, } diff --git a/designs/wahid/src/front.mjs b/designs/wahid/src/front.mjs index 460564467d7..8adff217f51 100644 --- a/designs/wahid/src/front.mjs +++ b/designs/wahid/src/front.mjs @@ -30,6 +30,7 @@ import { s3Armhole, shoulderSlopeReduction, backNeckCutout, + legacyWaistHips, } from './options.mjs' function wahidFront({ @@ -51,6 +52,14 @@ function wahidFront({ // Cleanup from Brian for (let i of Object.keys(paths)) delete paths[i] delete snippets.armholePitchNotch + + if (!options.legacyWaistHips) { + // Use actual measurements to set waist and hips points + points.waist = new Point((measurements.waist * (1 + options.waistEase)) / 4, points.cfWaist.y) + points.hips = new Point((measurements.hips * (1 + options.hipsEase)) / 4, points.cfHips.y) + points.hem = new Point(points.hips.x, points.cfHem.y) + } + // Neck cutout points.closureTop = new Point( measurements.chest * options.frontOverlap * -1, @@ -176,15 +185,31 @@ function wahidFront({ points.dartHipLeft, points.pocketTopMid.y + pwvh ) - points.pocketTopLeft = points.pocketTopMidLeft.shift(180 + options.pocketAngle, pw / 2) - points.pocketBottomLeft = points.pocketTopLeft.shift(options.pocketAngle - 90, pwh) + // The pocket can start out offset from the horizontal/vertical. + const startingAngleOffset = points.pocketBottomMidLeft.angle(points.pocketTopMidLeft) - 90 + points.pocketTopLeft = points.pocketTopMidLeft.shift( + 180 + options.pocketAngle + startingAngleOffset, + pw / 2 + ) + points.pocketBottomLeft = points.pocketTopLeft.shift( + options.pocketAngle - 90 + startingAngleOffset, + pwh + ) points.pocketTopMidRight = points.pocketTopMidLeft.flipX(points.pocketTopMid) points.pocketBottomMidRight = points.pocketBottomMidLeft.flipX(points.pocketTopMid) - points.pocketTopRight = points.pocketTopMidRight.shift(options.pocketAngle, pw / 2) - points.pocketBottomRight = points.pocketTopRight.shift(options.pocketAngle - 90, pwh) + points.pocketTopRight = points.pocketTopMidRight.shift( + options.pocketAngle - startingAngleOffset, + pw / 2 + ) + points.pocketBottomRight = points.pocketTopRight.shift( + options.pocketAngle - 90 - startingAngleOffset, + pwh + ) // Store pocket bag length store.set('pocketBagLength', points.pocketTopMid.dy(points.cfHem) * 0.75) if (options.frontScyeDart) { + // Save original armhole width so we can restore it later + const original_chest_width = points.cfArmhole.dist(points.armhole) // Front scye dart points._dartWidth = points.dartTop.shiftFractionTowards( points.armholeHollow.rotate(options.frontScyeDart, points.dartTop), @@ -230,6 +255,10 @@ function wahidFront({ if (typeof points[p] !== 'undefined') points[p] = points[p].rotate(options.frontScyeDart, points.dartTop) } + if (!options.legacyWaistHips) { + // Set armhole back to original width + points.armhole = points.cfArmhole.shiftTowards(points.armhole, original_chest_width) + } points.armholeHollowCp1 = points.armholeHollowCp2.rotate(180, points.armholeHollow) } // Facing/Lining boundary (flb) @@ -561,6 +590,7 @@ export const front = { s3Armhole, shoulderSlopeReduction, backNeckCutout, + legacyWaistHips, }, draft: wahidFront, } diff --git a/designs/wahid/src/options.mjs b/designs/wahid/src/options.mjs index a2d0f4b8986..b95b0c6335b 100644 --- a/designs/wahid/src/options.mjs +++ b/designs/wahid/src/options.mjs @@ -28,6 +28,7 @@ export const shoulderInset = { pct: 10, min: 0, max: 20, menu: 'advanced' } export const neckInset = { pct: 5, min: 0, max: 10, menu: 'advanced' } export const pocketAngle = { deg: 5, min: 0, max: 5, menu: 'advanced' } export const shoulderSlopeReduction = { pct: 0, min: 0, max: 80, menu: 'advanced' } +export const legacyWaistHips = { bool: false, menu: 'advanced' } // Hide inherited options export const bicepsEase = 0.15 diff --git a/designs/wahid/src/shared.mjs b/designs/wahid/src/shared.mjs index f138af9c00f..a0b3e7098bd 100644 --- a/designs/wahid/src/shared.mjs +++ b/designs/wahid/src/shared.mjs @@ -16,6 +16,22 @@ export const constructMainDart = (part) => { store.set('wr12', wr12) store.set('hr12', hr12) + if (!options.legacyWaistHips) { + // Use largest chest-or-hips measurement to determine reduction + const largest_measurement = chest >= hips ? chest : hips + reduce.waist = largest_measurement - waist + reduce.hips = largest_measurement - hips + if (reduce.hips < 0) reduce.hips = 0 + if (reduce.waist < 0) reduce.waist = 0 + // Use a different reduction factor + const reduction_factor = 15 + wr12 = reduce.waist / reduction_factor + hr12 = reduce.hips / reduction_factor + // Shift side seam to other direction by total amount added to dart + store.set('wr12', wr12 * -2) + store.set('hr12', hr12 * -2) + } + points.dartWaistCenter = new Point(points.armhole.x / 2, points.waist.y) points.dartWaistRight = points.dartWaistCenter.shift(0, wr12) points.dartWaistLeft = points.dartWaistCenter.shift(180, wr12) diff --git a/sites/org/docs/docs/designs/wahid/options/legacywaisthips/readme.mdx b/sites/org/docs/docs/designs/wahid/options/legacywaisthips/readme.mdx new file mode 100644 index 00000000000..32c8b7aa4f5 --- /dev/null +++ b/sites/org/docs/docs/designs/wahid/options/legacywaisthips/readme.mdx @@ -0,0 +1,21 @@ +--- +title: 'Legacy waist and hips calculations' +--- + +This option allows you to use the legacy way of calculating the waist +and hips. + +The legacy (v3) way used the chest circumference to set the intial waist +and hips points. +It then used waist and hips measurements to attempt to move the waist +and hips points towards the actual measurement values. + +The new, v4 way instead uses the actual waist and hips measurements to +set the waist and hips points. +It also contains corrections to the front waist dart and side seam +adjustments to maintain the correct width and ease at the waist and hips. +It also adjusts the armhole point after the dart rotation to maintain +the correct width and ease at the armhole. + +If you enable this option, Wahid will revert to the v3 way of calculating +waist and hips points. From 74ba6c23299496b12ae069ebc5d64132a1177631 Mon Sep 17 00:00:00 2001 From: Benjamin Fan Date: Sun, 18 May 2025 09:44:18 +0000 Subject: [PATCH 06/46] fix(react): Untranslated strings also need a trailing space (#349) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The bug appears in part title cutlist instructions. The bug behavior exists only in the React component. It does not exist with the core SVG renderer. Before: ![Screenshot 2025-05-12 at 10.59.49 AM.png](/attachments/cb43d749-bad3-4d54-95ba-ae1ed4675bd2) After: ![Screenshot 2025-05-12 at 10.59.15 AM.png](/attachments/979ca23a-1db4-49e6-8b31-4e2cd84ecbdf) Edit: (Added, in case the keyword needs to be in the PR description/first comment, not just in a subsequent comment): Fixes #331 Co-authored-by: Benjamin Fan Reviewed-on: https://codeberg.org/freesewing/freesewing/pulls/349 Reviewed-by: Joost De Cock Co-authored-by: Benjamin Fan Co-committed-by: Benjamin Fan --- packages/react/components/Pattern/utils.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react/components/Pattern/utils.mjs b/packages/react/components/Pattern/utils.mjs index 0ee0401da26..880d51c6887 100644 --- a/packages/react/components/Pattern/utils.mjs +++ b/packages/react/components/Pattern/utils.mjs @@ -74,7 +74,7 @@ export const translateStrings = (list, translations = {}) => { else if (string) { if (translations[string]) { translated += `${translations[string]}`.replace(/"/g, '"') + ' ' - } else translated += `${string}` + } else translated += `${string}` + ' ' } } From 64223a141aa16a03847394df6ed6a9cf25cb00fb Mon Sep 17 00:00:00 2001 From: Benjamin Fan Date: Sun, 18 May 2025 10:01:31 +0000 Subject: [PATCH 07/46] fix(react): Pattern clone fix and improvment (#353) This PR: 1. Fixes an issue where the pattern clone operation fails, resulting in a hang/freeze. 2. Appends " (clone)" text to the cloned pattern's name. The hang/freeze problem was reported on Discord: https://discord.com/channels/698854858052075530/944926520282054666/1372209603080753212 discord://discord.com/channels/698854858052075530/944926520282054666/1372209603080753212 Because a successful pattern clone operation immediately loads the new, cloned pattern in the browser, the loading status "success" message is not seen by the user. Instead the user sees the new pattern, but because the new pattern looks exactly like the old pattern, it is not immediately clear to the user that the operation succeeded. This PR adds " (clone)" to the cloned pattern's name, making it easier to see that the clone operation succeeded and than the user is actually looking at the new, cloned pattern. It also helps differentiate the new, cloned pattern from the original pattern. Co-authored-by: Benjamin Fan Reviewed-on: https://codeberg.org/freesewing/freesewing/pulls/353 Reviewed-by: Joost De Cock Co-authored-by: Benjamin Fan Co-committed-by: Benjamin Fan --- packages/react/components/Account/Pattern.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react/components/Account/Pattern.mjs b/packages/react/components/Account/Pattern.mjs index 34f53caffa9..0346f1ca0f0 100644 --- a/packages/react/components/Account/Pattern.mjs +++ b/packages/react/components/Account/Pattern.mjs @@ -109,7 +109,7 @@ export const Pattern = ({ id, Link }) => { delete data.data delete data.userId delete data.img - data.settings = JSON.parse(data.settings) + data.name += ' (clone)' const [status, body] = await backend.createPattern(data) if (status === 201 && body.result === 'created') { setLoadingStatus([true, 'Loading newly created pattern', true, true]) From 094863c9931226e0c5e7b272c5bf7cd44c2ed2ea Mon Sep 17 00:00:00 2001 From: Benjamin Fan Date: Sun, 18 May 2025 10:02:47 +0000 Subject: [PATCH 08/46] fix(studio,eu): Remove submenus from account measurements sets and patterns. (#354) Fixes #311 in both the repository studio and in the freesewing.eu site. (Because I am not able to test the stand-alone studio, I'll submit a separate PR to add the fix there.) Co-authored-by: Benjamin Fan Reviewed-on: https://codeberg.org/freesewing/freesewing/pulls/354 Reviewed-by: Joost De Cock Co-authored-by: Benjamin Fan Co-committed-by: Benjamin Fan --- sites/org/docusaurus.config.mjs | 16 ++++++++++++++++ sites/studio/docusaurus.config.mjs | 23 +++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/sites/org/docusaurus.config.mjs b/sites/org/docusaurus.config.mjs index f08ffe502e6..7d8703f4a09 100644 --- a/sites/org/docusaurus.config.mjs +++ b/sites/org/docusaurus.config.mjs @@ -25,6 +25,22 @@ function customizeSidebar(items) { } } + // Filter out submenus in Your Measurements Sets and Your Patterns + for (const item in items) { + if (items[item].label === 'Account') { + for (const design in items[item].items) { + for (const subpage in items[item].items[design].items) { + if ( + items[item].items[design].items[subpage].label === 'Your Measurements Sets' || + items[item].items[design].items[subpage].label === 'Your Patterns' + ) { + items[item].items[design].items[subpage].items = [] + } + } + } + } + } + return items } diff --git a/sites/studio/docusaurus.config.mjs b/sites/studio/docusaurus.config.mjs index 369dfa1c9a4..4ed76f5ba0e 100644 --- a/sites/studio/docusaurus.config.mjs +++ b/sites/studio/docusaurus.config.mjs @@ -2,6 +2,25 @@ import { themes as prismThemes } from 'prism-react-renderer' import { docusaurusPlugins } from './plugins/index.mjs' import smartypants from 'remark-smartypants' +function customizeSidebar(items) { + // Filter out submenus in Your Measurements Sets and Your Patterns + for (const item in items) { + if (items[item].label === 'Account') { + for (const design in items[item].items) { + for (const subpage in items[item].items[design].items) { + if ( + items[item].items[design].items[subpage].label === 'Your Measurements Sets' || + items[item].items[design].items[subpage].label === 'Your Patterns' + ) { + items[item].items[design].items[subpage].items = [] + } + } + } + } + } + return items +} + const config = { title: 'FreeSewing Studio', tagline: 'FreeSewing for Designers', @@ -25,6 +44,10 @@ const config = { docs: { routeBasePath: '/', sidebarPath: './sidebars.js', + async sidebarItemsGenerator({ defaultSidebarItemsGenerator, ...args }) { + const sidebarItems = await defaultSidebarItemsGenerator(args) + return customizeSidebar(sidebarItems) + }, remarkPlugins: [[smartypants, { dashes: 'oldschool' }]], }, theme: { From 7c796a689efc33a8036e14bd75afb374b24a9202 Mon Sep 17 00:00:00 2001 From: Benjamin Fan Date: Sun, 18 May 2025 10:04:20 +0000 Subject: [PATCH 09/46] fix(studio): Remove submenus from account measurements sets and patterns. (#355) Reviewed-on: https://codeberg.org/freesewing/freesewing/pulls/355 Reviewed-by: Joost De Cock Co-authored-by: Benjamin Fan Co-committed-by: Benjamin Fan --- .../studio/template/docusaurus.config.mjs | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/packages/studio/template/docusaurus.config.mjs b/packages/studio/template/docusaurus.config.mjs index da43c448fba..dbc5eeeb1be 100644 --- a/packages/studio/template/docusaurus.config.mjs +++ b/packages/studio/template/docusaurus.config.mjs @@ -2,6 +2,25 @@ import { themes as prismThemes } from 'prism-react-renderer' import { docusaurusPlugins } from './plugins/index.mjs' import smartypants from 'remark-smartypants' +function customizeSidebar(items) { + // Filter out submenus in Your Measurements Sets and Your Patterns + for (const item in items) { + if (items[item].label === 'Account') { + for (const design in items[item].items) { + for (const subpage in items[item].items[design].items) { + if ( + items[item].items[design].items[subpage].label === 'Your Measurements Sets' || + items[item].items[design].items[subpage].label === 'Your Patterns' + ) { + items[item].items[design].items[subpage].items = [] + } + } + } + } + } + return items +} + const config = { title: 'FreeSewing Studio', tagline: 'FreeSewing for Designers', @@ -28,6 +47,10 @@ const config = { docs: { routeBasePath: '/', sidebarPath: './sidebars.js', + async sidebarItemsGenerator({ defaultSidebarItemsGenerator, ...args }) { + const sidebarItems = await defaultSidebarItemsGenerator(args) + return customizeSidebar(sidebarItems) + }, remarkPlugins: [[smartypants, { dashes: 'oldschool' }]], }, theme: { From bdf8a407920b0d1a56f65b23086484a138ef6d1b Mon Sep 17 00:00:00 2001 From: Benjamin Fan Date: Sun, 18 May 2025 10:26:03 +0000 Subject: [PATCH 10/46] fix(react): Units icon uses default style if no settings (#356) Fixes a side effect of the "there are no longer default settings" change. Fixes #344 Co-authored-by: Benjamin Fan Reviewed-on: https://codeberg.org/freesewing/freesewing/pulls/356 Reviewed-by: Joost De Cock Co-authored-by: Benjamin Fan Co-committed-by: Benjamin Fan --- packages/react/components/Editor/components/HeaderMenu.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react/components/Editor/components/HeaderMenu.mjs b/packages/react/components/Editor/components/HeaderMenu.mjs index 49f59b3d3f9..ee444d20193 100644 --- a/packages/react/components/Editor/components/HeaderMenu.mjs +++ b/packages/react/components/Editor/components/HeaderMenu.mjs @@ -302,7 +302,7 @@ export const HeaderMenuDraftViewIcons = (props) => { tooltip="Switches Units between metric and imperial (see Core Settings)" > ) : null} From 5dc1cd98fb95ddcb2f641178bab94414e8346538 Mon Sep 17 00:00:00 2001 From: Benjamin Fan Date: Sun, 18 May 2025 10:58:16 +0000 Subject: [PATCH 11/46] fix(react): Display doNotTranslate list option values (#358) When testing with the repository studio, it fixes the issue with Breanna (the only design that uses `doNotTranslate` list options), and I didn't see any regressions with other designs like Hi. Fixes #347 Co-authored-by: Benjamin Fan Reviewed-on: https://codeberg.org/freesewing/freesewing/pulls/358 Reviewed-by: Joost De Cock Co-authored-by: Benjamin Fan Co-committed-by: Benjamin Fan --- packages/react/components/Editor/components/menus/Input.mjs | 4 +++- packages/react/components/Editor/components/menus/Value.mjs | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/react/components/Editor/components/menus/Input.mjs b/packages/react/components/Editor/components/menus/Input.mjs index 0eb32377987..25fd0dba999 100644 --- a/packages/react/components/Editor/components/menus/Input.mjs +++ b/packages/react/components/Editor/components/menus/Input.mjs @@ -149,7 +149,9 @@ export const MenuListInput = ({ : 'tw:flex-col tw:items-start' }`} > -
{config.choiceTitles[entry]}
+
+ {config.doNotTranslate ? entry : config.choiceTitles[entry]} +
{compact || !config.choiceDescriptions ? null : (
{ else if (val) key = else key = - const translated = config.doNotTranslate || key + const translated = config.doNotTranslate ? val : key return {translated} } From a3fe0cd477c09dfdf74b32d2f1ad17f7c099cadd Mon Sep 17 00:00:00 2001 From: Benjamin Fan Date: Sun, 18 May 2025 13:31:02 +0000 Subject: [PATCH 12/46] fix(react): Add link to design docs to Pattern Editor's Documentation view (#359) This PR adds a link to the design documentation to the Pattern Editor's Documentation View. It also fixes a few typos and changes a URL from freesewing.org to freesewing.eu. Fixes #267 Co-authored-by: Benjamin Fan Reviewed-on: https://codeberg.org/freesewing/freesewing/pulls/359 Reviewed-by: Joost De Cock Co-authored-by: Benjamin Fan Co-committed-by: Benjamin Fan --- .../Editor/components/views/DocsView.mjs | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/packages/react/components/Editor/components/views/DocsView.mjs b/packages/react/components/Editor/components/views/DocsView.mjs index 9f14a3ee682..19750c43fb0 100644 --- a/packages/react/components/Editor/components/views/DocsView.mjs +++ b/packages/react/components/Editor/components/views/DocsView.mjs @@ -1,5 +1,5 @@ // Dependencies -import { linkClasses } from '@freesewing/utils' +import { linkClasses, capitalize } from '@freesewing/utils' // Hooks import React from 'react' // Components @@ -20,7 +20,22 @@ export const DocsView = ({ state, config, update }) => { <>
-

Documenation

+

Documentation

+ {state?.design ? ( + +
Design Documentation
+

+ You can find documentation for the {capitalize(state.design)} design at: +
+ + {`FreeSewing.eu/docs/designs/${state.design}`} + +

+
+ ) : null}
Understanding the FreeSewing Pattern Editor

@@ -29,8 +44,8 @@ export const DocsView = ({ state, config, update }) => { {`FreeSewing.org/docs/about/editor`} + href="https://freesewing.eu/docs/about/editor" + >{`FreeSewing.eu/docs/about/editor`}

From 3799e039ae1f81990157f55007723c644060d4c9 Mon Sep 17 00:00:00 2001 From: Benjamin Fan Date: Sun, 18 May 2025 13:33:30 +0000 Subject: [PATCH 13/46] fix(react): PDF cover page improvements (#360) Exported PDF cover page improvements: 1. Translates flags, instead of just printing the bare keys 2. Omit layout info, when the parts are moved around in pattern layout Fixes #274 Fixes #350 Co-authored-by: Benjamin Fan Reviewed-on: https://codeberg.org/freesewing/freesewing/pulls/360 Reviewed-by: Joost De Cock Co-authored-by: Benjamin Fan Co-committed-by: Benjamin Fan --- packages/react/components/Editor/lib/export/index.mjs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/react/components/Editor/lib/export/index.mjs b/packages/react/components/Editor/lib/export/index.mjs index 21696d68771..05669ad4625 100644 --- a/packages/react/components/Editor/lib/export/index.mjs +++ b/packages/react/components/Editor/lib/export/index.mjs @@ -158,7 +158,9 @@ export const handleExport = async ({ workerArgs.strings.setName = settings?.metadata?.setName ? settings.metadata.setName : 'ephemeral' - workerArgs.strings.yaml = yaml.dump(settings) + const settingsWithoutLayout = structuredClone(settings) + delete settingsWithoutLayout.layout + workerArgs.strings.yaml = yaml.dump(settingsWithoutLayout) workerArgs.strings.version = store?.data?.version ? store.data.version : '' const notes = store?.plugins?.['plugin-annotations']?.flags?.note ? store?.plugins?.['plugin-annotations']?.flags?.note @@ -190,9 +192,9 @@ const flagsToString = (flags, mustache, t) => { let first = true let string = '' for (const flag of Object.values(flags)) { - let title = flag.replace ? mustache.render(flag.title, flag.replace) : flag.title + let title = flag.replace ? mustache.render(t(flag.title), flag.replace) : t(flag.title) title = he.decode(title) - let desc = flag.replace ? mustache.render(flag.desc, flag.replace) : flag.desc + let desc = flag.replace ? mustache.render(t(flag.desc), flag.replace) : t(flag.desc) desc = desc.replaceAll('\n\n', '\n') desc = desc.replaceAll('\n', ' ') desc = he.decode(desc) From b864574e878d31eabc43b009f572db72a501b217 Mon Sep 17 00:00:00 2001 From: Benjamin Fan Date: Sun, 18 May 2025 13:34:06 +0000 Subject: [PATCH 14/46] fix(wahid): Add interfacing to front cutlist (#362) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wahid's cutting instructions and sewing instructions mention 2 front interfacing parts. So, it is a bug that the pattern is missing the “cut 2 from interfacing”. This issue was brought up on the Forum: https://forum.freesewing.eu/t/hello-thank-you-and-a-couple-of-suggestions-for-wahid/208 Co-authored-by: Benjamin Fan Reviewed-on: https://codeberg.org/freesewing/freesewing/pulls/362 Reviewed-by: Joost De Cock Co-authored-by: Benjamin Fan Co-committed-by: Benjamin Fan --- designs/wahid/src/front.mjs | 1 + 1 file changed, 1 insertion(+) diff --git a/designs/wahid/src/front.mjs b/designs/wahid/src/front.mjs index 8adff217f51..4f113a05264 100644 --- a/designs/wahid/src/front.mjs +++ b/designs/wahid/src/front.mjs @@ -343,6 +343,7 @@ function wahidFront({ */ // Cutlist store.cutlist.setCut({ cut: 2, from: 'fabric' }) + store.cutlist.addCut({ cut: 2, from: 'interfacing' }) // Buttons points.button1 = new Point(0, points.closureTop.y + 10) From a7eb3e0072f23cca3358692d54d1c1b4e635eae5 Mon Sep 17 00:00:00 2001 From: Benjamin Fan Date: Mon, 19 May 2025 08:02:56 +0200 Subject: [PATCH 15/46] fix(react): Allow bookmark title to be edited (#366) Currently it isn't possible to edit the title of a bookmark (for example, when bookmarking a Measurements Set) for 2 reasons: 1. The modal closes as soon as you click in the title text edit box. 2. The created bookmark uses the original title, ignoring edits made to it. This PR fixes both issues. Co-authored-by: Benjamin Fan Reviewed-on: https://codeberg.org/freesewing/freesewing/pulls/366 Reviewed-by: Joost De Cock Co-authored-by: Benjamin Fan Co-committed-by: Benjamin Fan --- packages/react/components/Account/Bookmarks.mjs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/react/components/Account/Bookmarks.mjs b/packages/react/components/Account/Bookmarks.mjs index cd25e37bb32..c6eed2402eb 100644 --- a/packages/react/components/Account/Bookmarks.mjs +++ b/packages/react/components/Account/Bookmarks.mjs @@ -259,7 +259,12 @@ export const BookmarkButton = ({ slug, type, title }) => { className={`tw:daisy-btn tw:daisy-btn-secondary tw:daisy-btn-outline ${horFlexClasses}`} onClick={() => setModal( - + ) @@ -291,6 +296,7 @@ export const CreateBookmark = ({ type, title, slug }) => { const bookmark = async (evt) => { evt.stopPropagation() setLoadingStatus([true, 'Contacting backend']) + let title = name const [status] = await backend.createBookmark({ type, title, url }) if (status === 201) { setLoadingStatus([true, 'Bookmark created', true, true]) From ed8a166ea906aa4e74f9220679aafca5c967b27a Mon Sep 17 00:00:00 2001 From: Benjamin Fan Date: Mon, 19 May 2025 08:04:05 +0200 Subject: [PATCH 16/46] fix(reference:api): Revert incorrect Example formatting (#367) This PR reverts the incorrect lint/prettier changes applied to code in the reference Core API docs l by the husky pre-commit hook, the problem mentioned in Issue #333. (These are just the changes for the Core API docs. Additional PRs will be filed for changes in the other reference, howtos, and guides documentation.) Co-authored-by: Benjamin Fan Reviewed-on: https://codeberg.org/freesewing/freesewing/pulls/367 Reviewed-by: Joost De Cock Co-authored-by: Benjamin Fan Co-committed-by: Benjamin Fan --- .../reference/api/path/addclass/readme.mdx | 19 +++-- .../reference/api/path/addtext/readme.mdx | 15 ++-- .../reference/api/path/angleat/readme.mdx | 44 ++++++------ .../docs/reference/api/path/attr/readme.mdx | 22 +++--- .../api/path/circlesegment/readme.mdx | 25 ++++--- .../docs/reference/api/path/close/readme.mdx | 22 +++--- .../docs/reference/api/path/curve/readme.mdx | 20 +++--- .../docs/reference/api/path/curve_/readme.mdx | 10 +-- .../docs/reference/api/path/end/readme.mdx | 24 +++---- .../docs/reference/api/path/hide/readme.mdx | 16 ++--- .../docs/reference/api/path/insop/readme.mdx | 43 ++++++------ .../docs/reference/api/path/line/readme.mdx | 16 ++--- .../docs/reference/api/path/noop/readme.mdx | 42 ++++++----- .../reference/api/path/setclass/readme.mdx | 19 +++-- .../reference/api/path/sethidden/readme.mdx | 16 ++--- .../reference/api/path/settext/readme.mdx | 15 ++-- .../docs/reference/api/path/smurve/readme.mdx | 28 ++++---- .../reference/api/path/smurve_/readme.mdx | 28 ++++---- .../docs/reference/api/path/start/readme.mdx | 24 +++---- .../docs/reference/api/path/ucurve/readme.mdx | 18 ++--- .../docs/reference/api/path/unhide/readme.mdx | 18 +++-- .../reference/api/point/addcircle/readme.mdx | 22 +++--- .../reference/api/point/addtext/readme.mdx | 15 ++-- .../docs/reference/api/point/attr/readme.mdx | 21 +++--- .../docs/reference/api/point/clone/readme.mdx | 24 +++---- .../reference/api/point/setcircle/readme.mdx | 28 ++++---- .../reference/api/point/settext/readme.mdx | 20 +++--- .../reference/api/snippet/attr/readme.mdx | 20 +++--- .../reference/api/snippet/rotate/readme.mdx | 28 ++++---- .../reference/api/snippet/scale/readme.mdx | 28 ++++---- .../api/utils/beamintersectsline/readme.mdx | 2 +- .../api/utils/curveintersectsx/readme.mdx | 64 ++++++++--------- .../api/utils/curveintersectsy/readme.mdx | 66 +++++++++-------- .../api/utils/curvesintersect/readme.mdx | 70 +++++++++---------- 34 files changed, 421 insertions(+), 471 deletions(-) diff --git a/sites/dev/docs/reference/api/path/addclass/readme.mdx b/sites/dev/docs/reference/api/path/addclass/readme.mdx index 6e7125af5d6..b382e899ce7 100644 --- a/sites/dev/docs/reference/api/path/addclass/readme.mdx +++ b/sites/dev/docs/reference/api/path/addclass/readme.mdx @@ -20,18 +20,17 @@ This method is chainable as it returns the `Path` object ```js ({ Point, points, Path, paths, part }) => { -points.from = new Point(5, 10) -points.to = new Point(95, 10) + points.from = new Point(5, 10) + points.to = new Point(95, 10) -paths.line = new Path() -.move(points.from) -.line(points.to) -.addClass('note dashed') + paths.line = new Path() + .move(points.from) + .line(points.to) + .addClass('note dashed') -return part + return part } - -```` +``` ## Notes @@ -42,4 +41,4 @@ as the two following calls yield the same result: ```js path.attr('class', 'fabric') path.addClass('fabric') -```` +``` diff --git a/sites/dev/docs/reference/api/path/addtext/readme.mdx b/sites/dev/docs/reference/api/path/addtext/readme.mdx index 628fdd7032c..8df98787137 100644 --- a/sites/dev/docs/reference/api/path/addtext/readme.mdx +++ b/sites/dev/docs/reference/api/path/addtext/readme.mdx @@ -24,15 +24,14 @@ This method is chainable as it returns the `Path` object points.from = new Point(5, 10) points.to = new Point(95, 10) -paths.line = new Path() -.move(points.from) -.line(points.to) -.addText('FreeSewing rocks') + paths.line = new Path() + .move(points.from) + .line(points.to) + .addText('FreeSewing rocks') -return part + return part } - -```` +``` ## Notes @@ -43,7 +42,7 @@ as the two following calls yield the same result: ```js path.attr('data-text', 'Hello') path.addText('Hello') -```` +``` The difference with [Path.setText()](/reference/api/path/addtext) is that this method will add to the existing text whereas `Path.setText()` will overwrite diff --git a/sites/dev/docs/reference/api/path/angleat/readme.mdx b/sites/dev/docs/reference/api/path/angleat/readme.mdx index 7068802c39c..f10772ccfe8 100644 --- a/sites/dev/docs/reference/api/path/angleat/readme.mdx +++ b/sites/dev/docs/reference/api/path/angleat/readme.mdx @@ -20,35 +20,35 @@ number|false path.angleAt(Point point) ```js ({ Point, points, Path, paths, snippets, Snippet, part }) => { -points.A = new Point(45, 60) -points.B = new Point(10, 30) -points.BCp2 = new Point(40, 20) -points.C = new Point(90, 30) -points.CCp1 = new Point(50, -30) -points.D = new Point(50, 80) -points.DCp1 = new Point(70, 30) + points.A = new Point(45, 60) + points.B = new Point(10, 30) + points.BCp2 = new Point(40, 20) + points.C = new Point(90, 30) + points.CCp1 = new Point(50, -30) + points.D = new Point(50, 80) + points.DCp1 = new Point(70, 30) -paths.demo = new Path() -.move(points.D) -.curve(points.DCp1, points.DCp1, points.C) -.curve(points.CCp1, points.BCp2, points.B) -.line(points.A) + paths.demo = new Path() + .move(points.D) + .curve(points.DCp1, points.DCp1, points.C) + .curve(points.CCp1, points.BCp2, points.B) + .line(points.A) -points.testPoint = paths.demo.shiftFractionAlong(0.55) -snippets.point = new Snippet("notch", points.testPoint) + points.testPoint = paths.demo.shiftFractionAlong(0.55) + snippets.point = new Snippet("notch", points.testPoint) -let angle = paths.demo.angleAt(points.testPoint) -//draw a tangent path -paths.tangent = new Path() - .move(points.testPoint.shift(angle, -30)) - .line(points.testPoint.shift(angle, 30)) - .attr("class", "lining dashed") + let angle = paths.demo.angleAt(points.testPoint) + //draw a tangent path + paths.tangent = new Path() + .move(points.testPoint.shift(angle, -30)) + .line(points.testPoint.shift(angle, 30)) + .attr("class", "lining dashed") -return part + return part } ``` - + ## Notes Keep in mind that calculations with Bézier curves are often approximations. diff --git a/sites/dev/docs/reference/api/path/attr/readme.mdx b/sites/dev/docs/reference/api/path/attr/readme.mdx index a3dacc9cc72..72cdedc33ef 100644 --- a/sites/dev/docs/reference/api/path/attr/readme.mdx +++ b/sites/dev/docs/reference/api/path/attr/readme.mdx @@ -28,20 +28,19 @@ This method is chainable as it returns the `Path` object ```js ({ Point, points, Path, paths, part }) => { -points.from = new Point(10, 20) -points.cp1 = new Point(20, -10) -points.cp2 = new Point(50, 50) -points.to = new Point(70, 20) + points.from = new Point(10, 20) + points.cp1 = new Point(20, -10) + points.cp2 = new Point(50, 50) + points.to = new Point(70, 20) -paths.example = new Path() -.move(points.from) -.curve(points.cp1, points.cp2, points.to) -.attr("class", "canvas") -.setText("FreeSewing rocks", "text-xs center") + paths.example = new Path() + .move(points.from) + .curve(points.cp1, points.cp2, points.to) + .attr("class", "canvas") + .setText("FreeSewing rocks", "text-xs center") -return part + return part } - ``` @@ -57,4 +56,3 @@ all call this method under the hood. See [Using Attributes](/howtos/code/attributes) for information about custom Attributes that can be used with Paths. -``` diff --git a/sites/dev/docs/reference/api/path/circlesegment/readme.mdx b/sites/dev/docs/reference/api/path/circlesegment/readme.mdx index 011722041a4..fd5e5bb95d6 100644 --- a/sites/dev/docs/reference/api/path/circlesegment/readme.mdx +++ b/sites/dev/docs/reference/api/path/circlesegment/readme.mdx @@ -36,23 +36,22 @@ This method is chainable as it returns the `Path` object ```js ({ Point, points, Path, paths, part }) => { -points.from = new Point(10, 20) -points.origin = new Point(40, 0) + points.from = new Point(10, 20) + points.origin = new Point(40, 0) -paths.line = new Path() -.move(points.from) -.circleSegment(90, points.origin) -.setText("→ Path.circleSegment() →", "text-sm center fill-note") + paths.line = new Path() + .move(points.from) + .circleSegment(90, points.origin) + .setText("→ Path.circleSegment() →", "text-sm center fill-note") -paths.helper = new Path() -.move(paths.line.start()) -.line(points.origin) -.line(paths.line.end()) -.setClass('dotted stroke-sm') + paths.helper = new Path() + .move(paths.line.start()) + .line(points.origin) + .line(paths.line.end()) + .setClass('dotted stroke-sm') -return part + return part } ``` -``` diff --git a/sites/dev/docs/reference/api/path/close/readme.mdx b/sites/dev/docs/reference/api/path/close/readme.mdx index 401e3f5e936..2e9b9b11bbd 100644 --- a/sites/dev/docs/reference/api/path/close/readme.mdx +++ b/sites/dev/docs/reference/api/path/close/readme.mdx @@ -20,20 +20,18 @@ This method is chainable as it returns the `Path` object ```js ({ Point, points, Path, paths, part }) => { -points.from = new Point(10, 20) -points.cp2 = new Point(60, 30) -points.to = new Point(90, 20) + points.from = new Point(10, 20) + points.cp2 = new Point(60, 30) + points.to = new Point(90, 20) -paths.line = new Path() -.move(points.from) -.\_curve(points.cp2, points.to) -.close() -.reverse() // To keep text from being upside-down -.setText('Path.\_close()', 'text-sm right fill-note') + paths.line = new Path() + .move(points.from) + ._curve(points.cp2, points.to) + .close() + .reverse() // To keep text from being upside-down + .setText('Path._close()', 'text-sm right fill-note') -return part + return part } - ``` -``` diff --git a/sites/dev/docs/reference/api/path/curve/readme.mdx b/sites/dev/docs/reference/api/path/curve/readme.mdx index 9417645efa6..aef43cbcbfd 100644 --- a/sites/dev/docs/reference/api/path/curve/readme.mdx +++ b/sites/dev/docs/reference/api/path/curve/readme.mdx @@ -21,19 +21,17 @@ This method is chainable as it returns the `Path` object ```js ({ Point, points, Path, paths, part }) => { -points.from = new Point(10, 20) -points.cp1 = new Point(40, 0) -points.cp2 = new Point(60, 40) -points.to = new Point(90, 20) + points.from = new Point(10, 20) + points.cp1 = new Point(40, 0) + points.cp2 = new Point(60, 40) + points.to = new Point(90, 20) -paths.line = new Path() -.move(points.from) -.curve(points.cp1, points.cp2, points.to) -.setText("Path.curve()", "text-sm center fill-note") + paths.line = new Path() + .move(points.from) + .curve(points.cp1, points.cp2, points.to) + .setText("Path.curve()", "text-sm center fill-note") -return part + return part } - ``` -``` diff --git a/sites/dev/docs/reference/api/path/curve_/readme.mdx b/sites/dev/docs/reference/api/path/curve_/readme.mdx index 26f99862e16..48cf1c5d22f 100644 --- a/sites/dev/docs/reference/api/path/curve_/readme.mdx +++ b/sites/dev/docs/reference/api/path/curve_/readme.mdx @@ -3,7 +3,7 @@ title: Path.curve_() --- The `Path.curve_()` method draws a cubic Bézier curve from the current position -via two control points to a given endpoint. However, the end control point is +via two control points to a given endpoint. However, the end control point is identical to the end point. ## Signature @@ -18,10 +18,12 @@ This method is chainable as it returns the `Path` object ## Example + ```js -;({ Point, points, Path, paths, part }) => { +({ Point, points, Path, paths, part }) => { + points.from = new Point(10, 20) points.cp1 = new Point(40, 0) points.to = new Point(90, 20) @@ -29,8 +31,8 @@ This method is chainable as it returns the `Path` object paths.line = new Path() .move(points.from) .curve_(points.cp1, points.to) - .setText('Path.curve_()', 'text-sm center fill-note') - .attr('data-text-dy', -1) + .setText("Path.curve_()", "text-sm center fill-note") + .attr("data-text-dy", -1) return part } diff --git a/sites/dev/docs/reference/api/path/end/readme.mdx b/sites/dev/docs/reference/api/path/end/readme.mdx index c281b0df185..7b6db98e748 100644 --- a/sites/dev/docs/reference/api/path/end/readme.mdx +++ b/sites/dev/docs/reference/api/path/end/readme.mdx @@ -20,22 +20,20 @@ This method is chainable as it returns the `Path` object ```js ({ Point, points, Path, paths, snippets, Snippet, part }) => { -points.A = new Point(45, 60) -points.B = new Point(10, 30) -points.BCp2 = new Point(40, 20) -points.C = new Point(90, 30) -points.CCp1 = new Point(50, -30) + points.A = new Point(45, 60) + points.B = new Point(10, 30) + points.BCp2 = new Point(40, 20) + points.C = new Point(90, 30) + points.CCp1 = new Point(50, -30) -paths.demo = new Path() -.move(points.A) -.line(points.B) -.curve(points.BCp2, points.CCp1, points.C) + paths.demo = new Path() + .move(points.A) + .line(points.B) + .curve(points.BCp2, points.CCp1, points.C) -snippets.end = new Snippet("notch", paths.demo.end()) + snippets.end = new Snippet("notch", paths.demo.end()) -return part + return part } - ``` -``` diff --git a/sites/dev/docs/reference/api/path/hide/readme.mdx b/sites/dev/docs/reference/api/path/hide/readme.mdx index f6405f0eb57..0d082d3cd63 100644 --- a/sites/dev/docs/reference/api/path/hide/readme.mdx +++ b/sites/dev/docs/reference/api/path/hide/readme.mdx @@ -20,17 +20,15 @@ This method is chainable as it returns the `Path` object ```js ({ Point, points, Path, paths, part }) => { -points.top = new Point(50, 0) -points.left = new Point (20,50) -points.right = new Point (80,50) + points.top = new Point(50, 0) + points.left = new Point (20,50) + points.right = new Point (80,50) -paths.a = new Path().move(points.top).line(points.right).setText('a') -paths.b = new Path().move(points.right).line(points.left).setText('b').hide() -paths.c = new Path().move(points.left).line(points.top).setText('c') + paths.a = new Path().move(points.top).line(points.right).setText('a') + paths.b = new Path().move(points.right).line(points.left).setText('b').hide() + paths.c = new Path().move(points.left).line(points.top).setText('c') -return part + return part } - ``` -``` diff --git a/sites/dev/docs/reference/api/path/insop/readme.mdx b/sites/dev/docs/reference/api/path/insop/readme.mdx index fb923ceece2..f36c979fef5 100644 --- a/sites/dev/docs/reference/api/path/insop/readme.mdx +++ b/sites/dev/docs/reference/api/path/insop/readme.mdx @@ -15,39 +15,38 @@ Path path.insop(string id, Path path) This method is chainable as it returns the `Path` object ::: + ```js ({ Point, points, Path, paths, part }) => { -points.left = new Point(10,10) -points.dartLeft = new Point(40, 10) -points.dartTip = new Point(50, 50) -points.dartRight = new Point(60, 10) -points.right = new Point(90, 10) + points.left = new Point(10,10) + points.dartLeft = new Point(40, 10) + points.dartTip = new Point(50, 50) + points.dartRight = new Point(60, 10) + points.right = new Point(90, 10) -paths.withoutDart = new Path() -.move(points.left) -.line(points.dartLeft) -.noop('dart') -.line(points.right) + paths.withoutDart = new Path() + .move(points.left) + .line(points.dartLeft) + .noop('dart') + .line(points.right) -paths.withDart = paths.withoutDart -.clone() -.insop( -'dart', -new Path() -.line(points.dartTip) -.line(points.dartRight) -) -.attr('style', 'stroke-width: 2px; stroke-opacity: 0.5; stroke: orange;') + paths.withDart = paths.withoutDart + .clone() + .insop( + 'dart', + new Path() + .line(points.dartTip) + .line(points.dartRight) + ) + .attr('style', 'stroke-width: 2px; stroke-opacity: 0.5; stroke: orange;') -return part + return part } - ``` ## Notes This is often used to insert darts into a path. -``` diff --git a/sites/dev/docs/reference/api/path/line/readme.mdx b/sites/dev/docs/reference/api/path/line/readme.mdx index 40c719bce89..4832c6a00a5 100644 --- a/sites/dev/docs/reference/api/path/line/readme.mdx +++ b/sites/dev/docs/reference/api/path/line/readme.mdx @@ -21,17 +21,15 @@ This method is chainable as it returns the `Path` object ```js ({ Point, points, Path, paths, part }) => { -points.from = new Point(10, 10) -points.to = new Point(90, 10) + points.from = new Point(10, 10) + points.to = new Point(90, 10) -paths.line = new Path() -.move(points.from) -.line(points.to) -.setText("Path.line()", "text-sm center fill-note") + paths.line = new Path() + .move(points.from) + .line(points.to) + .setText("Path.line()", "text-sm center fill-note") -return part + return part } - ``` -``` diff --git a/sites/dev/docs/reference/api/path/noop/readme.mdx b/sites/dev/docs/reference/api/path/noop/readme.mdx index 98c9cee7203..ed9391bb46c 100644 --- a/sites/dev/docs/reference/api/path/noop/readme.mdx +++ b/sites/dev/docs/reference/api/path/noop/readme.mdx @@ -22,31 +22,29 @@ This method is chainable as it returns the `Path` object ```js ({ Point, points, Path, paths, part }) => { -points.left = new Point(10,10) -points.dartLeft = new Point(40, 10) -points.dartTip = new Point(50, 50) -points.dartRight = new Point(60, 10) -points.right = new Point(90, 10) + points.left = new Point(10,10) + points.dartLeft = new Point(40, 10) + points.dartTip = new Point(50, 50) + points.dartRight = new Point(60, 10) + points.right = new Point(90, 10) -paths.withoutDart = new Path() -.move(points.left) -.line(points.dartLeft) -.noop('dart') -.line(points.right) + paths.withoutDart = new Path() + .move(points.left) + .line(points.dartLeft) + .noop('dart') + .line(points.right) -paths.withDart = paths.withoutDart -.clone() -.insop( -'dart', -new Path() -.line(points.dartTip) -.line(points.dartRight) -) -.attr('style', 'stroke-width: 2px; stroke-opacity: 0.5; stroke: orange;') + paths.withDart = paths.withoutDart + .clone() + .insop( + 'dart', + new Path() + .line(points.dartTip) + .line(points.dartRight) + ) + .attr('style', 'stroke-width: 2px; stroke-opacity: 0.5; stroke: orange;') -return part + return part } - ``` -``` diff --git a/sites/dev/docs/reference/api/path/setclass/readme.mdx b/sites/dev/docs/reference/api/path/setclass/readme.mdx index 20d89623396..930322bbe74 100644 --- a/sites/dev/docs/reference/api/path/setclass/readme.mdx +++ b/sites/dev/docs/reference/api/path/setclass/readme.mdx @@ -20,18 +20,17 @@ This method is chainable as it returns the `Path` object ```js ({ Point, points, Path, paths, part }) => { -points.from = new Point(5, 10) -points.to = new Point(95, 10) + points.from = new Point(5, 10) + points.to = new Point(95, 10) -paths.line = new Path() -.move(points.from) -.line(points.to) -.setClass('note dashed') + paths.line = new Path() + .move(points.from) + .line(points.to) + .setClass('note dashed') -return part + return part } - -```` +``` ## Notes @@ -42,4 +41,4 @@ as the two following calls yield the same result: ```js path.attr('class', 'fabric', true) path.setClass('fabric') -```` +``` diff --git a/sites/dev/docs/reference/api/path/sethidden/readme.mdx b/sites/dev/docs/reference/api/path/sethidden/readme.mdx index ddf431aea5a..968444f47ad 100644 --- a/sites/dev/docs/reference/api/path/sethidden/readme.mdx +++ b/sites/dev/docs/reference/api/path/sethidden/readme.mdx @@ -21,17 +21,15 @@ This method is chainable as it returns the `Path` object ```js ({ Point, points, Path, paths, part }) => { -points.top = new Point(50, 0) -points.left = new Point (20,50) -points.right = new Point (80,50) + points.top = new Point(50, 0) + points.left = new Point (20,50) + points.right = new Point (80,50) -paths.a = new Path().move(points.top).line(points.right).setText('a') -paths.b = new Path().move(points.right).line(points.left).setText('b').setHidden(true) -paths.c = new Path().move(points.left).line(points.top).setText('c') + paths.a = new Path().move(points.top).line(points.right).setText('a') + paths.b = new Path().move(points.right).line(points.left).setText('b').setHidden(true) + paths.c = new Path().move(points.left).line(points.top).setText('c') -return part + return part } - ``` -``` diff --git a/sites/dev/docs/reference/api/path/settext/readme.mdx b/sites/dev/docs/reference/api/path/settext/readme.mdx index acf7203cd23..e521afa2a9a 100644 --- a/sites/dev/docs/reference/api/path/settext/readme.mdx +++ b/sites/dev/docs/reference/api/path/settext/readme.mdx @@ -24,15 +24,14 @@ This method is chainable as it returns the `Path` object points.from = new Point(5, 10) points.to = new Point(95, 10) -paths.line = new Path() -.move(points.from) -.line(points.to) -.setText('FreeSewing rocks') + paths.line = new Path() + .move(points.from) + .line(points.to) + .setText('FreeSewing rocks') -return part + return part } - -```` +``` ## Notes @@ -43,7 +42,7 @@ as the two following calls yield the same result: ```js path.attr('data-text', 'Hello') path.setText('Hello') -```` +``` The difference with [Path.addText()](/reference/api/path/addtext) is that this method will overwrite existing text on the path, whereas `Path.addText()` will diff --git a/sites/dev/docs/reference/api/path/smurve/readme.mdx b/sites/dev/docs/reference/api/path/smurve/readme.mdx index dac2cf65ab9..e69c8588547 100644 --- a/sites/dev/docs/reference/api/path/smurve/readme.mdx +++ b/sites/dev/docs/reference/api/path/smurve/readme.mdx @@ -21,24 +21,22 @@ This method is chainable as it returns the `Path` object ```js ({ Point, points, Path, paths, part }) => { -points.aFrom = new Point(10, 10) -points.aCp1 = new Point(40, 40) -points.aCp2 = new Point(70, -20) -points.aTo = new Point(100, 10) + points.aFrom = new Point(10, 10) + points.aCp1 = new Point(40, 40) + points.aCp2 = new Point(70, -20) + points.aTo = new Point(100, 10) -points.bCp2 = new Point(50,50) -points.bTo = new Point(10,50) + points.bCp2 = new Point(50,50) + points.bTo = new Point(10,50) -paths.smurve = new Path() -.move(points.aFrom) -.curve(points.aCp1, points.aCp2,points.aTo) -.smurve(points.bCp2, points.bTo) -.reverse() // Puts text at the end -.setText('Path.smurve()') + paths.smurve = new Path() + .move(points.aFrom) + .curve(points.aCp1, points.aCp2,points.aTo) + .smurve(points.bCp2, points.bTo) + .reverse() // Puts text at the end + .setText('Path.smurve()') -return part + return part } - ``` -``` diff --git a/sites/dev/docs/reference/api/path/smurve_/readme.mdx b/sites/dev/docs/reference/api/path/smurve_/readme.mdx index b677203c034..cf64310fa46 100644 --- a/sites/dev/docs/reference/api/path/smurve_/readme.mdx +++ b/sites/dev/docs/reference/api/path/smurve_/readme.mdx @@ -14,7 +14,7 @@ Path path.smurve_(Point cp2, Point end) ``` :::tip -This method is chainable as it returns the `Path` object +This method is chainable as it returns the `Path` objecti ::: ## Example @@ -23,23 +23,21 @@ This method is chainable as it returns the `Path` object ```js ({ Point, points, Path, paths, part }) => { -points.aFrom = new Point(10, 10) -points.aCp1 = new Point(40, 40) -points.aCp2 = new Point(70, -20) -points.aTo = new Point(100, 10) + points.aFrom = new Point(10, 10) + points.aCp1 = new Point(40, 40) + points.aCp2 = new Point(70, -20) + points.aTo = new Point(100, 10) -points.bTo = new Point(10,50) + points.bTo = new Point(10,50) -paths.smurve = new Path() -.move(points.aFrom) -.curve(points.aCp1, points.aCp2,points.aTo) -.smurve\_(points.bTo) -.reverse() // Puts text at the end -.setText('Path.smurve()') + paths.smurve = new Path() + .move(points.aFrom) + .curve(points.aCp1, points.aCp2,points.aTo) + .smurve_(points.bTo) + .reverse() // Puts text at the end + .setText('Path.smurve()') -return part + return part } - ``` -``` diff --git a/sites/dev/docs/reference/api/path/start/readme.mdx b/sites/dev/docs/reference/api/path/start/readme.mdx index bf01f1f7a3a..2a74758f579 100644 --- a/sites/dev/docs/reference/api/path/start/readme.mdx +++ b/sites/dev/docs/reference/api/path/start/readme.mdx @@ -20,22 +20,20 @@ This method is chainable as it returns the `Path` object ```js ({ Point, points, Path, paths, snippets, Snippet, part }) => { -points.A = new Point(45, 60) -points.B = new Point(10, 30) -points.BCp2 = new Point(40, 20) -points.C = new Point(90, 30) -points.CCp1 = new Point(50, -30) + points.A = new Point(45, 60) + points.B = new Point(10, 30) + points.BCp2 = new Point(40, 20) + points.C = new Point(90, 30) + points.CCp1 = new Point(50, -30) -paths.demo = new Path() -.move(points.A) -.line(points.B) -.curve(points.BCp2, points.CCp1, points.C) + paths.demo = new Path() + .move(points.A) + .line(points.B) + .curve(points.BCp2, points.CCp1, points.C) -snippets.end = new Snippet("notch", paths.demo.start()) + snippets.end = new Snippet("notch", paths.demo.start()) -return part + return part } - ``` -``` diff --git a/sites/dev/docs/reference/api/path/ucurve/readme.mdx b/sites/dev/docs/reference/api/path/ucurve/readme.mdx index 082f61b8e09..9c19f0f9cb8 100644 --- a/sites/dev/docs/reference/api/path/ucurve/readme.mdx +++ b/sites/dev/docs/reference/api/path/ucurve/readme.mdx @@ -23,17 +23,17 @@ This method is chainable as it returns the `Path` object ```js ({ Point, points, Path, paths, part }) => { -points.from = new Point(5, 20) -points.cp2 = new Point(60, 50) -points.to = new Point(90, 20) + points.from = new Point(5, 20) + points.cp2 = new Point(60, 50) + points.to = new Point(90, 20) -paths.line = new Path() -.move(points.from) -.\_curve(points.cp2, points.to) -.setText("Path.\_curve()", "text-sm center fill-note") -.attr("data-text-dy", -1) + paths.line = new Path() + .move(points.from) + ._curve(points.cp2, points.to) + .setText("Path._curve()", "text-sm center fill-note") + .attr("data-text-dy", -1) -return part + return part } ```` diff --git a/sites/dev/docs/reference/api/path/unhide/readme.mdx b/sites/dev/docs/reference/api/path/unhide/readme.mdx index 9fe308188e3..15a1ec1abc3 100644 --- a/sites/dev/docs/reference/api/path/unhide/readme.mdx +++ b/sites/dev/docs/reference/api/path/unhide/readme.mdx @@ -2,7 +2,7 @@ title: Path.unhide() --- -The `Path.unhide()` method unhides the path so it appears in the output. By +The `Path.unhide()` method unhides the path so it appears in the output. By default, paths are not hidden. So you should only call this on path previously hidden via `Path.hide()`. @@ -22,17 +22,15 @@ This method is chainable as it returns the `Path` object ```js ({ Point, points, Path, paths, part }) => { -points.top = new Point(50, 0) -points.left = new Point (20,50) -points.right = new Point (80,50) + points.top = new Point(50, 0) + points.left = new Point (20,50) + points.right = new Point (80,50) -paths.a = new Path().move(points.top).line(points.right).setText('a') -paths.b = new Path().move(points.right).line(points.left).setText('b').hide().unhide() -paths.c = new Path().move(points.left).line(points.top).setText('c') + paths.a = new Path().move(points.top).line(points.right).setText('a') + paths.b = new Path().move(points.right).line(points.left).setText('b').hide().unhide() + paths.c = new Path().move(points.left).line(points.top).setText('c') -return part + return part } - ``` -``` diff --git a/sites/dev/docs/reference/api/point/addcircle/readme.mdx b/sites/dev/docs/reference/api/point/addcircle/readme.mdx index a5670fb1f3e..11732fba30e 100644 --- a/sites/dev/docs/reference/api/point/addcircle/readme.mdx +++ b/sites/dev/docs/reference/api/point/addcircle/readme.mdx @@ -28,20 +28,18 @@ This method is chainable as it returns the `Point` object .addCircle(3, 'lining dashed') .addCircle(7, 'mark dashed') -points.b = new Point(50, 10) -.addCircle(1, 'interfacing') -.addCircle(3, 'fabric') -.addCircle(5, 'lining') -.addCircle(7, 'mark') -.addCircle(9, 'note') + points.b = new Point(50, 10) + .addCircle(1, 'interfacing') + .addCircle(3, 'fabric') + .addCircle(5, 'lining') + .addCircle(7, 'mark') + .addCircle(9, 'note') -points.c = new Point(70, 10) -.addCircle(3, 'interfacing') -.addCircle(7, 'mark lashed') + points.c = new Point(70, 10) + .addCircle(3, 'interfacing') + .addCircle(7, 'mark lashed') -return part + return part } - ``` -``` diff --git a/sites/dev/docs/reference/api/point/addtext/readme.mdx b/sites/dev/docs/reference/api/point/addtext/readme.mdx index c3fe109ffe1..07d6ec1a30f 100644 --- a/sites/dev/docs/reference/api/point/addtext/readme.mdx +++ b/sites/dev/docs/reference/api/point/addtext/readme.mdx @@ -28,19 +28,18 @@ This method is chainable as it returns the `Point` object .addText('FreeSewing') .addText('rocks') -// Avoid the text getting cropped -paths.hidden = new Path() -.move(points.anchor) -.line(points.anchor.shift(0, 80)) -.addClass('hidden') + // Avoid the text getting cropped + paths.hidden = new Path() + .move(points.anchor) + .line(points.anchor.shift(0, 80)) + .addClass('hidden') -return part + + return part } - ``` ## Notes Remember to [use translation keys, not text](/guides/best-practices#use-translation-keys) -``` diff --git a/sites/dev/docs/reference/api/point/attr/readme.mdx b/sites/dev/docs/reference/api/point/attr/readme.mdx index 6d5a91baa63..fce80ff16b5 100644 --- a/sites/dev/docs/reference/api/point/attr/readme.mdx +++ b/sites/dev/docs/reference/api/point/attr/readme.mdx @@ -18,6 +18,7 @@ Point point.attr( If the third parameter is set to `true` it will call [`this.attributes.set()`](/reference/api/attributes/set/) instead, thereby overwriting the value of the attribute. + :::tip This method is chainable as it returns the `Point` object ::: @@ -28,19 +29,18 @@ This method is chainable as it returns the `Point` object ```js ({ Point, points, Path, paths, part }) => { -points.anchor = new Point(100, 25) -.attr('data-text', 'FreeSewing') -.attr('data-text', 'rocks') + points.anchor = new Point(100, 25) + .attr('data-text', 'FreeSewing') + .attr('data-text', 'rocks') -// Avoid the text getting cropped -paths.hidden = new Path() -.move(points.anchor) -.line(points.anchor.shift(0, 80)) -.addClass('hidden') + // Avoid the text getting cropped + paths.hidden = new Path() + .move(points.anchor) + .line(points.anchor.shift(0, 80)) + .addClass('hidden') -return part + return part } - ``` @@ -48,4 +48,3 @@ return part See [Using Attributes](/howtos/code/attributes) for information about custom Attributes that can be used with Points. -``` diff --git a/sites/dev/docs/reference/api/point/clone/readme.mdx b/sites/dev/docs/reference/api/point/clone/readme.mdx index 4b99dd5fe0d..1025c05455f 100644 --- a/sites/dev/docs/reference/api/point/clone/readme.mdx +++ b/sites/dev/docs/reference/api/point/clone/readme.mdx @@ -21,22 +21,21 @@ This method is chainable as it returns the `Point` object ```js ({ Point, points, Path, paths, Snippet, snippets, part }) => { -points.A = new Point(25, 25) -.setText("Point A", "text-xl") -.attr("data-text-fill-opacity", "0.5") -points.B = points.A.clone().setText("Point B") + points.A = new Point(25, 25) + .setText("Point A", "text-xl") + .attr("data-text-fill-opacity", "0.5") + points.B = points.A.clone().setText("Point B") -snippets.x = new Snippet("notch", points.A) + snippets.x = new Snippet("notch", points.A) -// Avoid the text getting cropped -paths.hidden = new Path() -.move(new Point(20,10)) -.move(new Point(75,30)) -.addClass('hidden') + // Avoid the text getting cropped + paths.hidden = new Path() + .move(new Point(20,10)) + .move(new Point(75,30)) + .addClass('hidden') -return part + return part } - ``` @@ -46,4 +45,3 @@ return part The [`Point.copy()`](/reference/api/point/copy/) method will only copy the point's coordinates, whereas this `Point.clone()` method will also copy its attributes. -``` diff --git a/sites/dev/docs/reference/api/point/setcircle/readme.mdx b/sites/dev/docs/reference/api/point/setcircle/readme.mdx index 37bc7b4cce5..cfb40878603 100644 --- a/sites/dev/docs/reference/api/point/setcircle/readme.mdx +++ b/sites/dev/docs/reference/api/point/setcircle/readme.mdx @@ -31,24 +31,22 @@ This method is chainable as it returns the `Point` object ```js ({ Point, points, part }) => { -points.a = new Point(30, 10) -.setCircle(3, 'lining dashed') -.setCircle(7, 'mark dashed') + points.a = new Point(30, 10) + .setCircle(3, 'lining dashed') + .setCircle(7, 'mark dashed') -points.b = new Point(50, 10) -.setCircle(1, 'interfacing') -.setCircle(3, 'fabric') -.setCircle(5, 'lining') -.setCircle(7, 'mark') -.setCircle(9, 'note') + points.b = new Point(50, 10) + .setCircle(1, 'interfacing') + .setCircle(3, 'fabric') + .setCircle(5, 'lining') + .setCircle(7, 'mark') + .setCircle(9, 'note') -points.c = new Point(70, 10) -.setCircle(3, 'interfacing') -.setCircle(7, 'mark lashed') + points.c = new Point(70, 10) + .setCircle(3, 'interfacing') + .setCircle(7, 'mark lashed') -return part + return part } - ``` -``` diff --git a/sites/dev/docs/reference/api/point/settext/readme.mdx b/sites/dev/docs/reference/api/point/settext/readme.mdx index 69eec3e4b0c..c0ee45a126d 100644 --- a/sites/dev/docs/reference/api/point/settext/readme.mdx +++ b/sites/dev/docs/reference/api/point/settext/readme.mdx @@ -25,23 +25,21 @@ This method is chainable as it returns the `Point` object ```js ({ Point, points, Path, paths, part }) => { -points.anchor = new Point(100, 25) -.setText('FreeSewing') -.setText('rocks') + points.anchor = new Point(100, 25) + .setText('FreeSewing') + .setText('rocks') -// Avoid the text getting cropped -paths.hidden = new Path() -.move(points.anchor) -.line(points.anchor.shift(0, 80)) -.addClass('hidden') + // Avoid the text getting cropped + paths.hidden = new Path() + .move(points.anchor) + .line(points.anchor.shift(0, 80)) + .addClass('hidden') -return part + return part } - ``` ## Notes Remember to [use translation keys, not text](/guides/best-practices#use-translation-keys) -``` diff --git a/sites/dev/docs/reference/api/snippet/attr/readme.mdx b/sites/dev/docs/reference/api/snippet/attr/readme.mdx index f61a504d78f..5178912bbb5 100644 --- a/sites/dev/docs/reference/api/snippet/attr/readme.mdx +++ b/sites/dev/docs/reference/api/snippet/attr/readme.mdx @@ -3,7 +3,7 @@ title: Snippet.attr() --- The `Snippet.attr()` method can be used to add attributes to the Snippet -object. It calls `this.attributes.add()` under the hood, and returns the +object. It calls `this.attributes.add()` under the hood, and returns the Snippet object. If the third parameter is set to `true` it will call `this.attributes.set()` @@ -29,18 +29,17 @@ This method is chainable as it returns the `Snippet` object ```js ({ Point, points, Path, paths, Snippet, snippets, part }) => { -snippets.logo = new Snippet('logo', new Point(0,0)) -.attr("data-scale", 0.75) -.attr("data-rotate", 180) + snippets.logo = new Snippet('logo', new Point(0,0)) + .attr("data-scale", 0.75) + .attr("data-rotate", 180) -// Prevent clipping -paths.diag = new Path() -.move(new Point(-25,-10)) -.move(new Point(25,35)) + // Prevent clipping + paths.diag = new Path() + .move(new Point(-25,-10)) + .move(new Point(25,35)) -return part + return part } - ``` @@ -48,4 +47,3 @@ return part See [Using Attributes](/howtos/code/attributes) for information about what Attributes can be used with Snippets. ::: -``` diff --git a/sites/dev/docs/reference/api/snippet/rotate/readme.mdx b/sites/dev/docs/reference/api/snippet/rotate/readme.mdx index 2aa89075917..4a8b237055a 100644 --- a/sites/dev/docs/reference/api/snippet/rotate/readme.mdx +++ b/sites/dev/docs/reference/api/snippet/rotate/readme.mdx @@ -21,22 +21,20 @@ This method is chainable as it returns the `Snippet` object ```js ({ Point, Path, paths, Snippet, snippets, part }) => { -for (const i of [0,1,2,3,4,5,6]) { -snippets[`demo${i}`] = new Snippet( -"logo", -new Point(60*i, 0) -).rotate(60 * i) + for (const i of [0,1,2,3,4,5,6]) { + snippets[`demo${i}`] = new Snippet( + "logo", + new Point(60*i, 0) + ).rotate(60 * i) + } + + // Prevent clipping + paths.diag = new Path() + .move(new Point(-30,-50)) + .move(new Point(400,50)) + + return part } - -// Prevent clipping -paths.diag = new Path() -.move(new Point(-30,-50)) -.move(new Point(400,50)) - -return part -} - ``` -``` diff --git a/sites/dev/docs/reference/api/snippet/scale/readme.mdx b/sites/dev/docs/reference/api/snippet/scale/readme.mdx index c3c9f49adcd..6eaea35d026 100644 --- a/sites/dev/docs/reference/api/snippet/scale/readme.mdx +++ b/sites/dev/docs/reference/api/snippet/scale/readme.mdx @@ -21,22 +21,20 @@ This method is chainable as it returns the `Snippet` object ```js ({ Point, Path, paths, Snippet, snippets, part }) => { -for (const i of [1,2,3,4,5,6]) { -snippets[`demo${i}`] = new Snippet( -"logo", -new Point(30\*i, 0) -).scale(i/10) + for (const i of [1,2,3,4,5,6]) { + snippets[`demo${i}`] = new Snippet( + "logo", + new Point(30*i, 0) + ).scale(i/10) + } + + // Prevent clipping + paths.diag = new Path() + .move(new Point(0,-30)) + .move(new Point(200,20)) + + return part } - -// Prevent clipping -paths.diag = new Path() -.move(new Point(0,-30)) -.move(new Point(200,20)) - -return part -} - ``` -``` diff --git a/sites/dev/docs/reference/api/utils/beamintersectsline/readme.mdx b/sites/dev/docs/reference/api/utils/beamintersectsline/readme.mdx index fc3976d8389..d30c3a6297e 100644 --- a/sites/dev/docs/reference/api/utils/beamintersectsline/readme.mdx +++ b/sites/dev/docs/reference/api/utils/beamintersectsline/readme.mdx @@ -24,7 +24,7 @@ Point | false utils.beamIntersectsLine( ```js -;({ Point, points, Path, paths, Snippet, snippets, utils, part }) => { +({ Point, points, Path, paths, Snippet, snippets, utils, part }) => { points.A = new Point(45, 20) points.B = new Point(60, 15) points.C = new Point(10, 10) diff --git a/sites/dev/docs/reference/api/utils/curveintersectsx/readme.mdx b/sites/dev/docs/reference/api/utils/curveintersectsx/readme.mdx index c85f2eaee6f..4fe6f395f72 100644 --- a/sites/dev/docs/reference/api/utils/curveintersectsx/readme.mdx +++ b/sites/dev/docs/reference/api/utils/curveintersectsx/readme.mdx @@ -28,41 +28,40 @@ multiple intersections are found. ```js ({ Point, points, Path, paths, Snippet, snippets, utils, part }) => { -points.start = new Point(10, 15) -points.cp1 = new Point(80, 10) -points.cp2 = new Point(-50, 80) -points.end = new Point(110, 70) + points.start = new Point(10, 15) + points.cp1 = new Point(80, 10) + points.cp2 = new Point(-50, 80) + points.end = new Point(110, 70) -paths.curve = new Path() -.move(points.start) -.curve(points.cp1, points.cp2, points.end) + paths.curve = new Path() + .move(points.start) + .curve(points.cp1, points.cp2, points.end) -for (let x of [30, 40]) { -points["from" + x] = new Point(x, 10) -points["to" + x] = new Point(x, 80) -paths["line" + x] = new Path() -.move(points["from" + x]) -.line(points["to" + x]) -.addClass("lining dashed") + for (let x of [30, 40]) { + points["from" + x] = new Point(x, 10) + points["to" + x] = new Point(x, 80) + paths["line" + x] = new Path() + .move(points["from" + x]) + .line(points["to" + x]) + .addClass("lining dashed") + } + + snippets.i40 = new Snippet( + "notch", + utils.curveIntersectsX(points.start, points.cp1, points.cp2, points.end, 40) + ) + + for (let p of utils.curveIntersectsX( + points.start, + points.cp1, + points.cp2, + points.end, + 30 + )) + snippets[p.y] = new Snippet("notch", p) + + return part } - -snippets.i40 = new Snippet( -"notch", -utils.curveIntersectsX(points.start, points.cp1, points.cp2, points.end, 40) -) - -for (let p of utils.curveIntersectsX( -points.start, -points.cp1, -points.cp2, -points.end, -30 -)) -snippets[p.y] = new Snippet("notch", p) - -return part -} - ``` @@ -73,4 +72,3 @@ This is a low-level (and faster) variant of [`Path.intersectsX()`](/reference/api/path/intersectsx). Instead of a path, you describe a single curve by passing the four points that describes it. -``` diff --git a/sites/dev/docs/reference/api/utils/curveintersectsy/readme.mdx b/sites/dev/docs/reference/api/utils/curveintersectsy/readme.mdx index d842e8b8022..4c5234ca1f9 100644 --- a/sites/dev/docs/reference/api/utils/curveintersectsy/readme.mdx +++ b/sites/dev/docs/reference/api/utils/curveintersectsy/readme.mdx @@ -22,47 +22,46 @@ a single intersection is found, and an array of [Point](/reference/api/point/) objects if multiple intersections are found. -## Example +## Example ```js ({ Point, points, Path, paths, Snippet, snippets, utils, part }) => { -points.start = new Point(10, 45) -points.cp1 = new Point(50, 10) -points.cp2 = new Point(0, 80) -points.end = new Point(110, 70) + points.start = new Point(10, 45) + points.cp1 = new Point(50, 10) + points.cp2 = new Point(0, 80) + points.end = new Point(110, 70) -paths.curve = new Path() -.move(points.start) -.curve(points.cp1, points.cp2, points.end) + paths.curve = new Path() + .move(points.start) + .curve(points.cp1, points.cp2, points.end) -for (let y of [40, 50]) { -points["from" + y] = new Point(10, y) -points["to" + y] = new Point(110, y) -paths["line" + y] = new Path() -.move(points["from" + y]) -.line(points["to" + y]) -.addClass("lining dashed") + for (let y of [40, 50]) { + points["from" + y] = new Point(10, y) + points["to" + y] = new Point(110, y) + paths["line" + y] = new Path() + .move(points["from" + y]) + .line(points["to" + y]) + .addClass("lining dashed") + } + + snippets.i50 = new Snippet( + "notch", + utils.curveIntersectsY(points.start, points.cp1, points.cp2, points.end, 50) + ) + + for (let p of utils.curveIntersectsY( + points.start, + points.cp1, + points.cp2, + points.end, + 40 + )) + snippets[p.x] = new Snippet("notch", p) + + return part } - -snippets.i50 = new Snippet( -"notch", -utils.curveIntersectsY(points.start, points.cp1, points.cp2, points.end, 50) -) - -for (let p of utils.curveIntersectsY( -points.start, -points.cp1, -points.cp2, -points.end, -40 -)) -snippets[p.x] = new Snippet("notch", p) - -return part -} - ``` @@ -72,4 +71,3 @@ This is a low-level (and faster) variant of [`Path.intersectsY()`](/reference/api/path/intersectsy). Instead of a path, you describe a single curve by passing the four points that describes it. -``` diff --git a/sites/dev/docs/reference/api/utils/curvesintersect/readme.mdx b/sites/dev/docs/reference/api/utils/curvesintersect/readme.mdx index 2fb5174b1f9..599f1c3d1c4 100644 --- a/sites/dev/docs/reference/api/utils/curvesintersect/readme.mdx +++ b/sites/dev/docs/reference/api/utils/curvesintersect/readme.mdx @@ -31,45 +31,43 @@ multiple intersections are found. ```js ({ Point, points, Path, paths, Snippet, snippets, utils, getId, part }) => { -points.A = new Point(10, 10) -points.Acp = new Point(310, 40) -points.B = new Point(110, 70) -points.Bcp = new Point(-210, 40) + points.A = new Point(10, 10) + points.Acp = new Point(310, 40) + points.B = new Point(110, 70) + points.Bcp = new Point(-210, 40) -points.C = new Point(20, -5) -points.Ccp = new Point(60, 300) -points.D = new Point(100, 85) -points.Dcp = new Point(70, -220) -paths.curveA = new Path() -.move(points.A) -.curve(points.Acp, points.Bcp, points.B) -paths.curveB = new Path() -.move(points.C) -.curve(points.Ccp, points.Dcp, points.D) + points.C = new Point(20, -5) + points.Ccp = new Point(60, 300) + points.D = new Point(100, 85) + points.Dcp = new Point(70, -220) + paths.curveA = new Path() + .move(points.A) + .curve(points.Acp, points.Bcp, points.B) + paths.curveB = new Path() + .move(points.C) + .curve(points.Ccp, points.Dcp, points.D) -const intersections = utils.curvesIntersect( -points.A, -points.Acp, -points.Bcp, -points.B, -points.C, -points.Ccp, -points.Dcp, -points.D -) + const intersections = utils.curvesIntersect( + points.A, + points.Acp, + points.Bcp, + points.B, + points.C, + points.Ccp, + points.Dcp, + points.D + ) -if (intersections) { -if (intersections instanceof Array) { -for (const p of intersections) -snippets[getId()] = new Snippet('notch', p) -} else { -snippets[getId()] = new Snippet('notch', intersections) + if (intersections) { + if (intersections instanceof Array) { + for (const p of intersections) + snippets[getId()] = new Snippet('notch', p) + } else { + snippets[getId()] = new Snippet('notch', intersections) + } + } + + return part } -} - -return part -} - ``` -``` From d6a1ea81db3afcda5bf03111a35b73809186654e Mon Sep 17 00:00:00 2001 From: Benjamin Fan Date: Mon, 19 May 2025 08:04:38 +0200 Subject: [PATCH 17/46] fix(reference:macros): Fix typo in Examples (#368) (A few similar typo fixes to Core API docs were made in #367.) Co-authored-by: Benjamin Fan Reviewed-on: https://codeberg.org/freesewing/freesewing/pulls/368 Reviewed-by: Joost De Cock Co-authored-by: Benjamin Fan Co-committed-by: Benjamin Fan --- sites/dev/docs/reference/api/path/intersectsbeam/readme.mdx | 2 +- sites/dev/docs/reference/macros/hem/readme.mdx | 4 ++-- sites/dev/docs/reference/macros/join/readme.mdx | 2 +- sites/dev/docs/reference/macros/offset/readme.mdx | 2 +- sites/dev/docs/reference/macros/sa/readme.mdx | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/sites/dev/docs/reference/api/path/intersectsbeam/readme.mdx b/sites/dev/docs/reference/api/path/intersectsbeam/readme.mdx index 3f232e6ecbd..a9bef72769b 100644 --- a/sites/dev/docs/reference/api/path/intersectsbeam/readme.mdx +++ b/sites/dev/docs/reference/api/path/intersectsbeam/readme.mdx @@ -23,7 +23,7 @@ array path.intersectsBeam(Point a, Point b) ```js -;({ Point, points, Path, paths, snippets, Snippet, getId, part }) => { +({ Point, points, Path, paths, snippets, Snippet, getId, part }) => { points.A = new Point(45, 60) points.B = new Point(10, 30) points.BCp2 = new Point(40, 20) diff --git a/sites/dev/docs/reference/macros/hem/readme.mdx b/sites/dev/docs/reference/macros/hem/readme.mdx index 6c1c769fd54..ba2d52dc4d8 100644 --- a/sites/dev/docs/reference/macros/hem/readme.mdx +++ b/sites/dev/docs/reference/macros/hem/readme.mdx @@ -25,7 +25,7 @@ Path macro('hem', { ```js -;({ Point, points, Path, paths, macro, part }) => { +({ Point, points, Path, paths, macro, part }) => { paths.inseam = new Path().move(new Point(150, 0)).line(new Point(200, 200)).hide() paths.outseam = new Path() @@ -95,7 +95,7 @@ The hem path already includes the seam allowance, so it doesn't need any additio ```js -;({ Point, points, Path, paths, macro, part }) => { +({ Point, points, Path, paths, macro, part }) => { paths.inseam = new Path().move(new Point(150, 0)).line(new Point(200, 200)).hide() paths.outseam = new Path() diff --git a/sites/dev/docs/reference/macros/join/readme.mdx b/sites/dev/docs/reference/macros/join/readme.mdx index 495a66c5e44..f9024f7866d 100644 --- a/sites/dev/docs/reference/macros/join/readme.mdx +++ b/sites/dev/docs/reference/macros/join/readme.mdx @@ -44,7 +44,7 @@ Path macro('join', { ```js -;({ Point, points, Path, paths, macro, part }) => { +({ Point, points, Path, paths, macro, part }) => { paths.a = new Path().move(new Point(10, 10)).line(new Point(10, 20)) paths.b = new Path().move(new Point(25, 30)).line(new Point(55, 30)) diff --git a/sites/dev/docs/reference/macros/offset/readme.mdx b/sites/dev/docs/reference/macros/offset/readme.mdx index 02972388918..22e60f4fac5 100644 --- a/sites/dev/docs/reference/macros/offset/readme.mdx +++ b/sites/dev/docs/reference/macros/offset/readme.mdx @@ -41,7 +41,7 @@ Path macro('offset', { ```js -;({ Point, points, Path, paths, macro, part }) => { +({ Point, points, Path, paths, macro, part }) => { paths.outline = new Path() .move(new Point(10, 30)) .line(new Point(30, 30)) diff --git a/sites/dev/docs/reference/macros/sa/readme.mdx b/sites/dev/docs/reference/macros/sa/readme.mdx index 6a22dceb166..5ba5b434a67 100644 --- a/sites/dev/docs/reference/macros/sa/readme.mdx +++ b/sites/dev/docs/reference/macros/sa/readme.mdx @@ -39,7 +39,7 @@ macro('sa', { ```js -;({ Point, points, Path, paths, macro, part }) => { +({ Point, points, Path, paths, macro, part }) => { paths.outline = new Path() .move(new Point(10, 30)) .line(new Point(30, 30)) From db8189a55aceeb0dcb60a86c76901ca17f550031 Mon Sep 17 00:00:00 2001 From: Benjamin Fan Date: Mon, 19 May 2025 08:05:23 +0200 Subject: [PATCH 18/46] fix(react): Allow imperial formatted values to be displayed (#371) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ![Screenshot 2025-05-17 at 3.58.26 PM.png](/attachments/6c83d019-9ec9-4081-8e3c-88ec1ac9c36d) ![Screenshot 2025-05-17 at 3.50.22 PM.png](/attachments/eb5293ac-1cd4-4583-b68f-2314899e3346) Co-authored-by: Benjamin Fan Reviewed-on: https://codeberg.org/freesewing/freesewing/pulls/371 Reviewed-by: Joost De Cock Co-authored-by: Benjamin Fan Co-committed-by: Benjamin Fan --- packages/react/components/Editor/components/menus/Container.mjs | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/react/components/Editor/components/menus/Container.mjs b/packages/react/components/Editor/components/menus/Container.mjs index ddee87adacc..b61f167af4b 100644 --- a/packages/react/components/Editor/components/menus/Container.mjs +++ b/packages/react/components/Editor/components/menus/Container.mjs @@ -217,6 +217,7 @@ export const MenuItemGroup = ({ config={item} changed={menuValueWasChanged(currentValues[itemName], item)} Design={Design} + units={state?.settings?.units} />
, From af0dcc97847f383c4eb56eb955c91c2a08a51d12 Mon Sep 17 00:00:00 2001 From: Benjamin Fan Date: Mon, 19 May 2025 08:05:49 +0200 Subject: [PATCH 19/46] fix(tutorials): Revert incorrect example code formatting (#363) This PR essentially reverts the incorrect `lint`/`prettier` changes applied to `` code in the Pattern Design tutorial by the husky pre-commit hook, the problem mentioned in Issue #333. This is not a full fix. Changes are also needed in the Reference Core API docs. However, I'd like to file these as separate PRs to avoid confusion since there are a lot of files. Co-authored-by: Benjamin Fan Reviewed-on: https://codeberg.org/freesewing/freesewing/pulls/363 Reviewed-by: Joost De Cock Co-authored-by: Benjamin Fan Co-committed-by: Benjamin Fan --- .../part2/avoiding-overlap/readme.mdx | 224 ++++---- .../completing-the-neck-opening/readme.mdx | 61 +- .../constructing-the-neck-opening/readme.mdx | 69 +-- .../part2/creating-the-closure/readme.mdx | 210 ++++--- .../part2/drawing-the-bib-outline/readme.mdx | 133 ++--- .../part2/drawing-the-straps/readme.mdx | 472 ++++++++------- .../part2/fitting-the-neck-opening/readme.mdx | 65 +-- .../part2/rounding-the-corners/readme.mdx | 419 +++++++------- .../part2/shaping-the-straps/readme.mdx | 157 +++-- .../part3/annotations/readme.mdx | 315 +++++----- .../pattern-design/part3/complete/readme.mdx | 454 +++++++-------- .../pattern-design/part3/flag/readme.mdx | 541 +++++++++--------- .../pattern-design/part3/paperless/readme.mdx | 523 +++++++++-------- .../pattern-design/part3/sa/readme.mdx | 41 +- 14 files changed, 1804 insertions(+), 1880 deletions(-) diff --git a/sites/dev/docs/tutorials/pattern-design/part2/avoiding-overlap/readme.mdx b/sites/dev/docs/tutorials/pattern-design/part2/avoiding-overlap/readme.mdx index baf2192eeb9..d9879cfec29 100644 --- a/sites/dev/docs/tutorials/pattern-design/part2/avoiding-overlap/readme.mdx +++ b/sites/dev/docs/tutorials/pattern-design/part2/avoiding-overlap/readme.mdx @@ -11,10 +11,9 @@ Specifically, we're going to rotate our strap out of the way until it no longer The rest of our bib should stay as it is, so let's start by making a list of points we need to rotate. -However, there is a catch. +However, there is a catch. ## Macros and auto-generated IDs - We have used the `round` macro to help us round the corners of our strap, and it added a bunch of auto-generated points to our pattern. We need to rotate these points too, but what are their names? @@ -50,7 +49,7 @@ that return value, but if we did, it would look like this: ``` Those names aren't very handy to remember. So I will rewrite this code a bit to -we'll capture these return values from the `round` macros and create +we'll capture these return values from the `round` macros and create easy-to-remember points from them: @@ -69,38 +68,36 @@ function draftBib({ part, }) { -/\* - -- Construct the quarter neck opening - _/ + /* + * Construct the quarter neck opening + */ let tweak = 1 - let target = (measurements.head _ options.neckRatio) /4 + let target = (measurements.head * options.neckRatio) /4 let delta do { - points.right = new Point( - tweak _ measurements.head / 10, - 0 - ) - points.bottom = new Point( - 0, - tweak _ measurements.head / 12 - ) - - + points.right = new Point( + tweak * measurements.head / 10, + 0 + ) + points.bottom = new Point( + 0, + tweak * measurements.head / 12 + ) + points.rightCp1 = points.right.shift( - 90, + 90, points.bottom.dy(points.right) / 2 ) points.bottomCp2 = points.bottom.shift( - 0, + 0, points.bottom.dx(points.right) / 2 ) - + paths.quarterNeck = new Path() .move(points.right) .curve( - points.rightCp1, - points.bottomCp2, + points.rightCp1, + points.bottomCp2, points.bottom ) .hide() @@ -108,13 +105,11 @@ function draftBib({ delta = paths.quarterNeck.length() - target if (delta > 0) tweak = tweak * 0.99 else tweak = tweak * 1.02 + } while (Math.abs(delta) > 1) -} while (Math.abs(delta) > 1) - -/\* - -- Construct the complete neck opening - \*/ + /* + * Construct the complete neck opening + */ points.rightCp2 = points.rightCp1.flipY() points.bottomCp1 = points.bottomCp2.flipX() points.left = points.right.flipX() @@ -124,103 +119,97 @@ function draftBib({ points.topCp1 = points.bottomCp2.flipY() points.topCp2 = points.bottomCp1.flipY() -paths.neck = new Path() -.move(points.top) -.curve(points.topCp2, points.leftCp1, points.left) -.curve(points.leftCp2, points.bottomCp1, points.bottom) -.curve(points.bottomCp2, points.rightCp1, points.right) -.curve(points.rightCp2, points.topCp1, points.top) -.close() -.addClass('fabric') + paths.neck = new Path() + .move(points.top) + .curve(points.topCp2, points.leftCp1, points.left) + .curve(points.leftCp2, points.bottomCp1, points.bottom) + .curve(points.bottomCp2, points.rightCp1, points.right) + .curve(points.rightCp2, points.topCp1, points.top) + .close() + .addClass('fabric') -/\* + /* + * Drawing the bib outline + */ + const width = measurements.head * options.widthRatio + const length = measurements.head * options.lengthRatio -- Drawing the bib outline - _/ - const width = measurements.head _ options.widthRatio - const length = measurements.head \* options.lengthRatio + points.topLeft = new Point( + width / -2, + points.top.y - (width / 2 - points.right.x) + ) + points.topRight = points.topLeft.shift(0, width) + points.bottomLeft = points.topLeft.shift(-90, length) + points.bottomRight = points.topRight.shift(-90, length) -points.topLeft = new Point( -width / -2, -points.top.y - (width / 2 - points.right.x) -) -points.topRight = points.topLeft.shift(0, width) -points.bottomLeft = points.topLeft.shift(-90, length) -points.bottomRight = points.topRight.shift(-90, length) - -/\* - -- Shape the straps - \*/ + /* + * Shape the straps + */ points.edgeLeft = new Point(points.topLeft.x, points.left.y) points.edgeRight = new Point(points.topRight.x, points.right.y) points.edgeTop = new Point(0, points.topLeft.y) -points.edgeLeftCp = points.edgeLeft.shiftFractionTowards(points.topLeft, 0.5) -points.edgeRightCp = points.edgeLeftCp.flipX() -points.edgeTopLeftCp = points.edgeTop.shiftFractionTowards( -points.topLeft, -0.5 -) -points.edgeTopRightCp = points.edgeTopLeftCp.flipX() + points.edgeLeftCp = points.edgeLeft.shiftFractionTowards(points.topLeft, 0.5) + points.edgeRightCp = points.edgeLeftCp.flipX() + points.edgeTopLeftCp = points.edgeTop.shiftFractionTowards( + points.topLeft, + 0.5 + ) + points.edgeTopRightCp = points.edgeTopLeftCp.flipX() -// Round the straps -const strap = points.edgeTop.dy(points.top) + // Round the straps + const strap = points.edgeTop.dy(points.top) -points.tipRight = points.edgeTop.translate(strap / 2, strap / 2) -points.tipRightTop = new Point(points.tipRight.x, points.edgeTop.y) -points.tipRightBottom = new Point(points.tipRight.x, points.top.y) + points.tipRight = points.edgeTop.translate(strap / 2, strap / 2) + points.tipRightTop = new Point(points.tipRight.x, points.edgeTop.y) + points.tipRightBottom = new Point(points.tipRight.x, points.top.y) -// highlight-start -/\* - -- Macros will return the auto-generated IDs - \*/ + // highlight-start + /* + * Macros will return the auto-generated IDs + */ const ids1 = { - tipRightTop: macro("round", { - id: "tipRightTop", - from: points.edgeTop, - to: points.tipRight, - via: points.tipRightTop, - hide: false - }), - tipRightBottom: macro("round", { - id: "tipRightBottom", - from: points.tipRight, - to: points.top, - via: points.tipRightBottom, - hide: false - }) + tipRightTop: macro("round", { + id: "tipRightTop", + from: points.edgeTop, + to: points.tipRight, + via: points.tipRightTop, + hide: false + }), + tipRightBottom: macro("round", { + id: "tipRightBottom", + from: points.tipRight, + to: points.top, + via: points.tipRightBottom, + hide: false + }) } -/\* - -- Create points from them with easy names - \*/ + /* + * Create points from them with easy names + */ for (const side in ids1) { - for (const id of ['start', 'cp1', 'cp2', 'end']) { - points[`${side}${utils.capitalize(id)}`] = points[ids1[side].points[id]].copy() - } + for (const id of ['start', 'cp1', 'cp2', 'end']) { + points[`${side}${utils.capitalize(id)}`] = points[ids1[side].points[id]].copy() + } } // highlight-end - -/\* - -- Now, adapt our `rect` path so it's no longer a rectangle: - \*/ + + /* + * Now, adapt our `rect` path so it's no longer a rectangle: + */ paths.rect = new Path() - .move(points.edgeTop) - .curve(points.edgeTopLeftCp, points.edgeLeftCp, points.edgeLeft) - .line(points.bottomLeft) - .line(points.bottomRight) - .line(points.edgeRight) - .curve(points.edgeRightCp, points.edgeTopRightCp, points.edgeTop) - .close() + .move(points.edgeTop) + .curve(points.edgeTopLeftCp, points.edgeLeftCp, points.edgeLeft) + .line(points.bottomLeft) + .line(points.bottomRight) + .line(points.edgeRight) + .curve(points.edgeRightCp, points.edgeTopRightCp, points.edgeTop) + .close() -return part + return part } - -```` +``` Once we have our list of points to rotate, we can rotate them. How far? Until the strap no longer overlaps. @@ -247,28 +236,28 @@ function draftBib({ let delta do { points.right = new Point( - tweak * measurements.head / 10, + tweak * measurements.head / 10, 0 ) points.bottom = new Point( - 0, + 0, tweak * measurements.head / 12 ) - + points.rightCp1 = points.right.shift( - 90, + 90, points.bottom.dy(points.right) / 2 ) points.bottomCp2 = points.bottom.shift( - 0, + 0, points.bottom.dx(points.right) / 2 ) - + paths.quarterNeck = new Path() .move(points.right) .curve( - points.rightCp1, - points.bottomCp2, + points.rightCp1, + points.bottomCp2, points.bottom ) .hide() @@ -277,7 +266,7 @@ function draftBib({ if (delta > 0) tweak = tweak * 0.99 else tweak = tweak * 1.02 } while (Math.abs(delta) > 1) - + /* * Construct the complete neck opening */ @@ -433,6 +422,5 @@ function draftBib({ return part } -```` - +``` diff --git a/sites/dev/docs/tutorials/pattern-design/part2/completing-the-neck-opening/readme.mdx b/sites/dev/docs/tutorials/pattern-design/part2/completing-the-neck-opening/readme.mdx index 49606b57b51..def9e32cb98 100644 --- a/sites/dev/docs/tutorials/pattern-design/part2/completing-the-neck-opening/readme.mdx +++ b/sites/dev/docs/tutorials/pattern-design/part2/completing-the-neck-opening/readme.mdx @@ -25,38 +25,36 @@ function draftBib({ part, }) { -/\* - -- Construct the quarter neck opening - _/ + /* + * Construct the quarter neck opening + */ let tweak = 1 - let target = (measurements.head _ options.neckRatio) /4 + let target = (measurements.head * options.neckRatio) /4 let delta do { - points.right = new Point( - tweak _ measurements.head / 10, - 0 - ) - points.bottom = new Point( - 0, - tweak _ measurements.head / 12 - ) - + points.right = new Point( + tweak * measurements.head / 10, + 0 + ) + points.bottom = new Point( + 0, + tweak * measurements.head / 12 + ) points.rightCp1 = points.right.shift( - 90, + 90, points.bottom.dy(points.right) / 2 ) points.bottomCp2 = points.bottom.shift( - 0, + 0, points.bottom.dx(points.right) / 2 ) paths.quarterNeck = new Path() .move(points.right) .curve( - points.rightCp1, - points.bottomCp2, + points.rightCp1, + points.bottomCp2, points.bottom ) // highlight-start @@ -66,13 +64,11 @@ function draftBib({ delta = paths.quarterNeck.length() - target if (delta > 0) tweak = tweak * 0.99 else tweak = tweak * 1.02 + } while (Math.abs(delta) > 1) -} while (Math.abs(delta) > 1) - -return part + return part } - -```` +``` We're saying: _hide this path_. In other words, don't show it. @@ -109,28 +105,28 @@ function draftBib({ let delta do { points.right = new Point( - tweak * measurements.head / 10, + tweak * measurements.head / 10, 0 ) points.bottom = new Point( - 0, + 0, tweak * measurements.head / 12 ) points.rightCp1 = points.right.shift( - 90, + 90, points.bottom.dy(points.right) / 2 ) points.bottomCp2 = points.bottom.shift( - 0, + 0, points.bottom.dx(points.right) / 2 ) - + paths.quarterNeck = new Path() .move(points.right) .curve( - points.rightCp1, - points.bottomCp2, + points.rightCp1, + points.bottomCp2, points.bottom ) .hide() @@ -164,12 +160,11 @@ function draftBib({ // highlight-end return part } -```` - +``` To add the points, we're using the `Point.flipX()` and `Point.flipY()` methods -here. There's a few new Path methods too, like `close()` and `addClass()`. +here. There's a few new Path methods too, like `close()` and `addClass()`. Perhaps you can figure out what they do? If not, both [the Point documentation](/reference/api/point/) and [the Path diff --git a/sites/dev/docs/tutorials/pattern-design/part2/constructing-the-neck-opening/readme.mdx b/sites/dev/docs/tutorials/pattern-design/part2/constructing-the-neck-opening/readme.mdx index 96f4fd93f51..9b3e3e8f831 100644 --- a/sites/dev/docs/tutorials/pattern-design/part2/constructing-the-neck-opening/readme.mdx +++ b/sites/dev/docs/tutorials/pattern-design/part2/constructing-the-neck-opening/readme.mdx @@ -51,41 +51,39 @@ function draftBib({ }) { // highlight-start -/\* - -- Construct the quarter neck opening - \*/ + /* + * Construct the quarter neck opening + */ points.right = new Point( - measurements.head / 10, - 0 + measurements.head / 10, + 0 ) points.bottom = new Point( - 0, - measurements.head / 12 + 0, + measurements.head / 12 ) -points.rightCp1 = points.right.shift( -90, -points.bottom.dy(points.right) / 2 -) -points.bottomCp2 = points.bottom.shift( -0, -points.bottom.dx(points.right) / 2 -) + points.rightCp1 = points.right.shift( + 90, + points.bottom.dy(points.right) / 2 + ) + points.bottomCp2 = points.bottom.shift( + 0, + points.bottom.dx(points.right) / 2 + ) -paths.quarterNeck = new Path() -.move(points.right) -.curve( -points.rightCp1, -points.bottomCp2, -points.bottom -) + paths.quarterNeck = new Path() + .move(points.right) + .curve( + points.rightCp1, + points.bottomCp2, + points.bottom + ) // highlight-end -return part + return part } - -```` +``` We've added some points to our part, and drawn our first path. @@ -95,10 +93,10 @@ Let's look at each line in detail. ```js points.right = new Point( - measurements.head / 10, + measurements.head / 10, 0 ) -```` +``` - We're adding a point named `right` to the `points` object which holds our part's points @@ -110,7 +108,10 @@ points.right = new Point( The creation of `points.bottom` is very similar, so let's skip to the next line: ```js -points.rightCp1 = points.right.shift(90, points.bottom.dy(points.right) / 2) +points.rightCp1 = points.right.shift( + 90, + points.bottom.dy(points.right) / 2 +) ``` - We're adding a point named `rightCp1`, which will become the _control point_ @@ -129,9 +130,7 @@ the right (0 degrees) for half of the X-delta between points `bottom` and `right`. :::tip - ##### Further reading - The `Point.shift()` and `Point.dy()` are just the tip of the iceberg. Points come with a bunch of these methods. You can find them all in [the Point API docs](/reference/api/point/). @@ -145,7 +144,11 @@ introduced on the next line: Paths. ```js paths.quarterNeck = new Path() .move(points.right) - .curve(points.rightCp1, points.bottomCp2, points.bottom) + .curve( + points.rightCp1, + points.bottomCp2, + points.bottom + ) ``` - We're adding a path named `quarterNeck` to the `paths` object which holds our @@ -163,7 +166,7 @@ From there, we drew a cubic Bézier curve to our `bottom` point by using :::tip -Many of the methods in the FreeSewing API are _chainable_ allowing you +Many of the methods in the FreeSewing API are *chainable* allowing you to string them together like in this example. ::: diff --git a/sites/dev/docs/tutorials/pattern-design/part2/creating-the-closure/readme.mdx b/sites/dev/docs/tutorials/pattern-design/part2/creating-the-closure/readme.mdx index 5548e1302ea..25219458725 100644 --- a/sites/dev/docs/tutorials/pattern-design/part2/creating-the-closure/readme.mdx +++ b/sites/dev/docs/tutorials/pattern-design/part2/creating-the-closure/readme.mdx @@ -17,12 +17,10 @@ tedious. There are macros to add titles to our pattern, or grainline indicators, a scalebox, and there's a macro to round corners. The `round` macro. -:::note -You can find more information on the `round` macro in [the macros docs](/reference/macros/round/). -::: +:::note You can find more information on the `round` macro in [the macros docs](/reference/macros/round/).::: We need a half circle here, but the `round` macro works on 90° angles, so -we'll use it twice. As such, we'll add some points to guide the macro, and +we'll use it twice. As such, we'll add some points to guide the macro, and then put it to work. Like our neck opening, we've only drawn half since we can simply copy the @@ -43,51 +41,48 @@ function draftBib({ part, }) { -/\* - -- Construct the quarter neck opening - _/ + /* + * Construct the quarter neck opening + */ let tweak = 1 - let target = (measurements.head _ options.neckRatio) /4 + let target = (measurements.head * options.neckRatio) /4 let delta do { - points.right = new Point( - tweak _ measurements.head / 10, - 0 - ) - points.bottom = new Point( - 0, - tweak _ measurements.head / 12 - ) + points.right = new Point( + tweak * measurements.head / 10, + 0 + ) + points.bottom = new Point( + 0, + tweak * measurements.head / 12 + ) + + points.rightCp1 = points.right.shift( + 90, + points.bottom.dy(points.right) / 2 + ) + points.bottomCp2 = points.bottom.shift( + 0, + points.bottom.dx(points.right) / 2 + ) + + paths.quarterNeck = new Path() + .move(points.right) + .curve( + points.rightCp1, + points.bottomCp2, + points.bottom + ) + .hide() - points.rightCp1 = points.right.shift( - 90, - points.bottom.dy(points.right) / 2 - ) - points.bottomCp2 = points.bottom.shift( - 0, - points.bottom.dx(points.right) / 2 - ) + delta = paths.quarterNeck.length() - target + if (delta > 0) tweak = tweak * 0.99 + else tweak = tweak * 1.02 + } while (Math.abs(delta) > 1) - paths.quarterNeck = new Path() - .move(points.right) - .curve( - points.rightCp1, - points.bottomCp2, - points.bottom - ) - .hide() - - delta = paths.quarterNeck.length() - target - if (delta > 0) tweak = tweak _ 0.99 - else tweak = tweak _ 1.02 - -} while (Math.abs(delta) > 1) - -/\* - -- Construct the complete neck opening - \*/ + /* + * Construct the complete neck opening + */ points.rightCp2 = points.rightCp1.flipY() points.bottomCp1 = points.bottomCp2.flipX() points.left = points.right.flipX() @@ -97,88 +92,83 @@ function draftBib({ points.topCp1 = points.bottomCp2.flipY() points.topCp2 = points.bottomCp1.flipY() -paths.neck = new Path() -.move(points.top) -.curve(points.topCp2, points.leftCp1, points.left) -.curve(points.leftCp2, points.bottomCp1, points.bottom) -.curve(points.bottomCp2, points.rightCp1, points.right) -.curve(points.rightCp2, points.topCp1, points.top) -.close() -.addClass('fabric') + paths.neck = new Path() + .move(points.top) + .curve(points.topCp2, points.leftCp1, points.left) + .curve(points.leftCp2, points.bottomCp1, points.bottom) + .curve(points.bottomCp2, points.rightCp1, points.right) + .curve(points.rightCp2, points.topCp1, points.top) + .close() + .addClass('fabric') -/\* + /* + * Drawing the bib outline + */ + const width = measurements.head * options.widthRatio + const length = measurements.head * options.lengthRatio -- Drawing the bib outline - _/ - const width = measurements.head _ options.widthRatio - const length = measurements.head \* options.lengthRatio + points.topLeft = new Point( + width / -2, + points.top.y - (width / 2 - points.right.x) + ) + points.topRight = points.topLeft.shift(0, width) + points.bottomLeft = points.topLeft.shift(-90, length) + points.bottomRight = points.topRight.shift(-90, length) -points.topLeft = new Point( -width / -2, -points.top.y - (width / 2 - points.right.x) -) -points.topRight = points.topLeft.shift(0, width) -points.bottomLeft = points.topLeft.shift(-90, length) -points.bottomRight = points.topRight.shift(-90, length) - -/\* - -- Shape the straps - \*/ + /* + * Shape the straps + */ points.edgeLeft = new Point(points.topLeft.x, points.left.y) points.edgeRight = new Point(points.topRight.x, points.right.y) points.edgeTop = new Point(0, points.topLeft.y) -points.edgeLeftCp = points.edgeLeft.shiftFractionTowards(points.topLeft, 0.5) -points.edgeRightCp = points.edgeLeftCp.flipX() -points.edgeTopLeftCp = points.edgeTop.shiftFractionTowards( -points.topLeft, -0.5 -) -points.edgeTopRightCp = points.edgeTopLeftCp.flipX() + points.edgeLeftCp = points.edgeLeft.shiftFractionTowards(points.topLeft, 0.5) + points.edgeRightCp = points.edgeLeftCp.flipX() + points.edgeTopLeftCp = points.edgeTop.shiftFractionTowards( + points.topLeft, + 0.5 + ) + points.edgeTopRightCp = points.edgeTopLeftCp.flipX() -// highlight-start -// Round the straps -const strap = points.edgeTop.dy(points.top) + // highlight-start + // Round the straps + const strap = points.edgeTop.dy(points.top) -points.tipRight = points.edgeTop.translate(strap / 2, strap / 2) -points.tipRightTop = new Point(points.tipRight.x, points.edgeTop.y) -points.tipRightBottom = new Point(points.tipRight.x, points.top.y) + points.tipRight = points.edgeTop.translate(strap / 2, strap / 2) + points.tipRightTop = new Point(points.tipRight.x, points.edgeTop.y) + points.tipRightBottom = new Point(points.tipRight.x, points.top.y) -macro("round", { -id: "tipRightTop", -from: points.edgeTop, -to: points.tipRight, -via: points.tipRightTop, -hide: false -}) -macro("round", { -id: "tipRightBottom", -from: points.tipRight, -to: points.top, -via: points.tipRightBottom, -hide: false -}) -// highlight-end + macro("round", { + id: "tipRightTop", + from: points.edgeTop, + to: points.tipRight, + via: points.tipRightTop, + hide: false + }) + macro("round", { + id: "tipRightBottom", + from: points.tipRight, + to: points.top, + via: points.tipRightBottom, + hide: false + }) + // highlight-end /* - -- Now, adapt our `rect` path so it's no longer a rectangle: - \*/ + * Now, adapt our `rect` path so it's no longer a rectangle: + */ paths.rect = new Path() - .move(points.edgeTop) - .curve(points.edgeTopLeftCp, points.edgeLeftCp, points.edgeLeft) - .line(points.bottomLeft) - .line(points.bottomRight) - .line(points.edgeRight) - .curve(points.edgeRightCp, points.edgeTopRightCp, points.edgeTop) - .close() + .move(points.edgeTop) + .curve(points.edgeTopLeftCp, points.edgeLeftCp, points.edgeLeft) + .line(points.bottomLeft) + .line(points.bottomRight) + .line(points.edgeRight) + .curve(points.edgeRightCp, points.edgeTopRightCp, points.edgeTop) + .close() -return part + return part } - ``` Notice that we always draw our path at the end after we've manipulated our points. -``` diff --git a/sites/dev/docs/tutorials/pattern-design/part2/drawing-the-bib-outline/readme.mdx b/sites/dev/docs/tutorials/pattern-design/part2/drawing-the-bib-outline/readme.mdx index 2065cc6c9c8..107c09a3f6d 100644 --- a/sites/dev/docs/tutorials/pattern-design/part2/drawing-the-bib-outline/readme.mdx +++ b/sites/dev/docs/tutorials/pattern-design/part2/drawing-the-bib-outline/readme.mdx @@ -17,47 +17,46 @@ function draftBib({ part, }) { -// Construct the quarter neck opening -let tweak = 1 -let target = (measurements.head _ options.neckRatio) /4 -let delta -do { -points.right = new Point( -tweak _ measurements.head / 10, -0 -) -points.bottom = new Point( -0, -tweak \* measurements.head / 12 -) - + // Construct the quarter neck opening + let tweak = 1 + let target = (measurements.head * options.neckRatio) /4 + let delta + do { + points.right = new Point( + tweak * measurements.head / 10, + 0 + ) + points.bottom = new Point( + 0, + tweak * measurements.head / 12 + ) + points.rightCp1 = points.right.shift( - 90, + 90, points.bottom.dy(points.right) / 2 ) points.bottomCp2 = points.bottom.shift( - 0, + 0, points.bottom.dx(points.right) / 2 ) -paths.quarterNeck = new Path() -.move(points.right) -.curve( -points.rightCp1, -points.bottomCp2, -points.bottom -) -.hide() + paths.quarterNeck = new Path() + .move(points.right) + .curve( + points.rightCp1, + points.bottomCp2, + points.bottom + ) + .hide() -delta = paths.quarterNeck.length() - target -if (delta > 0) tweak = tweak _ 0.99 -else tweak = tweak _ 1.02 -} while (Math.abs(delta) > 1) + delta = paths.quarterNeck.length() - target + if (delta > 0) tweak = tweak * 0.99 + else tweak = tweak * 1.02 + } while (Math.abs(delta) > 1) -/\* - -- Construct the complete neck opening - \*/ + /* + * Construct the complete neck opening + */ points.rightCp2 = points.rightCp1.flipY() points.bottomCp1 = points.bottomCp2.flipX() points.left = points.right.flipX() @@ -67,45 +66,43 @@ else tweak = tweak _ 1.02 points.topCp1 = points.bottomCp2.flipY() points.topCp2 = points.bottomCp1.flipY() -paths.neck = new Path() -.move(points.top) -.curve(points.topCp2, points.leftCp1, points.left) -.curve(points.leftCp2, points.bottomCp1, points.bottom) -.curve(points.bottomCp2, points.rightCp1, points.right) -.curve(points.rightCp2, points.topCp1, points.top) -.close() -.addClass('fabric') + paths.neck = new Path() + .move(points.top) + .curve(points.topCp2, points.leftCp1, points.left) + .curve(points.leftCp2, points.bottomCp1, points.bottom) + .curve(points.bottomCp2, points.rightCp1, points.right) + .curve(points.rightCp2, points.topCp1, points.top) + .close() + .addClass('fabric') // highlight-start -/\* + /* + * Drawing the bib outline + */ + const width = measurements.head * options.widthRatio + const length = measurements.head * options.lengthRatio -- Drawing the bib outline - _/ - const width = measurements.head _ options.widthRatio - const length = measurements.head \* options.lengthRatio + points.topLeft = new Point( + width / -2, + points.top.y - (width / 2 - points.right.x) + ) + points.topRight = points.topLeft.shift(0, width) + points.bottomLeft = points.topLeft.shift(-90, length) + points.bottomRight = points.topRight.shift(-90, length) -points.topLeft = new Point( -width / -2, -points.top.y - (width / 2 - points.right.x) -) -points.topRight = points.topLeft.shift(0, width) -points.bottomLeft = points.topLeft.shift(-90, length) -points.bottomRight = points.topRight.shift(-90, length) - -paths.rect = new Path() -.move(points.topLeft) -.line(points.bottomLeft) -.line(points.bottomRight) -.line(points.topRight) -.line(points.topLeft) -.close() -.addClass('fabric') + paths.rect = new Path() + .move(points.topLeft) + .line(points.bottomLeft) + .line(points.bottomRight) + .line(points.topRight) + .line(points.topLeft) + .close() + .addClass('fabric') // highlight-end -return part + return part } - -```` +``` First thing we did was create the `width` and `length` variables to @@ -114,7 +111,7 @@ save ourselves some typing: ```js const width = measurements.head * options.widthRatio const length = measurements.head * options.lengthRatio -```` +``` Both the length and width of our bib are a factor of the head circumference. This way, our bib size will adapt to the size of the baby, and the user can tweak @@ -123,7 +120,10 @@ the length and width by playing with the options we added to the pattern. Once we have our variables, we're adding some new points, and a second path called `rect`. ```js -points.topLeft = new Point(width / -2, points.top.y - (width / 2 - points.right.x)) +points.topLeft = new Point( + width / -2, + points.top.y - (width / 2 - points.right.x) +) points.topRight = points.topLeft.shift(0, width) points.bottomLeft = points.topLeft.shift(-90, length) points.bottomRight = points.topRight.shift(-90, length) @@ -142,3 +142,4 @@ We're calculating the `topLeft` point so that the top edge of our bib and the sides are equidistant from the neck opening. We didn't have to do that. But it looks nicely balanced this way. + diff --git a/sites/dev/docs/tutorials/pattern-design/part2/drawing-the-straps/readme.mdx b/sites/dev/docs/tutorials/pattern-design/part2/drawing-the-straps/readme.mdx index a16a8917690..410a1b80100 100644 --- a/sites/dev/docs/tutorials/pattern-design/part2/drawing-the-straps/readme.mdx +++ b/sites/dev/docs/tutorials/pattern-design/part2/drawing-the-straps/readme.mdx @@ -28,38 +28,36 @@ function draftBib({ part, }) { -/\* - -- Construct the neck opening - _/ + /* + * Construct the neck opening + */ let tweak = 1 - let target = (measurements.head _ options.neckRatio) /4 + let target = (measurements.head * options.neckRatio) /4 let delta do { - points.right = new Point( - tweak _ measurements.head / 10, - 0 - ) - points.bottom = new Point( - 0, - tweak _ measurements.head / 12 - ) - - + points.right = new Point( + tweak * measurements.head / 10, + 0 + ) + points.bottom = new Point( + 0, + tweak * measurements.head / 12 + ) + points.rightCp1 = points.right.shift( - 90, + 90, points.bottom.dy(points.right) / 2 ) points.bottomCp2 = points.bottom.shift( - 0, + 0, points.bottom.dx(points.right) / 2 ) - + paths.quarterNeck = new Path() .move(points.right) .curve( - points.rightCp1, - points.bottomCp2, + points.rightCp1, + points.bottomCp2, points.bottom ) .hide() @@ -67,13 +65,11 @@ function draftBib({ delta = paths.quarterNeck.length() - target if (delta > 0) tweak = tweak * 0.99 else tweak = tweak * 1.02 + } while (Math.abs(delta) > 1) -} while (Math.abs(delta) > 1) - -/\* - -- Construct the complete neck opening - \*/ + /* + * Construct the complete neck opening + */ points.rightCp2 = points.rightCp1.flipY() points.bottomCp1 = points.bottomCp2.flipX() points.left = points.right.flipX() @@ -83,239 +79,233 @@ function draftBib({ points.topCp1 = points.bottomCp2.flipY() points.topCp2 = points.bottomCp1.flipY() -// strikeout-start -/_ Remove this path -paths.neck = new Path() -.move(points.top) -.curve(points.topCp2, points.leftCp1, points.left) -.curve(points.leftCp2, points.bottomCp1, points.bottom) -.curve(points.bottomCp2, points.rightCp1, points.right) -.curve(points.rightCp2, points.topCp1, points.top) -.close() -.addClass('fabric') -_/ -// strikeout-end + // strikeout-start + /* Remove this path + paths.neck = new Path() + .move(points.top) + .curve(points.topCp2, points.leftCp1, points.left) + .curve(points.leftCp2, points.bottomCp1, points.bottom) + .curve(points.bottomCp2, points.rightCp1, points.right) + .curve(points.rightCp2, points.topCp1, points.top) + .close() + .addClass('fabric') + */ + // strikeout-end -// Drawing the bib outline -const width = measurements.head _ options.widthRatio -const length = measurements.head _ options.lengthRatio + // Drawing the bib outline + const width = measurements.head * options.widthRatio + const length = measurements.head * options.lengthRatio -points.topLeft = new Point( -width / -2, -points.top.y - (width / 2 - points.right.x) -) -points.topRight = points.topLeft.shift(0, width) -points.bottomLeft = points.topLeft.shift(-90, length) -points.bottomRight = points.topRight.shift(-90, length) + points.topLeft = new Point( + width / -2, + points.top.y - (width / 2 - points.right.x) + ) + points.topRight = points.topLeft.shift(0, width) + points.bottomLeft = points.topLeft.shift(-90, length) + points.bottomRight = points.topRight.shift(-90, length) -/\* - -- Shape the straps - \*/ + /* + * Shape the straps + */ points.edgeLeft = new Point(points.topLeft.x, points.left.y) points.edgeRight = new Point(points.topRight.x, points.right.y) points.edgeTop = new Point(0, points.topLeft.y) -points.edgeLeftCp = points.edgeLeft.shiftFractionTowards(points.topLeft, 0.5) -points.edgeRightCp = points.edgeLeftCp.flipX() -points.edgeTopLeftCp = points.edgeTop.shiftFractionTowards( -points.topLeft, -0.5 -) -points.edgeTopRightCp = points.edgeTopLeftCp.flipX() + points.edgeLeftCp = points.edgeLeft.shiftFractionTowards(points.topLeft, 0.5) + points.edgeRightCp = points.edgeLeftCp.flipX() + points.edgeTopLeftCp = points.edgeTop.shiftFractionTowards( + points.topLeft, + 0.5 + ) + points.edgeTopRightCp = points.edgeTopLeftCp.flipX() -// Round the straps -const strap = points.edgeTop.dy(points.top) + // Round the straps + const strap = points.edgeTop.dy(points.top) -points.tipRight = points.edgeTop.translate(strap / 2, strap / 2) -points.tipRightTop = new Point(points.tipRight.x, points.edgeTop.y) -points.tipRightBottom = new Point(points.tipRight.x, points.top.y) + points.tipRight = points.edgeTop.translate(strap / 2, strap / 2) + points.tipRightTop = new Point(points.tipRight.x, points.edgeTop.y) + points.tipRightBottom = new Point(points.tipRight.x, points.top.y) -/\* - -- Macros will return the auto-generated IDs - _/ + /* + * Macros will return the auto-generated IDs + */ const ids1 = { - tipRightTop: macro("round", { - id: "tipRightTop", - from: points.edgeTop, - to: points.tipRight, - via: points.tipRightTop, - // strikeout-start - /_ Remove this to have the macro - _ only create the points we need - _ and not draw a path - hide: false - _/ - // strikeout-end - }), - tipRightBottom: macro("round", { - id: "tipRightBottom", - from: points.tipRight, - to: points.top, - via: points.tipRightBottom, - // strikeout-start - /_ Remove this to have the macro - _ only create the points we need - _ and not draw a path - hide: false - \*/ - // strikeout-end - }) + tipRightTop: macro("round", { + id: "tipRightTop", + from: points.edgeTop, + to: points.tipRight, + via: points.tipRightTop, + // strikeout-start + /* Remove this to have the macro + * only create the points we need + * and not draw a path + hide: false + */ + // strikeout-end + }), + tipRightBottom: macro("round", { + id: "tipRightBottom", + from: points.tipRight, + to: points.top, + via: points.tipRightBottom, + // strikeout-start + /* Remove this to have the macro + * only create the points we need + * and not draw a path + hide: false + */ + // strikeout-end + }) } -/\* - -- Create points from them with easy names - \*/ + /* + * Create points from them with easy names + */ for (const side in ids1) { - for (const id of ['start', 'cp1', 'cp2', 'end']) { - points[`${side}${utils.capitalize(id)}`] = points[ids1[side].points[id]].copy() - } + for (const id of ['start', 'cp1', 'cp2', 'end']) { + points[`${side}${utils.capitalize(id)}`] = points[ids1[side].points[id]].copy() + } } -/\* + /* + * This is the list of points we need to rotate + * to move our strap out of the way + */ -- This is the list of points we need to rotate -- to move our strap out of the way - \*/ + const rotateThese = [ + "edgeTopLeftCp", + "edgeTop", + "tipRight", + "tipRightTop", + "tipRightTopStart", + "tipRightTopCp1", + "tipRightTopCp2", + "tipRightTopEnd", + "tipRightBottomStart", + "tipRightBottomCp1", + "tipRightBottomCp2", + "tipRightBottomEnd", + "tipRightBottom", + "top", + "topCp2" + ] + /* + * We're rotating all the points in + * the `rotateThese` array around + * the `edgeLeft` point. + * + * We're using increments of 1 degree + * until the `tipRightBottomStart` point + * is 1 mm beyond the center of our bib. + */ + while (points.tipRightBottomStart.x > -1) { + for (const p of rotateThese) points[p] = points[p].rotate(1, points.edgeLeft) + } -const rotateThese = [ -"edgeTopLeftCp", -"edgeTop", -"tipRight", -"tipRightTop", -"tipRightTopStart", -"tipRightTopCp1", -"tipRightTopCp2", -"tipRightTopEnd", -"tipRightBottomStart", -"tipRightBottomCp1", -"tipRightBottomCp2", -"tipRightBottomEnd", -"tipRightBottom", -"top", -"topCp2" -] -/\* -_ We're rotating all the points in -_ the `rotateThese` array around -_ the `edgeLeft` point. -_ -_ We're using increments of 1 degree -_ until the `tipRightBottomStart` point -_ is 1 mm beyond the center of our bib. -_/ -while (points.tipRightBottomStart.x > -1) { -for (const p of rotateThese) points[p] = points[p].rotate(1, points.edgeLeft) + // strikeout-start + /* Remove this repetition + macro("round", { + from: points.edgeTop, + to: points.tipRight, + via: points.tipRightTop, + prefix: "tipRightTop", + hide: false, + class: 'contrast dotted', + }) + macro("round", { + from: points.tipRight, + to: points.top, + via: points.tipRightBottom, + prefix: "tipRightBottom", + hide: false, + class: 'contrast dotted', + }) + + paths.rect = new Path() + .move(points.edgeTop) + .curve(points.edgeTopLeftCp, points.edgeLeftCp, points.edgeLeft) + .line(points.bottomLeft) + .line(points.bottomRight) + .line(points.edgeRight) + .curve(points.edgeRightCp, points.edgeTopRightCp, points.edgeTop) + .close() + */ + // strikeout-end + + // highlight-start + // Add points for second strap + points.edgeTopRightCp = points.edgeTopLeftCp.flipX() + points.topCp1 = points.topCp2.flipX() + points.tipLeftTopStart = points.tipRightTopStart.flipX() + points.tipLeftTopCp1 = points.tipRightTopCp1.flipX() + points.tipLeftTopCp2 = points.tipRightTopCp2.flipX() + points.tipLeftTopEnd = points.tipRightTopEnd.flipX() + points.tipLeftBottomStart = points.tipRightBottomStart.flipX() + points.tipLeftBottomCp1 = points.tipRightBottomCp1.flipX() + points.tipLeftBottomCp2 = points.tipRightBottomCp2.flipX() + points.tipLeftBottomEnd = points.tipRightBottomEnd.flipX() + + // Create one path for the bib outline + paths.seam = new Path() + .move(points.edgeLeft) + .line(points.bottomLeft) + .line(points.bottomRight) + .line(points.edgeRight) + .curve( + points.edgeRightCp, + points.edgeTopRightCp, + points.tipLeftTopStart + ) + .curve( + points.tipLeftTopCp1, + points.tipLeftTopCp2, + points.tipLeftTopEnd + ) + .curve( + points.tipLeftBottomCp1, + points.tipLeftBottomCp2, + points.tipLeftBottomEnd + ) + .curve( + points.topCp1, + points.rightCp2, + points.right + ) + .curve( + points.rightCp1, + points.bottomCp2, + points.bottom + ) + .curve( + points.bottomCp1, + points.leftCp2, + points.left + ) + .curve( + points.leftCp1, + points.topCp2, + points.tipRightBottomEnd + ) + .curve( + points.tipRightBottomCp2, + points.tipRightBottomCp1, + points.tipRightBottomStart + ) + .curve( + points.tipRightTopCp2, + points.tipRightTopCp1, + points.tipRightTopStart + ) + .curve( + points.edgeTopLeftCp, + points.edgeLeftCp, + points.edgeLeft + ) + .close() + .addClass("fabric") + // highlight-end + + return part } - -// strikeout-start -/\* Remove this repetition -macro("round", { -from: points.edgeTop, -to: points.tipRight, -via: points.tipRightTop, -prefix: "tipRightTop", -hide: false, -class: 'contrast dotted', -}) -macro("round", { -from: points.tipRight, -to: points.top, -via: points.tipRightBottom, -prefix: "tipRightBottom", -hide: false, -class: 'contrast dotted', -}) - -paths.rect = new Path() -.move(points.edgeTop) -.curve(points.edgeTopLeftCp, points.edgeLeftCp, points.edgeLeft) -.line(points.bottomLeft) -.line(points.bottomRight) -.line(points.edgeRight) -.curve(points.edgeRightCp, points.edgeTopRightCp, points.edgeTop) -.close() -\*/ -// strikeout-end - -// highlight-start -// Add points for second strap -points.edgeTopRightCp = points.edgeTopLeftCp.flipX() -points.topCp1 = points.topCp2.flipX() -points.tipLeftTopStart = points.tipRightTopStart.flipX() -points.tipLeftTopCp1 = points.tipRightTopCp1.flipX() -points.tipLeftTopCp2 = points.tipRightTopCp2.flipX() -points.tipLeftTopEnd = points.tipRightTopEnd.flipX() -points.tipLeftBottomStart = points.tipRightBottomStart.flipX() -points.tipLeftBottomCp1 = points.tipRightBottomCp1.flipX() -points.tipLeftBottomCp2 = points.tipRightBottomCp2.flipX() -points.tipLeftBottomEnd = points.tipRightBottomEnd.flipX() - -// Create one path for the bib outline -paths.seam = new Path() -.move(points.edgeLeft) -.line(points.bottomLeft) -.line(points.bottomRight) -.line(points.edgeRight) -.curve( -points.edgeRightCp, -points.edgeTopRightCp, -points.tipLeftTopStart -) -.curve( -points.tipLeftTopCp1, -points.tipLeftTopCp2, -points.tipLeftTopEnd -) -.curve( -points.tipLeftBottomCp1, -points.tipLeftBottomCp2, -points.tipLeftBottomEnd -) -.curve( -points.topCp1, -points.rightCp2, -points.right -) -.curve( -points.rightCp1, -points.bottomCp2, -points.bottom -) -.curve( -points.bottomCp1, -points.leftCp2, -points.left -) -.curve( -points.leftCp1, -points.topCp2, -points.tipRightBottomEnd -) -.curve( -points.tipRightBottomCp2, -points.tipRightBottomCp1, -points.tipRightBottomStart -) -.curve( -points.tipRightTopCp2, -points.tipRightTopCp1, -points.tipRightTopStart -) -.curve( -points.edgeTopLeftCp, -points.edgeLeftCp, -points.edgeLeft -) -.close() -.addClass("fabric") -// highlight-end - -return part -} - ``` -``` diff --git a/sites/dev/docs/tutorials/pattern-design/part2/fitting-the-neck-opening/readme.mdx b/sites/dev/docs/tutorials/pattern-design/part2/fitting-the-neck-opening/readme.mdx index d2d935f9962..8771c5711da 100644 --- a/sites/dev/docs/tutorials/pattern-design/part2/fitting-the-neck-opening/readme.mdx +++ b/sites/dev/docs/tutorials/pattern-design/part2/fitting-the-neck-opening/readme.mdx @@ -4,7 +4,7 @@ sidebar_position: 70 --- We are not going to create some opening that we _hope_ is the right size, we're -going to make sure it is. Here's how we'll make sure the neck opening is _just +going to make sure it is. Here's how we'll make sure the neck opening is _just right_: @@ -19,56 +19,54 @@ function draftBib({ part, }) { -/\* - -- Construct the quarter neck opening - _/ - // highlight-start + /* + * Construct the quarter neck opening + */ +// highlight-start let tweak = 1 - let target = (measurements.head _ options.neckRatio) /4 + let target = (measurements.head * options.neckRatio) /4 let delta do { - // highlight-end - points.right = new Point( - // highlight-start - tweak _ measurements.head / 10, - // highlight-end - 0 - ) - points.bottom = new Point( - 0, - // highlight-start - tweak _ measurements.head / 12 - // highlight-end - ) - +// highlight-end + points.right = new Point( +// highlight-start + tweak * measurements.head / 10, +// highlight-end + 0 + ) + points.bottom = new Point( + 0, +// highlight-start + tweak * measurements.head / 12 +// highlight-end + ) points.rightCp1 = points.right.shift( - 90, + 90, points.bottom.dy(points.right) / 2 ) points.bottomCp2 = points.bottom.shift( - 0, + 0, points.bottom.dx(points.right) / 2 ) paths.quarterNeck = new Path() .move(points.right) .curve( - points.rightCp1, - points.bottomCp2, + points.rightCp1, + points.bottomCp2, points.bottom ) -// highlight-start -delta = paths.quarterNeck.length() - target -if (delta > 0) tweak = tweak _ 0.99 -else tweak = tweak _ 1.02 -} while (Math.abs(delta) > 1) -// highlight-end -return part -} +// highlight-start + delta = paths.quarterNeck.length() - target + if (delta > 0) tweak = tweak * 0.99 + else tweak = tweak * 1.02 + } while (Math.abs(delta) > 1) +// highlight-end + return part +} ``` @@ -96,4 +94,3 @@ are within 1 mm of our target value. Now that we're happy with the length of our quarter neck opening, let's complete the entire neck opening. -``` diff --git a/sites/dev/docs/tutorials/pattern-design/part2/rounding-the-corners/readme.mdx b/sites/dev/docs/tutorials/pattern-design/part2/rounding-the-corners/readme.mdx index 7cd0b4925cb..2cafb2fe324 100644 --- a/sites/dev/docs/tutorials/pattern-design/part2/rounding-the-corners/readme.mdx +++ b/sites/dev/docs/tutorials/pattern-design/part2/rounding-the-corners/readme.mdx @@ -22,38 +22,36 @@ function draftBib({ part, }) { -/\* - -- Construct the quarter neck opening - _/ + /* + * Construct the quarter neck opening + */ let tweak = 1 - let target = (measurements.head _ options.neckRatio) /4 + let target = (measurements.head * options.neckRatio) /4 let delta do { - points.right = new Point( - tweak _ measurements.head / 10, - 0 - ) - points.bottom = new Point( - 0, - tweak _ measurements.head / 12 - ) - - + points.right = new Point( + tweak * measurements.head / 10, + 0 + ) + points.bottom = new Point( + 0, + tweak * measurements.head / 12 + ) + points.rightCp1 = points.right.shift( - 90, + 90, points.bottom.dy(points.right) / 2 ) points.bottomCp2 = points.bottom.shift( - 0, + 0, points.bottom.dx(points.right) / 2 ) - + paths.quarterNeck = new Path() .move(points.right) .curve( - points.rightCp1, - points.bottomCp2, + points.rightCp1, + points.bottomCp2, points.bottom ) .hide() @@ -61,13 +59,11 @@ function draftBib({ delta = paths.quarterNeck.length() - target if (delta > 0) tweak = tweak * 0.99 else tweak = tweak * 1.02 + } while (Math.abs(delta) > 1) -} while (Math.abs(delta) > 1) - -/\* - -- Construct the complete neck opening - \*/ + /* + * Construct the complete neck opening + */ points.rightCp2 = points.rightCp1.flipY() points.bottomCp1 = points.bottomCp2.flipX() points.left = points.right.flipX() @@ -77,225 +73,216 @@ function draftBib({ points.topCp1 = points.bottomCp2.flipY() points.topCp2 = points.bottomCp1.flipY() -// Drawing the bib outline -const width = measurements.head _ options.widthRatio -const length = measurements.head _ options.lengthRatio + // Drawing the bib outline + const width = measurements.head * options.widthRatio + const length = measurements.head * options.lengthRatio -points.topLeft = new Point( -width / -2, -points.top.y - (width / 2 - points.right.x) -) -points.topRight = points.topLeft.shift(0, width) -points.bottomLeft = points.topLeft.shift(-90, length) -points.bottomRight = points.topRight.shift(-90, length) + points.topLeft = new Point( + width / -2, + points.top.y - (width / 2 - points.right.x) + ) + points.topRight = points.topLeft.shift(0, width) + points.bottomLeft = points.topLeft.shift(-90, length) + points.bottomRight = points.topRight.shift(-90, length) -/\* - -- Shape the straps - \*/ + /* + * Shape the straps + */ points.edgeLeft = new Point(points.topLeft.x, points.left.y) points.edgeRight = new Point(points.topRight.x, points.right.y) points.edgeTop = new Point(0, points.topLeft.y) -points.edgeLeftCp = points.edgeLeft.shiftFractionTowards(points.topLeft, 0.5) -points.edgeRightCp = points.edgeLeftCp.flipX() -points.edgeTopLeftCp = points.edgeTop.shiftFractionTowards( -points.topLeft, -0.5 -) -points.edgeTopRightCp = points.edgeTopLeftCp.flipX() + points.edgeLeftCp = points.edgeLeft.shiftFractionTowards(points.topLeft, 0.5) + points.edgeRightCp = points.edgeLeftCp.flipX() + points.edgeTopLeftCp = points.edgeTop.shiftFractionTowards( + points.topLeft, + 0.5 + ) + points.edgeTopRightCp = points.edgeTopLeftCp.flipX() -// Round the straps -const strap = points.edgeTop.dy(points.top) + // Round the straps + const strap = points.edgeTop.dy(points.top) -points.tipRight = points.edgeTop.translate(strap / 2, strap / 2) -points.tipRightTop = new Point(points.tipRight.x, points.edgeTop.y) -points.tipRightBottom = new Point(points.tipRight.x, points.top.y) + points.tipRight = points.edgeTop.translate(strap / 2, strap / 2) + points.tipRightTop = new Point(points.tipRight.x, points.edgeTop.y) + points.tipRightBottom = new Point(points.tipRight.x, points.top.y) -/\* - -- Macros will return the auto-generated IDs - \*/ + /* + * Macros will return the auto-generated IDs + */ const ids1 = { - tipRightTop: macro("round", { - id: "tipRightTop", - from: points.edgeTop, - to: points.tipRight, - via: points.tipRightTop, - }), - tipRightBottom: macro("round", { - id: "tipRightBottom", - from: points.tipRight, - to: points.top, - via: points.tipRightBottom, - }) + tipRightTop: macro("round", { + id: "tipRightTop", + from: points.edgeTop, + to: points.tipRight, + via: points.tipRightTop, + }), + tipRightBottom: macro("round", { + id: "tipRightBottom", + from: points.tipRight, + to: points.top, + via: points.tipRightBottom, + }) } -/\* - -- Create points from them with easy names - \*/ + /* + * Create points from them with easy names + */ for (const side in ids1) { - for (const id of ['start', 'cp1', 'cp2', 'end']) { - points[`${side}${utils.capitalize(id)}`] = points[ids1[side].points[id]].copy() + for (const id of ['start', 'cp1', 'cp2', 'end']) { + points[`${side}${utils.capitalize(id)}`] = points[ids1[side].points[id]].copy() + } } - } - /* - -- This is the list of points we need to rotate -- to move our strap out of the way - _/ + * This is the list of points we need to rotate + * to move our strap out of the way + */ const rotateThese = [ - "edgeTopLeftCp", - "edgeTop", - "tipRight", - "tipRightTop", - "tipRightTopStart", - "tipRightTopCp1", - "tipRightTopCp2", - "tipRightTopEnd", - "tipRightBottomStart", - "tipRightBottomCp1", - "tipRightBottomCp2", - "tipRightBottomEnd", - "tipRightBottom", - "top", - "topCp2" + "edgeTopLeftCp", + "edgeTop", + "tipRight", + "tipRightTop", + "tipRightTopStart", + "tipRightTopCp1", + "tipRightTopCp2", + "tipRightTopEnd", + "tipRightBottomStart", + "tipRightBottomCp1", + "tipRightBottomCp2", + "tipRightBottomEnd", + "tipRightBottom", + "top", + "topCp2" ] - /_ - - We're rotating all the points in - - the `rotateThese` array around - - the `edgeLeft` point. - - - - We're using increments of 1 degree - - until the `tipRightBottomStart` point - - is 1 mm beyond the center of our bib. - \*/ - while (points.tipRightBottomStart.x > -1) { + /* + * We're rotating all the points in + * the `rotateThese` array around + * the `edgeLeft` point. + * + * We're using increments of 1 degree + * until the `tipRightBottomStart` point + * is 1 mm beyond the center of our bib. + */ + while (points.tipRightBottomStart.x > -1) { for (const p of rotateThese) points[p] = points[p].rotate(1, points.edgeLeft) - } + } -// Add points for second strap -points.edgeTopRightCp = points.edgeTopLeftCp.flipX() -points.topCp1 = points.topCp2.flipX() -points.tipLeftTopStart = points.tipRightTopStart.flipX() -points.tipLeftTopCp1 = points.tipRightTopCp1.flipX() -points.tipLeftTopCp2 = points.tipRightTopCp2.flipX() -points.tipLeftTopEnd = points.tipRightTopEnd.flipX() -points.tipLeftBottomStart = points.tipRightBottomStart.flipX() -points.tipLeftBottomCp1 = points.tipRightBottomCp1.flipX() -points.tipLeftBottomCp2 = points.tipRightBottomCp2.flipX() -points.tipLeftBottomEnd = points.tipRightBottomEnd.flipX() + // Add points for second strap + points.edgeTopRightCp = points.edgeTopLeftCp.flipX() + points.topCp1 = points.topCp2.flipX() + points.tipLeftTopStart = points.tipRightTopStart.flipX() + points.tipLeftTopCp1 = points.tipRightTopCp1.flipX() + points.tipLeftTopCp2 = points.tipRightTopCp2.flipX() + points.tipLeftTopEnd = points.tipRightTopEnd.flipX() + points.tipLeftBottomStart = points.tipRightBottomStart.flipX() + points.tipLeftBottomCp1 = points.tipRightBottomCp1.flipX() + points.tipLeftBottomCp2 = points.tipRightBottomCp2.flipX() + points.tipLeftBottomEnd = points.tipRightBottomEnd.flipX() -// highlight-start -/\* - -- Round the bottom corners -- Macros will return the auto-generated IDs - \*/ + // highlight-start + /* + * Round the bottom corners + * Macros will return the auto-generated IDs + */ const ids2 = { - bottomLeft: macro("round", { - id: "bottomLeft", - from: points.topLeft, - to: points.bottomRight, - via: points.bottomLeft, - radius: points.bottomRight.x / 4, - }), - bottomRight: macro("round", { - id: "bottomRight", - from: points.bottomLeft, - to: points.topRight, - via: points.bottomRight, - radius: points.bottomRight.x / 4, - }) + bottomLeft: macro("round", { + id: "bottomLeft", + from: points.topLeft, + to: points.bottomRight, + via: points.bottomLeft, + radius: points.bottomRight.x / 4, + }), + bottomRight: macro("round", { + id: "bottomRight", + from: points.bottomLeft, + to: points.topRight, + via: points.bottomRight, + radius: points.bottomRight.x / 4, + }) } -/\* - -- Create points from them with easy names - \*/ + /* + * Create points from them with easy names + */ for (const side in ids2) { - for (const id of ['start', 'cp1', 'cp2', 'end']) { - points[`${side}${utils.capitalize(id)}`] = points[ids2[side].points[id]].copy() - } + for (const id of ['start', 'cp1', 'cp2', 'end']) { + points[`${side}${utils.capitalize(id)}`] = points[ids2[side].points[id]].copy() + } } // highlight-end -// Create one path for the bib outline -paths.seam = new Path() -.move(points.edgeLeft) -// strikeout-start -/_ We only need to replace the start -_ with the new lines below -.line(points.bottomLeft) -.line(points.bottomRight) -\*/ -// strikeout-end -// highlight-start -.line(points.bottomLeftStart) -.curve(points.bottomLeftCp1, points.bottomLeftCp2, points.bottomLeftEnd) -.line(points.bottomRightStart) -.curve(points.bottomRightCp1, points.bottomRightCp2, points.bottomRightEnd) -// highlight-end -.line(points.edgeRight) -.curve( -points.edgeRightCp, -points.edgeTopRightCp, -points.tipLeftTopStart -) -.curve( -points.tipLeftTopCp1, -points.tipLeftTopCp2, -points.tipLeftTopEnd -) -.curve( -points.tipLeftBottomCp1, -points.tipLeftBottomCp2, -points.tipLeftBottomEnd -) -.curve( -points.topCp1, -points.rightCp2, -points.right -) -.curve( -points.rightCp1, -points.bottomCp2, -points.bottom -) -.curve( -points.bottomCp1, -points.leftCp2, -points.left -) -.curve( -points.leftCp1, -points.topCp2, -points.tipRightBottomEnd -) -.curve( -points.tipRightBottomCp2, -points.tipRightBottomCp1, -points.tipRightBottomStart -) -.curve( -points.tipRightTopCp2, -points.tipRightTopCp1, -points.tipRightTopStart -) -.curve( -points.edgeTopLeftCp, -points.edgeLeftCp, -points.edgeLeft -) -.close() -.addClass("fabric") + // Create one path for the bib outline + paths.seam = new Path() + .move(points.edgeLeft) + // strikeout-start + /* We only need to replace the start + * with the new lines below + .line(points.bottomLeft) + .line(points.bottomRight) + */ + // strikeout-end + // highlight-start + .line(points.bottomLeftStart) + .curve(points.bottomLeftCp1, points.bottomLeftCp2, points.bottomLeftEnd) + .line(points.bottomRightStart) + .curve(points.bottomRightCp1, points.bottomRightCp2, points.bottomRightEnd) + // highlight-end + .line(points.edgeRight) + .curve( + points.edgeRightCp, + points.edgeTopRightCp, + points.tipLeftTopStart + ) + .curve( + points.tipLeftTopCp1, + points.tipLeftTopCp2, + points.tipLeftTopEnd + ) + .curve( + points.tipLeftBottomCp1, + points.tipLeftBottomCp2, + points.tipLeftBottomEnd + ) + .curve( + points.topCp1, + points.rightCp2, + points.right + ) + .curve( + points.rightCp1, + points.bottomCp2, + points.bottom + ) + .curve( + points.bottomCp1, + points.leftCp2, + points.left + ) + .curve( + points.leftCp1, + points.topCp2, + points.tipRightBottomEnd + ) + .curve( + points.tipRightBottomCp2, + points.tipRightBottomCp1, + points.tipRightBottomStart + ) + .curve( + points.tipRightTopCp2, + points.tipRightTopCp1, + points.tipRightTopStart + ) + .curve( + points.edgeTopLeftCp, + points.edgeLeftCp, + points.edgeLeft + ) + .close() + .addClass("fabric") -return part + return part } - ``` -``` diff --git a/sites/dev/docs/tutorials/pattern-design/part2/shaping-the-straps/readme.mdx b/sites/dev/docs/tutorials/pattern-design/part2/shaping-the-straps/readme.mdx index 25739c8d295..b6990397044 100644 --- a/sites/dev/docs/tutorials/pattern-design/part2/shaping-the-straps/readme.mdx +++ b/sites/dev/docs/tutorials/pattern-design/part2/shaping-the-straps/readme.mdx @@ -15,6 +15,7 @@ As always, [the API docs](/reference/api/point/) have all the details. ::: + ```design/src/bib.mjs function draftBib({ @@ -27,38 +28,36 @@ function draftBib({ part, }) { -/\* - -- Construct the quarter neck opening - _/ + /* + * Construct the quarter neck opening + */ let tweak = 1 - let target = (measurements.head _ options.neckRatio) /4 + let target = (measurements.head * options.neckRatio) /4 let delta do { - points.right = new Point( - tweak _ measurements.head / 10, - 0 - ) - points.bottom = new Point( - 0, - tweak _ measurements.head / 12 - ) - - + points.right = new Point( + tweak * measurements.head / 10, + 0 + ) + points.bottom = new Point( + 0, + tweak * measurements.head / 12 + ) + points.rightCp1 = points.right.shift( - 90, + 90, points.bottom.dy(points.right) / 2 ) points.bottomCp2 = points.bottom.shift( - 0, + 0, points.bottom.dx(points.right) / 2 ) paths.quarterNeck = new Path() .move(points.right) .curve( - points.rightCp1, - points.bottomCp2, + points.rightCp1, + points.bottomCp2, points.bottom ) .hide() @@ -66,13 +65,11 @@ function draftBib({ delta = paths.quarterNeck.length() - target if (delta > 0) tweak = tweak * 0.99 else tweak = tweak * 1.02 + } while (Math.abs(delta) > 1) -} while (Math.abs(delta) > 1) - -/\* - -- Construct the complete neck opening - \*/ + /* + * Construct the complete neck opening + */ points.rightCp2 = points.rightCp1.flipY() points.bottomCp1 = points.bottomCp2.flipX() points.left = points.right.flipX() @@ -82,81 +79,75 @@ function draftBib({ points.topCp1 = points.bottomCp2.flipY() points.topCp2 = points.bottomCp1.flipY() -paths.neck = new Path() -.move(points.top) -.curve(points.topCp2, points.leftCp1, points.left) -.curve(points.leftCp2, points.bottomCp1, points.bottom) -.curve(points.bottomCp2, points.rightCp1, points.right) -.curve(points.rightCp2, points.topCp1, points.top) -.close() -.addClass('fabric') + paths.neck = new Path() + .move(points.top) + .curve(points.topCp2, points.leftCp1, points.left) + .curve(points.leftCp2, points.bottomCp1, points.bottom) + .curve(points.bottomCp2, points.rightCp1, points.right) + .curve(points.rightCp2, points.topCp1, points.top) + .close() + .addClass('fabric') -/\* + /* + * Drawing the bib outline + */ + const width = measurements.head * options.widthRatio + const length = measurements.head * options.lengthRatio -- Drawing the bib outline - _/ - const width = measurements.head _ options.widthRatio - const length = measurements.head \* options.lengthRatio - -points.topLeft = new Point( -width / -2, -points.top.y - (width / 2 - points.right.x) -) -points.topRight = points.topLeft.shift(0, width) -points.bottomLeft = points.topLeft.shift(-90, length) -points.bottomRight = points.topRight.shift(-90, length) + points.topLeft = new Point( + width / -2, + points.top.y - (width / 2 - points.right.x) + ) + points.topRight = points.topLeft.shift(0, width) + points.bottomLeft = points.topLeft.shift(-90, length) + points.bottomRight = points.topRight.shift(-90, length) // strikeout-start -/\* - -- Remove this path +/* +* Remove this path paths.rect = new Path() - .move(points.topLeft) - .line(points.bottomLeft) - .line(points.bottomRight) - .line(points.topRight) - .line(points.topLeft) - .close() - .addClass('fabric') - \*/ - // strikeout-end + .move(points.topLeft) + .line(points.bottomLeft) + .line(points.bottomRight) + .line(points.topRight) + .line(points.topLeft) + .close() + .addClass('fabric') +*/ +// strikeout-end // highlight-start -/\* - -- Shape the straps - \*/ + /* + * Shape the straps + */ points.edgeLeft = new Point(points.topLeft.x, points.left.y) points.edgeRight = new Point(points.topRight.x, points.right.y) points.edgeTop = new Point(0, points.topLeft.y) -points.edgeLeftCp = points.edgeLeft.shiftFractionTowards(points.topLeft, 0.5) -points.edgeRightCp = points.edgeLeftCp.flipX() -points.edgeTopLeftCp = points.edgeTop.shiftFractionTowards( -points.topLeft, -0.5 -) -points.edgeTopRightCp = points.edgeTopLeftCp.flipX() + points.edgeLeftCp = points.edgeLeft.shiftFractionTowards(points.topLeft, 0.5) + points.edgeRightCp = points.edgeLeftCp.flipX() + points.edgeTopLeftCp = points.edgeTop.shiftFractionTowards( + points.topLeft, + 0.5 + ) + points.edgeTopRightCp = points.edgeTopLeftCp.flipX() -/\* - -- Now, adapt our `rect` path so it's no longer a rectangle: - \*/ + /* + * Now, adapt our `rect` path so it's no longer a rectangle: + */ paths.rect = new Path() - .move(points.edgeTop) - .curve(points.edgeTopLeftCp, points.edgeLeftCp, points.edgeLeft) - .line(points.bottomLeft) - .line(points.bottomRight) - .line(points.edgeRight) - .curve(points.edgeRightCp, points.edgeTopRightCp, points.edgeTop) - .close() + .move(points.edgeTop) + .curve(points.edgeTopLeftCp, points.edgeLeftCp, points.edgeLeft) + .line(points.bottomLeft) + .line(points.bottomRight) + .line(points.edgeRight) + .curve(points.edgeRightCp, points.edgeTopRightCp, points.edgeTop) + .close() // highlight-end -return part + return part } - ``` -``` diff --git a/sites/dev/docs/tutorials/pattern-design/part3/annotations/readme.mdx b/sites/dev/docs/tutorials/pattern-design/part3/annotations/readme.mdx index d8020b7f8be..e955e02970b 100644 --- a/sites/dev/docs/tutorials/pattern-design/part3/annotations/readme.mdx +++ b/sites/dev/docs/tutorials/pattern-design/part3/annotations/readme.mdx @@ -3,9 +3,9 @@ title: Adding annotations sidebar_position: 20 --- -Our pattern is still a little bit _bare_. It would be nice to add some _annotations_ to it. +Our pattern is still a little bit *bare*. It would be nice to add some *annotations* to it. -When I say _annotations_ it's an umbrella term for things like text or other +When I say *annotations* it's an umbrella term for things like text or other bits of information that help the user understand the pattern. ## Adding snippets @@ -42,17 +42,15 @@ function draftBib({ part, }) { -/\* - -- Construct the neck opening - _/ - const target = (measurements.head _ options.neckRatio) / 4 + /* + * Construct the neck opening + */ + const target = (measurements.head * options.neckRatio) / 4 let tweak = 1 let delta do { - points.right = new Point((tweak _ measurements.head) / 10, 0) - points.bottom = new Point(0, (tweak _ measurements.head) / 12) - + points.right = new Point((tweak * measurements.head) / 10, 0) + points.bottom = new Point(0, (tweak * measurements.head) / 12) points.rightCp1 = points.right.shift(90, points.bottom.dy(points.right) / 2) points.bottomCp2 = points.bottom.shift(0, points.bottom.dx(points.right) / 2) @@ -64,116 +62,108 @@ function draftBib({ delta = paths.neck.length() - target if (delta > 0) tweak = tweak * 0.99 else tweak = tweak * 1.02 + } while (Math.abs(delta) > 1) -} while (Math.abs(delta) > 1) + points.rightCp2 = points.rightCp1.flipY() + points.bottomCp1 = points.bottomCp2.flipX() -points.rightCp2 = points.rightCp1.flipY() -points.bottomCp1 = points.bottomCp2.flipX() + points.left = points.right.flipX() + points.leftCp1 = points.rightCp2.flipX() + points.leftCp2 = points.rightCp1.flipX() -points.left = points.right.flipX() -points.leftCp1 = points.rightCp2.flipX() -points.leftCp2 = points.rightCp1.flipX() + points.top = points.bottom.flipY() + points.topCp1 = points.bottomCp2.flipY() + points.topCp2 = points.bottomCp1.flipY() -points.top = points.bottom.flipY() -points.topCp1 = points.bottomCp2.flipY() -points.topCp2 = points.bottomCp1.flipY() + /* + * Construct the outline + */ + let width = measurements.head * options.widthRatio + let length = measurements.head * options.lengthRatio -/\* + points.topLeft = new Point(width / -2, points.top.y - (width / 2 - points.right.x)) + points.topRight = points.topLeft.shift(0, width) + points.bottomLeft = points.topLeft.shift(-90, length) + points.bottomRight = points.topRight.shift(-90, length) -- Construct the outline - _/ - let width = measurements.head _ options.widthRatio - let length = measurements.head \* options.lengthRatio + points.edgeLeft = new Point(points.topLeft.x, points.left.y) + points.edgeRight = new Point(points.topRight.x, points.right.y) + points.edgeTop = new Point(0, points.topLeft.y) -points.topLeft = new Point(width / -2, points.top.y - (width / 2 - points.right.x)) -points.topRight = points.topLeft.shift(0, width) -points.bottomLeft = points.topLeft.shift(-90, length) -points.bottomRight = points.topRight.shift(-90, length) + points.edgeLeftCp = points.edgeLeft.shiftFractionTowards(points.topLeft, 0.5) + points.edgeRightCp = points.edgeLeftCp.flipX() + points.edgeTopLeftCp = points.edgeTop.shiftFractionTowards(points.topLeft, 0.5) + points.edgeTopRightCp = points.edgeTopLeftCp.flipX() -points.edgeLeft = new Point(points.topLeft.x, points.left.y) -points.edgeRight = new Point(points.topRight.x, points.right.y) -points.edgeTop = new Point(0, points.topLeft.y) - -points.edgeLeftCp = points.edgeLeft.shiftFractionTowards(points.topLeft, 0.5) -points.edgeRightCp = points.edgeLeftCp.flipX() -points.edgeTopLeftCp = points.edgeTop.shiftFractionTowards(points.topLeft, 0.5) -points.edgeTopRightCp = points.edgeTopLeftCp.flipX() - -/\* - -- Round the end of the straps - \*/ + /* + * Round the end of the straps + */ let strap = points.edgeTop.dy(points.top) -points.tipRight = points.edgeTop.translate(strap / 2, strap / 2) -points.tipRightTop = new Point(points.tipRight.x, points.edgeTop.y) -points.tipRightBottom = new Point(points.tipRight.x, points.top.y) + points.tipRight = points.edgeTop.translate(strap / 2, strap / 2) + points.tipRightTop = new Point(points.tipRight.x, points.edgeTop.y) + points.tipRightBottom = new Point(points.tipRight.x, points.top.y) -/\* - -- Macros will return the auto-generated IDs - \*/ + /* + * Macros will return the auto-generated IDs + */ const ids1 = { - tipRightTop: macro('round', { - id: 'tipRightTop', - from: points.edgeTop, - to: points.tipRight, - via: points.tipRightTop, - }), - tipRightBottom: macro('round', { - id: 'tipRightBottom', - from: points.tipRight, - to: points.top, - via: points.tipRightBottom, - }), + tipRightTop: macro('round', { + id: 'tipRightTop', + from: points.edgeTop, + to: points.tipRight, + via: points.tipRightTop, + }), + tipRightBottom: macro('round', { + id: 'tipRightBottom', + from: points.tipRight, + to: points.top, + via: points.tipRightBottom, + }), } -/\* - -- Create points from them with easy names - \*/ + /* + * Create points from them with easy names + */ for (const side in ids1) { - for (const id of ['start', 'cp1', 'cp2', 'end']) { - points[`${side}${utils.capitalize(id)}`] = points[ids1[side].points[id]].copy() - } + for (const id of ['start', 'cp1', 'cp2', 'end']) { + points[`${side}${utils.capitalize(id)}`] = points[ids1[side].points[id]].copy() + } } -/\* - -- Rotate straps so they don't overlap - \*/ + /* + * Rotate straps so they don't overlap + */ let rotateThese = [ - 'edgeTopLeftCp', - 'edgeTop', - 'tipRight', - 'tipRightTop', - 'tipRightTopStart', - 'tipRightTopCp1', - 'tipRightTopCp2', - 'tipRightTopEnd', - 'tipRightBottomStart', - 'tipRightBottomCp1', - 'tipRightBottomCp2', - 'tipRightBottomEnd', - 'tipRightBottom', - 'top', - 'topCp2', + 'edgeTopLeftCp', + 'edgeTop', + 'tipRight', + 'tipRightTop', + 'tipRightTopStart', + 'tipRightTopCp1', + 'tipRightTopCp2', + 'tipRightTopEnd', + 'tipRightBottomStart', + 'tipRightBottomCp1', + 'tipRightBottomCp2', + 'tipRightBottomEnd', + 'tipRightBottom', + 'top', + 'topCp2', ] -while (points.tipRightBottomStart.x > -1) { -for (let p of rotateThese) points[p] = points[p].rotate(1, points.edgeLeft) -} + while (points.tipRightBottomStart.x > -1) { + for (let p of rotateThese) points[p] = points[p].rotate(1, points.edgeLeft) + } -/\* - -- Add points to anchor snaps on - \*/ + /* + * Add points to anchor snaps on + */ points.snapLeft = points.top.shiftFractionTowards(points.edgeTop, 0.5) -/\* - -- Mirror points to the other side - \*/ + /* + * Mirror points to the other side + */ points.edgeTopRightCp = points.edgeTopLeftCp.flipX() points.topCp1 = points.topCp2.flipX() points.tipLeftTopStart = points.tipRightTopStart.flipX() @@ -186,88 +176,83 @@ for (let p of rotateThese) points[p] = points[p].rotate(1, points.edgeLeft) points.tipLeftBottomEnd = points.tipRightBottomEnd.flipX() points.snapRight = points.snapLeft.flipX() -/\* - -- Round the bottom of the bib -- Radius is fixed, but you could use an option for it) -- -- Macros will return the auto-generated IDs - _/ + /* + * Round the bottom of the bib + * Radius is fixed, but you could use an option for it) + * + * Macros will return the auto-generated IDs + */ const ids2 = { - bottomLeft: macro('round', { - id: 'bottomLeft', - from: points.topLeft, - to: points.bottomRight, - via: points.bottomLeft, - radius: points.bottomRight.x / 4, - }), - bottomRight: macro('round', { - id: 'bottomRight', - from: points.bottomLeft, - to: points.topRight, - via: points.bottomRight, - radius: points.bottomRight.x / 4, - }), + bottomLeft: macro('round', { + id: 'bottomLeft', + from: points.topLeft, + to: points.bottomRight, + via: points.bottomLeft, + radius: points.bottomRight.x / 4, + }), + bottomRight: macro('round', { + id: 'bottomRight', + from: points.bottomLeft, + to: points.topRight, + via: points.bottomRight, + radius: points.bottomRight.x / 4, + }), } - /_ -- Create points from them with easy names - \*/ + /* + * Create points from them with easy names + */ for (const side in ids2) { - for (const id of ['start', 'cp1', 'cp2', 'end']) { - points[`${side}${utils.capitalize(id)}`] = points[ids2[side].points[id]].copy() - } + for (const id of ['start', 'cp1', 'cp2', 'end']) { + points[`${side}${utils.capitalize(id)}`] = points[ids2[side].points[id]].copy() + } } -/\* - -- Construct the path - \*/ + /* + * Construct the path + */ paths.seam = new Path() - .move(points.edgeLeft) - .line(points.bottomLeftStart) - .curve(points.bottomLeftCp1, points.bottomLeftCp2, points.bottomLeftEnd) - .line(points.bottomRightStart) - .curve(points.bottomRightCp1, points.bottomRightCp2, points.bottomRightEnd) - .line(points.edgeRight) - .curve(points.edgeRightCp, points.edgeTopRightCp, points.tipLeftTopStart) - .curve(points.tipLeftTopCp1, points.tipLeftTopCp2, points.tipLeftTopEnd) - .curve(points.tipLeftBottomCp1, points.tipLeftBottomCp2, points.tipLeftBottomEnd) - .curve(points.topCp1, points.rightCp2, points.right) - .curve(points.rightCp1, points.bottomCp2, points.bottom) - .curve(points.bottomCp1, points.leftCp2, points.left) - .curve(points.leftCp1, points.topCp2, points.tipRightBottomEnd) - .curve(points.tipRightBottomCp2, points.tipRightBottomCp1, points.tipRightBottomStart) - .curve(points.tipRightTopCp2, points.tipRightTopCp1, points.tipRightTopStart) - .curve(points.edgeTopLeftCp, points.edgeLeftCp, points.edgeLeft) - .close() - .attr('class', 'fabric') + .move(points.edgeLeft) + .line(points.bottomLeftStart) + .curve(points.bottomLeftCp1, points.bottomLeftCp2, points.bottomLeftEnd) + .line(points.bottomRightStart) + .curve(points.bottomRightCp1, points.bottomRightCp2, points.bottomRightEnd) + .line(points.edgeRight) + .curve(points.edgeRightCp, points.edgeTopRightCp, points.tipLeftTopStart) + .curve(points.tipLeftTopCp1, points.tipLeftTopCp2, points.tipLeftTopEnd) + .curve(points.tipLeftBottomCp1, points.tipLeftBottomCp2, points.tipLeftBottomEnd) + .curve(points.topCp1, points.rightCp2, points.right) + .curve(points.rightCp1, points.bottomCp2, points.bottom) + .curve(points.bottomCp1, points.leftCp2, points.left) + .curve(points.leftCp1, points.topCp2, points.tipRightBottomEnd) + .curve(points.tipRightBottomCp2, points.tipRightBottomCp1, points.tipRightBottomStart) + .curve(points.tipRightTopCp2, points.tipRightTopCp1, points.tipRightTopStart) + .curve(points.edgeTopLeftCp, points.edgeLeftCp, points.edgeLeft) + .close() + .attr('class', 'fabric') -// highlight-start -/\* + // highlight-start + /* + * + * Annotations + * + */ -- -- Annotations -- \*/ - -/\* - -- Add the snaps - \*/ + /* + * Add the snaps + */ snippets.snapStud = new Snippet('snap-stud', points.snapLeft) snippets.snapSocket = new Snippet('snap-socket', points.snapRight).attr('opacity', 0.5) -/\* - -- Add the logo - \*/ + /* + * Add the logo + */ points.logo = new Point(0, 0) snippets.logo = new Snippet('logo', points.logo) // highlight-end -return part + return part } - -```` +``` ## Setting the cutlist, adding a title and scalebox @@ -537,6 +522,6 @@ function draftBib({ return part } -```` - +``` + diff --git a/sites/dev/docs/tutorials/pattern-design/part3/complete/readme.mdx b/sites/dev/docs/tutorials/pattern-design/part3/complete/readme.mdx index 958dc410454..2da692d1e84 100644 --- a/sites/dev/docs/tutorials/pattern-design/part3/complete/readme.mdx +++ b/sites/dev/docs/tutorials/pattern-design/part3/complete/readme.mdx @@ -7,18 +7,18 @@ Laser cutters is merely an example of a situation where your user wants not the complete detailed pattern with all annotations, but just the outlines. Essentially what we had at the end of part 2 of this tutorial. -Since then, we've added a bunch of embellishments, and perhaps the user does +Since then, we've added a bunch of embellishments, and perhaps the user does not want those. -Well, good news: there is a setting for that too. That setting is `complete`, +Well, good news: there is a setting for that too. That setting is `complete`, and more annotations will automatically take it into account. -For example, if you put a logo or title on the pattern, it will check the +For example, if you put a logo or title on the pattern, it will check the `complete` setting and if it is `false` it will do nothing. -When we say we're going to _complete_ our pattern, we mean we're going to add +When we say we're going to *complete* our pattern, we mean we're going to add things like a title and a scalebox and so on. -So while in most scenarios you don't have to worry about `complete`, you +So while in most scenarios you don't have to worry about `complete`, you should keep it in mind when you are adding text or paths to the design that should not be shown on a non-complete pattern. @@ -46,15 +46,15 @@ function draftBib({ part, }) { -/\* -_ Construct the neck opening -_/ -const target = (measurements.head _ options.neckRatio) / 4 -let tweak = 1 -let delta -do { -points.right = new Point((tweak _ measurements.head) / 10, 0) -points.bottom = new Point(0, (tweak \* measurements.head) / 12) + /* + * Construct the neck opening + */ + const target = (measurements.head * options.neckRatio) / 4 + let tweak = 1 + let delta + do { + points.right = new Point((tweak * measurements.head) / 10, 0) + points.bottom = new Point(0, (tweak * measurements.head) / 12) points.rightCp1 = points.right.shift(90, points.bottom.dy(points.right) / 2) points.bottomCp2 = points.bottom.shift(0, points.bottom.dx(points.right) / 2) @@ -66,229 +66,229 @@ points.bottom = new Point(0, (tweak \* measurements.head) / 12) delta = paths.neck.length() - target if (delta > 0) tweak = tweak * 0.99 else tweak = tweak * 1.02 + } while (Math.abs(delta) > 1) -} while (Math.abs(delta) > 1) + points.rightCp2 = points.rightCp1.flipY() + points.bottomCp1 = points.bottomCp2.flipX() -points.rightCp2 = points.rightCp1.flipY() -points.bottomCp1 = points.bottomCp2.flipX() + points.left = points.right.flipX() + points.leftCp1 = points.rightCp2.flipX() + points.leftCp2 = points.rightCp1.flipX() -points.left = points.right.flipX() -points.leftCp1 = points.rightCp2.flipX() -points.leftCp2 = points.rightCp1.flipX() + points.top = points.bottom.flipY() + points.topCp1 = points.bottomCp2.flipY() + points.topCp2 = points.bottomCp1.flipY() -points.top = points.bottom.flipY() -points.topCp1 = points.bottomCp2.flipY() -points.topCp2 = points.bottomCp1.flipY() + /* + * Construct the outline + */ + let width = measurements.head * options.widthRatio + let length = measurements.head * options.lengthRatio -/\* -_ Construct the outline -_/ -let width = measurements.head _ options.widthRatio -let length = measurements.head _ options.lengthRatio + points.topLeft = new Point(width / -2, points.top.y - (width / 2 - points.right.x)) + points.topRight = points.topLeft.shift(0, width) + points.bottomLeft = points.topLeft.shift(-90, length) + points.bottomRight = points.topRight.shift(-90, length) -points.topLeft = new Point(width / -2, points.top.y - (width / 2 - points.right.x)) -points.topRight = points.topLeft.shift(0, width) -points.bottomLeft = points.topLeft.shift(-90, length) -points.bottomRight = points.topRight.shift(-90, length) + points.edgeLeft = new Point(points.topLeft.x, points.left.y) + points.edgeRight = new Point(points.topRight.x, points.right.y) + points.edgeTop = new Point(0, points.topLeft.y) -points.edgeLeft = new Point(points.topLeft.x, points.left.y) -points.edgeRight = new Point(points.topRight.x, points.right.y) -points.edgeTop = new Point(0, points.topLeft.y) + points.edgeLeftCp = points.edgeLeft.shiftFractionTowards(points.topLeft, 0.5) + points.edgeRightCp = points.edgeLeftCp.flipX() + points.edgeTopLeftCp = points.edgeTop.shiftFractionTowards(points.topLeft, 0.5) + points.edgeTopRightCp = points.edgeTopLeftCp.flipX() -points.edgeLeftCp = points.edgeLeft.shiftFractionTowards(points.topLeft, 0.5) -points.edgeRightCp = points.edgeLeftCp.flipX() -points.edgeTopLeftCp = points.edgeTop.shiftFractionTowards(points.topLeft, 0.5) -points.edgeTopRightCp = points.edgeTopLeftCp.flipX() + /* + * Round the end of the straps + */ + let strap = points.edgeTop.dy(points.top) -/\* -_ Round the end of the straps -_/ -let strap = points.edgeTop.dy(points.top) + points.tipRight = points.edgeTop.translate(strap / 2, strap / 2) + points.tipRightTop = new Point(points.tipRight.x, points.edgeTop.y) + points.tipRightBottom = new Point(points.tipRight.x, points.top.y) -points.tipRight = points.edgeTop.translate(strap / 2, strap / 2) -points.tipRightTop = new Point(points.tipRight.x, points.edgeTop.y) -points.tipRightBottom = new Point(points.tipRight.x, points.top.y) + /* + * Macros will return the auto-generated IDs + */ + const ids1 = { + tipRightTop: macro('round', { + id: 'tipRightTop', + from: points.edgeTop, + to: points.tipRight, + via: points.tipRightTop, + }), + tipRightBottom: macro('round', { + id: 'tipRightBottom', + from: points.tipRight, + to: points.top, + via: points.tipRightBottom, + }), + } -/\* -_ Macros will return the auto-generated IDs -_/ -const ids1 = { -tipRightTop: macro('round', { -id: 'tipRightTop', -from: points.edgeTop, -to: points.tipRight, -via: points.tipRightTop, -}), -tipRightBottom: macro('round', { -id: 'tipRightBottom', -from: points.tipRight, -to: points.top, -via: points.tipRightBottom, -}), + /* + * Create points from them with easy names + */ + for (const side in ids1) { + for (const id of ['start', 'cp1', 'cp2', 'end']) { + points[`${side}${utils.capitalize(id)}`] = points[ids1[side].points[id]].copy() + } + } + + /* + * Rotate straps so they don't overlap + */ + let rotateThese = [ + 'edgeTopLeftCp', + 'edgeTop', + 'tipRight', + 'tipRightTop', + 'tipRightTopStart', + 'tipRightTopCp1', + 'tipRightTopCp2', + 'tipRightTopEnd', + 'tipRightBottomStart', + 'tipRightBottomCp1', + 'tipRightBottomCp2', + 'tipRightBottomEnd', + 'tipRightBottom', + 'top', + 'topCp2', + ] + + while (points.tipRightBottomStart.x > -1) { + for (let p of rotateThese) points[p] = points[p].rotate(1, points.edgeLeft) + } + + /* + * Add points to anchor snaps on + */ + points.snapLeft = points.top.shiftFractionTowards(points.edgeTop, 0.5) + + /* + * Mirror points to the other side + */ + points.edgeTopRightCp = points.edgeTopLeftCp.flipX() + points.topCp1 = points.topCp2.flipX() + points.tipLeftTopStart = points.tipRightTopStart.flipX() + points.tipLeftTopCp1 = points.tipRightTopCp1.flipX() + points.tipLeftTopCp2 = points.tipRightTopCp2.flipX() + points.tipLeftTopEnd = points.tipRightTopEnd.flipX() + points.tipLeftBottomStart = points.tipRightBottomStart.flipX() + points.tipLeftBottomCp1 = points.tipRightBottomCp1.flipX() + points.tipLeftBottomCp2 = points.tipRightBottomCp2.flipX() + points.tipLeftBottomEnd = points.tipRightBottomEnd.flipX() + points.snapRight = points.snapLeft.flipX() + + /* + * Round the bottom of the bib + * Radius is fixed, but you could use an option for it) + * + * Macros will return the auto-generated IDs + */ + const ids2 = { + bottomLeft: macro('round', { + id: 'bottomLeft', + from: points.topLeft, + to: points.bottomRight, + via: points.bottomLeft, + radius: points.bottomRight.x / 4, + }), + bottomRight: macro('round', { + id: 'bottomRight', + from: points.bottomLeft, + to: points.topRight, + via: points.bottomRight, + radius: points.bottomRight.x / 4, + }), + } + /* + * Create points from them with easy names + */ + for (const side in ids2) { + for (const id of ['start', 'cp1', 'cp2', 'end']) { + points[`${side}${utils.capitalize(id)}`] = points[ids2[side].points[id]].copy() + } + } + + /* + * Construct the path + */ + paths.seam = new Path() + .move(points.edgeLeft) + .line(points.bottomLeftStart) + .curve(points.bottomLeftCp1, points.bottomLeftCp2, points.bottomLeftEnd) + .line(points.bottomRightStart) + .curve(points.bottomRightCp1, points.bottomRightCp2, points.bottomRightEnd) + .line(points.edgeRight) + .curve(points.edgeRightCp, points.edgeTopRightCp, points.tipLeftTopStart) + .curve(points.tipLeftTopCp1, points.tipLeftTopCp2, points.tipLeftTopEnd) + .curve(points.tipLeftBottomCp1, points.tipLeftBottomCp2, points.tipLeftBottomEnd) + .curve(points.topCp1, points.rightCp2, points.right) + .curve(points.rightCp1, points.bottomCp2, points.bottom) + .curve(points.bottomCp1, points.leftCp2, points.left) + .curve(points.leftCp1, points.topCp2, points.tipRightBottomEnd) + .curve(points.tipRightBottomCp2, points.tipRightBottomCp1, points.tipRightBottomStart) + .curve(points.tipRightTopCp2, points.tipRightTopCp1, points.tipRightTopStart) + .curve(points.edgeTopLeftCp, points.edgeLeftCp, points.edgeLeft) + .close() + .attr('class', 'fabric') + + /* + * + * Annotations + * + */ + + /* + * Cut list + */ + store.cutlist.addCut({ cut: 1, from: 'fabric' }) + + /* + * Add the snaps + */ + snippets.snapStud = new Snippet('snap-stud', points.snapLeft) + snippets.snapSocket = new Snippet('snap-socket', points.snapRight).attr('opacity', 0.5) + + // highlight-start + /* + * Add the bias tape + */ + if (complete) + paths.bias = paths.seam + .offset(-5) + .addClass('note dashed') + .addText('tutorial:finishWithBiasTape', 'center fill-note') + // highlight-end + + /* + * Add the title + */ + points.title = points.bottom.shift(-90, 45) + macro('title', { + at: points.title, + nr: 1, + title: 'bib', + align: 'center', + scale: 0.8, + }) + + /* + * Add the scalebox + */ + points.scalebox = points.title.shift(-90, 65) + macro('scalebox', { at: points.scalebox }) + + /* + * Add the logo + */ + points.logo = new Point(0, 0) + snippets.logo = new Snippet('logo', points.logo) + + return part } - -/\* -_ Create points from them with easy names -_/ -for (const side in ids1) { -for (const id of ['start', 'cp1', 'cp2', 'end']) { -points[`${side}${utils.capitalize(id)}`] = points[ids1[side].points[id]].copy() -} -} - -/\* -_ Rotate straps so they don't overlap -_/ -let rotateThese = [ -'edgeTopLeftCp', -'edgeTop', -'tipRight', -'tipRightTop', -'tipRightTopStart', -'tipRightTopCp1', -'tipRightTopCp2', -'tipRightTopEnd', -'tipRightBottomStart', -'tipRightBottomCp1', -'tipRightBottomCp2', -'tipRightBottomEnd', -'tipRightBottom', -'top', -'topCp2', -] - -while (points.tipRightBottomStart.x > -1) { -for (let p of rotateThese) points[p] = points[p].rotate(1, points.edgeLeft) -} - -/\* -_ Add points to anchor snaps on -_/ -points.snapLeft = points.top.shiftFractionTowards(points.edgeTop, 0.5) - -/\* -_ Mirror points to the other side -_/ -points.edgeTopRightCp = points.edgeTopLeftCp.flipX() -points.topCp1 = points.topCp2.flipX() -points.tipLeftTopStart = points.tipRightTopStart.flipX() -points.tipLeftTopCp1 = points.tipRightTopCp1.flipX() -points.tipLeftTopCp2 = points.tipRightTopCp2.flipX() -points.tipLeftTopEnd = points.tipRightTopEnd.flipX() -points.tipLeftBottomStart = points.tipRightBottomStart.flipX() -points.tipLeftBottomCp1 = points.tipRightBottomCp1.flipX() -points.tipLeftBottomCp2 = points.tipRightBottomCp2.flipX() -points.tipLeftBottomEnd = points.tipRightBottomEnd.flipX() -points.snapRight = points.snapLeft.flipX() - -/\* -_ Round the bottom of the bib -_ Radius is fixed, but you could use an option for it) \* -_ Macros will return the auto-generated IDs -_/ -const ids2 = { -bottomLeft: macro('round', { -id: 'bottomLeft', -from: points.topLeft, -to: points.bottomRight, -via: points.bottomLeft, -radius: points.bottomRight.x / 4, -}), -bottomRight: macro('round', { -id: 'bottomRight', -from: points.bottomLeft, -to: points.topRight, -via: points.bottomRight, -radius: points.bottomRight.x / 4, -}), -} -/\* -_ Create points from them with easy names -_/ -for (const side in ids2) { -for (const id of ['start', 'cp1', 'cp2', 'end']) { -points[`${side}${utils.capitalize(id)}`] = points[ids2[side].points[id]].copy() -} -} - -/\* -_ Construct the path -_/ -paths.seam = new Path() -.move(points.edgeLeft) -.line(points.bottomLeftStart) -.curve(points.bottomLeftCp1, points.bottomLeftCp2, points.bottomLeftEnd) -.line(points.bottomRightStart) -.curve(points.bottomRightCp1, points.bottomRightCp2, points.bottomRightEnd) -.line(points.edgeRight) -.curve(points.edgeRightCp, points.edgeTopRightCp, points.tipLeftTopStart) -.curve(points.tipLeftTopCp1, points.tipLeftTopCp2, points.tipLeftTopEnd) -.curve(points.tipLeftBottomCp1, points.tipLeftBottomCp2, points.tipLeftBottomEnd) -.curve(points.topCp1, points.rightCp2, points.right) -.curve(points.rightCp1, points.bottomCp2, points.bottom) -.curve(points.bottomCp1, points.leftCp2, points.left) -.curve(points.leftCp1, points.topCp2, points.tipRightBottomEnd) -.curve(points.tipRightBottomCp2, points.tipRightBottomCp1, points.tipRightBottomStart) -.curve(points.tipRightTopCp2, points.tipRightTopCp1, points.tipRightTopStart) -.curve(points.edgeTopLeftCp, points.edgeLeftCp, points.edgeLeft) -.close() -.attr('class', 'fabric') - -/\* \* -_ Annotations -_ -\*/ - -/\* -_ Cut list -_/ -store.cutlist.addCut({ cut: 1, from: 'fabric' }) - -/\* -_ Add the snaps -_/ -snippets.snapStud = new Snippet('snap-stud', points.snapLeft) -snippets.snapSocket = new Snippet('snap-socket', points.snapRight).attr('opacity', 0.5) - -// highlight-start -/\* -_ Add the bias tape -_/ -if (complete) -paths.bias = paths.seam -.offset(-5) -.addClass('note dashed') -.addText('tutorial:finishWithBiasTape', 'center fill-note') -// highlight-end - -/\* -_ Add the title -_/ -points.title = points.bottom.shift(-90, 45) -macro('title', { -at: points.title, -nr: 1, -title: 'bib', -align: 'center', -scale: 0.8, -}) - -/\* -_ Add the scalebox -_/ -points.scalebox = points.title.shift(-90, 65) -macro('scalebox', { at: points.scalebox }) - -/\* -_ Add the logo -_/ -points.logo = new Point(0, 0) -snippets.logo = new Snippet('logo', points.logo) - -return part -} - -```` +``` @@ -556,6 +556,6 @@ function draftBib({ return part } -```` - +``` + diff --git a/sites/dev/docs/tutorials/pattern-design/part3/flag/readme.mdx b/sites/dev/docs/tutorials/pattern-design/part3/flag/readme.mdx index a550e10c252..e7265c2f32f 100644 --- a/sites/dev/docs/tutorials/pattern-design/part3/flag/readme.mdx +++ b/sites/dev/docs/tutorials/pattern-design/part3/flag/readme.mdx @@ -4,7 +4,7 @@ sidebar_position: 50 --- As a designer, there are times you want to bring something to the attention of -the user. I am not talking about generic information that can go in the +the user. I am not talking about generic information that can go in the documentation, but rather a message that is tailored specifically to this pattern, much like this pattern is specifically tailored to the user. @@ -47,15 +47,15 @@ function draftBib({ part, }) { -/\* -_ Construct the neck opening -_/ -const target = (measurements.head _ options.neckRatio) / 4 -let tweak = 1 -let delta -do { -points.right = new Point((tweak _ measurements.head) / 10, 0) -points.bottom = new Point(0, (tweak \* measurements.head) / 12) + /* + * Construct the neck opening + */ + const target = (measurements.head * options.neckRatio) / 4 + let tweak = 1 + let delta + do { + points.right = new Point((tweak * measurements.head) / 10, 0) + points.bottom = new Point(0, (tweak * measurements.head) / 12) points.rightCp1 = points.right.shift(90, points.bottom.dy(points.right) / 2) points.bottomCp2 = points.bottom.shift(0, points.bottom.dx(points.right) / 2) @@ -67,278 +67,277 @@ points.bottom = new Point(0, (tweak \* measurements.head) / 12) delta = paths.neck.length() - target if (delta > 0) tweak = tweak * 0.99 else tweak = tweak * 1.02 + } while (Math.abs(delta) > 1) -} while (Math.abs(delta) > 1) + points.rightCp2 = points.rightCp1.flipY() + points.bottomCp1 = points.bottomCp2.flipX() -points.rightCp2 = points.rightCp1.flipY() -points.bottomCp1 = points.bottomCp2.flipX() + points.left = points.right.flipX() + points.leftCp1 = points.rightCp2.flipX() + points.leftCp2 = points.rightCp1.flipX() -points.left = points.right.flipX() -points.leftCp1 = points.rightCp2.flipX() -points.leftCp2 = points.rightCp1.flipX() + points.top = points.bottom.flipY() + points.topCp1 = points.bottomCp2.flipY() + points.topCp2 = points.bottomCp1.flipY() -points.top = points.bottom.flipY() -points.topCp1 = points.bottomCp2.flipY() -points.topCp2 = points.bottomCp1.flipY() + /* + * Construct the outline + */ + let width = measurements.head * options.widthRatio + let length = measurements.head * options.lengthRatio -/\* -_ Construct the outline -_/ -let width = measurements.head _ options.widthRatio -let length = measurements.head _ options.lengthRatio + points.topLeft = new Point(width / -2, points.top.y - (width / 2 - points.right.x)) + points.topRight = points.topLeft.shift(0, width) + points.bottomLeft = points.topLeft.shift(-90, length) + points.bottomRight = points.topRight.shift(-90, length) -points.topLeft = new Point(width / -2, points.top.y - (width / 2 - points.right.x)) -points.topRight = points.topLeft.shift(0, width) -points.bottomLeft = points.topLeft.shift(-90, length) -points.bottomRight = points.topRight.shift(-90, length) + points.edgeLeft = new Point(points.topLeft.x, points.left.y) + points.edgeRight = new Point(points.topRight.x, points.right.y) + points.edgeTop = new Point(0, points.topLeft.y) -points.edgeLeft = new Point(points.topLeft.x, points.left.y) -points.edgeRight = new Point(points.topRight.x, points.right.y) -points.edgeTop = new Point(0, points.topLeft.y) + points.edgeLeftCp = points.edgeLeft.shiftFractionTowards(points.topLeft, 0.5) + points.edgeRightCp = points.edgeLeftCp.flipX() + points.edgeTopLeftCp = points.edgeTop.shiftFractionTowards(points.topLeft, 0.5) + points.edgeTopRightCp = points.edgeTopLeftCp.flipX() -points.edgeLeftCp = points.edgeLeft.shiftFractionTowards(points.topLeft, 0.5) -points.edgeRightCp = points.edgeLeftCp.flipX() -points.edgeTopLeftCp = points.edgeTop.shiftFractionTowards(points.topLeft, 0.5) -points.edgeTopRightCp = points.edgeTopLeftCp.flipX() + /* + * Round the end of the straps + */ + let strap = points.edgeTop.dy(points.top) -/\* -_ Round the end of the straps -_/ -let strap = points.edgeTop.dy(points.top) + points.tipRight = points.edgeTop.translate(strap / 2, strap / 2) + points.tipRightTop = new Point(points.tipRight.x, points.edgeTop.y) + points.tipRightBottom = new Point(points.tipRight.x, points.top.y) -points.tipRight = points.edgeTop.translate(strap / 2, strap / 2) -points.tipRightTop = new Point(points.tipRight.x, points.edgeTop.y) -points.tipRightBottom = new Point(points.tipRight.x, points.top.y) + /* + * Macros will return the auto-generated IDs + */ + const ids1 = { + tipRightTop: macro('round', { + id: 'tipRightTop', + from: points.edgeTop, + to: points.tipRight, + via: points.tipRightTop, + }), + tipRightBottom: macro('round', { + id: 'tipRightBottom', + from: points.tipRight, + to: points.top, + via: points.tipRightBottom, + }), + } -/\* -_ Macros will return the auto-generated IDs -_/ -const ids1 = { -tipRightTop: macro('round', { -id: 'tipRightTop', -from: points.edgeTop, -to: points.tipRight, -via: points.tipRightTop, -}), -tipRightBottom: macro('round', { -id: 'tipRightBottom', -from: points.tipRight, -to: points.top, -via: points.tipRightBottom, -}), + /* + * Create points from them with easy names + */ + for (const side in ids1) { + for (const id of ['start', 'cp1', 'cp2', 'end']) { + points[`${side}${utils.capitalize(id)}`] = points[ids1[side].points[id]].copy() + } + } + + /* + * Rotate straps so they don't overlap + */ + let rotateThese = [ + 'edgeTopLeftCp', + 'edgeTop', + 'tipRight', + 'tipRightTop', + 'tipRightTopStart', + 'tipRightTopCp1', + 'tipRightTopCp2', + 'tipRightTopEnd', + 'tipRightBottomStart', + 'tipRightBottomCp1', + 'tipRightBottomCp2', + 'tipRightBottomEnd', + 'tipRightBottom', + 'top', + 'topCp2', + ] + + while (points.tipRightBottomStart.x > -1) { + for (let p of rotateThese) points[p] = points[p].rotate(1, points.edgeLeft) + } + + /* + * Add points to anchor snaps on + */ + points.snapLeft = points.top.shiftFractionTowards(points.edgeTop, 0.5) + + /* + * Mirror points to the other side + */ + points.edgeTopRightCp = points.edgeTopLeftCp.flipX() + points.topCp1 = points.topCp2.flipX() + points.tipLeftTopStart = points.tipRightTopStart.flipX() + points.tipLeftTopCp1 = points.tipRightTopCp1.flipX() + points.tipLeftTopCp2 = points.tipRightTopCp2.flipX() + points.tipLeftTopEnd = points.tipRightTopEnd.flipX() + points.tipLeftBottomStart = points.tipRightBottomStart.flipX() + points.tipLeftBottomCp1 = points.tipRightBottomCp1.flipX() + points.tipLeftBottomCp2 = points.tipRightBottomCp2.flipX() + points.tipLeftBottomEnd = points.tipRightBottomEnd.flipX() + points.snapRight = points.snapLeft.flipX() + + /* + * Round the bottom of the bib + * Radius is fixed, but you could use an option for it) + * + * Macros will return the auto-generated IDs + */ + const ids2 = { + bottomLeft: macro('round', { + id: 'bottomLeft', + from: points.topLeft, + to: points.bottomRight, + via: points.bottomLeft, + radius: points.bottomRight.x / 4, + }), + bottomRight: macro('round', { + id: 'bottomRight', + from: points.bottomLeft, + to: points.topRight, + via: points.bottomRight, + radius: points.bottomRight.x / 4, + }), + } + /* + * Create points from them with easy names + */ + for (const side in ids2) { + for (const id of ['start', 'cp1', 'cp2', 'end']) { + points[`${side}${utils.capitalize(id)}`] = points[ids2[side].points[id]].copy() + } + } + + /* + * Construct the path + */ + paths.seam = new Path() + .move(points.edgeLeft) + .line(points.bottomLeftStart) + .curve(points.bottomLeftCp1, points.bottomLeftCp2, points.bottomLeftEnd) + .line(points.bottomRightStart) + .curve(points.bottomRightCp1, points.bottomRightCp2, points.bottomRightEnd) + .line(points.edgeRight) + .curve(points.edgeRightCp, points.edgeTopRightCp, points.tipLeftTopStart) + .curve(points.tipLeftTopCp1, points.tipLeftTopCp2, points.tipLeftTopEnd) + .curve(points.tipLeftBottomCp1, points.tipLeftBottomCp2, points.tipLeftBottomEnd) + .curve(points.topCp1, points.rightCp2, points.right) + .curve(points.rightCp1, points.bottomCp2, points.bottom) + .curve(points.bottomCp1, points.leftCp2, points.left) + .curve(points.leftCp1, points.topCp2, points.tipRightBottomEnd) + .curve(points.tipRightBottomCp2, points.tipRightBottomCp1, points.tipRightBottomStart) + .curve(points.tipRightTopCp2, points.tipRightTopCp1, points.tipRightTopStart) + .curve(points.edgeTopLeftCp, points.edgeLeftCp, points.edgeLeft) + .close() + .attr('class', 'fabric') + + /* + * + * Annotations + * + */ + + // highlight-start + /* + * Let the user know about the bias tape and fabric requirements + */ + store.flag.note({ + msg: 'tutorial:biasTapeLength', + replace: { + l: units(paths.seam.length()), + }, + }) + // highlight-end + + /* + * Cut list + */ + store.cutlist.addCut({ cut: 1, from: 'fabric' }) + + /* + * Add the snaps + */ + snippets.snapStud = new Snippet('snap-stud', points.snapLeft) + snippets.snapSocket = new Snippet('snap-socket', points.snapRight).attr('opacity', 0.5) + + /* + * Add the bias tape + */ + if (complete) + paths.bias = paths.seam + .offset(-5) + .addClass('note dashed') + .addText('finishWithBiasTape', 'center fill-note') + + /* + * Add the title + */ + points.title = points.bottom.shift(-90, 45) + macro('title', { + at: points.title, + nr: 1, + title: 'bib', + align: 'center', + scale: 0.8, + }) + + /* + * Add the scalebox + */ + points.scalebox = points.title.shift(-90, 65) + macro('scalebox', { at: points.scalebox }) + + /* + * Add the logo + */ + points.logo = new Point(0, 0) + snippets.logo = new Snippet('logo', points.logo) + + /* + * Add dimensions + */ + macro('hd', { + id: 'wFull', + from: points.bottomLeftStart, + to: points.bottomRightEnd, + y: points.bottomLeft.y + 15, + }) + macro('vd', { + id: 'hBottomToOpeningBottom', + from: points.bottomRightStart, + to: points.bottom, + x: points.bottomRight.x + 15, + }) + macro('vd', { + id: 'hBottomToOpeningCenter', + from: points.bottomRightStart, + to: points.right, + x: points.bottomRight.x + 30, + }) + macro('vd', { + id: 'hTotal', + from: points.bottomRightStart, + to: points.tipLeftTopStart, + x: points.bottomRight.x + 45, + }) + macro('hd', { + id: 'wOpening', + from: points.left, + to: points.right, + y: points.left.y + 25, + }) + macro('ld', { + id: 'wStrap', + from: points.tipLeftBottomEnd, + to: points.tipLeftTopStart, + d: -15, + }) + + return part } - -/\* -_ Create points from them with easy names -_/ -for (const side in ids1) { -for (const id of ['start', 'cp1', 'cp2', 'end']) { -points[`${side}${utils.capitalize(id)}`] = points[ids1[side].points[id]].copy() -} -} - -/\* -_ Rotate straps so they don't overlap -_/ -let rotateThese = [ -'edgeTopLeftCp', -'edgeTop', -'tipRight', -'tipRightTop', -'tipRightTopStart', -'tipRightTopCp1', -'tipRightTopCp2', -'tipRightTopEnd', -'tipRightBottomStart', -'tipRightBottomCp1', -'tipRightBottomCp2', -'tipRightBottomEnd', -'tipRightBottom', -'top', -'topCp2', -] - -while (points.tipRightBottomStart.x > -1) { -for (let p of rotateThese) points[p] = points[p].rotate(1, points.edgeLeft) -} - -/\* -_ Add points to anchor snaps on -_/ -points.snapLeft = points.top.shiftFractionTowards(points.edgeTop, 0.5) - -/\* -_ Mirror points to the other side -_/ -points.edgeTopRightCp = points.edgeTopLeftCp.flipX() -points.topCp1 = points.topCp2.flipX() -points.tipLeftTopStart = points.tipRightTopStart.flipX() -points.tipLeftTopCp1 = points.tipRightTopCp1.flipX() -points.tipLeftTopCp2 = points.tipRightTopCp2.flipX() -points.tipLeftTopEnd = points.tipRightTopEnd.flipX() -points.tipLeftBottomStart = points.tipRightBottomStart.flipX() -points.tipLeftBottomCp1 = points.tipRightBottomCp1.flipX() -points.tipLeftBottomCp2 = points.tipRightBottomCp2.flipX() -points.tipLeftBottomEnd = points.tipRightBottomEnd.flipX() -points.snapRight = points.snapLeft.flipX() - -/\* -_ Round the bottom of the bib -_ Radius is fixed, but you could use an option for it) \* -_ Macros will return the auto-generated IDs -_/ -const ids2 = { -bottomLeft: macro('round', { -id: 'bottomLeft', -from: points.topLeft, -to: points.bottomRight, -via: points.bottomLeft, -radius: points.bottomRight.x / 4, -}), -bottomRight: macro('round', { -id: 'bottomRight', -from: points.bottomLeft, -to: points.topRight, -via: points.bottomRight, -radius: points.bottomRight.x / 4, -}), -} -/\* -_ Create points from them with easy names -_/ -for (const side in ids2) { -for (const id of ['start', 'cp1', 'cp2', 'end']) { -points[`${side}${utils.capitalize(id)}`] = points[ids2[side].points[id]].copy() -} -} - -/\* -_ Construct the path -_/ -paths.seam = new Path() -.move(points.edgeLeft) -.line(points.bottomLeftStart) -.curve(points.bottomLeftCp1, points.bottomLeftCp2, points.bottomLeftEnd) -.line(points.bottomRightStart) -.curve(points.bottomRightCp1, points.bottomRightCp2, points.bottomRightEnd) -.line(points.edgeRight) -.curve(points.edgeRightCp, points.edgeTopRightCp, points.tipLeftTopStart) -.curve(points.tipLeftTopCp1, points.tipLeftTopCp2, points.tipLeftTopEnd) -.curve(points.tipLeftBottomCp1, points.tipLeftBottomCp2, points.tipLeftBottomEnd) -.curve(points.topCp1, points.rightCp2, points.right) -.curve(points.rightCp1, points.bottomCp2, points.bottom) -.curve(points.bottomCp1, points.leftCp2, points.left) -.curve(points.leftCp1, points.topCp2, points.tipRightBottomEnd) -.curve(points.tipRightBottomCp2, points.tipRightBottomCp1, points.tipRightBottomStart) -.curve(points.tipRightTopCp2, points.tipRightTopCp1, points.tipRightTopStart) -.curve(points.edgeTopLeftCp, points.edgeLeftCp, points.edgeLeft) -.close() -.attr('class', 'fabric') - -/\* \* -_ Annotations -_ -\*/ - -// highlight-start -/\* -_ Let the user know about the bias tape and fabric requirements -_/ -store.flag.note({ -msg: 'tutorial:biasTapeLength', -replace: { -l: units(paths.seam.length()), -}, -}) -// highlight-end - -/\* -_ Cut list -_/ -store.cutlist.addCut({ cut: 1, from: 'fabric' }) - -/\* -_ Add the snaps -_/ -snippets.snapStud = new Snippet('snap-stud', points.snapLeft) -snippets.snapSocket = new Snippet('snap-socket', points.snapRight).attr('opacity', 0.5) - -/\* -_ Add the bias tape -_/ -if (complete) -paths.bias = paths.seam -.offset(-5) -.addClass('note dashed') -.addText('finishWithBiasTape', 'center fill-note') - -/\* -_ Add the title -_/ -points.title = points.bottom.shift(-90, 45) -macro('title', { -at: points.title, -nr: 1, -title: 'bib', -align: 'center', -scale: 0.8, -}) - -/\* -_ Add the scalebox -_/ -points.scalebox = points.title.shift(-90, 65) -macro('scalebox', { at: points.scalebox }) - -/\* -_ Add the logo -_/ -points.logo = new Point(0, 0) -snippets.logo = new Snippet('logo', points.logo) - -/\* -_ Add dimensions -_/ -macro('hd', { -id: 'wFull', -from: points.bottomLeftStart, -to: points.bottomRightEnd, -y: points.bottomLeft.y + 15, -}) -macro('vd', { -id: 'hBottomToOpeningBottom', -from: points.bottomRightStart, -to: points.bottom, -x: points.bottomRight.x + 15, -}) -macro('vd', { -id: 'hBottomToOpeningCenter', -from: points.bottomRightStart, -to: points.right, -x: points.bottomRight.x + 30, -}) -macro('vd', { -id: 'hTotal', -from: points.bottomRightStart, -to: points.tipLeftTopStart, -x: points.bottomRight.x + 45, -}) -macro('hd', { -id: 'wOpening', -from: points.left, -to: points.right, -y: points.left.y + 25, -}) -macro('ld', { -id: 'wStrap', -from: points.tipLeftBottomEnd, -to: points.tipLeftTopStart, -d: -15, -}) - -return part -} - ``` -``` diff --git a/sites/dev/docs/tutorials/pattern-design/part3/paperless/readme.mdx b/sites/dev/docs/tutorials/pattern-design/part3/paperless/readme.mdx index 973cd68a797..2ebbda71b93 100644 --- a/sites/dev/docs/tutorials/pattern-design/part3/paperless/readme.mdx +++ b/sites/dev/docs/tutorials/pattern-design/part3/paperless/readme.mdx @@ -14,14 +14,14 @@ So let's make the extra effort to make our bib design support paperless. ## The paperless setting Users can request paperless patterns by setting [the `paperless` -setting](/reference/settings/paperless) to a _truthy_ value. +setting](/reference/settings/paperless) to a *truthy* value. With paperless enabled, FreeSewing will automatically render a grid for each pattern part with metric or imperial markings, depending on the units requested by the user. Such a grid is already a good starting point. In addition, we'll be using -different macros to add _dimensions_ to the pattern. +different macros to add *dimensions* to the pattern. While the grid gets added automatically, the dimensions we have to add ourselves. Thankfully, there's macros that can help us with that, specifically: @@ -58,15 +58,15 @@ function draftBib({ part, }) { -/\* -_ Construct the neck opening -_/ -const target = (measurements.head _ options.neckRatio) / 4 -let tweak = 1 -let delta -do { -points.right = new Point((tweak _ measurements.head) / 10, 0) -points.bottom = new Point(0, (tweak \* measurements.head) / 12) + /* + * Construct the neck opening + */ + const target = (measurements.head * options.neckRatio) / 4 + let tweak = 1 + let delta + do { + points.right = new Point((tweak * measurements.head) / 10, 0) + points.bottom = new Point(0, (tweak * measurements.head) / 12) points.rightCp1 = points.right.shift(90, points.bottom.dy(points.right) / 2) points.bottomCp2 = points.bottom.shift(0, points.bottom.dx(points.right) / 2) @@ -78,268 +78,267 @@ points.bottom = new Point(0, (tweak \* measurements.head) / 12) delta = paths.neck.length() - target if (delta > 0) tweak = tweak * 0.99 else tweak = tweak * 1.02 + } while (Math.abs(delta) > 1) -} while (Math.abs(delta) > 1) + points.rightCp2 = points.rightCp1.flipY() + points.bottomCp1 = points.bottomCp2.flipX() -points.rightCp2 = points.rightCp1.flipY() -points.bottomCp1 = points.bottomCp2.flipX() + points.left = points.right.flipX() + points.leftCp1 = points.rightCp2.flipX() + points.leftCp2 = points.rightCp1.flipX() -points.left = points.right.flipX() -points.leftCp1 = points.rightCp2.flipX() -points.leftCp2 = points.rightCp1.flipX() + points.top = points.bottom.flipY() + points.topCp1 = points.bottomCp2.flipY() + points.topCp2 = points.bottomCp1.flipY() -points.top = points.bottom.flipY() -points.topCp1 = points.bottomCp2.flipY() -points.topCp2 = points.bottomCp1.flipY() + /* + * Construct the outline + */ + let width = measurements.head * options.widthRatio + let length = measurements.head * options.lengthRatio -/\* -_ Construct the outline -_/ -let width = measurements.head _ options.widthRatio -let length = measurements.head _ options.lengthRatio + points.topLeft = new Point(width / -2, points.top.y - (width / 2 - points.right.x)) + points.topRight = points.topLeft.shift(0, width) + points.bottomLeft = points.topLeft.shift(-90, length) + points.bottomRight = points.topRight.shift(-90, length) -points.topLeft = new Point(width / -2, points.top.y - (width / 2 - points.right.x)) -points.topRight = points.topLeft.shift(0, width) -points.bottomLeft = points.topLeft.shift(-90, length) -points.bottomRight = points.topRight.shift(-90, length) + points.edgeLeft = new Point(points.topLeft.x, points.left.y) + points.edgeRight = new Point(points.topRight.x, points.right.y) + points.edgeTop = new Point(0, points.topLeft.y) -points.edgeLeft = new Point(points.topLeft.x, points.left.y) -points.edgeRight = new Point(points.topRight.x, points.right.y) -points.edgeTop = new Point(0, points.topLeft.y) + points.edgeLeftCp = points.edgeLeft.shiftFractionTowards(points.topLeft, 0.5) + points.edgeRightCp = points.edgeLeftCp.flipX() + points.edgeTopLeftCp = points.edgeTop.shiftFractionTowards(points.topLeft, 0.5) + points.edgeTopRightCp = points.edgeTopLeftCp.flipX() -points.edgeLeftCp = points.edgeLeft.shiftFractionTowards(points.topLeft, 0.5) -points.edgeRightCp = points.edgeLeftCp.flipX() -points.edgeTopLeftCp = points.edgeTop.shiftFractionTowards(points.topLeft, 0.5) -points.edgeTopRightCp = points.edgeTopLeftCp.flipX() + /* + * Round the end of the straps + */ + let strap = points.edgeTop.dy(points.top) -/\* -_ Round the end of the straps -_/ -let strap = points.edgeTop.dy(points.top) + points.tipRight = points.edgeTop.translate(strap / 2, strap / 2) + points.tipRightTop = new Point(points.tipRight.x, points.edgeTop.y) + points.tipRightBottom = new Point(points.tipRight.x, points.top.y) -points.tipRight = points.edgeTop.translate(strap / 2, strap / 2) -points.tipRightTop = new Point(points.tipRight.x, points.edgeTop.y) -points.tipRightBottom = new Point(points.tipRight.x, points.top.y) + /* + * Macros will return the auto-generated IDs + */ + const ids1 = { + tipRightTop: macro('round', { + id: 'tipRightTop', + from: points.edgeTop, + to: points.tipRight, + via: points.tipRightTop, + }), + tipRightBottom: macro('round', { + id: 'tipRightBottom', + from: points.tipRight, + to: points.top, + via: points.tipRightBottom, + }), + } -/\* -_ Macros will return the auto-generated IDs -_/ -const ids1 = { -tipRightTop: macro('round', { -id: 'tipRightTop', -from: points.edgeTop, -to: points.tipRight, -via: points.tipRightTop, -}), -tipRightBottom: macro('round', { -id: 'tipRightBottom', -from: points.tipRight, -to: points.top, -via: points.tipRightBottom, -}), + /* + * Create points from them with easy names + */ + for (const side in ids1) { + for (const id of ['start', 'cp1', 'cp2', 'end']) { + points[`${side}${utils.capitalize(id)}`] = points[ids1[side].points[id]].copy() + } + } + + /* + * Rotate straps so they don't overlap + */ + let rotateThese = [ + 'edgeTopLeftCp', + 'edgeTop', + 'tipRight', + 'tipRightTop', + 'tipRightTopStart', + 'tipRightTopCp1', + 'tipRightTopCp2', + 'tipRightTopEnd', + 'tipRightBottomStart', + 'tipRightBottomCp1', + 'tipRightBottomCp2', + 'tipRightBottomEnd', + 'tipRightBottom', + 'top', + 'topCp2', + ] + + while (points.tipRightBottomStart.x > -1) { + for (let p of rotateThese) points[p] = points[p].rotate(1, points.edgeLeft) + } + + /* + * Add points to anchor snaps on + */ + points.snapLeft = points.top.shiftFractionTowards(points.edgeTop, 0.5) + + /* + * Mirror points to the other side + */ + points.edgeTopRightCp = points.edgeTopLeftCp.flipX() + points.topCp1 = points.topCp2.flipX() + points.tipLeftTopStart = points.tipRightTopStart.flipX() + points.tipLeftTopCp1 = points.tipRightTopCp1.flipX() + points.tipLeftTopCp2 = points.tipRightTopCp2.flipX() + points.tipLeftTopEnd = points.tipRightTopEnd.flipX() + points.tipLeftBottomStart = points.tipRightBottomStart.flipX() + points.tipLeftBottomCp1 = points.tipRightBottomCp1.flipX() + points.tipLeftBottomCp2 = points.tipRightBottomCp2.flipX() + points.tipLeftBottomEnd = points.tipRightBottomEnd.flipX() + points.snapRight = points.snapLeft.flipX() + + /* + * Round the bottom of the bib + * Radius is fixed, but you could use an option for it) + * + * Macros will return the auto-generated IDs + */ + const ids2 = { + bottomLeft: macro('round', { + id: 'bottomLeft', + from: points.topLeft, + to: points.bottomRight, + via: points.bottomLeft, + radius: points.bottomRight.x / 4, + }), + bottomRight: macro('round', { + id: 'bottomRight', + from: points.bottomLeft, + to: points.topRight, + via: points.bottomRight, + radius: points.bottomRight.x / 4, + }), + } + /* + * Create points from them with easy names + */ + for (const side in ids2) { + for (const id of ['start', 'cp1', 'cp2', 'end']) { + points[`${side}${utils.capitalize(id)}`] = points[ids2[side].points[id]].copy() + } + } + + /* + * Construct the path + */ + paths.seam = new Path() + .move(points.edgeLeft) + .line(points.bottomLeftStart) + .curve(points.bottomLeftCp1, points.bottomLeftCp2, points.bottomLeftEnd) + .line(points.bottomRightStart) + .curve(points.bottomRightCp1, points.bottomRightCp2, points.bottomRightEnd) + .line(points.edgeRight) + .curve(points.edgeRightCp, points.edgeTopRightCp, points.tipLeftTopStart) + .curve(points.tipLeftTopCp1, points.tipLeftTopCp2, points.tipLeftTopEnd) + .curve(points.tipLeftBottomCp1, points.tipLeftBottomCp2, points.tipLeftBottomEnd) + .curve(points.topCp1, points.rightCp2, points.right) + .curve(points.rightCp1, points.bottomCp2, points.bottom) + .curve(points.bottomCp1, points.leftCp2, points.left) + .curve(points.leftCp1, points.topCp2, points.tipRightBottomEnd) + .curve(points.tipRightBottomCp2, points.tipRightBottomCp1, points.tipRightBottomStart) + .curve(points.tipRightTopCp2, points.tipRightTopCp1, points.tipRightTopStart) + .curve(points.edgeTopLeftCp, points.edgeLeftCp, points.edgeLeft) + .close() + .attr('class', 'fabric') + + /* + * + * Annotations + * + */ + + /* + * Cut list + */ + store.cutlist.addCut({ cut: 1, from: 'fabric' }) + + /* + * Add the snaps + */ + snippets.snapStud = new Snippet('snap-stud', points.snapLeft) + snippets.snapSocket = new Snippet('snap-socket', points.snapRight).attr('opacity', 0.5) + + /* + * Add the bias tape + */ + if (complete) + paths.bias = paths.seam + .offset(-5) + .addClass('note dashed') + .addText('fronscratch:finishWithBiasTape', 'center fill-note') + + /* + * Add the title + */ + points.title = points.bottom.shift(-90, 45) + macro('title', { + at: points.title, + nr: 1, + title: 'bib', + align: 'center', + scale: 0.8, + }) + + /* + * Add the scalebox + */ + points.scalebox = points.title.shift(-90, 65) + macro('scalebox', { at: points.scalebox }) + + /* + * Add the logo + */ + points.logo = new Point(0, 0) + snippets.logo = new Snippet('logo', points.logo) + + // highlight-start + /* + * Add dimensions + */ + macro('hd', { + id: 'wFull', + from: points.bottomLeftStart, + to: points.bottomRightEnd, + y: points.bottomLeft.y + 15, + }) + macro('vd', { + id: 'hBottomToOpeningBottom', + from: points.bottomRightStart, + to: points.bottom, + x: points.bottomRight.x + 15, + }) + macro('vd', { + id: 'hBottomToOpeningCenter', + from: points.bottomRightStart, + to: points.right, + x: points.bottomRight.x + 30, + }) + macro('vd', { + id: 'hTotal', + from: points.bottomRightStart, + to: points.tipLeftTopStart, + x: points.bottomRight.x + 45, + }) + macro('hd', { + id: 'wOpening', + from: points.left, + to: points.right, + y: points.left.y + 25, + }) + macro('ld', { + id: 'wStrap', + from: points.tipLeftBottomEnd, + to: points.tipLeftTopStart, + d: -15, + }) + // highlight-end + + return part } - -/\* -_ Create points from them with easy names -_/ -for (const side in ids1) { -for (const id of ['start', 'cp1', 'cp2', 'end']) { -points[`${side}${utils.capitalize(id)}`] = points[ids1[side].points[id]].copy() -} -} - -/\* -_ Rotate straps so they don't overlap -_/ -let rotateThese = [ -'edgeTopLeftCp', -'edgeTop', -'tipRight', -'tipRightTop', -'tipRightTopStart', -'tipRightTopCp1', -'tipRightTopCp2', -'tipRightTopEnd', -'tipRightBottomStart', -'tipRightBottomCp1', -'tipRightBottomCp2', -'tipRightBottomEnd', -'tipRightBottom', -'top', -'topCp2', -] - -while (points.tipRightBottomStart.x > -1) { -for (let p of rotateThese) points[p] = points[p].rotate(1, points.edgeLeft) -} - -/\* -_ Add points to anchor snaps on -_/ -points.snapLeft = points.top.shiftFractionTowards(points.edgeTop, 0.5) - -/\* -_ Mirror points to the other side -_/ -points.edgeTopRightCp = points.edgeTopLeftCp.flipX() -points.topCp1 = points.topCp2.flipX() -points.tipLeftTopStart = points.tipRightTopStart.flipX() -points.tipLeftTopCp1 = points.tipRightTopCp1.flipX() -points.tipLeftTopCp2 = points.tipRightTopCp2.flipX() -points.tipLeftTopEnd = points.tipRightTopEnd.flipX() -points.tipLeftBottomStart = points.tipRightBottomStart.flipX() -points.tipLeftBottomCp1 = points.tipRightBottomCp1.flipX() -points.tipLeftBottomCp2 = points.tipRightBottomCp2.flipX() -points.tipLeftBottomEnd = points.tipRightBottomEnd.flipX() -points.snapRight = points.snapLeft.flipX() - -/\* -_ Round the bottom of the bib -_ Radius is fixed, but you could use an option for it) \* -_ Macros will return the auto-generated IDs -_/ -const ids2 = { -bottomLeft: macro('round', { -id: 'bottomLeft', -from: points.topLeft, -to: points.bottomRight, -via: points.bottomLeft, -radius: points.bottomRight.x / 4, -}), -bottomRight: macro('round', { -id: 'bottomRight', -from: points.bottomLeft, -to: points.topRight, -via: points.bottomRight, -radius: points.bottomRight.x / 4, -}), -} -/\* -_ Create points from them with easy names -_/ -for (const side in ids2) { -for (const id of ['start', 'cp1', 'cp2', 'end']) { -points[`${side}${utils.capitalize(id)}`] = points[ids2[side].points[id]].copy() -} -} - -/\* -_ Construct the path -_/ -paths.seam = new Path() -.move(points.edgeLeft) -.line(points.bottomLeftStart) -.curve(points.bottomLeftCp1, points.bottomLeftCp2, points.bottomLeftEnd) -.line(points.bottomRightStart) -.curve(points.bottomRightCp1, points.bottomRightCp2, points.bottomRightEnd) -.line(points.edgeRight) -.curve(points.edgeRightCp, points.edgeTopRightCp, points.tipLeftTopStart) -.curve(points.tipLeftTopCp1, points.tipLeftTopCp2, points.tipLeftTopEnd) -.curve(points.tipLeftBottomCp1, points.tipLeftBottomCp2, points.tipLeftBottomEnd) -.curve(points.topCp1, points.rightCp2, points.right) -.curve(points.rightCp1, points.bottomCp2, points.bottom) -.curve(points.bottomCp1, points.leftCp2, points.left) -.curve(points.leftCp1, points.topCp2, points.tipRightBottomEnd) -.curve(points.tipRightBottomCp2, points.tipRightBottomCp1, points.tipRightBottomStart) -.curve(points.tipRightTopCp2, points.tipRightTopCp1, points.tipRightTopStart) -.curve(points.edgeTopLeftCp, points.edgeLeftCp, points.edgeLeft) -.close() -.attr('class', 'fabric') - -/\* \* -_ Annotations -_ -\*/ - -/\* -_ Cut list -_/ -store.cutlist.addCut({ cut: 1, from: 'fabric' }) - -/\* -_ Add the snaps -_/ -snippets.snapStud = new Snippet('snap-stud', points.snapLeft) -snippets.snapSocket = new Snippet('snap-socket', points.snapRight).attr('opacity', 0.5) - -/\* -_ Add the bias tape -_/ -if (complete) -paths.bias = paths.seam -.offset(-5) -.addClass('note dashed') -.addText('fronscratch:finishWithBiasTape', 'center fill-note') - -/\* -_ Add the title -_/ -points.title = points.bottom.shift(-90, 45) -macro('title', { -at: points.title, -nr: 1, -title: 'bib', -align: 'center', -scale: 0.8, -}) - -/\* -_ Add the scalebox -_/ -points.scalebox = points.title.shift(-90, 65) -macro('scalebox', { at: points.scalebox }) - -/\* -_ Add the logo -_/ -points.logo = new Point(0, 0) -snippets.logo = new Snippet('logo', points.logo) - -// highlight-start -/\* -_ Add dimensions -_/ -macro('hd', { -id: 'wFull', -from: points.bottomLeftStart, -to: points.bottomRightEnd, -y: points.bottomLeft.y + 15, -}) -macro('vd', { -id: 'hBottomToOpeningBottom', -from: points.bottomRightStart, -to: points.bottom, -x: points.bottomRight.x + 15, -}) -macro('vd', { -id: 'hBottomToOpeningCenter', -from: points.bottomRightStart, -to: points.right, -x: points.bottomRight.x + 30, -}) -macro('vd', { -id: 'hTotal', -from: points.bottomRightStart, -to: points.tipLeftTopStart, -x: points.bottomRight.x + 45, -}) -macro('hd', { -id: 'wOpening', -from: points.left, -to: points.right, -y: points.left.y + 25, -}) -macro('ld', { -id: 'wStrap', -from: points.tipLeftBottomEnd, -to: points.tipLeftTopStart, -d: -15, -}) -// highlight-end - -return part -} - ``` -``` diff --git a/sites/dev/docs/tutorials/pattern-design/part3/sa/readme.mdx b/sites/dev/docs/tutorials/pattern-design/part3/sa/readme.mdx index 0ee0b438311..9dca120f1de 100644 --- a/sites/dev/docs/tutorials/pattern-design/part3/sa/readme.mdx +++ b/sites/dev/docs/tutorials/pattern-design/part3/sa/readme.mdx @@ -24,30 +24,29 @@ function draftBib({ part, }) { -points.topLeft = new Point(0,0) -points.bottomRight = new Point(100,40) -points.topRight = new Point(points.bottomRight.x, points.topLeft.y) -points.bottomLeft = new Point(points.topLeft.x, points.bottomRight.y) -points.cp1 = new Point(50, 20) -points.cp2 = new Point(70, 60) + points.topLeft = new Point(0,0) + points.bottomRight = new Point(100,40) + points.topRight = new Point(points.bottomRight.x, points.topLeft.y) + points.bottomLeft = new Point(points.topLeft.x, points.bottomRight.y) + points.cp1 = new Point(50, 20) + points.cp2 = new Point(70, 60) -paths.shape = new Path() -.move(points.topLeft) -.line(points.bottomLeft) -.curve(points.cp1, points.cp2, points.bottomRight) -.line(points.topRight) -.line(points.topLeft) -.close() -.addClass('fabric') + paths.shape = new Path() + .move(points.topLeft) + .line(points.bottomLeft) + .curve(points.cp1, points.cp2, points.bottomRight) + .line(points.topRight) + .line(points.topLeft) + .close() + .addClass('fabric') -// highlight-start -if (sa) paths.sa = paths.shape.offset(sa).addClass('fabric sa') -// highlight-end + // highlight-start + if (sa) paths.sa = paths.shape.offset(sa).addClass('fabric sa') + // highlight-end -return part + return part } - -```` +``` As you can see from the source, we can destructure an `sa` variable (short for @@ -64,7 +63,7 @@ seam allowance: if (sa) paths.sa = paths.shape .offset(sa) .addClass('fabric sa') -```` +``` To refer back to our three question: Whether the user wants seam allowance, and if so how much seam allowance is answered by the `sa` value passed to our draft From cb100346d8ecea234c4d4ed2b99024142ae4de02 Mon Sep 17 00:00:00 2001 From: Andrew James Date: Mon, 19 May 2025 08:20:36 +0000 Subject: [PATCH 20/46] remove duplicated css classes --- packages/react/components/Collection/index.mjs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/react/components/Collection/index.mjs b/packages/react/components/Collection/index.mjs index c4f3731196c..ae9be8d5329 100644 --- a/packages/react/components/Collection/index.mjs +++ b/packages/react/components/Collection/index.mjs @@ -289,12 +289,12 @@ const DesignCard = ({ name, lineDrawing = false, linkTo, Link, onClick }) => { const inner = (
@@ -302,14 +302,14 @@ const DesignCard = ({ name, lineDrawing = false, linkTo, Link, onClick }) => {
{lineDrawing ? ( -
- +
+
) : ( )}
From 51213b336697be726e569c71af2c2caca657b201 Mon Sep 17 00:00:00 2001 From: Benjamin Fan Date: Mon, 19 May 2025 17:20:45 -0700 Subject: [PATCH 21/46] fix(dev:docs): Dimension macro, boundary box, and typo fixes --- .../docs/reference/api/part/attr/readme.mdx | 8 ++++++-- .../reference/api/path/roughlength/readme.mdx | 6 +++++- .../reference/api/path/translate/readme.mdx | 8 ++++++-- .../docs/reference/api/path/ucurve/readme.mdx | 5 ++--- .../docs/reference/api/point/shift/readme.mdx | 4 +++- .../api/point/shiftfractiontowards/readme.mdx | 8 ++++++-- .../api/point/shiftoutwards/readme.mdx | 3 ++- .../api/point/shifttowards/readme.mdx | 8 +++++++- .../docs/reference/api/point/slope/readme.mdx | 6 +++++- .../reference/api/point/translate/readme.mdx | 10 ++++++++-- .../reference/api/snippet/scale/readme.mdx | 2 +- .../docs/reference/packages/config/readme.mdx | 8 ++++---- .../part2/creating-the-closure/readme.mdx | 20 ++++++++++--------- 13 files changed, 66 insertions(+), 30 deletions(-) diff --git a/sites/dev/docs/reference/api/part/attr/readme.mdx b/sites/dev/docs/reference/api/part/attr/readme.mdx index c1e1238aa39..8bfd20b33d1 100644 --- a/sites/dev/docs/reference/api/part/attr/readme.mdx +++ b/sites/dev/docs/reference/api/part/attr/readme.mdx @@ -12,7 +12,7 @@ instead, thereby overwriting the value of the attribute. ```js -Part Part.attr( +Part Part.attr( string name, mixed value, bool overwrite = false @@ -46,7 +46,11 @@ paths.line = new Path() .close() .addText('I have been flipped!', 'left') -part.attr('transform', 'scale(1,-1) translate(0,-40)') +paths.bbox = new Path() + .move(new Point(0,-40)) + .move(new Point(120,60)) + +part.attr('transform', 'scale(1,-1) translate(0,-40)') return part } diff --git a/sites/dev/docs/reference/api/path/roughlength/readme.mdx b/sites/dev/docs/reference/api/path/roughlength/readme.mdx index 54aba630353..5f01af9e894 100644 --- a/sites/dev/docs/reference/api/path/roughlength/readme.mdx +++ b/sites/dev/docs/reference/api/path/roughlength/readme.mdx @@ -12,7 +12,7 @@ Number path.roughLength() ## Example - + ```js ({ Point, points, Path, paths, macro, units, part }) => { @@ -27,12 +27,16 @@ Number path.roughLength() macro("pd", { path: paths.example, + id: 'macro1', d: -10, + force: true, text: `Path.roughLength() = ${units(paths.example.roughLength())}` }) macro("pd", { path: paths.example, + id: 'macro2', d: 10, + force: true, text: `Path.length() = ${units(paths.example.length())}` }) diff --git a/sites/dev/docs/reference/api/path/translate/readme.mdx b/sites/dev/docs/reference/api/path/translate/readme.mdx index cde37225fc5..121e11eb7fe 100644 --- a/sites/dev/docs/reference/api/path/translate/readme.mdx +++ b/sites/dev/docs/reference/api/path/translate/readme.mdx @@ -36,12 +36,16 @@ Path path.translate(float deltaX, float deltaY) macro("ld", { from: points.B, to: points.step1, - noStartMarker: true + noStartMarker: true, + id: 'macro1', + force: true, }) macro("ld", { from: points.step1, to: points.step2, - noStartMarker: true + noStartMarker: true, + id: 'macro2', + force: true, }) return part diff --git a/sites/dev/docs/reference/api/path/ucurve/readme.mdx b/sites/dev/docs/reference/api/path/ucurve/readme.mdx index 9c19f0f9cb8..796940c9e44 100644 --- a/sites/dev/docs/reference/api/path/ucurve/readme.mdx +++ b/sites/dev/docs/reference/api/path/ucurve/readme.mdx @@ -35,8 +35,7 @@ This method is chainable as it returns the `Path` object return part } - -```` +``` @@ -48,4 +47,4 @@ as the two following calls yield the same result: ```js path.curve(point1, point1, point2) path._curve(point1, point2) -```` +``` diff --git a/sites/dev/docs/reference/api/point/shift/readme.mdx b/sites/dev/docs/reference/api/point/shift/readme.mdx index 85667c260bf..f77d82bbea6 100644 --- a/sites/dev/docs/reference/api/point/shift/readme.mdx +++ b/sites/dev/docs/reference/api/point/shift/readme.mdx @@ -27,7 +27,9 @@ Point point.shift(float angle, float distance) macro("ld", { from: points.B, to: points.A, - d: -10 + d: -10, + id: 'macro1', + force: true, }) return part diff --git a/sites/dev/docs/reference/api/point/shiftfractiontowards/readme.mdx b/sites/dev/docs/reference/api/point/shiftfractiontowards/readme.mdx index 7cc6211edab..7fa89deecbc 100644 --- a/sites/dev/docs/reference/api/point/shiftfractiontowards/readme.mdx +++ b/sites/dev/docs/reference/api/point/shiftfractiontowards/readme.mdx @@ -38,13 +38,17 @@ Point point.shiftFractionTowards(Point target, float fraction) macro("ld", { from: points.C, to: points.A, - d: -10 + d: -10, + id: 'macro1', + force: true, }) macro("ld", { from: points.B, to: points.A, - d: 20 + d: 20, + id: 'macro2', + force: true, }) return part diff --git a/sites/dev/docs/reference/api/point/shiftoutwards/readme.mdx b/sites/dev/docs/reference/api/point/shiftoutwards/readme.mdx index 227791adfd0..43a51785c29 100644 --- a/sites/dev/docs/reference/api/point/shiftoutwards/readme.mdx +++ b/sites/dev/docs/reference/api/point/shiftoutwards/readme.mdx @@ -31,7 +31,8 @@ Point point.shiftOutwards(Point target, float distance) macro("ld", { from: points.C, to: points.B, - d: -10 + d: -10, + force: true, }) return part diff --git a/sites/dev/docs/reference/api/point/shifttowards/readme.mdx b/sites/dev/docs/reference/api/point/shifttowards/readme.mdx index 56bd8d4223f..e2b581373b4 100644 --- a/sites/dev/docs/reference/api/point/shifttowards/readme.mdx +++ b/sites/dev/docs/reference/api/point/shifttowards/readme.mdx @@ -31,9 +31,15 @@ Point point.shiftTowards(Point target, float distance) macro("ld", { from: points.C, to: points.A, - d: -10 + d: -10, + force: true, }) + // Boundary box + paths.bbox = new Path() + .move(new Point(10,10)) + .move(new Point(125,70)) + return part } ``` diff --git a/sites/dev/docs/reference/api/point/slope/readme.mdx b/sites/dev/docs/reference/api/point/slope/readme.mdx index 7905410f573..b9f8726d303 100644 --- a/sites/dev/docs/reference/api/point/slope/readme.mdx +++ b/sites/dev/docs/reference/api/point/slope/readme.mdx @@ -2,7 +2,7 @@ title: Point.slope() --- -The `Point.slope()` method returns the slope (dy/dx) of a line between two Points. +The `Point.slope()` method returns the slope (dy/dx) of a line between two Points. ## Signature @@ -29,11 +29,15 @@ point.slope(otherPoint) from: points.A, to: points.B, y: points.B.y, + id: 'macro1', + force: true, }) macro('vd', { to: points.B, from: points.A, x: 0, + id: 'macro2', + force: true, }) paths.line = new Path() diff --git a/sites/dev/docs/reference/api/point/translate/readme.mdx b/sites/dev/docs/reference/api/point/translate/readme.mdx index b0eee9cd3d7..417f3089c59 100644 --- a/sites/dev/docs/reference/api/point/translate/readme.mdx +++ b/sites/dev/docs/reference/api/point/translate/readme.mdx @@ -24,7 +24,7 @@ Positive values for `deltaY` will move the point downwards. ```js -({ Point, points, Snippet, snippets, macro, part }) => { +({ Point, points, Path, paths, Snippet, snippets, macro, part }) => { points.A = new Point(10, 10).setText("Point A", "text-sm") points.B = points.A.translate(120, 60) @@ -42,9 +42,15 @@ Positive values for `deltaY` will move the point downwards. from: points.A, to: points.B, text: "translate(120,60)", - noStartMarker: true + noStartMarker: true, + force: true, }) + // Bounding box + paths.bbox = new Path() + .move(new Point(10, 10)) + .move(new Point(130, 80)) + return part } ``` diff --git a/sites/dev/docs/reference/api/snippet/scale/readme.mdx b/sites/dev/docs/reference/api/snippet/scale/readme.mdx index 6eaea35d026..249b276d11b 100644 --- a/sites/dev/docs/reference/api/snippet/scale/readme.mdx +++ b/sites/dev/docs/reference/api/snippet/scale/readme.mdx @@ -17,7 +17,7 @@ This method is chainable as it returns the `Snippet` object ## Example - + ```js ({ Point, Path, paths, Snippet, snippets, part }) => { diff --git a/sites/dev/docs/reference/packages/config/readme.mdx b/sites/dev/docs/reference/packages/config/readme.mdx index a128565498a..7df19bf666d 100644 --- a/sites/dev/docs/reference/packages/config/readme.mdx +++ b/sites/dev/docs/reference/packages/config/readme.mdx @@ -91,12 +91,12 @@ In other words, a measurement that captures an angle, rather than a distance. }} returns={{ type: 'boolean', desc: 'true of it is a degree measurement, false if not' }} /> -```js import {isDegreeMeasurement} from '@freesewing/config' +```js +import {isDegreeMeasurement} from '@freesewing/config' const result = isDegreeMeasurement('shoulderSlope') // result now holds: true - -```` +``` ### logoPath @@ -104,7 +104,7 @@ Holds a string that is the SVG pathstring for the FreeSewing logo, Skully. ```js import { logoPath } from '@freesewing/config' -```` +``` diff --git a/sites/dev/docs/tutorials/pattern-design/part2/creating-the-closure/readme.mdx b/sites/dev/docs/tutorials/pattern-design/part2/creating-the-closure/readme.mdx index 25219458725..4382837c7c9 100644 --- a/sites/dev/docs/tutorials/pattern-design/part2/creating-the-closure/readme.mdx +++ b/sites/dev/docs/tutorials/pattern-design/part2/creating-the-closure/readme.mdx @@ -17,7 +17,9 @@ tedious. There are macros to add titles to our pattern, or grainline indicators, a scalebox, and there's a macro to round corners. The `round` macro. -:::note You can find more information on the `round` macro in [the macros docs](/reference/macros/round/).::: +:::note +You can find more information on the `round` macro in [the macros docs](/reference/macros/round/). +::: We need a half circle here, but the `round` macro works on 90° angles, so we'll use it twice. As such, we'll add some points to guide the macro, and @@ -49,28 +51,28 @@ function draftBib({ let delta do { points.right = new Point( - tweak * measurements.head / 10, + tweak * measurements.head / 10, 0 ) points.bottom = new Point( - 0, + 0, tweak * measurements.head / 12 ) - + points.rightCp1 = points.right.shift( - 90, + 90, points.bottom.dy(points.right) / 2 ) points.bottomCp2 = points.bottom.shift( - 0, + 0, points.bottom.dx(points.right) / 2 ) - + paths.quarterNeck = new Path() .move(points.right) .curve( - points.rightCp1, - points.bottomCp2, + points.rightCp1, + points.bottomCp2, points.bottom ) .hide() From 630fa964172b49ef9079b14678255cc3ad5b4468 Mon Sep 17 00:00:00 2001 From: Benjamin Fan Date: Mon, 19 May 2025 17:25:17 -0700 Subject: [PATCH 22/46] fix(dev:docs): Improve SVG signatures --- .../dev/docs/reference/api/svg/defs/readme.mdx | 17 +++++++++++++++-- .../dev/docs/reference/api/svg/style/readme.mdx | 11 +++++++++-- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/sites/dev/docs/reference/api/svg/defs/readme.mdx b/sites/dev/docs/reference/api/svg/defs/readme.mdx index 87a33ed4bde..0a8baff1f60 100644 --- a/sites/dev/docs/reference/api/svg/defs/readme.mdx +++ b/sites/dev/docs/reference/api/svg/defs/readme.mdx @@ -9,8 +9,21 @@ SVG document. ## Signature -```svg +```js +Defs svg.defs = { + list = { + buttonhole: ` + + `, + }, +} +``` + +Result: +``` - /* svg.defs will be inserted */ + + + ``` diff --git a/sites/dev/docs/reference/api/svg/style/readme.mdx b/sites/dev/docs/reference/api/svg/style/readme.mdx index 02a0a6348ab..0bd9fcfc0cf 100644 --- a/sites/dev/docs/reference/api/svg/style/readme.mdx +++ b/sites/dev/docs/reference/api/svg/style/readme.mdx @@ -7,9 +7,16 @@ section of the SVG document. ## Signature -```svg +```js +String svg.style += 'circle {stroke:black;}' +``` + +Result: +``` ``` From e36593943292ba48b0c71acb255632358e100ace Mon Sep 17 00:00:00 2001 From: Benjamin Fan Date: Mon, 19 May 2025 17:26:32 -0700 Subject: [PATCH 23/46] fix(dev:docs): Improve Point.flipY() example code --- .../docs/reference/api/point/flipy/readme.mdx | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/sites/dev/docs/reference/api/point/flipy/readme.mdx b/sites/dev/docs/reference/api/point/flipy/readme.mdx index 391e3663879..4cf223ecaf8 100644 --- a/sites/dev/docs/reference/api/point/flipy/readme.mdx +++ b/sites/dev/docs/reference/api/point/flipy/readme.mdx @@ -66,6 +66,26 @@ Point point.flipY(Point mirror = false) .line(points.houseWallRight) .line(points.end) + paths.skylineBot = new Path() + .move(points._start) + .line(points._churchTowerWallLeft) + .line(points._churchTowerRoofLeft) + .line(points._churchTowerTop) + .line(points._churchTowerRoofRight) + .line(points._churchRoofRight) + .line(points._churchWallRight) + .line(points._houseWallLeft) + .line(points._houseRoofLeft) + .line(points._houseRoofTop) + .line(points._houseRoofRight) + .line(points._houseWallRight) + .line(points._end) + + paths.mirror = new Path() + .move(points.mirror) + .line(points.mirrorLineEnd) + .setClass("note dashed") + return part } ``` From fa5dc0b7b11d5ff8b496add3911e41086d9f9e5f Mon Sep 17 00:00:00 2001 From: joostdecock Date: Sat, 24 May 2025 08:35:30 +0200 Subject: [PATCH 24/46] [dev] fix: Remove prebuild scripts. See #378 --- sites/dev/package.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/sites/dev/package.json b/sites/dev/package.json index 2a6bf7c88cb..77dc1aed1e7 100644 --- a/sites/dev/package.json +++ b/sites/dev/package.json @@ -10,9 +10,6 @@ "deploy": "docusaurus deploy", "clear": "docusaurus clear", "serve": "docusaurus serve", - "prebuild": "./scripts/prebuild.sh", - "predev": "npm run prebuild", - "prestart": "npm run prebuild", "write-translations": "docusaurus write-translations", "write-heading-ids": "docusaurus write-heading-ids" }, From 96dd83fc10c0d2e78413b7dbc932800a3c432273 Mon Sep 17 00:00:00 2001 From: Benjamin Fan Date: Tue, 20 May 2025 10:26:58 -0700 Subject: [PATCH 25/46] fix(react): Fix Collection background image URL --- packages/react/components/Collection/index.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react/components/Collection/index.mjs b/packages/react/components/Collection/index.mjs index ae9be8d5329..5e6c1df1231 100644 --- a/packages/react/components/Collection/index.mjs +++ b/packages/react/components/Collection/index.mjs @@ -282,7 +282,7 @@ const DesignCard = ({ name, lineDrawing = false, linkTo, Link, onClick }) => { const exampleImageUrl = examples.href[name] ? examples.href[name] : noExample const bg = { aspectRatio: '1/1.4' } if (!lineDrawing) { - bg.backgroundImage = `url(${exampleImageUrl}` + bg.backgroundImage = `url(${exampleImageUrl})` bg.backgroundSize = 'cover' bg.backgroundPosition = 'center center' } From 9469a9493cc795e29c674a787e016cedaee2e3a0 Mon Sep 17 00:00:00 2001 From: Jonathan Haas Date: Wed, 21 May 2025 11:39:37 +0200 Subject: [PATCH 26/46] fix(react): Ignore pointer events on tooltip text of Xray point component --- packages/react/components/Xray/point.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react/components/Xray/point.mjs b/packages/react/components/Xray/point.mjs index b3876db4bfd..693f13f7bc1 100644 --- a/packages/react/components/Xray/point.mjs +++ b/packages/react/components/Xray/point.mjs @@ -60,7 +60,7 @@ export const PointXray = ({ : null } > - + {pointName} {round(point.x)},{round(point.y)} From e7c34473228b8f0da728771274d84571f00cf22f Mon Sep 17 00:00:00 2001 From: Benjamin Fan Date: Tue, 20 May 2025 08:14:33 -0700 Subject: [PATCH 27/46] fix(dev): Add pluginPathUtils to component --- sites/dev/src/theme/MDXComponents/example.mjs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sites/dev/src/theme/MDXComponents/example.mjs b/sites/dev/src/theme/MDXComponents/example.mjs index c7170a010cb..97a9f1ec0ee 100644 --- a/sites/dev/src/theme/MDXComponents/example.mjs +++ b/sites/dev/src/theme/MDXComponents/example.mjs @@ -3,6 +3,7 @@ import Tabs from '@theme/Tabs' import TabItem from '@theme/TabItem' import { pluginFlip } from '@freesewing/plugin-flip' import { pluginGore } from '@freesewing/plugin-gore' +import { pluginPathUtils } from '@freesewing/plugin-path-utils' import { pluginRingsector } from '@freesewing/plugin-ringsector' import { Design } from '@freesewing/core' import yaml from 'js-yaml' @@ -49,7 +50,7 @@ const buildPattern = (children, settings = { margin: 5 }, tutorial = false, pape lengthRatio: { pct: 75, min: 55, max: 85, menu: 'style' }, } : {}, - plugins: [pluginFlip, pluginGore, pluginRingsector], + plugins: [pluginFlip, pluginGore, pluginPathUtils, pluginRingsector], } const design = new Design({ parts: [part], From 7f4c04308c101d584cdc629ed240d046115f33b9 Mon Sep 17 00:00:00 2001 From: Benjamin Fan Date: Wed, 21 May 2025 11:43:36 -0700 Subject: [PATCH 28/46] fix(dev:docs): Improvements to path-utils plugin and macros --- .../dev/docs/reference/macros/hem/readme.mdx | 10 +++- .../dev/docs/reference/macros/join/readme.mdx | 56 +++++++++++-------- .../docs/reference/macros/offset/readme.mdx | 47 ++++++++++------ sites/dev/docs/reference/macros/sa/readme.mdx | 47 ++++++++++------ .../reference/plugins/path-utils/readme.mdx | 10 +--- 5 files changed, 106 insertions(+), 64 deletions(-) diff --git a/sites/dev/docs/reference/macros/hem/readme.mdx b/sites/dev/docs/reference/macros/hem/readme.mdx index ba2d52dc4d8..4f7468dd466 100644 --- a/sites/dev/docs/reference/macros/hem/readme.mdx +++ b/sites/dev/docs/reference/macros/hem/readme.mdx @@ -4,6 +4,14 @@ title: hem The `hem` macro drafts a hem allowance with fold lines. +:::note +##### Not a core-plugins macro + +The `hem` macro is not provided by the [core plugins](/reference/plugins/core), +so you need to load the [path-utils plugin](/reference/plugins/path-utils) +explicitly if you want to use it. +::: + ## Signature ```js @@ -68,7 +76,7 @@ Path macro('hem', { | `prefix` | `'hemMacro'` | `number` | The name prefix used for paths created by this macro. | | `cssClass` | `'fabric'` | `number` | The CSS class added to the fold lines and the hem outline. Should usually match the CSS class for the part outline | -## Detailed Description +## Notes This macro will create the following paths (assuming the default `'hemMacro'` prefix is used): diff --git a/sites/dev/docs/reference/macros/join/readme.mdx b/sites/dev/docs/reference/macros/join/readme.mdx index f9024f7866d..001c9f33b47 100644 --- a/sites/dev/docs/reference/macros/join/readme.mdx +++ b/sites/dev/docs/reference/macros/join/readme.mdx @@ -4,31 +4,19 @@ title: join The `join` macro joins multiple paths together. -Unlike the core `path.join(...)` function, the `join` macro can extend line ends to meet in a sharp corner and will automatically -trim useless path ends when adjacent paths in the array are intersecting. +Unlike the core [`Path.join()`](/reference/api/path/join) function, +the `join` macro can extend line ends to meet in a sharp corner and +will automatically trim useless path ends when adjacent paths in the +array are intersecting. -The join function accepts an array of `Path` objects -(either names in the `paths` array or direct references to `Path` objects). -This array can contain `null` values or hidden paths (created with `path.hide()`) to create gaps. - -:::warning - -Since hidden paths will create gaps in the resulting paths, make sure that all the paths you want to -include in the join are visible before calling the macro. - -You can hide them afterwards again, if needed. +:::note +##### Not a core-plugins macro +The `join` macro is not provided by the [core plugins](/reference/plugins/core), +so you need to load the [path-utils plugin](/reference/plugins/path-utils) +explicitly if you want to use it. ::: -By default, the `join` macro will join the paths in a circular fashion, joining the end -of the last path in the array to the start of the first path, creating a full outline. -If this is not desired, insert a `null` element between paths where you want the gap -(or at the end of the `paths` parameter). - -Note that a `null` value will create a basic gap in the output, -if you instead include a hidden path, this method will still create sharp corners as if the path were present, -but the actual path will be skipped in the output. - ## Signature ```js @@ -72,5 +60,29 @@ Path macro('join', { | Property | Default | Type | Description | | -------: | ---------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `paths` | | `array` | An array of pathnames, the names of Paths in the `paths` array to join (you can also reference `Path` objects directly, or insert `null` elements to create gaps) | -| `mode` | `'corner'` | `string` | Mode for joining paths. Either `'corner'` or `'cut'`. `'cut'` will join the paths directly without extending them (like `path.join(...)`). | +| `mode` | `'corner'` | `string` | Mode for joining paths. Either `'corner'` or `'cut'`. `'cut'` will join the paths directly without extending them (like `Path.join()`). | | `limit` | `null` | `number` | Allows limiting the length of corners in `'corner'` mode. Prevents overly long joins on very sharp angles. Ignored if `null` or `false`. | + +## Notes + +The `join` macro accepts an array of `Path` objects +(either names in the `paths` array or direct references to `Path` objects). +This array can contain `null` values or hidden paths (created with `Path.hide()`) to create gaps. + +:::warning + +Since hidden paths will create gaps in the resulting paths, make sure that all the paths you want to +include in the join are visible before calling the macro. + +You can hide them afterwards again, if needed. + +::: + +By default, the `join` macro will join the paths in a circular fashion, joining the end +of the last path in the array to the start of the first path, creating a full outline. +If this is not desired, insert a `null` element between paths where you want the gap +(or at the end of the `paths` parameter). + +Note that a `null` value will create a basic gap in the output. +If you instead include a hidden path, this method will still create sharp corners as if the path were present, +but the actual path will be skipped in the output. diff --git a/sites/dev/docs/reference/macros/offset/readme.mdx b/sites/dev/docs/reference/macros/offset/readme.mdx index 22e60f4fac5..1a9b51a3242 100644 --- a/sites/dev/docs/reference/macros/offset/readme.mdx +++ b/sites/dev/docs/reference/macros/offset/readme.mdx @@ -4,25 +4,17 @@ title: offset The `offset` macro will offset and join paths. -Unlike the core `path.join(...)` and `path.offset(...)` functions, the `offset` macro can extend line ends to meet in a sharp corner and will automatically +Unlike the core [`Path.join()`](/reference/api/path/join) and +[`Path.offset()`](/reference/api/path/offset) functions, the `offset` +macro can extend line ends to meet in a sharp corner and will automatically trim useless path ends when adjacent paths in the array are intersecting. -The offset macro accepts an array of `Path` objects with their offset, like `{p: 'somePath', offset: 30}` or `{p: ['path1', 'path2'], offset: sa * 3, hidden: true}`. -For the paths in the `p` attribute, you can reference either names in the `paths` array or insert direct references to `Path` objects. -The array can contain `null` values to create gaps (e.g., for cuts on the fold or for other sections that don't need seam allowance). - -By default, the `offset` macro will offset the paths in a circular fashion, joining the end -of the last path in the array to the start of the first path, creating a full outline. -If this is not desired, insert `null` elements where you want to create gaps. - -You can use `offset: 0` to include paths which don't need an additional offset. - -You can use `hidden: true` to omit path segments from the output, but still build corner joins as if they were there. -This can be used for cut-on-fold lines, where no seam allowance is needed. - :::note -To create a seam allowance, prefer the `sa` macro instead of the `offset` macro. It does pretty much the same, -but the `sa` macro defaults to offsetting paths by the user defined seam allowance. +##### Not a core-plugins macro + +The `offset` macro is not provided by the [core plugins](/reference/plugins/core), +so you need to load the [path-utils plugin](/reference/plugins/path-utils) +explicitly if you want to use it. ::: ## Signature @@ -79,6 +71,27 @@ Path macro('offset', { | Property | Default | Type | Description | | -------: | ---------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `paths` | | `array` | An array of paths with their offset and visibility. You can use path names in the `paths` array or reference `Path` objects directly, or insert `null` elements to create gaps. | -| `mode` | `'corner'` | `string` | Mode for joining paths. Either `'corner'` or `'cut'`. `'cut'` will join the paths directly (like `path.join(...)`) without extending the corners. | +| `mode` | `'corner'` | `string` | Mode for joining paths. Either `'corner'` or `'cut'`. `'cut'` will join the paths directly (like `Path.join()`) without extending the corners. | | `limit` | `null` | `number` | Allows limiting the length of extended path corners in `'corner'` mode. Prevents overly long joins on very sharp angles. Ignored if `null` or `false`. | | `class` | `'offset'` | `string` | CSS class that is automatically applied to the resulting path. | + +## Notes + +The `offset` macro accepts an array of `Path` objects with their offset, like `{p: 'somePath', offset: 30}` or `{p: ['path1', 'path2'], offset: sa * 3, hidden: true}`. +For the paths in the `p` attribute, you can reference either names in the `paths` array or insert direct references to `Path` objects. +The array can contain `null` values to create gaps (e.g., for cuts on the fold or for other sections that don't need seam allowance). + +By default, the `offset` macro will offset the paths in a circular fashion, joining the end +of the last path in the array to the start of the first path, creating a full outline. +If this is not desired, insert `null` elements where you want to create gaps. + +You can use `offset: 0` to include paths which don't need an additional offset. + +You can use `hidden: true` to omit path segments from the output, but still build corner joins as if they were there. +This can be used for cut-on-fold lines, where no seam allowance is needed. + +:::note +To create a seam allowance, prefer the [`sa`](/reference/macros/sa) macro +instead of the `offset` macro. It does pretty much the same, +but the `sa` macro defaults to offsetting paths by the user defined seam allowance. +::: diff --git a/sites/dev/docs/reference/macros/sa/readme.mdx b/sites/dev/docs/reference/macros/sa/readme.mdx index 5ba5b434a67..8870c3daf28 100644 --- a/sites/dev/docs/reference/macros/sa/readme.mdx +++ b/sites/dev/docs/reference/macros/sa/readme.mdx @@ -4,24 +4,19 @@ title: sa The `sa` macro will create seam allowance paths. -Unlike the core `path.join(...)` and `path.offset(...)` functions, the `sa` macro can extend line ends to meet in a sharp corner and will automatically -trim useless path ends when adjacent paths in the array are intersecting. +Unlike the core [`Path.join()`](/reference/api/path/join) and +[`Path.offset()`](/reference/api/path/offset) functions, the +`sa` macro can extend line ends to meet in a sharp corner and +will automatically trim useless path ends when adjacent paths +in the array are intersecting. -The sa macro accepts an array of `Path` objects -(either names in the `paths` array or direct references to `Path` objects). -This array can contain `null` values to create gaps (e.g. for cuts on the fold or for other sections that don't need seam allowance). +:::note +##### Not a core-plugins macro -By default, the `sa` macro will sa the paths in a circular fashion, joining the end -of the last path in the array to the start of the first path, creating a full outline. -If this is not desired, insert `null` elements where you want to create gaps. - -You can optionally override the offset and invisibility for individual paths. -To do so, insert an object literal like `{p: 'somePath', offset: 30}` or `{p: ['path1', 'path2'], offset: sa * 3, hidden: true}` into the `paths` array. - -You can use `offset: 0` to include paths which have already build-in the seam allowance (e.g. the result of the `hem` macro). - -You can use `hidden: true` to hide path segments from the output, but still build corner joins as if they were there. -This can be used for cut-on-fold lines, where no seam allowance is needed. +The `sa` macro is not provided by the [core plugins](/reference/plugins/core), +so you need to load the [path-utils plugin](/reference/plugins/path-utils) +explicitly if you want to use it. +::: ## Signature @@ -76,7 +71,25 @@ macro('sa', { | Property | Default | Type | Description | | -------: | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `paths` | | `array` | An array of paths. You can use path names in the `paths` array or reference `Path` objects directly, or insert `null` elements to create gaps. You can also override offset and visibility for individual paths in the same way as with the `offset` macro. | -| `mode` | `'corner'` | `string` | Mode for joining paths. Either `'corner'` or `'cut'`. `'cut'` will join the paths directly (like `path.join(...)`) without extending the corners. | +| `mode` | `'corner'` | `string` | Mode for joining paths. Either `'corner'` or `'cut'`. `'cut'` will join the paths directly (like `Path.join()`) without extending the corners. | | `limit` | `null` | `number` | Allows limiting the length of extended path corners in `'corner'` mode. Prevents overly long joins on very sharp angles. Ignored if `null` or `false`. | | `sa` | (seam allowance) | `number` | Allows you to override the seam allowance used for this macro. Defaults to the standard seam allowance (`sa` parameter in draft function). | | `class` | `'sa'` | `string` | CSS class that is automatically applied to the resulting path. | + +## Notes + +The `sa` macro accepts an array of `Path` objects +(either names in the `paths` array or direct references to `Path` objects). +This array can contain `null` values to create gaps (e.g. for cuts on the fold or for other sections that don't need seam allowance). + +By default, the `sa` macro will sa the paths in a circular fashion, joining the end +of the last path in the array to the start of the first path, creating a full outline. +If this is not desired, insert `null` elements where you want to create gaps. + +You can optionally override the offset and invisibility for individual paths. +To do so, insert an object literal like `{p: 'somePath', offset: 30}` or `{p: ['path1', 'path2'], offset: sa * 3, hidden: true}` into the `paths` array. + +You can use `offset: 0` to include paths which have already build-in the seam allowance (e.g. the result of the `hem` macro). + +You can use `hidden: true` to hide path segments from the output, but still build corner joins as if they were there. +This can be used for cut-on-fold lines, where no seam allowance is needed. diff --git a/sites/dev/docs/reference/plugins/path-utils/readme.mdx b/sites/dev/docs/reference/plugins/path-utils/readme.mdx index 5efdd903991..3c1459d6f2c 100644 --- a/sites/dev/docs/reference/plugins/path-utils/readme.mdx +++ b/sites/dev/docs/reference/plugins/path-utils/readme.mdx @@ -2,7 +2,9 @@ title: plugin-path-utils --- -Published as [@freesewing/plugin-path-utils][1], this plugin provides the [hem](/reference/macros/hem), [sa](/reference/macros/sa), [offset](/reference/macros/offset) and [sa](/reference/macros/join) macros, +Published as [@freesewing/plugin-path-utils][1], this plugin provides the +[hem](/reference/macros/hem), [join](/reference/macros/join), +[offset](/reference/macros/offset), and [sa](/reference/macros/sa) macros, whose main purpose is to make it easier to construct seam allowance paths. ## Installation @@ -25,10 +27,4 @@ import { pathUtilsPlugin } from '@freesewing/plugin-path-utils' import { pluginPathUtils } from '@freesewing/plugin-path-utils' ``` -## Notes - -This plugin is part of the [core-plugins bundle](/reference/plugins/core), -so there is no need to install or import it manually unless you wish to forego -loading of core plugins yet still want to load this plugin. - [1]: https://www.npmjs.com/package/@freesewing/plugin-path-utils From c60f73befd90537eaf37b14d5f34e2aae3f1dda0 Mon Sep 17 00:00:00 2001 From: Benjamin Fan Date: Wed, 21 May 2025 14:48:54 -0700 Subject: [PATCH 29/46] fix(react): Add URL formats to Bookmarked Set picker --- packages/react/components/Editor/components/Set.mjs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/react/components/Editor/components/Set.mjs b/packages/react/components/Editor/components/Set.mjs index e8c38e5fc83..8ab87cc0fc6 100644 --- a/packages/react/components/Editor/components/Set.mjs +++ b/packages/react/components/Editor/components/Set.mjs @@ -130,10 +130,15 @@ export const BookmarkedSetPicker = ({ const [status, body] = await backend.getBookmarks() const loadedSets = {} if (status === 200 && body.result === 'success') { + const setsRE = /\/set(\?id=|s\/)(\d+)$/ + const unique_ids = new Set() for (const bookmark of body.bookmarks.filter((bookmark) => bookmark.type === 'set')) { - let set + const match = bookmark.url.match(setsRE) + if (match) unique_ids.add(match[2]) + } + for (const id of unique_ids) { try { - const [status, body] = await backend.getSet(bookmark.url.slice(6)) + const [status, body] = await backend.getSet(id) if (status === 200 && body.result === 'success') { const [hasMeasies] = hasRequiredMeasurements(Design, body.set.measies) loadedSets[body.set.id] = { ...body.set, hasMeasies } From b3a45962efacc5ebf4f2a92fbc628dbabb7fcd0d Mon Sep 17 00:00:00 2001 From: Benjamin Fan Date: Wed, 21 May 2025 12:21:28 -0700 Subject: [PATCH 30/46] fix(dev:docs): Minor change to Point.shiftFractionTowards() --- .../docs/reference/api/point/shiftfractiontowards/readme.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sites/dev/docs/reference/api/point/shiftfractiontowards/readme.mdx b/sites/dev/docs/reference/api/point/shiftfractiontowards/readme.mdx index 7fa89deecbc..1432726179d 100644 --- a/sites/dev/docs/reference/api/point/shiftfractiontowards/readme.mdx +++ b/sites/dev/docs/reference/api/point/shiftfractiontowards/readme.mdx @@ -15,7 +15,7 @@ negative values to shift the point in the opposite direction. Point point.shiftFractionTowards(Point target, float fraction) ``` -## Point.shiftFractionTowards() example +## Example ```js From bfc2296cec8a9804496ab983849a8fc6d8090a0d Mon Sep 17 00:00:00 2001 From: Benjamin Fan Date: Wed, 21 May 2025 20:14:22 -0700 Subject: [PATCH 31/46] fix(react,utils): Change imperial step to 1/16 in. --- .../components/Editor/components/menus/Input.mjs | 16 +++++++++++----- packages/utils/src/index.mjs | 2 +- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/packages/react/components/Editor/components/menus/Input.mjs b/packages/react/components/Editor/components/menus/Input.mjs index 25fd0dba999..1be1f5c8d2f 100644 --- a/packages/react/components/Editor/components/menus/Input.mjs +++ b/packages/react/components/Editor/components/menus/Input.mjs @@ -205,12 +205,18 @@ export const MenuMmInput = (props) => { /* * Set a default step that matches the unit. * - * Note that we could try to use something like 1.5875 for imperial to move in steps of 1/16 inches, - * but we round the mm values to two digits in the options, which would accumulate rounding errors. - * - * Because of this, we use 10ths of inches instead of 16ths of inches. + * Imperial: + * mm, inch, decimal digits precision needed: + * 1.27 mm, 0.1 in, 2 digits + * 3.175 mm, 1/8 in, 3 digits + * 1.5875 mm, 1/16 in, 4 digits + * 0.79375 mm, 1/32 in, 5 digits + * We previously rounded mm values to 2 digits in the options and used + * a 1.27 mm (1/10 in) step because precision didn't support 1/16 in + * or 1/32 in steps. + * We now round mm values to 4 digits and use a 1.5875 mm (1/16 in.) step. */ - const defaultStep = imperial ? 1.27 : 1 // mm + const defaultStep = imperial ? 1.5875 : 1 // mm return ( Date: Thu, 22 May 2025 10:29:24 +0200 Subject: [PATCH 32/46] fix (react): make the Sample menu less strict about translations It can be helpful to be able to use the sample function on incomplete designs without proper translation, so don't crash if an option is missing its translation --- packages/react/components/Editor/components/menus/TestMenu.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react/components/Editor/components/menus/TestMenu.mjs b/packages/react/components/Editor/components/menus/TestMenu.mjs index fdba2078c52..d01d8891dae 100644 --- a/packages/react/components/Editor/components/menus/TestMenu.mjs +++ b/packages/react/components/Editor/components/menus/TestMenu.mjs @@ -88,7 +88,7 @@ const SampleOptionButton = ({ name, i18n, update }) => ( onClick={() => update.settings('sample', { type: 'option', option: name })} > - {i18n.en.o[name].t} + {i18n.en?.o[name]?.t ?? name} ) From 96ae664829342a678ac63872ad6b6b4f1a7d7a1b Mon Sep 17 00:00:00 2001 From: Jonathan Haas Date: Thu, 22 May 2025 11:58:38 +0200 Subject: [PATCH 33/46] feat(react): Change the expand icon to have the arrows point inwards if expand is disabled --- .../react/components/Editor/components/HeaderMenu.mjs | 9 ++++++--- packages/react/components/Icon/index.mjs | 7 +++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/packages/react/components/Editor/components/HeaderMenu.mjs b/packages/react/components/Editor/components/HeaderMenu.mjs index ee444d20193..9e2915f68ea 100644 --- a/packages/react/components/Editor/components/HeaderMenu.mjs +++ b/packages/react/components/Editor/components/HeaderMenu.mjs @@ -11,6 +11,7 @@ import { ViewIcon, viewLabels } from './views/index.mjs' import { Tooltip } from './Tooltip.mjs' import { AsideIcon, + CompactIcon, DetailIcon, ExpandIcon, ExportIcon, @@ -336,9 +337,11 @@ export const HeaderMenuDraftViewIcons = (props) => { } tooltip="Turns Expand on or off (see Core Settings)" > - + {[false, 0, '0'].includes(settings.expand) ? ( + + ) : ( + + )} ) : null} diff --git a/packages/react/components/Icon/index.mjs b/packages/react/components/Icon/index.mjs index 5ac9753c75e..42b8a2bff42 100644 --- a/packages/react/components/Icon/index.mjs +++ b/packages/react/components/Icon/index.mjs @@ -143,6 +143,13 @@ export const CodeIcon = (props) => ( ) +// Looks like arrows pointing inwards +export const CompactIcon = (props) => ( + + + +) + // FIXME export const CompareIcon = (props) => ( From 743314062dc61caf0e721bff7fbab1e21a7cd78a Mon Sep 17 00:00:00 2001 From: Benjamin Fan Date: Thu, 22 May 2025 08:17:34 -0700 Subject: [PATCH 34/46] fix(react): Handle no-settings scenario --- packages/react/components/Editor/components/views/TestView.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react/components/Editor/components/views/TestView.mjs b/packages/react/components/Editor/components/views/TestView.mjs index 4ba076b2104..0153ff6bd0a 100644 --- a/packages/react/components/Editor/components/views/TestView.mjs +++ b/packages/react/components/Editor/components/views/TestView.mjs @@ -43,7 +43,7 @@ export const TestView = ({ Design, state, update, config }) => { if (missingMeasurements(state)) return const { settings } = state - if (settings.sample) { + if (settings?.sample) { /* * When testing/sampling one design, and then switching the editor to a different design, * we run the risk that settings.sample holds invalid configuration. Like testing an unused From c66c9e0a93883f11e3d5c6060954267b1cf5fc46 Mon Sep 17 00:00:00 2001 From: Jonathan Haas Date: Thu, 22 May 2025 19:31:50 +0200 Subject: [PATCH 35/46] feat(react): Replace the flag number with a colored badge --- .../Editor/components/HeaderMenu.mjs | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/packages/react/components/Editor/components/HeaderMenu.mjs b/packages/react/components/Editor/components/HeaderMenu.mjs index 9e2915f68ea..0d5c15db305 100644 --- a/packages/react/components/Editor/components/HeaderMenu.mjs +++ b/packages/react/components/Editor/components/HeaderMenu.mjs @@ -242,7 +242,8 @@ export const HeaderMenuDraftViewUiPreferences = (props) => { } export const HeaderMenuDraftViewFlags = (props) => { - const count = Object.keys(flattenFlags(props.flags)).length + const flatFlags = flattenFlags(props.flags) + const count = Object.keys(flatFlags).length return ( { Flags - ({count}) + it.type === 'error') ? 'error' : 'secondary' + } + /> } @@ -264,6 +270,17 @@ export const HeaderMenuDraftViewFlags = (props) => { ) } +const NumberBadge = ({ value, color = 'secondary', className = '' }) => { + return ( +
+ {value} +
+ ) +} + export const HeaderMenuDraftViewIcons = (props) => { const { update, state } = props const { settings = {} } = state // Guard against undefined settings From 7a456d4004800a9eae97a76076b5556c4b99b2b6 Mon Sep 17 00:00:00 2001 From: Benjamin Fan Date: Sat, 23 Nov 2024 23:42:05 -0800 Subject: [PATCH 36/46] fix(hugo): Add Collar Ease option to allow neck opening size adjustments --- designs/hugo/src/back.mjs | 2 + designs/hugo/src/front.mjs | 2 + designs/hugo/src/options.mjs | 2 +- designs/hugo/src/sleeve.mjs | 40 +++++++++++++++++++ .../hugo/options/collarease/readme.mdx | 12 ++++++ 5 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 sites/orgdocs/docs/designs/hugo/options/collarease/readme.mdx diff --git a/designs/hugo/src/back.mjs b/designs/hugo/src/back.mjs index ed5053bc40c..8dec8b7ff22 100644 --- a/designs/hugo/src/back.mjs +++ b/designs/hugo/src/back.mjs @@ -34,6 +34,8 @@ function hugoBack({ const neckOpening = new Path() .move(points.cbNeck) .curve(points.cbNeck, points.neckCp2, points.neck) + const length = neckOpening.length() * 2 + store.set('front_neck_len', length) points.raglanTipBack = neckOpening.shiftFractionAlong(0.7) const neckOpeningParts = neckOpening.split(points.raglanTipBack) // Paths diff --git a/designs/hugo/src/front.mjs b/designs/hugo/src/front.mjs index a1e66b8828b..871b45019a9 100644 --- a/designs/hugo/src/front.mjs +++ b/designs/hugo/src/front.mjs @@ -61,6 +61,8 @@ function hugoFront({ const neckOpening = new Path() .move(points.cfNeck) .curve(points.cfNeckCp1, points.neckCp2, points.neck) + const length = neckOpening.length() * 2 + store.set('back_neck_len', length) points.raglanTipFront = neckOpening.shiftFractionAlong(0.8) const neckOpeningParts = neckOpening.split(points.raglanTipFront) diff --git a/designs/hugo/src/options.mjs b/designs/hugo/src/options.mjs index cdb7a7a17bd..4e5f0c411e5 100644 --- a/designs/hugo/src/options.mjs +++ b/designs/hugo/src/options.mjs @@ -1,4 +1,3 @@ -export const collarEase = 0.05 export const armholeDepthFactor = 0.5 export const shoulderEase = 0 export const shoulderSlopeReduction = 0 @@ -14,3 +13,4 @@ export const lengthBonus = { pct: 10, min: 0, max: 20, menu: 'style' } export const sleeveLengthBonus = { pct: 2, min: 0, max: 10, menu: 'style' } export const ribbingHeight = { pct: 10, min: 4, max: 20, menu: 'style' } export const pocketWidth = { pct: 50, min: 35, max: 65, menu: 'style' } +export const collarEase = { pct: 15, min: 0, max: 40, menu: 'fit' } diff --git a/designs/hugo/src/sleeve.mjs b/designs/hugo/src/sleeve.mjs index 4e33d322271..36500205515 100644 --- a/designs/hugo/src/sleeve.mjs +++ b/designs/hugo/src/sleeve.mjs @@ -17,6 +17,8 @@ function hugoSleeve({ options, measurements, macro, + log, + units, part, }) { // Top of raglan sleeve @@ -233,6 +235,44 @@ function hugoSleeve({ y: points.wristLeft.y + 15 + sa, }) + /* + * Check neck opening size and warn if necessary. + */ + const sleeve_neck_len = + new Path() + .move(points.raglanTipBack) + .curve(points.raglanTipBackCp2, points.raglanTopCp1, points.raglanTop) + .curve(points.raglanTopCp2, points.raglanTipFrontCp1, points.raglanTipFront) + .length() * 2 + + const neck_opening = store.get('front_neck_len') + store.get('back_neck_len') + sleeve_neck_len + const diff = measurements.head - neck_opening + const discrepancy = diff / measurements.head + const warning_limit = 0.04 + let label = ' bigger than ' + if (diff > 0) label = ' smaller than ' + + log.info( + ': ' + + units(neck_opening) + + ' neck opening is ' + + units(Math.abs(diff)) + + label + + ' than ' + + units(measurements.head) + + ' head circumference, with Collar Ease set to ' + + (options.collarEase * 100).toFixed(0) + + '%.' + ) + + if (discrepancy > warning_limit) { + log.warn( + 'Please check and adjust Collar Ease option setting ' + + 'as needed to ensure neck opening is large enough to accommodate ' + + 'head circumference.' + ) + } + return part } diff --git a/sites/orgdocs/docs/designs/hugo/options/collarease/readme.mdx b/sites/orgdocs/docs/designs/hugo/options/collarease/readme.mdx new file mode 100644 index 00000000000..a1470c15e6c --- /dev/null +++ b/sites/orgdocs/docs/designs/hugo/options/collarease/readme.mdx @@ -0,0 +1,12 @@ +--- +title: 'Collar ease' +--- + +![Collar ease](collarease.svg) + +Controls the amount of ease at your collar/neck and the size +of the neck opening.. + +Hugo uses the neck circumference measurement rather than head +circumference to produce the neck opening size when generating patterns. +Use this option to adjust the neck opening size if needed. From a675c655a554bb182596b2f955703459ff23a032 Mon Sep 17 00:00:00 2001 From: Benjamin Fan Date: Sat, 23 Nov 2024 23:51:19 -0800 Subject: [PATCH 37/46] fix(docs): Add Hugo Collar Ease svg --- .../hugo/options/collarease/collarease.svg | 153 ++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 sites/orgdocs/docs/designs/hugo/options/collarease/collarease.svg diff --git a/sites/orgdocs/docs/designs/hugo/options/collarease/collarease.svg b/sites/orgdocs/docs/designs/hugo/options/collarease/collarease.svg new file mode 100644 index 00000000000..f5e1a583775 --- /dev/null +++ b/sites/orgdocs/docs/designs/hugo/options/collarease/collarease.svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + From 52b8e16e3574ada1b3a84112110bc24408272636 Mon Sep 17 00:00:00 2001 From: Jonathan Haas Date: Fri, 23 May 2025 14:14:54 +0200 Subject: [PATCH 38/46] fix(hugo): Replace the log message about the head circumference with a flag warning, as that's more visible to the user --- designs/hugo/i18n/en.json | 4 +++- designs/hugo/src/sleeve.mjs | 12 +++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/designs/hugo/i18n/en.json b/designs/hugo/i18n/en.json index 6fa1376795d..c5f14cac049 100644 --- a/designs/hugo/i18n/en.json +++ b/designs/hugo/i18n/en.json @@ -23,7 +23,9 @@ "cutNeckBinding.t": "The neck binding is not shown", "cutNeckBinding.d": "The **Neck Binding** (10) is a rectangular piece of main fabric {{{ w }}} wide and {{{ l }}} long, with the grainline parallel to the length.", "cutWaistband.t": "The waistband is not shown", - "cutWaistband.d": "The **Waistband** (8) is a rectangular piece of ribbing fabric {{{ w }}} wide and {{{ l }}} long, with the grainline parallel to the width." + "cutWaistband.d": "The **Waistband** (8) is a rectangular piece of ribbing fabric {{{ w }}} wide and {{{ l }}} long, with the grainline parallel to the width.", + "neckCircumference.t": "The neck opening is too small", + "neckCircumference.d": "The neck opening of {{{ opening }}} is smaller than the head circumference of {{{ head }}}.\n\nPlease check and adjust Collar Ease option setting as needed to ensure the neck opening is large enough to accommodate head circumference." }, "o": { "ribbingHeight": { diff --git a/designs/hugo/src/sleeve.mjs b/designs/hugo/src/sleeve.mjs index 36500205515..440c89d61e4 100644 --- a/designs/hugo/src/sleeve.mjs +++ b/designs/hugo/src/sleeve.mjs @@ -266,11 +266,13 @@ function hugoSleeve({ ) if (discrepancy > warning_limit) { - log.warn( - 'Please check and adjust Collar Ease option setting ' + - 'as needed to ensure neck opening is large enough to accommodate ' + - 'head circumference.' - ) + store.flag.warn({ + msg: `hugo:neckCircumference`, + replace: { + opening: units(neck_opening), + head: units(measurements.head), + }, + }) } return part From 34ca199ee3c0bf1789e55c6b7045e86285284d1b Mon Sep 17 00:00:00 2001 From: Benjamin Fan Date: Thu, 22 May 2025 10:20:18 -0700 Subject: [PATCH 39/46] fix(dev/docs): Updates to flag store methods --- .../store-methods/flag.error/readme.mdx | 7 ++- .../store-methods/flag.fixme/readme.mdx | 7 ++- .../store-methods/flag.info/readme.mdx | 58 +++++++++++++------ .../store-methods/flag.note/readme.mdx | 7 ++- .../store-methods/flag.preset/readme.mdx | 1 - .../store-methods/flag.tip/readme.mdx | 7 ++- .../store-methods/flag.warn/readme.mdx | 7 ++- 7 files changed, 65 insertions(+), 29 deletions(-) diff --git a/sites/dev/docs/reference/store-methods/flag.error/readme.mdx b/sites/dev/docs/reference/store-methods/flag.error/readme.mdx index 215083ab38c..51456ac1bde 100644 --- a/sites/dev/docs/reference/store-methods/flag.error/readme.mdx +++ b/sites/dev/docs/reference/store-methods/flag.error/readme.mdx @@ -11,7 +11,6 @@ However, in our own UI on FreeSewing.org, we use this mechanism to allow designer to flag information to the user, and even suggest changes to the pattern configuration. - ## Signature ```js @@ -23,4 +22,8 @@ undefined Store.flag.error({ Since these methods are not part of FreeSewing's core API, what you pass to this method does depend on your own implementation. -For a more detailed example of how we use this, see [flag.info()](/reference/store-methods/flag.info). +:::note RELATED +The above Signature contains abbreviated information. +For full details about this method's Signature, Configuration, and +Example usage, see [flag.info()](/reference/store-methods/flag.info). +::: diff --git a/sites/dev/docs/reference/store-methods/flag.fixme/readme.mdx b/sites/dev/docs/reference/store-methods/flag.fixme/readme.mdx index d64c09075d9..5ac66c00685 100644 --- a/sites/dev/docs/reference/store-methods/flag.fixme/readme.mdx +++ b/sites/dev/docs/reference/store-methods/flag.fixme/readme.mdx @@ -11,7 +11,6 @@ However, in our own UI on FreeSewing.org, we use this mechanism to allow designer to flag information to the user, and even suggest changes to the pattern configuration. - ## Signature ```js @@ -23,4 +22,8 @@ undefined Store.flag.fixme({ Since these methods are not part of FreeSewing's core API, what you pass to this method does depend on your own implementation. -For a more detailed example of how we use this, see [flag.info()](/reference/store-methods/flag.info). +:::note RELATED +The above Signature contains abbreviated information. +For full details about this method's Signature, Configuration, and +Example usage, see [flag.info()](/reference/store-methods/flag.info). +::: diff --git a/sites/dev/docs/reference/store-methods/flag.info/readme.mdx b/sites/dev/docs/reference/store-methods/flag.info/readme.mdx index 8ac3ffcfdaf..964adf23fd4 100644 --- a/sites/dev/docs/reference/store-methods/flag.info/readme.mdx +++ b/sites/dev/docs/reference/store-methods/flag.info/readme.mdx @@ -11,17 +11,28 @@ However, in our own UI on FreeSewing.org, we use this mechanism to allow designer to flag information to the user, and even suggest changes to the pattern configuration. +:::tip +The Signature, Configuration, and Example information below applies to the +`flag.error()`, `flag.fixme()`, `flag.info()`, `flag.note()`, +`flag.tip()`, and `flag.warn()` methods. +::: ## Signature ```js undefined Store.flag.info({ + id: 'id_string', title: 'flag:expandIsOn.t', desc: 'flag:expandIsOn.d', + msg: 'flag:expandIsOn', notes: [ 'sorcha:moreInfo1', 'sorcha:moreInfo2', ], + replace: { + key1: //code for replacement value, + key2: //code for replacement value, + }, suggest: { text: 'flag:disable', icon: 'expand', @@ -37,29 +48,41 @@ The example above is from our implementation, which uses the following propertie ## Configuration -| Property | Type | Description | -| ----------:| ------------------- | ----------- | -| `id` | String | An ID for this flag message. If none is provided, `title` will be used | -| `title` | String | The title of the message | -| `desc` | String | The description of the message | -| `notes` | String or Array of Strings | More information/notes (see [Notes](#notes))| -| `suggest.text` | String | Text to go on the button to implement the suggested configuration change | -| `suggest.icon` | String | Icon name to go on the button to implement the suggested configuration change. (see [suggest.icon](#suggesticon)) | -| `suggest.update.settings` | Array | An array describing the changes to apply to the `settings` if the user accepts the suggestion. (see [suggest.update](#suggestupdate)) | -| `suggest.update.ui` | Array | An array describing the changes to apply to the `ui` if the user accepts the suggestion. (see [suggest.update](#suggestupdate)) | +| Property | Type | Description | +| ------------------------: | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `id` | String | An ID for this flag message. If none is provided, `title` will be used | +| `title` | String | The translation key for the title of the message | +| `desc` | String | The translation key for the description of the message | +| `msg` | String | The translation key for the message | +| `notes` | String or Array of Strings | Translation keys for more information/notes (see [Notes](#notes)) | +| `replace` | Object | Key/values for text replacements (see [Replacement Values](#replacement-values)) | +| `suggest.text` | String | Text to go on the button to implement the suggested configuration change | +| `suggest.icon` | String | Icon name to go on the button to implement the suggested configuration change. (see [suggest.icon](#suggesticon)) | +| `suggest.update.settings` | Array | An array describing the changes to apply to the `settings` if the user accepts the suggestion. (see [suggest.update](#suggestupdate)) | +| `suggest.update.ui` | Array | An array describing the changes to apply to the `ui` if the user accepts the suggestion. (see [suggest.update](#suggestupdate)) | ### Notes Notes are optional, but allow you to add more text/content to the flag message. -Unlike `desc` which can only hold a string, `notes` can hold either a string or an array of strings. +Unlike `title` or `desc` which can only hold a string, `notes` can hold either a string or an array of strings. -Both `desc` and `notes` will be rendered as markdown. +`notes` are also translation keys, and the translation strings will be +rendered as markdown. + +### Replacement Values + +The translation strings for `title`, `desc`, and `notes` can contain +variables that allow calculated values to be inserted into messages. + +The optional `replace` object holds key/value pair properties where +keys are variable names and values contain code that generates +the replacement text for that variable. ### suggest.icon -An optional name of an icon. Or leave it out to not render and icon. -The idea is that the icon helps convey the message, the following icon names are supported: +An optional name of an icon. Or leave it out to not render an icon. +The idea is that the icon helps convey the message, with the following icon names supported: - `note` - `info` @@ -77,12 +100,12 @@ Any other name will be ignored. Note that the `suggest` object is optional. Without it, it will merely display a message to the user. However, when a suggest key is present, a button will be created that the user can click to accept the suggested changes. -The `suggest.update` object has only two possible top-level keys: +The `suggest.update` object has only two possible top-level keys: -- `settings` +- `settings` - `ui` -They both take the same parameter, an array with two elements: +They both take the same parameter, an array with two elements: ```mjs Array [`path`, `value`] @@ -129,4 +152,3 @@ So to set the `waistEase` option to `0.2`, it should look like this: return part } ``` - diff --git a/sites/dev/docs/reference/store-methods/flag.note/readme.mdx b/sites/dev/docs/reference/store-methods/flag.note/readme.mdx index 96237cf8a29..1af8ce08cb2 100644 --- a/sites/dev/docs/reference/store-methods/flag.note/readme.mdx +++ b/sites/dev/docs/reference/store-methods/flag.note/readme.mdx @@ -11,7 +11,6 @@ However, in our own UI on FreeSewing.org, we use this mechanism to allow designer to flag information to the user, and even suggest changes to the pattern configuration. - ## Signature ```js @@ -23,4 +22,8 @@ undefined Store.flag.note({ Since these methods are not part of FreeSewing's core API, what you pass to this method does depend on your own implementation. -For a more detailed example of how we use this, see [flag.info()](/reference/store-methods/flag.info). +:::note RELATED +The above Signature contains abbreviated information. +For full details about this method's Signature, Configuration, and +Example usage, see [flag.info()](/reference/store-methods/flag.info). +::: diff --git a/sites/dev/docs/reference/store-methods/flag.preset/readme.mdx b/sites/dev/docs/reference/store-methods/flag.preset/readme.mdx index 1895122c4d4..e2c65b79490 100644 --- a/sites/dev/docs/reference/store-methods/flag.preset/readme.mdx +++ b/sites/dev/docs/reference/store-methods/flag.preset/readme.mdx @@ -38,4 +38,3 @@ The example above is from our implementation, which uses the following propertie return part } ``` - diff --git a/sites/dev/docs/reference/store-methods/flag.tip/readme.mdx b/sites/dev/docs/reference/store-methods/flag.tip/readme.mdx index 44751b1e384..bdc84cf91da 100644 --- a/sites/dev/docs/reference/store-methods/flag.tip/readme.mdx +++ b/sites/dev/docs/reference/store-methods/flag.tip/readme.mdx @@ -11,7 +11,6 @@ However, in our own UI on FreeSewing.org, we use this mechanism to allow designer to flag information to the user, and even suggest changes to the pattern configuration. - ## Signature ```js @@ -23,4 +22,8 @@ undefined Store.flag.tip({ Since these methods are not part of FreeSewing's core API, what you pass to this method does depend on your own implementation. -For a more detailed example of how we use this, see [flag.info()](/reference/store-methods/flag.info). +:::note RELATED +The above Signature contains abbreviated information. +For full details about this method's Signature, Configuration, and +Example usage, see [flag.info()](/reference/store-methods/flag.info). +::: diff --git a/sites/dev/docs/reference/store-methods/flag.warn/readme.mdx b/sites/dev/docs/reference/store-methods/flag.warn/readme.mdx index 6efc6fe595d..318b79389b4 100644 --- a/sites/dev/docs/reference/store-methods/flag.warn/readme.mdx +++ b/sites/dev/docs/reference/store-methods/flag.warn/readme.mdx @@ -11,7 +11,6 @@ However, in our own UI on FreeSewing.org, we use this mechanism to allow designer to flag information to the user, and even suggest changes to the pattern configuration. - ## Signature ```js @@ -23,4 +22,8 @@ undefined Store.flag.warn({ Since these methods are not part of FreeSewing's core API, what you pass to this method does depend on your own implementation. -For a more detailed example of how we use this, see [flag.info()](/reference/store-methods/flag.info). +:::note RELATED +The above Signature contains abbreviated information. +For full details about this method's Signature, Configuration, and +Example usage, see [flag.info()](/reference/store-methods/flag.info). +::: From ba4202fcd031482ca2454efca7730185b5b578f6 Mon Sep 17 00:00:00 2001 From: Benjamin Fan Date: Thu, 22 May 2025 09:43:10 -0700 Subject: [PATCH 40/46] fix(dev:docs): Minor tutorials fixes --- .../tutorials/getting-started-codespaces/readme.mdx | 13 ++++++++----- .../tutorials/getting-started-vercel/readme.mdx | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/sites/dev/docs/tutorials/getting-started-codespaces/readme.mdx b/sites/dev/docs/tutorials/getting-started-codespaces/readme.mdx index fdb471e8273..7848b7f55cc 100644 --- a/sites/dev/docs/tutorials/getting-started-codespaces/readme.mdx +++ b/sites/dev/docs/tutorials/getting-started-codespaces/readme.mdx @@ -16,9 +16,6 @@ via a web browser. The files and computer programs are hosted on and run from a remote server run by GitHub. -[gh]: https://github.com -[ghcs]: https://github.com/features/codespaces - For FreeSewing, you can use Codespaces to edit our repository files to modify existing designs, add new files to create new designs, and run the FreeSewing lab website so you can test designs. @@ -55,7 +52,7 @@ The Codespaces app will open in the browser window. The Codespaces app is basically the [Visual Studio Code][vs] app with Codespaces and GitHub integration built in. -[vs]: https://code.visualstudio.com 'Wait 45 seconds or so for the Codespace app to clone the repository from +'Wait 45 seconds or so for the Codespace app to clone the repository from GitHub to the codespace repository and start.' ## Editing files @@ -234,8 +231,14 @@ To delete a codespace: and select "Delete". :::note RELATED + For more information, please see: - [GitHub Codebases documentation](https://docs.github.com/en/codespaces). - [About billing for GitHub Codespaces](https://docs.github.com/en/billing/managing-billing-for-github-codespaces/about-billing-for-github-codespaces) - ::: + +::: + +[gh]: https://github.com +[ghcs]: https://github.com/features/codespaces +[vs]: https://code.visualstudio.com diff --git a/sites/dev/docs/tutorials/getting-started-vercel/readme.mdx b/sites/dev/docs/tutorials/getting-started-vercel/readme.mdx index 997c4853668..73cb76445a1 100644 --- a/sites/dev/docs/tutorials/getting-started-vercel/readme.mdx +++ b/sites/dev/docs/tutorials/getting-started-vercel/readme.mdx @@ -62,7 +62,7 @@ Free Hobby accounts are limited to 3 Projects per Git repository. Under each project there will be many, many deployments. -\_Deployments are simply builds, an instance of a website/app +_Deployments_ are simply builds, an instance of a website/app built from a specific commit version of a specific branch of the repository. These deployments can be accessed using a web browser to preview the web app or website. From 97a43c0151d5c3bcbe72b07cdbc3f3143e312cf8 Mon Sep 17 00:00:00 2001 From: Benjamin Fan Date: Fri, 23 May 2025 13:26:53 -0700 Subject: [PATCH 41/46] fix(dev/docs): Add git requirement to pattern design tutorial --- .../docs/tutorials/pattern-design/part1/readme.mdx | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/sites/dev/docs/tutorials/pattern-design/part1/readme.mdx b/sites/dev/docs/tutorials/pattern-design/part1/readme.mdx index 1acc688f6dd..34596f83c1f 100644 --- a/sites/dev/docs/tutorials/pattern-design/part1/readme.mdx +++ b/sites/dev/docs/tutorials/pattern-design/part1/readme.mdx @@ -30,3 +30,15 @@ npx @freesewing/studio If you don't have NodeJS on your system --- or if you're not sure what NodeJS is to begin with --- read on to learn how to install it. + +:::danger[Windows users also need to install `git`] + +The `git` command line utility is also a requirement for installing the +FreeSewing development environment. Linux and Mac systems come with +`git` pre-installed, but Windows users will need to install it manually. + +Please see the +[Getting started on Windows](/tutorials/getting-started-windows/) +tutorial for instructions on how to install `git` on a Windows system. + +::: From 90e2bf31f0b9ff5f8126a067c2e0eddc982f4fde Mon Sep 17 00:00:00 2001 From: Benjamin Fan Date: Fri, 23 May 2025 17:30:27 -0700 Subject: [PATCH 42/46] fix(backend): Comment correction --- sites/backend/src/controllers/apikeys.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sites/backend/src/controllers/apikeys.mjs b/sites/backend/src/controllers/apikeys.mjs index d16f363f01d..988a0740b52 100644 --- a/sites/backend/src/controllers/apikeys.mjs +++ b/sites/backend/src/controllers/apikeys.mjs @@ -35,7 +35,7 @@ ApikeysController.prototype.list = async (req, res, tools) => { /* * Read API key * - * This is the endpoint that handles creation of API keys/tokens + * This is the endpoint that handles reading of API keys/tokens * See: https://freesewing.dev/reference/backend/api/apikey */ ApikeysController.prototype.read = async (req, res, tools) => { From 9d16d1bf769a2cae9a0f987aeb043a402758009b Mon Sep 17 00:00:00 2001 From: Benjamin Fan Date: Fri, 23 May 2025 18:14:52 -0700 Subject: [PATCH 43/46] fix(dev/docs): Change URL from GitHub to Codeberg --- sites/dev/docs/guides/best-practices/readme.mdx | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/sites/dev/docs/guides/best-practices/readme.mdx b/sites/dev/docs/guides/best-practices/readme.mdx index e9f52d1ff32..a735b9694cb 100644 --- a/sites/dev/docs/guides/best-practices/readme.mdx +++ b/sites/dev/docs/guides/best-practices/readme.mdx @@ -133,7 +133,7 @@ For example, if you want to put "_Finish with bias tape_" on your pattern, don't tempted to do this: ```js -path.seam.attr("data-text", "Finish with bias tape"); +path.seam.attr('data-text', 'Finish with bias tape') ``` That (English) string is now hard-coded in your pattern. As FreeSewing supports @@ -142,16 +142,16 @@ translation out of the box, it would be a real shame not to make use of it. Instead, insert a key to identify the string: ```js -path.seam.attr("data-text", "finishWithBiasTape"); +path.seam.attr('data-text', 'finishWithBiasTape') ``` This way, different strings for different languages can be associated with the key, allowing translated text to be used. You can find and browse the translations and available translation keys for each design in the design's -[i18n folder on GitHub][1]. +[i18n folder on Codeberg][1]. -[1]: https://github.com/freesewing/freesewing/tree/develop/designs/aaron/i18n +[1]: https://codeberg.org/freesewing/freesewing/src/branch/develop/designs/aaron/i18n ## Construct paths counter-clockwise @@ -189,5 +189,3 @@ Constructing a path counter-clockwise will also ensure that the path offset goes rather than inwards. ::: - - From f903929a0a63c696f30f4d3c2c220ba2b2e19129 Mon Sep 17 00:00:00 2001 From: Benjamin Fan Date: Fri, 23 May 2025 18:49:56 -0700 Subject: [PATCH 44/46] fix(CONTRIBUTING): v4 updates --- CONTRIBUTING.md | 42 ++++++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1e32257ef3a..c179fa0b1e4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,50 +1,51 @@ # Contributing to FreeSewing -First off, -thank you for being part of the freesewing community, -and for taking the time to contribute! ❤️ +First off, +thank you for being part of the FreeSewing community, +and for taking the time to contribute! ❤️ The following is a set of guidelines for contributing to FreeSewing. -These are mostly guidelines, not rules. +These are mostly guidelines, not rules. Use your best judgment, and feel free to propose changes to this document in a pull request. ## Code of Conduct -When you engage with us, or when you engage with others, -please remember [the FreeSewing community standards](https://freesewing.org/docs/about/community-standards/). +When you engage with us, or when you engage with others, +please remember [the FreeSewing community standards](https://freesewing.eu/docs/about/community-standards/). -As a contributor, you are also expected to uphold [the FreeSewing Code of Conduct](https://freesewing.dev/guides/code-of-conduct). +As a contributor, you are also expected to uphold [the FreeSewing Code of Conduct](https://freesewing.dev/guides/code-of-conduct). - +:::tip ##### See something, say something -Please report unacceptable behavior to [us@freesewing.org](mailto:us@freesewing.org). +Please report unacceptable behavior to [us@freesewing.eu](mailto:us@freesewing.eu). - +::: ## I don't want to read this whole thing I just have a question! -Please don't file an issue to ask a question. -You'll get faster results by contacting us on Discord. -You can get to our Discord server via https://discord.freesewing.org/. +Please don't file an issue to ask a question. +You'll get faster results by contacting us on Discord or the Forum. +You can get to our Discord server via https://discord.freesewing.eu/ . +You can get to our Forum via https://forum.freesewing.eu/ . -Please keep in mind that our community members live all over the world. +Please keep in mind that our community members live all over the world. So what's daytime for you might be the middle of the night for others. Please be patient. Sooner or later, somebody will answer. ## What should I know before I get started? -Most of FreeSewing's source code lives in [our monorepo](https://github.com/freesewing/freesewing). +Most of FreeSewing's source code lives in [our monorepo](https://codeberg.org/freesewing/freesewing). There are some exceptions: - - [`svgtopdf`](https://github.com/freesewing/svgtopdf): The repository holding the source code for our on-demand tiler backend - [`tile`](https://github.com/freesewing/tile): The repository holding the source code for our command-line tiler ### FreeSewing packages -We publish a lot of JavaScript packages on NPM. You can find the full list [in the `packages` folder of our monorepo](https://github.com/freesewing/freesewing/tree/develop/packages). +We publish a lot of JavaScript packages on NPM. You can find the full list +[in the `packages` folder of our monorepo](https://codeberg.org/freesewing/freesewing/src/branch/develop/packages). ## How Can I Contribute? @@ -52,10 +53,7 @@ This file is mostly geared towards code contributors, but there's plenty of othe ### Your first contribution -Unsure where to begin contributing to FreeSewing? +Unsure where to begin contributing to FreeSewing? You can start by looking through the issues labeled [good first issue](https://codeberg.org/freesewing/freesewing/issues?q=&type=all&sort=&state=open&labels=344963). -Don't be afraid to take on an issue. If you get stuck, [we'll help you out](https://discord.freesewing.org/). - - - +Don't be afraid to take on an issue. If you get stuck, [we'll help you out](https://discord.freesewing.eu/). From 19397c1c6e95e3ec9b4dadcc0c774628dd451dd8 Mon Sep 17 00:00:00 2001 From: Benjamin Fan Date: Fri, 23 May 2025 20:05:28 -0700 Subject: [PATCH 45/46] fix(dev/docs): Add expand setting --- .../docs/reference/api/part/draft/readme.mdx | 59 ++++++++++--------- .../docs/reference/settings/expand/readme.mdx | 44 ++++++++++++++ sites/dev/docs/reference/settings/readme.mdx | 8 +-- 3 files changed, 78 insertions(+), 33 deletions(-) create mode 100644 sites/dev/docs/reference/settings/expand/readme.mdx diff --git a/sites/dev/docs/reference/api/part/draft/readme.mdx b/sites/dev/docs/reference/api/part/draft/readme.mdx index b28a175ef8c..bae3da938b7 100644 --- a/sites/dev/docs/reference/api/part/draft/readme.mdx +++ b/sites/dev/docs/reference/api/part/draft/readme.mdx @@ -13,35 +13,36 @@ function draft(props) The draft method receives a single parameter, an object which you can _destructure_ to access the following properties: -| Property | Description | -| --------:|:----------- | -|| **_Content constructors_** | -| `Path` | A [Path constructor](/reference/api/path) to create new paths | -| `Point` | A [Point constructor](/reference/api/point) to create new points | -| `Snippet` | A [Snippet constructor](/reference/api/snippet) to create new snippets | -|| **_Content containers_** | -| `paths` | Add a Path to your part by adding it to this object | -| `points` | Add a Points to your part by adding it to this object | -| `snippets` | Add a Snippet to your part by adding it to this object | -|| **_Access to settings_** | -| `absoluteOptions` | Access to `settings.absoluteOptions` | -| `complete` | Access to `settings.complete` | -| `measurements` | Access to `settings.measurements` | -| `options` | Access to `settings.options` | -| `paperless` | Access to `settings.paperless` | -| `sa` | Access to `settings.sa` | -| `scale` | Access to `settings.scale` | -|| **_Access to utilities_** | -| `context` | Allows access to the pattern object and other things higher in the tree | -| `getId` | See [the getId documentation](/reference/api/part/getid) | -| `log` | See [the Store Methods documentation](/reference/store-methods#store-methods-we-maintain) | -| `macro` | See [the macros documentation](/reference/macros/) | -| `store` | See [the store documentation](/reference/api/store) | -| `units` | A version of [`utils.units()`](/reference/api/utils/units) that is preconfigured with the user's chosen units | -| `utils` | See [the utils documentation](/reference/api/utils) | -| `Bezier` | The [bezier-js](https://pomax.github.io/bezierjs/) library's `Bezier` named export | -|| **_Return value_** | -| `part` | Your draft method **must** return this | +| Property | Description | +| ----------------: | :------------------------------------------------------------------------------------------------------------ | +| | **_Content constructors_** | +| `Path` | A [Path constructor](/reference/api/path) to create new paths | +| `Point` | A [Point constructor](/reference/api/point) to create new points | +| `Snippet` | A [Snippet constructor](/reference/api/snippet) to create new snippets | +| | **_Content containers_** | +| `paths` | Add a Path to your part by adding it to this object | +| `points` | Add a Points to your part by adding it to this object | +| `snippets` | Add a Snippet to your part by adding it to this object | +| | **_Access to settings_** | +| `absoluteOptions` | Access to `settings.absoluteOptions` | +| `complete` | Access to `settings.complete` | +| `expand` | Access to `settings.expand` | +| `measurements` | Access to `settings.measurements` | +| `options` | Access to `settings.options` | +| `paperless` | Access to `settings.paperless` | +| `sa` | Access to `settings.sa` | +| `scale` | Access to `settings.scale` | +| | **_Access to utilities_** | +| `context` | Allows access to the pattern object and other things higher in the tree | +| `getId` | See [the getId documentation](/reference/api/part/getid) | +| `log` | See [the Store Methods documentation](/reference/store-methods#store-methods-we-maintain) | +| `macro` | See [the macros documentation](/reference/macros/) | +| `store` | See [the store documentation](/reference/api/store) | +| `units` | A version of [`utils.units()`](/reference/api/utils/units) that is preconfigured with the user's chosen units | +| `utils` | See [the utils documentation](/reference/api/utils) | +| `Bezier` | The [bezier-js](https://pomax.github.io/bezierjs/) library's `Bezier` named export | +| | **_Return value_** | +| `part` | Your draft method **must** return this | :::tip diff --git a/sites/dev/docs/reference/settings/expand/readme.mdx b/sites/dev/docs/reference/settings/expand/readme.mdx new file mode 100644 index 00000000000..c63bf8e7dca --- /dev/null +++ b/sites/dev/docs/reference/settings/expand/readme.mdx @@ -0,0 +1,44 @@ +--- +title: expand +--- + +The `expand` setting controls whether all parts should be fully +drawn in a pattern. +Set `expand` to `false` when the pattern should instead omit parts and/or +draw abbreviated parts. + +Omitting parts and using abbreviated parts saves space and paper +in printed patterns. +Typically, this is done for parts that are simple shapes like +rectangles or that can be cut on the fold. + +## Signature + +```js +const settings = { + Boolean expand=true +} +``` + +The default `expand` setting is `true`. +Set this to `false` to draft a pattern with omitted or abbreviated parts, +rather than with fully-drawn parts. + +## Example + +```js +import { Aaron } from '@freesewing/aaron' + +const pattern = new Aaron({ + expand: false, +}) +``` + +## Notes + +The `expand` setting does not automatically cause pattern parts to +be omitted or abbreviated. +Instead, it is up to the pattern designer to have the design +check for the `expand` setting, +include all, full parts if set to `true`, +and omit or abbreviate relevant parts if set to `false`. diff --git a/sites/dev/docs/reference/settings/readme.mdx b/sites/dev/docs/reference/settings/readme.mdx index a89ecae8ec8..e85e8b804bc 100644 --- a/sites/dev/docs/reference/settings/readme.mdx +++ b/sites/dev/docs/reference/settings/readme.mdx @@ -3,7 +3,7 @@ title: Settings --- FreeSewing is all about parametric design, and the settings are the parameters -we pass to a pattern when drafting it. Perhaps the most important of all +we pass to a pattern when drafting it. Perhaps the most important of all settings are the measurements, but there are other settings too. ## Signature @@ -13,6 +13,7 @@ Object settings = { Object absoluteOptions, Boolean complete=true, Boolean embed=false, + Boolean expand=true, String idPrefix='fs-', Object|Boolean layout=true, String locale='en', @@ -43,12 +44,11 @@ objects in an array to the pattern constructor: ```js new pattern([ - { + { // settings }, - { + { // different settings }, ]) ``` - From be7f712bc66ca13689aae55097ebfe37b366a210 Mon Sep 17 00:00:00 2001 From: joostdecock Date: Sat, 24 May 2025 11:49:14 +0200 Subject: [PATCH 46/46] fix(org): Incorrect file location --- .../hugo/options/collarease/collarease.svg | 153 ++++++++++++++++++ .../hugo/options/collarease/readme.mdx | 12 ++ .../docs/docs/designs/hugo/options/readme.mdx | 11 ++ .../docs/designs/wahid/options/readme.mdx | 9 ++ 4 files changed, 185 insertions(+) create mode 100644 sites/org/docs/docs/designs/hugo/options/collarease/collarease.svg create mode 100644 sites/org/docs/docs/designs/hugo/options/collarease/readme.mdx diff --git a/sites/org/docs/docs/designs/hugo/options/collarease/collarease.svg b/sites/org/docs/docs/designs/hugo/options/collarease/collarease.svg new file mode 100644 index 00000000000..f5e1a583775 --- /dev/null +++ b/sites/org/docs/docs/designs/hugo/options/collarease/collarease.svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/sites/org/docs/docs/designs/hugo/options/collarease/readme.mdx b/sites/org/docs/docs/designs/hugo/options/collarease/readme.mdx new file mode 100644 index 00000000000..a1470c15e6c --- /dev/null +++ b/sites/org/docs/docs/designs/hugo/options/collarease/readme.mdx @@ -0,0 +1,12 @@ +--- +title: 'Collar ease' +--- + +![Collar ease](collarease.svg) + +Controls the amount of ease at your collar/neck and the size +of the neck opening.. + +Hugo uses the neck circumference measurement rather than head +circumference to produce the neck opening size when generating patterns. +Use this option to adjust the neck opening size if needed. diff --git a/sites/org/docs/docs/designs/hugo/options/readme.mdx b/sites/org/docs/docs/designs/hugo/options/readme.mdx index ec429a7d909..e98c63609c7 100644 --- a/sites/org/docs/docs/designs/hugo/options/readme.mdx +++ b/sites/org/docs/docs/designs/hugo/options/readme.mdx @@ -10,6 +10,7 @@ import Armholedepth from '@site/docs/docs/designs/hugo/options/armholedepth/read import Backneckcutout from '@site/docs/docs/designs/hugo/options/backneckcutout/readme.mdx' import Bicepsease from '@site/docs/docs/designs/hugo/options/bicepsease/readme.mdx' import Chestease from '@site/docs/docs/designs/hugo/options/chestease/readme.mdx' +import Collarease from '@site/docs/docs/designs/hugo/options/collarease/readme.mdx' import Cuffease from '@site/docs/docs/designs/hugo/options/cuffease/readme.mdx' import Draftforhighbust from '@site/docs/docs/designs/hugo/options/draftforhighbust/readme.mdx' import Hipsease from '@site/docs/docs/designs/hugo/options/hipsease/readme.mdx' @@ -52,6 +53,16 @@ import Sleevelengthbonus from '@site/docs/docs/designs/hugo/options/sleevelength +### Collar ease {#collarease} + +**The amount of ease around your neck** +- Type: **Percentage** +- Default: **15%** +- Minimum: **0%** +- Maximum: **40%** + + + ### Cuff ease {#cuffease} **The amount of ease at your wrist.** diff --git a/sites/org/docs/docs/designs/wahid/options/readme.mdx b/sites/org/docs/docs/designs/wahid/options/readme.mdx index 928d9486d9c..ab73b3c6446 100644 --- a/sites/org/docs/docs/designs/wahid/options/readme.mdx +++ b/sites/org/docs/docs/designs/wahid/options/readme.mdx @@ -21,6 +21,7 @@ import Hemradius from '@site/docs/docs/designs/wahid/options/hemradius/readme.md import Hemstyle from '@site/docs/docs/designs/wahid/options/hemstyle/readme.mdx' import Hipsease from '@site/docs/docs/designs/wahid/options/hipsease/readme.mdx' import Legacyarmholedepth from '@site/docs/docs/designs/wahid/options/legacyarmholedepth/readme.mdx' +import Legacywaisthips from '@site/docs/docs/designs/wahid/options/legacywaisthips/readme.mdx' import Lengthbonus from '@site/docs/docs/designs/wahid/options/lengthbonus/readme.mdx' import Neckinset from '@site/docs/docs/designs/wahid/options/neckinset/readme.mdx' import Necklinedrop from '@site/docs/docs/designs/wahid/options/necklinedrop/readme.mdx' @@ -255,6 +256,14 @@ import Weltheight from '@site/docs/docs/designs/wahid/options/weltheight/readme. +### Legacy waist and hips widths {#legacywaisthips} + +**Enable this option to use the legacy (v3) way to calculate the waist and hips widths (using chest circumference) rather than the new way (using the waist and hips measurements).** +- Type: **Boolean** +- Default: **false** + + + ### Neck inset {#neckinset} **How much the shoulder seam is cut inwards at the neck**