diff --git a/designs/tutorial/i18n/en.json b/designs/tutorial/i18n/en.json index 056f70802a5..a354b54c7ef 100644 --- a/designs/tutorial/i18n/en.json +++ b/designs/tutorial/i18n/en.json @@ -4,6 +4,8 @@ "p": { "bib": "Bib" }, - "s": {}, + "s": { + "finishWithBiasTape": "Finish with bias tape" + }, "o": {} } diff --git a/designs/tutorial/src/bib.mjs b/designs/tutorial/src/bib.mjs index 454513f84c9..f869cc6bcc4 100644 --- a/designs/tutorial/src/bib.mjs +++ b/designs/tutorial/src/bib.mjs @@ -173,7 +173,7 @@ export const bib = { paths.bias = paths.seam .offset(-5) .attr('class', 'various dashed') - .attr('data-text', 'finishWithBiasTape') + .attr('data-text', 'tutorial:finishWithBiasTape') .attr('data-text-class', 'center fill-various') // Add the title diff --git a/designs/tutorial/src/step1-4.mjs b/designs/tutorial/src/step1-4.mjs index dd73e6e29a8..99e7d46b027 100644 --- a/designs/tutorial/src/step1-4.mjs +++ b/designs/tutorial/src/step1-4.mjs @@ -13,11 +13,12 @@ export const step1 = { snippets, complete, sa, + store, paperless, macro, part, }) => { - let w = 500 * options.size + const w = 500 * options.size points.topLeft = new Point(0, 0) points.topRight = new Point(w, 0) points.bottomLeft = new Point(0, w / 2) @@ -32,33 +33,33 @@ export const step1 = { .close() .attr('class', 'fabric') - // Complete? - if (complete) { - points.logo = points.topLeft.shiftFractionTowards(points.bottomRight, 0.5) - snippets.logo = new Snippet('logo', points.logo) - points.text = points.logo - .shift(-90, w / 8) - .attr('data-text', 'hello') - .attr('data-text-class', 'center') + if (sa) paths.sa = paths.seam.offset(sa).attr('class', 'fabric sa') + /* + * Annotations + */ - if (sa) { - paths.sa = paths.seam.offset(sa).attr('class', 'fabric sa') - } - } + // Cutlist + store.cutlist.setCut({ cut: 1, from: 'fabric' }) - // Paperless? - if (paperless) { - macro('hd', { - from: points.bottomLeft, - to: points.bottomRight, - y: points.bottomLeft.y + sa + 15, - }) - macro('vd', { - from: points.bottomRight, - to: points.topRight, - x: points.topRight.x + sa + 15, - }) - } + // Logo & Hello + points.logo = points.topLeft.shiftFractionTowards(points.bottomRight, 0.5) + snippets.logo = new Snippet('logo', points.logo) + + if (complete) points.text = points.logo.shift(-90, w / 8).addText('hello', 'center') + + //Dimensions + macro('hd', { + id: 'width', + from: points.bottomLeft, + to: points.bottomRight, + y: points.bottomLeft.y + sa + 15, + }) + macro('vd', { + id: 'height', + from: points.bottomRight, + to: points.topRight, + x: points.topRight.x + sa + 15, + }) return part }, diff --git a/markdown/dev/guides/designs/en.md b/markdown/dev/guides/designs/en.md index 465c2aeb408..b6f63991ffa 100644 --- a/markdown/dev/guides/designs/en.md +++ b/markdown/dev/guides/designs/en.md @@ -2,10 +2,10 @@ title: Design guide --- -This short guide will illustrate and explain how designs work in FreeSewing. -Not to be confused with how sewing patterns work — although there are [great books -about that](https://www.assembil.com/how-patterns-work-book/) if you're -interested — it's about what goes on under the hood each time a sewing +Hi there and welcome to this guide that explains how FreeSewing designs work. + + +it's about what goes on under the hood each time a sewing pattern is generated by FreeSewing. This illustration is a good starting point to gain a better @@ -185,10 +185,11 @@ understanding of the structure of a FreeSewing design: ``` -If it looks like _a lot_ don't despair. There's a lot of repetition, and we'll -work through the building blocks step by step. +If it looks like _a lot_ don't despair. I included all the info on the +graphical overview, but most of it you can safely ignore and consider _under +the hood_ unless you want to do some really advanced things with FreeSewing. -If we look at our image, it can be divided into three areas: +If we look at our image through squinted eyes, we can identify three areas: - The[ **Settings**](#the-settings) on the left - The[ **Render stage**](#rendering-your-pattern) on the right diff --git a/markdown/dev/tutorials/pattern-design/adding-measurements/en.md b/markdown/dev/tutorials/pattern-design/adding-measurements/en.md index 111bf2da04b..fde9d8a7a60 100644 --- a/markdown/dev/tutorials/pattern-design/adding-measurements/en.md +++ b/markdown/dev/tutorials/pattern-design/adding-measurements/en.md @@ -3,68 +3,53 @@ title: Adding measurements order: 130 --- -FreeSewing is all about _made-to-measure_ sewing patterns; -we are going to draft our pattern according to the measurements provided to us. +FreeSewing is all about _made-to-measure_ sewing patterns -- or *parametric +design* to use a more generic term. + +That means that when drafting our pattern, I will take the measurements provided +by the user into account. Which begs the question, which measurements? -It is we, as the pattern designers, who decide which measurements are used -to draft our pattern. For our bib, the only measurement we need is the +As the pattern designers, you get to decide which measurements are used +to draft the pattern. For this bib, I am going to use the _head circumference_. - So let's add it as a required measurement. ## Adding required measurements -In our `design/src/bib.mjs` file, on the `bib` object, there is a key called -`measurements` (line 121) that will hold a list (an array) of all required measurements -for this part. +In our `design/src/bib.mjs` file, we will add a `measurements` property to the `bib` object. +This property will be an Array (a list) holding all required measurements for this part. -We are going to use [*the official name* of the measurement](/reference/measurements). For head +I am usign [*the official name* of the measurement](/reference/measurements) here. For head circumference, that name is `head`. ```design/src/bib.mjs -function draftBib({ part }) { +function draftBib({ part }) => { return part } export const bib = { name: 'tutorial.bib', draft: draftBib, - from: false, - hide: { - self: false, - from: false, - after: false - }, - options: {}, - // start-highlight - measurements: ['head'], - // end-highlight - optionalMeasurements: [], - plugins: [] + // highlight-start + measurements: [ 'head' ], + // highlight-end } ``` -Now everybody knows this part requires the `head` measurement. +From now on, this part requires the `head` measurement. -This change will also get picked up by the development environment, and we'll now see this screen: - -![This screen tells us that we are missing some required measurements](./required-measurements.png) - -Since it's just one measurement, let's simply enter a value by hand. +This change will also get picked up by the development environment, which will now complain that it is missing some measurements. +Since it's just one measurement, I will simply enter a value by hand. For example `38` as 38 cm is a realistic head circumference measurement for a baby. -Enter `38` in the box, and click on **Draft Design** in the sidebar under the **View** heading. -This brings us back to our work in progress: + +##### Why using standard measurements names matters -## Notes - -### Why using standard measurements names matters - -In principle, we can use any name we want for our measurements. -Our core library really doesn't care. +In principle, I can use any name I want for our measurements. +The FreeSewing core library does not care. However, if everybody uses their own (names for) measurements, then people aren't able to re-use their measurements across designs. @@ -73,5 +58,7 @@ So if you have any intention at all to play nice with the FreeSewing ecosystem, please make sure to re-use the names of existing measurements, rather than invent your own. -See our [best practices](/guides/best-practices/reuse-measurements) on this +See the [best practices](/guides/best-practices/reuse-measurements) on this topic for details. + + diff --git a/markdown/dev/tutorials/pattern-design/adding-options/en.md b/markdown/dev/tutorials/pattern-design/adding-options/en.md index 284732aa7ce..8f86d692e5e 100644 --- a/markdown/dev/tutorials/pattern-design/adding-options/en.md +++ b/markdown/dev/tutorials/pattern-design/adding-options/en.md @@ -3,65 +3,78 @@ title: Adding options order: 140 --- -We know what our bib should look like, and we have the _head_ measurement -to work with. But there's still a number of choices we have to make: +I have shown what our bib should look like, and added the _head_ measurement +to work with. But there's still a number of choices I have to make: - How large should the neck opening be? - How wide should the bib be? - How long should the bib be? -We can make all of these choices for the user and set them in stone, so to speak. +I could make all of these choices for the user and set them in stone, so to speak. -But since we're designing a pattern in code, it's trivial to make our pattern -flexible and let the user decide. All we have to do is add options to our part. +But since the pattern I am designing is code, it is trivial (and _IMHO_ very satisfying) +to make a pattern flexible and let the user choose. +All I need to do to give control to the user is add _options_ to the part. ## Add the neckRatio option -The first option we're going to add controls the ratio between the neck opening +The first option I will add controls the ratio between the neck opening and the head circumference. Let's call it `neckRatio`. -We'll add a new `options` key to our part object for this: +For this, I will add the `options` property to our `bib` object: ```design/src/bib.mjs -function draftBib({ part }) { - +function draftBib({ part }) => { return part } export const bib = { - name: 'tutorial.bib', draft: draftBib, - from: false, - hide: { - self: false, - from: false, - after: false - }, + measurements: [ 'head' ], // highlight-start options: { - neckRatio: { pct: 80, min: 70, max: 90, menu: 'fit' }, + neckRatio: { + pct: 80, + min: 70, + max: 90, + menu: 'fit' + }, }, // highlight-end - measurements: [], - optionalMeasurements: [], - plugins: [] } - ``` Can you guess what it means? -- We've added a option of type percentage +- We've added the `options` property to our `bib` object +- On the `options` property, we have added `neckRatio` which holds the configuration for our option +- It is a `pct` option -- whcih means it's a percentage +- Its default value is 90% - Its minimum value is 70% - Its maximum value is 90% -- Its default value is 80% -- We've added this option to the *fit* menu + +There are different types of options, but percentages are by far the most common ones. +They are all documented [in the part reference docs](/reference/api/part/config/options). -There are different types of options, but percentages are the most common ones. -They are all documented [in the part reference docs](/reference/api/part/config/options). +##### What is `menu` and why should you care? + +The `menu` property on our option is *extra*. +It will be ignored by FreeSewing's core library and if we leave it out, our design will produce the same result. + +Instead, this `menu` property is there for the benefit FreeSewing's development +environment which will use this to build a menu structure for the various +options. + +Each option type has a number of required properties. But in addition to that, +you can add more to facilitate integrating with a front-end or other user +interface. + +You will see that after adding this option, the development environment will +have a `fit` section under **Design Options**. This `menu` property is where +that is based on. @@ -70,25 +83,43 @@ They are all documented [in the part reference docs](/reference/api/part/config/ Let's do something similar for the width and length of our bib: ```design/src/bib.mjs -options: { - neckRatio: { pct: 80, min: 70, max: 90, menu: 'fit' }, - widthRatio: { pct: 45, min: 35, max: 55, menu: 'style' }, - lengthRatio: { pct: 75, min: 55, max: 85, menu: 'style' }, +function draftBib({ part }) => { + return part +} + +export const bib = { + name: 'tutorial.bib', + draft: draftBib, + measurements: [ 'head' ], + options: { + neckRatio: { + pct: 80, + min: 70, + max: 90, + menu: 'fit' + }, + // highlight-start + widthRatio: { + pct: 45, + min: 35, + max: 55, + menu: 'style' + }, + lengthRatio: { + pct: 75, + min: 55, + max: 85, + menu: 'style' + }, + // highlight-end + }, } ``` -- We've added `widthRatio` and `lengthRatio` options -- We've given all options sensible defaults -- We've given all options sensible maximum and minimum boundaries -- We've added these two new options to the *style* menu +This pretty much the exact same thing, except that are placing this in the `style` menu. -Later, we'll test-drive our pattern to see how it behaves when we adapt the options -between their minimum and maximum values. At that time, we can still tweak these values. +Later, I will test-drive our pattern to see how it behaves when we adapt the options +between their minimum and maximum values. At that time, I may need to tweak these values. -With that out of the way, let's start drawing our bib. +With that out of the way, I will start drawing the bib. -## Notes - -The `menu` key on an option does not do anything for our pattern as such. -Instead it signals to the frontend that this is how options should be grouped -together and presented to the user. diff --git a/markdown/dev/tutorials/pattern-design/draft-method/en.md b/markdown/dev/tutorials/pattern-design/draft-method/en.md index 6a7453e2783..ec538a9c164 100644 --- a/markdown/dev/tutorials/pattern-design/draft-method/en.md +++ b/markdown/dev/tutorials/pattern-design/draft-method/en.md @@ -7,49 +7,7 @@ Time to turn our attention to the draft method of our part. Inside our `design/src/bib.mjs` file, this is what it currently looks like: ```design/src/bib.mjs -function draftBib ({ - // Uncomment below to destructure what you need - /* - * Content constructors - */ - //Path, // A Path constructor to create new paths - //Point, // A Point constructor to create new points - //Snippet, // A Snippet constructor to create new snippets - /* - * Content constainers - */ - //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 - */ - //getId, //See the getId documentation - //hide, //See the hide documentation - //log, //See the logging documentation - //macro, //See the macros documentation - //setHidden, //See the setHidden documentation - //store, //See the store documentation - //unhide, //See the unhide documentation - //units, //See the units documentation - ///utils, //See the utils documentation - /* - * Return value - */ - part, // Your draft method must return this -}) { - - // Work your magic here +function draftBib({ part }) => { return part } ``` diff --git a/markdown/dev/tutorials/pattern-design/en.md b/markdown/dev/tutorials/pattern-design/en.md index 3c454537ca0..be2e817d5e5 100644 --- a/markdown/dev/tutorials/pattern-design/en.md +++ b/markdown/dev/tutorials/pattern-design/en.md @@ -2,8 +2,9 @@ title: Pattern design tutorial --- -Welcome to the FreeSewing pattern design tutorial, where we'll learn how to -design a made-to-measure sewing pattern, start to finish. +Hello there, and welcome to this FreeSewing pattern design tutorial. +My name is Joost, and in this tutorial I will show you +how to design a made-to-measure sewing pattern, start to finish. ##### Before you start @@ -13,11 +14,11 @@ guide](/guides/prerequisites). It's very short, but covers some basic terminology and concepts that we'll use throughout this guide. -We will be designing a pattern for a baby bib. It's a very simple pattern, but -that's the point. Our focus today is on learning FreeSewing and how to -translate our designs into code. +I will be designing a pattern for a baby bib. It's a very simple pattern, but +that's ok. It is a tutorial after all. This will give us plenty to work with. -At the end of this tutorial, we will have created this pattern: +At the end of this tutorial, I will have created this pattern, and if you +follow along, so will you: @@ -30,13 +31,16 @@ function draftBib({ measurements, options, macro, + store, complete, snippets, Snippet, part, }) { - // Construct the quarter neck opening + /* + * Construct the quarter neck opening + */ let tweak = 1 let target = (measurements.head * options.neckRatio) /4 let delta @@ -57,7 +61,9 @@ function draftBib({ 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,7 +73,9 @@ function draftBib({ points.topCp1 = points.bottomCp2.flipY() points.topCp2 = points.bottomCp1.flipY() - // Drawing the bib outline + /* + * Drawing the bib outline + */ const width = measurements.head * options.widthRatio const length = measurements.head * options.lengthRatio @@ -92,7 +100,9 @@ function draftBib({ ) points.edgeTopRightCp = points.edgeTopLeftCp.flipX() - // Round the straps + /* + * Round the straps + */ const strap = points.edgeTop.dy(points.top) points.tipRight = points.edgeTop.translate(strap / 2, strap / 2) @@ -132,10 +142,14 @@ function draftBib({ for (const p of rotateThese) points[p] = points[p].rotate(1, points.edgeLeft) } - // Snap anchor + /* + * Snap anchor + */ points.snapLeft = points.top.shiftFractionTowards(points.edgeTop, 0.5) - // Add points for second strap + /* + * Add points for second strap + */ points.edgeTopRightCp = points.edgeTopLeftCp.flipX() points.topCp1 = points.topCp2.flipX() points.tipLeftTopStart = points.tipRightTopStart.flipX() @@ -148,7 +162,9 @@ function draftBib({ points.tipLeftBottomEnd = points.tipRightBottomEnd.flipX() points.snapRight = points.snapLeft.flipX() - // Round the bottom corners + /* + * Round the bottom corners + */ macro("round", { from: points.topLeft, to: points.bottomRight, @@ -164,7 +180,9 @@ function draftBib({ prefix: "bottomRight" }) - // Create one path for the bib outline + /* + * Create one path for the bib outline + */ paths.seam = new Path() .move(points.edgeLeft) .line(points.bottomLeftStart) @@ -185,62 +203,66 @@ function draftBib({ .close() .addClass("fabric") - if (complete) { - // Add snaps - points.snapLeft = points.top - .shiftFractionTowards(points.edgeTop, 0.5) - points.snapRight = points.snapLeft.flipX() - snippets.snapStud = new Snippet('snap-stud', points.snapLeft) - snippets.snapSocket = new Snippet('snap-socket', points.snapRight) - .attr('opacity', 0.5) + /* + * Mark the bias tape, but only if complete is set + */ + if (complete) paths.bias = paths.seam + .offset(-5) + .addClass("various dashed") + .addText("finishWithBiasTape", "center fill-various") + /* + * Annotations + */ - // Add a logo - points.logo = new Point(0, 0) - snippets.logo = new Snippet("logo", points.logo) + // Cutlist + store.cutlist.setCut({ cut: 1, from: 'fabric' }) + + // Snaps + points.snapLeft = points.top.shiftFractionTowards(points.edgeTop, 0.5) + points.snapRight = points.snapLeft.flipX() + snippets.snapStud = new Snippet('snap-stud', points.snapLeft) + snippets.snapSocket = new Snippet('snap-socket', points.snapRight).attr('opacity', 0.5) - // Add a title - points.title = points.bottom.shift(-90, 45) - macro("title", { - at: points.title, - nr: 1, - title: "bib", - scale: 0.7 - }) + // Logo + points.logo = new Point(0, 0) + snippets.logo = new Snippet("logo", points.logo) - // Add a scalbox - points.scalebox = points.title.shift(-90, 55) - macro("scalebox", { at: points.scalebox }) + // Title + points.title = points.bottom.shift(-90, 45) + macro("title", { + at: points.title, + nr: 1, + title: "bib", + scale: 0.7 + }) - paths.bias = paths.seam - .offset(-5) - .addClass("various dashed") - .addText("finishWithBiasTape", "center fill-various") - - } + // Scalbox + points.scalebox = points.title.shift(-90, 55) + macro("scalebox", { at: points.scalebox }) return part } ``` -Before we can get started, let's make sure we have the required software -installed on our computer: - ## Prerequisites +Before I can get started, I want to make sure I have the required software +installed on my computer. + FreeSewing is a JavaScript library that can run in the browser, on -[Node.js](https://nodejs.org/), or a variety of other runtimes such as Deno, -AWS Lambda, and so on. +[Node.js](https://nodejs.org/), or a variety of other runtimes such as Bun, +Deno, AWS Lambda, and so on. -For development, we'll use Node.js. If we don't have Node.js on our system, -follow the link above and install it on our system. +For development, I will use Node.js. If you don't have Node.js on our system, +follow the link above and install it. -We need Node.js 16 or higher to use FreeSewing +You need Node.js 18 (lts/hydrogen) or higher to use FreeSewing -When we're done, we can test whether it works by running: +To test whether NodeJS is installed, and see it's version, you can run this command: ```sh node -v ``` -If we get the Node.js version number, we're all set. +If you get the Node.js version number, that means NodeJs is installed. Yay! diff --git a/markdown/dev/tutorials/pattern-design/new-design/en.md b/markdown/dev/tutorials/pattern-design/new-design/en.md index f25ec0716e9..5f23f75e702 100644 --- a/markdown/dev/tutorials/pattern-design/new-design/en.md +++ b/markdown/dev/tutorials/pattern-design/new-design/en.md @@ -3,42 +3,45 @@ title: Setting up the development environment order: 100 --- -Open a terminal and enter the following command: +FreeSewing provides a development environment that visualizes your design for you. + +To set it up, I will open a terminal and enter the following command: ```sh npx @freesewing/new-design@next ``` Remove `@next` suffix once v3 is in production -We'll be asked some questions. +It will ask some questions. All the defaults will do, but here are the details: - *What template would you like to use?* — Pick the default: **Tutorial** - *What package manager should we use?* — Pick the default: **npm**, unless you are certain you have **yarn** installed -After we've answered these questions, files will be copied, dependencies installed, and components downloaded. +After answering these questions, files will be copied, dependencies installed, and requirements downloaded. -This will take a few minutes because we're loading some software for our development environment. +This will take a few minutes because the development environment has a number +of dependencies that need to be downloaded. -When it's ready, enter the `tutorial` directory that was just created and run `npm run dev`: +When it's ready, you can enter the `tutorial` directory that was just created and run `npm run dev`: ```sh cd tutorial npm run dev ``` -Or if we chose to use yarn as package manager: +Or if you want to use yarn as package manager: ```sh cd tutorial yarn dev ``` -Now open our browser at http://localhost:8000 +Now open a browser and go to http://localhost:8000 If all goes well, we'll should see this landing page: @@ -48,5 +51,6 @@ If all goes well, we'll should see this landing page: ### Need help? -If you run into any issues, [join our **#development-help** chat room on on -Discord](https://discord.freesewing.org/) and we'll figure it out together. +If you run into any issues, head over to [FreeSewing.org/support](https://next.freesewing.org/support) +which lists the various ways in which you can get help. + diff --git a/markdown/dev/tutorials/pattern-design/our-first-part/en.md b/markdown/dev/tutorials/pattern-design/our-first-part/en.md index 5fe41f5ba9a..7f1ced7e4cb 100644 --- a/markdown/dev/tutorials/pattern-design/our-first-part/en.md +++ b/markdown/dev/tutorials/pattern-design/our-first-part/en.md @@ -1,77 +1,84 @@ --- -title: Our first part +title: Creating a part order: 120 --- Much like garments themselves, patterns are made up of _parts_. Most patterns will have multiple parts. A sleeve, a back part, the collar, and -so on. Our pattern is very simple, and only has one part: the bib. +so on. The pattern you create today is very simple, and only has one part: the bib. -It's a good idea to keep each part in its own file. We don't *have to* do -this, but it's a good habit to get into. When we create more elaborate designs -with multiple parts, keeping each in its own file makes for a more tidy -and approachable code base. + + +It's a good idea to keep each part in its own file. You don't *have to* do +this, but it's a good habit to get into. + + ## bib.mjs -The previous step has already set everything up for us. Our design's main file -lives in `design/src/index.mjs`, and our part lives in `design/src/bib.mjs`. +Since I chose the `tutorial` preset, the development environment is preconfigured for this tutorial. -This `bib.mjs` is where we'll do all our work. The file includes a comments to guide you on how to use it. We removed those for clarity in our example. It currently looks like this: +The design's main file lives in `design/src/index.mjs`, and the bib part lives in `design/src/bib.mjs`. + +This `bib.mjs` is where I will be doing most of the work. +The file that was created includes a lot of comments to provide guidance to those not using this tutorial. +I have removed those comments from the inline examples in this tutorial for clarity in our example. + +The `bib.mjs` file currently looks like this: ```design/src/bib.mjs -import { pluginBundle } from "@freesewing/plugin-bundle" - -function draftBib ({ - part, // Your draft method must return this -}) -{ - // Work your magic here +/* + * This function drafts the part + */ +function draftBib ({ part }) => { return part } -export const bib = { +/* + * This is the part object + */ +export const bib = { name: 'tutorial.bib', - draft: draftBib,[], - from: false, - hide: { - self: false, - from: false, - after: false - }, - options: {}, - measurements: [], - optionalMeasurements: [], - plugins: [ pluginBundle ] + draft: draftBib, } ``` ### The part object -Each part in FreeSewing is an object that describes everything there is to know about the part. +Each part in FreeSewing is an object that describes the part, and has a `draft` +method to do the actual work of drafting the part. The only mandatory keys on a part object are `name` and `draft`. + Refer to [the part reference documentation](/reference/api/part) for all details about configuring the part object + + +A design in FreeSewing is a thin wrapper around a collection of parts. +Each parts stands on its own, and parts from various designs can be combined +to create other designs. + + + #### The part name ```design/src/bib.mjs name: 'tutorial.bib', ``` -A part's `name` should be unique in a pattern. Apart from that, anything goes. -Although we probably want to give it a sensible name. +A part's `name` should be unique in a design. I used `tutorial.bib` as the +name, because that makes sense. -As we can see in the example above, we're using `tutorial.bib` as the name. + - -We **strongly** recommend that you follow this `design.part` naming scheme to avoid -naming conflicts when mixing parts from various designs to create new designs. - +I **strongly** recommend that you apply the same `designName.partName` naming scheme in all your parts. +This avoids naming conflicts when mixing parts from various designs to create a new design. + + #### The part's draft method @@ -81,7 +88,8 @@ naming conflicts when mixing parts from various designs to create new designs. The second mandatory key on the part object is `draft` which should hold the method that drafts the part. -In our example above, it refers to the `draftBib` function we defined at the top of the file. +In the example above, it refers to the `draftBib` function that was defined at the top of the same `bib.mjs` file. + For now this function doesn't do much, but that will change soon enough. @@ -99,56 +107,76 @@ to get started. Or, read on for an explanation of what's going on in the The `index.mjs` file is already complete and we won't be making any changes to -it. But for those who are curious about what's going on inside `index.mjs`, -we're including a version with comments below: +it. But if you are curious about what's going on inside `index.mjs`, +this is all we need: ```design/src/index.mjs -/* - * Import the `Design` constructor - * from the FreeSewing core library - * - * This Design constructor is a method - * (also known as a function) - * that creates a new Design - */ import { Design } from '@freesewing/core' -/* - * Import the `bib` part from the bib.mjs file - * in the same folder as this index.mjs file - * - * This is the part we'll be working on - * in this tutorial - */ import { bib } from './bib.mjs' +import { i18n } from '../i18n/index.mjs' -/* - * Create a new Pattern by passing - * a configuration object - * to the Design constructor - */ -const Pattern = new Design({ - /* - * This `data` key is optional, but we - * typically add a name and version here - */ - data: { - name: "Tutorial", - }, - /* - * This `parts` key is the most important thing - * It holds a list of `parts` for our Design. - * A Pattern/Design is in the end not much more - * than a collection of parts. - */ +const Tutorial = new Design({ parts: [ bib ], }) -/* - * We are exporting our Pattern - * (so others can use it) - * but we also (re-)export our bib part - * this allows others to re-use it - * in their own designs - */ -export { bib, Pattern } +export { bib, Tutorial, i18n } ``` + +If you are familiar with Javascript, I hope you are happy to see that FreeSewing uses ESM modules, and named exports. + +If you are not familiar with Javascript, these `import` statements are how we load code from other files. +There's three of them: + +```design/src/index.mjs +import { Design } from '@freesewing/core' +``` + +This loads the `Design` constructure from FreeSewing's core library. +A constructor is a function that creates something. So the `Design` constructor creates a Design. + +```design/src/index.mjs +import { bib } from './bib.mjs' +``` + +This loads the `bib` part from the `bib.mjs` file in the same folder. +This is what we will be working on. + +```design/src/index.mjs +import { i18n } from '../i18n/index.mjs' +``` + +And this loads something named `i18n` from the `index.mjs` file in the `i18n` +folder that's one level higher. These are the translations. + +I will show you how you can provide translations for your designs towards the +end of this tutorial. + +```design/src/index.mjs +const Tutorial = new Design({ + parts: [ bib ], +}) +``` + +This is where the magic happens. We create a new Design by passing the Design +constructure a configuration object. All it holds is the `parts` key that is +an array of our parts. + +Which goes to show that a design isn't much more than a bunch of parts. + +```design/src/index.mjs +export { bib, Tutorial, i18n } +``` + +And then all that's left to do is export things so that people can use them. +These are named exports. We are exporting three things: + +- `Tutorial` is our complete design. Exporting it means people can use it. +- `bib` is our part. We are exporting it so people can re-use just this part. +- `i18n` are the translations. We are exporting it so people can load them when using our Tutorial. + + + +Refer to [the design reference documentation](/reference/api/design) for +all details about what you can pass to the Design constructor. + + diff --git a/markdown/dev/tutorials/pattern-design/structure/en.md b/markdown/dev/tutorials/pattern-design/structure/en.md index b972cb395ab..6ae2e34aa14 100644 --- a/markdown/dev/tutorials/pattern-design/structure/en.md +++ b/markdown/dev/tutorials/pattern-design/structure/en.md @@ -6,6 +6,9 @@ order: 110 Inside our `tutorial` folder, the `design/src` folder holds the source code for the new pattern we will create. +If you want to support internationalization in your design, your translations +go in the `design/i18n` folder. + We can safely ignore all other files and folders, as they are part of the FreeSewing development environment. So feel free to skip ahead to [Our first part](/tutorials/pattern-design/our-first-part). diff --git a/sites/dev/pages/[...slug].mjs b/sites/dev/pages/[...slug].mjs index dbe61634675..71c5a33a22b 100644 --- a/sites/dev/pages/[...slug].mjs +++ b/sites/dev/pages/[...slug].mjs @@ -99,7 +99,7 @@ export default DocsPage export async function getStaticProps({ params }) { return { props: { - ...(await serverSideTranslations('en', ['docs', ...ns])), + ...(await serverSideTranslations('en', ['docs', 'tutorial', ...ns])), slug: params.slug.join('/'), page: { locale: 'en', diff --git a/sites/shared/components/dynamic-docs/wrapper.mjs b/sites/shared/components/dynamic-docs/wrapper.mjs index da88acbc991..4ec5a95f7e8 100644 --- a/sites/shared/components/dynamic-docs/wrapper.mjs +++ b/sites/shared/components/dynamic-docs/wrapper.mjs @@ -7,7 +7,7 @@ export const MdxWrapper = ({ title = false, path, language, children, noFooter = return ( <> {title ?

{title}

: null} -
{children}
+
{children}
{noFooter ? null : (
{ return ( <> {title ?

{title}

: null} -
+
{children}
{ @@ -59,6 +63,7 @@ const buildPattern = (children, settings = { margin: 5 }, tutorial = false, pape // Handles display of pattern in mormal or xray mode const ShowPattern = ({ renderProps, logs, mode = 'normal' }) => { + const { t } = useTranslation(ns) if (!renderProps) return null if (logs.pattern.error.length > 0 || logs.sets[0].error.length > 0) @@ -68,7 +73,11 @@ const ShowPattern = ({ renderProps, logs, mode = 'normal' }) => {
) - return mode === 'xray' ? : + return mode === 'xray' ? ( + + ) : ( + + ) } // Wrapper component dealing with the tabs and code view