From 18245aec34be1dbe9c64c4aed583f9f718b9bc92 Mon Sep 17 00:00:00 2001 From: anna-puk <100537439+anna-puk@users.noreply.github.com> Date: Sat, 24 Sep 2022 13:12:40 +0200 Subject: [PATCH 01/46] NOT WORKING: restore unice from older commit does not work, but good to have on hand to diff with --- config/software/designs.json | 7 + designs/unice/CHANGELOG.md | 15 + designs/unice/README.md | 284 +++++++++++++++++++ designs/unice/build.mjs | 50 ++++ designs/unice/config/index.js | 62 +++++ designs/unice/data.mjs | 4 + designs/unice/example/.babelrc | 10 + designs/unice/example/README.md | 96 +++++++ designs/unice/example/netlify.toml | 9 + designs/unice/example/package.json | 56 ++++ designs/unice/example/public/favicon.ico | Bin 0 -> 12053 bytes designs/unice/example/public/index.html | 41 +++ designs/unice/example/public/layout.css | 1 + designs/unice/example/public/manifest.json | 15 + designs/unice/example/src/App.js | 45 +++ designs/unice/example/src/index.js | 12 + designs/unice/example/src/layout.css | 273 ++++++++++++++++++ designs/unice/example/src/pattern | 1 + designs/unice/example/src/serviceWorker.js | 123 ++++++++ designs/unice/package.json | 67 +++++ designs/unice/src/back.mjs | 42 +++ designs/unice/src/front.mjs | 309 +++++++++++++++++++++ designs/unice/src/gusset.mjs | 4 + designs/unice/src/index.mjs | 14 + designs/unice/tests/shared.test.mjs | 16 ++ 25 files changed, 1556 insertions(+) create mode 100644 designs/unice/CHANGELOG.md create mode 100644 designs/unice/README.md create mode 100644 designs/unice/build.mjs create mode 100644 designs/unice/config/index.js create mode 100644 designs/unice/data.mjs create mode 100644 designs/unice/example/.babelrc create mode 100644 designs/unice/example/README.md create mode 100644 designs/unice/example/netlify.toml create mode 100644 designs/unice/example/package.json create mode 100644 designs/unice/example/public/favicon.ico create mode 100644 designs/unice/example/public/index.html create mode 100644 designs/unice/example/public/layout.css create mode 100644 designs/unice/example/public/manifest.json create mode 100644 designs/unice/example/src/App.js create mode 100644 designs/unice/example/src/index.js create mode 100644 designs/unice/example/src/layout.css create mode 100644 designs/unice/example/src/pattern create mode 100644 designs/unice/example/src/serviceWorker.js create mode 100644 designs/unice/package.json create mode 100644 designs/unice/src/back.mjs create mode 100644 designs/unice/src/front.mjs create mode 100644 designs/unice/src/gusset.mjs create mode 100644 designs/unice/src/index.mjs create mode 100644 designs/unice/tests/shared.test.mjs diff --git a/config/software/designs.json b/config/software/designs.json index 75abc902887..03ad76be50b 100644 --- a/config/software/designs.json +++ b/config/software/designs.json @@ -284,6 +284,13 @@ "difficulty": 1, "tags": [ "tops", "historic" ] }, + "unice": { + "description": "A FreeSewing pattern for a basic, highly-customizable underwear pattern", + "code": [ "Anna Puk", "Natalia Sayang" ], + "design": [ "Anna Puk", "Natalia Sayang" ], + "difficulty": 1, + "tags": [ "bottoms", "underwear" ] + }, "ursula": { "description": "A FreeSewing pattern for a basic, highly-customizable underwear pattern", "code": "Natalia Sayang", diff --git a/designs/unice/CHANGELOG.md b/designs/unice/CHANGELOG.md new file mode 100644 index 00000000000..6b458471bea --- /dev/null +++ b/designs/unice/CHANGELOG.md @@ -0,0 +1,15 @@ +# Change log for: @freesewing/unice + + +## 2.21.0 (2022-06-27) + +### Added + + - Unice is an underwear pattern + + +This is the **initial release**, and the start of this change log. + +> Prior to version 2, FreeSewing was not a JavaScript project. +> As such, that history is out of scope for this change log. + diff --git a/designs/unice/README.md b/designs/unice/README.md new file mode 100644 index 00000000000..3c02b12a2d2 --- /dev/null +++ b/designs/unice/README.md @@ -0,0 +1,284 @@ + +
+ +# @freesewing/unice + +A FreeSewing pattern for a basic, highly-customizable underwear pattern + + + + +> #### Note: Version 3 is a work in progress +> +> We are working on a new major version (v3) but it is not ready for prime-time. +> For production use, please refer to our v2 packages (the `latest` on NPM) +> or [the `v2` branch in our monorepo](https://github.com/freesewing/freesewing/tree/v2). + +## What am I looking at? π€ + +This repository is our *monorepo* holding all our NPM designs, plugins, other NPM packages, and (web)sites. + +This folder holds: @freesewing/unice + +If you're not entirely sure what to do or how to start, type this command: + +``` +npm run tips +``` + +> If you don't want to set up a dev environment, you can run it in your browser: +> +> [](https://gitpod.io/#https://github.com/freesewing/freesewing) +> +> We recommend that you fork our repository and then +> put `gitpod.io/#
+
+
+FreeSewing v2
+
A JavaScript library for made-to-measure sewing patterns
+ + +# unice example + +This project was bootstrapped with [Create Freesewing Pattern](https://en.freesewing.dev/create-freesewing-pattern): + +```js +npm init freesewing-pattern +``` + +This example folder is part of the local development environment. +It is **not** part of the pattern's source code. + +To run this example, follow these steps: + + - In the folder above this one, run: `yarn start` (or `npm start`) + - Then, in new terminal, run the same command in this folder: `yarn start` (or `npm start`) + +This will spin up the development environment, similar to [our online demo](https://unice.freesewing.dev/). + +## About FreeSewing π€ + +Where the world of makers and developers collide, that's where you'll find FreeSewing. + +Our [core library](https://freesewing.dev/en/freesewing) is a *batteries-included* toolbox +for parametric design of sewing patterns. It's a modular system (check our list +of [plugins](https://freesewing.dev/en/plugins) and getting started is as simple as: + +```bash +npm init freesewing-pattern +``` + +The [getting started] section on [freesewing.dev](https://freesewing.dev/) is a good +entrypoint to our documentation, but you'll find a lot more there, including +our [API documentation](https://freesewing.dev/en/freesewing/api), +as well as [examples](https://freesewing.dev/en/freesewing/examples), +and [best practices](https://freesewing.dev/en/do). + +If you're a maker, checkout [freesewing.org](https://freesewing/) where you can generate +our sewing patterns adapted to your measurements. + +## Support FreeSewing: Become a patron π₯° + +FreeSewing is an open source project run by a community, +and financially supported by our patrons. + +If you feel what we do is worthwhile, you too +should [become a patron](https://freesewing.org/patrons/join). + +## Links π©βπ» + + - π» Makers website: [freesewing.org](https://freesewing.org) + - π» Developers website: [freesewing.dev](https://freesewing.org) + - π¬ Chat: [gitter.im/freesewing](https://gitter.im/freesewing/freesewing) + - π¦ Twitter: [@freesewing_org](https://twitter.com/freesewing_org) + - π· Instagram: [@freesewing_org](https://instagram.com/freesewing_org) + +## License: MIT π€ + +Β© [Joost De Cock](https://github.com/joostdecock). +See [the license file](https://github.com/freesewing/freesewing/blob/develop/LICENSE) for details. + +## Where to get help π€― + +Our [chatroom on Gitter](https://gitter.im) is the best place to ask questions, +share your feedback, or just hang out. + +If you want to report a problem, please [create an issue](https://github.com/freesewing/freesewing/issues/new). + diff --git a/designs/unice/example/netlify.toml b/designs/unice/example/netlify.toml new file mode 100644 index 00000000000..9890e6c62f2 --- /dev/null +++ b/designs/unice/example/netlify.toml @@ -0,0 +1,9 @@ +[build] + base = "designs/unice/example" + publish = "build" + command = "npm run build" + +[[redirects]] + from = "/*" + to = "/index.html" + status = 200 diff --git a/designs/unice/example/package.json b/designs/unice/example/package.json new file mode 100644 index 00000000000..77774ed36a3 --- /dev/null +++ b/designs/unice/example/package.json @@ -0,0 +1,56 @@ +{ + "name": "unice", + "homepage": "https://unice.freesewing.dev/", + "version": "", + "private": true, + "dependencies": { + "@fontsource/permanent-marker": "latest", + "@fontsource/roboto-mono": "latest", + "@fontsource/ubuntu": "latest", + "@freesewing/components": "latest", + "@freesewing/core": "latest", + "@freesewing/css-theme": "latest", + "@freesewing/i18n": "latest", + "@freesewing/models": "latest", + "@freesewing/mui-theme": "latest", + "@freesewing/pattern-info": "latest", + "@freesewing/plugin-bundle": "latest", + "@freesewing/plugin-theme": "latest", + "@freesewing/plugin-i18n": "latest", + "@freesewing/plugin-svgattr": "latest", + "@freesewing/utils": "latest", + "@material-ui/core": "^4.11.4", + "@material-ui/icons": "^4.11.2", + "@material-ui/lab": "^v4.0.0-alpha.57", + "prismjs": "1.25.0", + "react": "^17.0.2", + "react-dom": "^17.0.2", + "react-intl": "^5.18.0", + "react-scripts": "^4.0.3", + "react-error-overlay": "6.0.9", + "file-saver": "^2.0.5", + "react-markdown": "6.0.2", + "source-map-explorer": "^2.5.2" + }, + "scripts": { + "analyze": "source-map-explorer 'build/static/js/*.js'", + "size": "source-map-explorer 'build/static/js/*.js' --tsv --no-root", + "start": "react-scripts start", + "build": "react-scripts build", + "test": "react-scripts test", + "eject": "react-scripts eject" + }, + "eslintConfig": { + "extends": "react-app" + }, + "browserslist": [ + "defaults" + ], + "devDependencies": { + "babel-plugin-prismjs": "2.0.1", + "react-error-overlay": "6.0.9" + }, + "resolutions": { + "react-error-overlay": "6.0.9" + } +} diff --git a/designs/unice/example/public/favicon.ico b/designs/unice/example/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..95061a260f10f9f0fb6464069a6d65df8dc8a471 GIT binary patch literal 12053 zcmZQzU}Ruq00Bk@1&0563=Con3=EwCe(tkhjo&0qbP&{T{4oFDrd{tv?_KCoF_?XOV*C9s`x&0j z-?LEiWWux_nU#D2HiwonsQkUmzo%1DPx0`vbZsHQbuv8dAH4P7aopR()4##@L22XU z3-ueM;(43i{;+P++$*7{7`dR{RHQrCJ-*|*qg?Uw0|t$=S=ttaR<66#{OQ&KW!vTZ zO|GhaU`wkA(9*HCi&y{P%M>4^IjLh^;L9VQ3?5CCJ3im!^0rTGX%!9Z2c%SIwp4TR zxQD!~O^~rrdAi^9QMThR(S|i2=O2=u{!nnA$PM3_UzW@=kzS$XUscA#_WX-IE1&ee zJv{mwJhzHI7VKLx-*Zo<^WpRI)6(}&^Zm`hpERpf{Kla}qFiTK1z+zHuvz`(NBTx4 zj=DSlEydPcNZ9F6{lR#T%m=5nt}#k7HLMq+5+u39Rv1WRt7q;!FBBp0KxIMR8iuB~ ze|FDUx!1YfpXJrbug)uc!*chDUnrG1Q`hi7i=ooKx|daJO6m7@A=U|vI=h}T-B_3@ zGr5H&obd^#PGTdMYTgoc?SK3C9azzz*_eO9v8z?Df$Kqq-cMfLd*<7o9h!A&^})%E zyZF|Kzc|6AFys6G*%1?*x}>Ppw$kzZ0?8jT*Dy3m{*yl6BogIu`mM#{ z1i|?ZikAwTKddp|tZY!hrQrS`TWm?dW2w0bg52v@AGpO}^IUrcbHYRJ2}~2zk9dhK z3V1BJd9rBze9Z#qx?i(*oNH>H)T-~mwSas1e>Wxh1>0sO2-Y8PXZ#Q@vVn Fb`~;aa9CwvR!xfjgo>X`;ZDlU^G>{l9+q ?bW=6%-jJg1_l!Y1hp0B z*7To0ta;LD#yLj|hPKTgT$svLtRg%0AD9??TlUy;xumgp 9^ z=%qdEWJ%L3Q<(kwoG#p+ zSUcL8Zrpu-G;Il+{Oz+Flp`0EKl#78KVI<6=j}B$VJkDDHZpOvF`Z!BsKOn%
WPJeWt z{nwv8+i%y#$^FxA@JpDQ=*XqNu0Vou!n}VwXT7&HcjbCu>Bq*^$8^IxL6JK!Lvii) zU|FpOCf^_B*YDb}hBthFE296=qnBw#W)h##p~IXJPXZWamL)b%tG6?;H@&-PU!&+D zCkX-f2a9z)7PhW=oc}6-anAJr=l3=4e)L&$1y@SfhX&0?@5l*G+_z1lT^`;~5AvVT zTrdClv+?Pe2ImMy7I#J&&P{A$D?TJHIV`ZChhb0pL~jM*u4ODI^A8@bXT1>fAYE)( zz$2x0t_7_Jg3f-wGvWXKx{1X>AMVtDVmfgpMebk$OWlb>B33y?lft^U+QkJk#W`JS zcp4$6a=O($OQumdVu4e;{J~GJQ|7+EP;)+rqmE7F)H4yA-zvMma@*9%EU|jS)SEuz zS!e#nAKz0x9b9@o(bi9TX8Q()>l3d2h;>ZTTE&oms3yWI`Jv|Yhnunm&E L2GjcPIV)(yL{^Y!gEqKoqT%lXML%z9d~FZw{3`xUqDlirKFNAdrf6; zVeGHXyL)qXrp`Hj=gu9TfRgL1_npie7be` Yp{ z?fz6GtD^bRZVf}zVuo1{S}yBe {E`urQYmuNqsf_B6O^U0=+yZ~M<4>w@{^pLnLvZh69|{`v2oqr3D@ ze_uCyOGw-CjZ7SUOcTCu-0my(s-pY%;*FtS4H|1%H|;6-G~vS4|4TJOEPYj1R_wIw z6qvVQ;gc|5<0$SsuN7u4yU@sV!YuOs`YD=xSsx|EB-{O~?u5PJDq~?gEm*NT^xCv# zZFA #?j7&x{)5kM`^PnYzZlaNu C8jllE@v&w12i+HC%W zGsr%ixxD*}pw9;xU(S_x0=_R_w8{Hg-($&Y$Cp1Q&b@a2{S%R|f2E@GUOu)EdtWiV z_xavSjZ71+?>6^2)KM+OTCmHLCBf+0j@jH&KV>&4c}?1R?1M)yQ^pEK&RY3r9ak z&+0Sr4cgkUWLoVu|IkwQr2!LPu37u}L;ioS1y6FUFMO!|l(p^Bkw+(0xE`npKfizU z$9H9cbv|iz-UsczZq{S$bT<%b`0~a7!iOE#8y08887-f{U;ZM{?(YBKLt)+JH~bUU zK9pQ{aKGv4?eDJr*8am 7urew{qod%?_?>p{(Y z5r=LOt%g;zE`P9cy7hC@(arl3jz@Z~>2#g-USjb+<{QkX?rnLm@GO01w@|{){#z1@ z1igcnR#e`&J;SQ+K)31NCt=H)uQV>vtzOFzcH3~Z?Y3?23~df8%)UM+Th@Z1I!mVf z>4`08PMkg+JU=^ENbSzm${S9eHxB0S_!eSpB6oA4lAuk~LWWrxb863LYa9t*dbqj! z`Hoxa>Iut3_V{03=35#*(@S* aS~B-F8g14 zkm<@KfeQiikJP?l=jdZPaqY;h{q4dZcs3On#oVx)+WoBfX_BT>&&rzV+`Q_E{FA<< zTw7Kxc&5tw{`^#-f70uXOi!ktb*ka^Tw!q9_4bCN3JcCQEZur1A@#`yCXPPk4~o7@ zCj>Pv-SqNXwD|G@hE2If*Veecb>bBKuyU47d;NrvB~9z&il_c`ZdFXos!#va^Z0ED z!=w%GY|fU)xcSHYsn4IRbJ}#r_SJt{kH=2Yd+#VSSzqc8v->6{jy|Cs0h=4HALiV0 z=!Tcp(eu;Tk58PNCdupZ@3#ua5s&Wql8@cBHXq#`v#i+3>0+Ky=gIgich85_w+?Ji zEIC%X@O{Vmf45aQS442C8<=>qez1KOUwb~YZC8`^PbmQz)`AsnB1uM*8uuyGo7?bK zGN|7=;TFB-k1$8*x!~Dy_4jfd!|$GW|6S3^;LefTbvuvRR>`w-I>efkvT{$=%nN3` zFt1T^2V2;VEeu8*razMkIwuXTLob+eM>g)h&Hdzk+&Am;d&j=Iw6}W-`IIiPSpDh< zo5Jf0fA35Sd17|reY^4pN#~8eVuza7<{4(axf9Jag4|JEKh;k2kAFi~PFd_iVrS zq#j3m?fa|;4V=Rg^0zTHEo4}7Vb9`|Pp3&|bsVe=wr}N95MN%RlqUP~!l{faD<;kq z+IjiW^Y EI81)HDuLE#S>RF8kBV})s!3Z?^Ku& z>;2j7L+o4Lg~z9_ES}_ECEK_?OYEc59FeChb3QoCdzm8r?0 y$7TwTh3g5rZ}XwZb}Q&kJ*=Js5slE z1_-f(f=1|q=n@a6cD@f0mtQz&&09X};jf7ylYE-qSfsxEbK75=;r`ue95Q>;=Py2a zd%Z!`yWD?$i%qhBr0*(R9k#Y-{$1b6vwXa#@+)=yn5ZJ#sI^dMapdN-EB9TLjro_J z5 mEa=dPSvIB z!gsxKC}lD){bciF9dpMfv$rZfU5)cLE@0l>VDr1u^Aoe3Tjs+PQ8vj7+-~=aIvA{D zbmrmPq@2i9H*b}-v7zYOIaZH_?kWmT*%xHrq|c|Bbaqe5kJ|Rb3x92U_N6?gwDbJ- zD+L1I%mW!t{WAFc!QR)a{k#7J|HQWS8NmUcs`*W(Xxq=wdT!KzMA}2J)sHc{S7bx^ z$)vq6r$27Xnefg`WAjtZTgM&y{(R*8@pf6|+_`S|o+mhKZusIZ(>&+*PO15B>n=Z6 zNc(%og{z@vpFrlJv_zY!C&TY6O-gEw4V<=Uk<#NicRZ$?&pIRM&cc+y8q _v&*B z+^hjt7a3+~e(l}yLg7yX*Tt-Lb4*zOithIHul%u^rD&q^d{?87Vp3*q@%pT-M?QS! zxz;AyX7%L6`qp5(z&E>^+us}u4PXdK655-=F~5uJuI-$hwR>FE7bxy}ugsg|w;@5f zDwuQW*%qD6mbr@q8M-FDa~CqTn7p>Zq;H{f`#Yw{C96&O7I?;4p6zg6bz(_(FQ2w! z*uxNuHvt9vy>F%M-1|MArGMAV#c#uAy#1u|=Z5ZGsk--?Z7~hE&)#dD@%^$+m7tb) zfxprkzrxj?8b-_uok|bXERUEK6gdB&^2ao-D^s{u|NbtTCu8pNVfJF{vs~=buPSG( z&udLy?%MTX=c&f2EsJjQM&{2J`ZMpo;O_hGb0^7ZG%y|BTUWxwx w=^_g8Mn?u`+S6WN7)fdgk z-p8A^dM%G-@8r+o>}$4dc4(~AS<@sFqned4+00?bI@?24%z}G=oMD{*@A|1nA2RN4 z;*p(uELzh$iPdN8jQ7STN)>PR`8Jn!b;SHHDirwh;9J4NhiBcg@(<}`i%iPQ;Jn7$ zRK)Y|Ht+J=D;Io`;(1shuI{uc 8nV*_JAB&HuwW;}6e|a!lO$a>3^r z;uA%S*4t0kSm3{=%0l4ioy&)kW^(^OlQ%0yaQBSlt2bxJSpDQUS)_c?#GSd#I)^K& z>9XTOmS<% ;L{k>kBt` z^Id$d9%ap(ZOEN6OT@ueJS3nlskuvhcg6N;oEkeWx3b&z*ab*!z5gcV*2DCuNE7Y5 zP50Pjb+R~w61B?NxZ0UASosbt;5@1B;aBwfwuIn;^4Uv&Fxo^NwoP0&{buH|#1~>I z*H#zUIhE_H{OpVN2x)B9J;1dfcGAlEb%#Txj6BV5**9>#3pe;$RoVNR{eSD_ZAr>P zOX9y5U)=fAv+M(FJmZ#afgO{xDxB1PjUL2t-1z;sQKnM=x}o&b?f#lp1?+Y$nPQSn zm+ZeJPI~{dJG`r}y`F19=d#(kyEa~0HC4PY8l8xiv)>o1byKdEu< p#zS*dXeV>m0p7;X(A~3j#N{xHr1JKHsye?Cq_YwcEN}HFI`t zaM}9qlj5SwVS*)Ae|BEhb!v{^U9ilLyVrPvkDKg~WBzVk>Gcz=WOyfQ3MFzovHwkB z@O|=5Omiu#OQ!AmBGx4@R~IsUYb&?$c>ldmKKJ@bYwKO*lS`gO`%Icurf`10&B w;71=Bz#*&l>NoRtpTdnV>l N z$Ntl$y(X29RaZ=n@A`e7%h&65)RH7ON6rxU6X|XYqK+XSmM${oepILU>4N0%d#k_S zJNiuK$n>{fCzQ82|Gvxfxj5b;` aH6_GZ$|5 zKD)w&y}?oH{QLJRR-b$w-rsaQVC7=8>5$ToS+*B0q-_qfzOkfhLDQz4zZX1sVzyey ztNVRM!h$VY+q`2W7x8XrZ` dKB&mys^Gp><8 zuCMa4UL>I$&*i *8V| 2TV563XL5+^fvW5FR-fG))#hvSCoS^d)cof2--A=0eEU_BdFxr5PMj`3r=(Q# zLlc{o{buYhKbFl=V_($st=V}+NnML5L+;|c5) E7=u{yF=Cl`ac6 zd})$TtvFe&RK}Z;GD+MZx^!D(Qmxq`u7n*2zb9YI`~6QNZ2!bl7xiP$J^tlU%6aU_ z7t <`HnWrx7XREL= zT+6#=S9Iq7FCBZ5 gE!Dla@85pZ7r&~Iua<4wyu|`?+Rl%zJa?JkC1@A3`scn*g(YhYEaXnd=IwjR zw(obS!XXXS@+&c0Hg5Yp_wb`bwe8<+t~}C8`R)}ep~||Ue_7|Dh7QdJGd};%`d3zV z=-GC?*{rD3Ry1Q$>j}&GSp_0b6`uWTY|Q! ->F 0in8CS;Bh=`kOwq2i1sh-ZgidC>)42MI;FI@J4l`?9Hdz=?oVQvkB1E~@@0yg1 z?^VYmJALO~`Ekc>$(OK$#x>lB#HZfeapGCEos{{j>^<)d^=>Y{rqOzDL*n5J{%)ea z2amj2ain#&dH%Y4#S0F*%DIU=S>86~mS2bF^GW-6OY&V=_T;@^%l`z4pSyWJSe&?D zIJNO&rCQ5xhfQX}6E^L&KAC&J _xq%^6Sf51 zTPU^UYl!KL9@e(Fx2G-^vX~X~9co(mlwajp#l~jVe}csU4NDgKcg82g&p6-e((s;< z-7)r4`S-`?Zd_i#Ab05R{U6``n?fthogRD=yV1N_=-%#LjieyIwf7TPdCDhz(vt0{ zKEC!N>&@TmD;*f`YnzCP+zj}A;N=&scfH!CM ? z1u S?jFS3EcVcIfIcUGsltLS@lS6Yd{Z z*%HEaY+3IT^~0A9ZmxHci7H(^v-$F0W);<`2a+PV?>lm4T9#R^lk1<@`$Dbur{kQK z$RGKpG6JCuK3A_REb@9VMJ1crY=OxS?mv<1o>m^Q;#u-RevKio_Cw#eHJ($~9yz)7 zX5*$6N7`cfPd|*FaU|a2fKL02w+!(+d;Twzej35Q-ov-PrMXaOon*el%>7*Lk0J{E z?O2x@3wb@x+rWKt%16Zy$viGQzT}9^_ JUd&E3e3mGZpC9{|hu4LBMlIB{e zmAUHC^cWe2M87oIUk99|+imwV=RRbASQTOWHqptc |bPkULayd ztz$$KOY0?`a~E%^%t{JpG%3Ak{=q89`?C1?JyO@^+4vmy$oBnp`_eL&4kiPx@AqHq z_h>%K)y(w5>tC%yOLwZo!vG!C0F~1PrIUEV`VZ@0=2kBXW#?KTXZUz-Qn+?;P<{}H z`{qq`pPr^SEnxU&lCorF&40lQalaqeMJ5Iag+ILS{?P7}wBgogb((>9x+i*XFmULa zG4GpoK}OEetwqf1CagZuY0rQCg8#%7CX(U(*C&X7lwpZ_cY61OCA)=W`f3I4U77pm zs^X8Ce7X%fF^!Wdzw;}6S@^L+?2wP<^_(revvvolie2%1SH-Es&OM>jT#|3o^#)G4 zghk$a9y=RfeCx62C+p{}%{jl$w&dkX`aCc_Qu&?R>~czo&OesMUA)UXUTNN7oxNvz z+an!G^>-piHo8B|({FvpxJ3Sb>zwvP0jJD&aop<97+f6A9Tp92Q}TC8c@z 1e$0RgP%zfL^P^&oXmv9yKV^JF=xLxF1cpIKNIs UWs2uf z3^-IE?RQb>&rjK!c;`6<$~G1ELIuwC?C4|32`rmA?K|&PnMu>{F-vBZA7uWs)ia~O z((jX}N5D?b!sp6?63U`prYHSm+5#pjS|0ai-5|kqTjqZ}m+R^x{%OHZo@e&2lHSo| z6RvD=q^q#&TMO$(F0Q5ilj2^#n6`P>eeUvI8-DfizLl9I;4S8N)NWSF0>&F#A_cX1 zUcGj%KTx?NY06}?l;*&{+nGYkS3Pt){^$QzuKHPbV%Z-&KRu!3tFYnC{THXms%IaJ z725u%{&B|LU8cVG{mSId_Xc?ui2J%<^;SM5a9hjO?`+ZG&}=E4rqdnD@5NJi-aTgw z?v1r;-1}JPPupIDD@SAQ38 C!C_xY7f2- z6~D`o-@w?$cQWwEcdd`=T}$`stvw(fd*=1}%v{NL%?370Kl*L&s@Ogwif<>=;WpM) zSEc9wyXE{|R=oJPbw{+)Yk`|gyH>84-MEwO*V`2daSv{0UE2MvH0B%Eofe)8CwxvE zowcKMzec{?B9 bUuhAGlycxQ zn v@8+m)huLtHjd#`3VmP$a_IK5lOEra< h7mmvFL*Eq2a} zG55?)ahb*%@*}*-NV~iB{>NK=WtQLfFYGe@GkMX989cmNqI$u9zdkZKF~`Kg_#`jm z?)UX<>LF^}^+DJ7e3uC+oHaG &+C%Pu{Vqh@1-nReCcC?zgPK+0^t>FW^LN6 z|MF{2PR8-P(!IZ~J-J`k5wc9jurgdK?u++@`i(b#h`+tgJZsj!kOd-sH-#Vjy?lBw zs>~^Wzf18xfwKW6|IL(x_= Q^EI#C48}RLA8ba&4bVPGObA8%;s?Q(42J>+r7TH zbv$8tyME{6e;n_s@41?}?=E{gCFpF+r;xc7tA+pE bA6g zxIg)$akA-uJG)75PPs6CQTzLPh3AzCq73~4@89mt{nqk>$4 W+3Y_3w}PT G(ynT7j?6u{w6~Aqxmb|}GdZud&&jZ%ztXb(( zRxj&V!&1?bs;?aWxNi2j{f|42Cg?~+$#N r2y}Y;zW^ r!w#T1|%YW}bdEUb&N8`^+!PAHPuIwupzLAr}TA(W3 zub|bi?Zt!HFTTuQ;#a<4;=%L}C2J&SaHRfFIs0U-gR|hhQk$l )dn7c7^}E1>iJSIn zREKr_k4q9-X!J-opmyd@{vD4eHLpI9suo+U+J2yM4NJw64_>=YwSCZMQ?+>S-LJNP zpJ&m8E-r&c4gUSD_4y__Tb;iY@^SBXZ*F1bzc@i{#W~IIMfa=Z;`kqJJl|@5-%tB1 z`;9%{9l6CtMN=2d4V~F}&367)J$`w=|5X{$`RxzOi tD(L9 z_gb}G-=^FY`1hXku)hC-{%13EX8bsqBA8 )MoBx=Vw>{ z|Nr3nl=eHH)yf=}r!Rb!aYAIJ`8QVAy;pXXX3sN`EBh8=Hly~ @J z ~XH`lNvm0CREv}ymbSN5U4V Yv?IWylr*tef^N~~#ReoHv#oB0j9eXHv1MP4k);;nE=o^VTWCQsR7=E?De zKj$8{)mXHUC5mg$M1?b(dBU5ba(G={U3stcLGInhvetUN@TqS8oF*+h_uD!?KDP0J z!jq%?|EumNT*|z4>gIR08TA!^m3J6saqzgjTz1thg5lgZt385F+mA(NT>aX4IJjQ; zR>{*1%k6JTs|Y{4n $S&B(y|=;j`TAv|5R%qr Rx)K51L?wEN|=m7Kx#oxM66Dqq~2b$GU_LDPI@ zxfAPUo_y5))AX&Vbcecp{*tm4@4Q_8hIH*tjlX)aRn#%++G@L9uYAfUTyS1r_SjN( zPJ3bS$uAeUbDp)G&ORJ+NBZ?gH?NnS^;R19y=1udc`@3@Z+-a8^zp~-zHQcZimwit z-w0tTGM=Y-*zXMI^Vtu~9l3Y-Pqz42uEhAl@k#RssgE8zUTzZ5thoNnQ`!8fPNVk5 zlNMPI>UdW*zIf{PBmUGRfj>zuMSRKp_Wdb-a+T-py&rJTmfpa`=Q^{X#A5cWbI >cYH!(Oo@r7oBo zA35=+;{&V4^EpCAvn(^8o}a&Z$FGWgl@*%;Q)h6LUp&qF%)-D^+aci7q63mA>{m#I zFH1UfFkJTIckcsNw& MNuez@)M pJ(daEwgPWr2jXx`7~9pWuMSK#*-I{b?$$xT#|c0DxmyEGwVCYxJo0r*K2>= zEL^bKitX*$ES6Zs2~ymeJ*)y1k)7X{9eAXY{LL+=*|>~j5%Zg?&jmdcZ*W&K3J16c zyi7W*->Cdi@n$t2kNZy#yH&GZtun1V ig+nB-T6 z6mfBJ-8l1H@Q!0d#;V2MAE&;EdD8lFw +H`U{_N#p7TJ@*`xr-ky>D){|XNk72#Xb+d%!hPJ=Sxje!uuWF5 zcq+$zHZ4MC(&-1@DH^BP#F7iFypvAv4!CI%^B}CzdV!0aScTVvRGa%HEjH5+Snt33 z`1w`UHz!i&t3SAKI#{jl^Ru&+${#uYD?D7EGv`XW^NW3rAHsfVBsd=C3wgYkJO1EB zg|w%W=ee(0)2y{%omI#Kt}Xhr+f^2Ib#PRxiris3@;l%0KAYvHnaPdrZ`zA;4sN{8 zq2u!Wu*rXhd0);d25=b(=i4rloE+Fttk_{W`@sGKOy`^1ng2WTT0FK|te0q^(>jxh z`(ezTX-rQ8I2rFV`5k3l5Ivv4QC_7$DX6OW@q`CQn%%8*TdNADi7Ijx%sg *PWTszBgHdG*SUBl-B>y|3pIg`5|OrH?hm%q5XuS6t{d%tVBg~@E?TLHem%q;}f cZ65z;e6+jU{sPb0%b+Fjp00i_>zopr0KR{Z`2YX_ literal 0 HcmV?d00001 diff --git a/designs/unice/example/public/index.html b/designs/unice/example/public/index.html new file mode 100644 index 00000000000..af182fd3cc0 --- /dev/null +++ b/designs/unice/example/public/index.html @@ -0,0 +1,41 @@ + + + + + + + + + + + + unice + + + + + + + diff --git a/designs/unice/example/public/layout.css b/designs/unice/example/public/layout.css new file mode 100644 index 00000000000..c62502f9791 --- /dev/null +++ b/designs/unice/example/public/layout.css @@ -0,0 +1 @@ +div.layout-wrapper{width:100%;margin:0;padding:0;background-color:red;background:#f8f9fa;background:linear-gradient(90deg, #f1f3f5 0%, #f1f3f5 25%, #f8f9fa 26%, #f8f9fa 100%)}div.layout-wrapper div.layout{display:flex;max-width:1600px;margin:auto;padding:0;flex-direction:row;flex-wrap:nowrap;justify-content:space-between;background-color:#f8f9fa;min-height:calc(100vh - 64px)}div.layout-wrapper div.layout>aside{width:33%;background:#f1f3f5;border-right:2px solid #dee2e6}div.layout-wrapper div.layout>section{margin:0;padding:1rem}div.layout-wrapper div.layout>section>div.content{max-width:66ch;min-width:340px}div.layout-wrapper div.layout>section>div.content.wide{max-width:100%;margin:auto}.theme-wrapper.dark header{background-color:#1a1d21}.theme-wrapper.dark div.layout-wrapper{background:#f8f9fa;background:linear-gradient(90deg, #1a1d21 0%, #1a1d21 25%, #212529 26%, #212529 100%)}.theme-wrapper.dark div.layout-wrapper div.layout{background-color:#212529}.theme-wrapper.dark div.layout-wrapper div.layout>aside{background-color:#1a1d21;border-right:2px solid #343a40}header a svg{color:#ced4da}header a:first-of-type svg{color:#f8f9fa}header a:hover svg{color:#b197fc}header a span,header button span{color:#ced4da}header a span svg,header button span svg{color:#dee2e6}header a:hover span,header button:hover span{color:#f8f9fa}header a:hover span svg,header button:hover span svg{color:#b197fc}header a,header button{padding:0 1vw !important}@media (min-width: 1200px){div.layout>section{width:63%}}@media (max-width: 1199px) and (min-width: 960px){div.layout>aside{width:298px}div.layout>section{width:calc(100% - 300px - 4rem);max-width:none;margin:0 1rem 0 3rem}}@media (max-width: 959px){div.layout>aside{width:218px}div.layout>section{width:calc(100% - 220px - 4rem);max-width:none;margin:0;padding:0 2rem}div.layout>section div.content{min-width:inherit}}@media (max-width: 599px){div.layout>aside{display:none}div.layout>section{width:calc(100%);margin:0 auto;padding:0 1.5rem;max-width:none}}div.gatsby-highlight{margin-bottom:1rem}@media (max-width: 599px){#mobile-menu{position:fixed;top:0;left:0;width:100%;height:100vh;padding:0 0 1rem;max-width:600px;z-index:-10;transition:opacity 0.25s ease 0s;opacity:0;overflow:scroll}#mobile-menu>ul,#mobile-menu>div{transform:translate(0px, 10px);transition:transform 0.25s ease 0s}.theme-wrapper.show-menu #mobile-menu{opacity:1;z-index:10}.theme-wrapper.show-menu #mobile-menu>div{transform:translate(0px, 0px)}}.theme-wrapper.light div.draft-ui-menu,.theme-wrapper.light div.menu{background:#f1f3f5}.theme-wrapper.dark div.draft-ui-menu,.theme-wrapper.dark div.menu{background:#343a40}.theme-wrapper.show-menu div.menu{opacity:1;z-index:10}.theme-wrapper.show-menu div.menu>div{transform:translate(0px, 0px)}div.spaced-buttons>button{margin:0 0.5rem 0.5rem 0}div.spaced>*{margin:0 0.5rem 0.5rem 0}ul#pre-main-menu{margin:0;padding:0}.boldish{font-weight:500}.freesewing.draft{padding:1rem}li.action{clear:both}li.action span.MuiSwitch-root{float:right}.theme-wrapper.light ul#draft-config li.action.toggle.off,.theme-wrapper.dark ul#draft-config li.action.toggle.off{color:#868e96}.theme-wrapper.light ul#draft-config li.action.toggle.off>span svg,.theme-wrapper.dark ul#draft-config li.action.toggle.off>span svg{color:#868e96}footer{background-color:#1a1d21;color:#adb5bd;padding:3rem 0 6rem}footer a{color:#dee2e6 !important;font-weight:400}footer a:hover{color:#d0bfff !important}footer div.cols{display:flex;flex-direction:row;justify-content:space-between;max-width:1600px;margin:auto;padding:0 1.5rem}footer div.cols>div{min-width:150px;max-width:calc(20% - 4rem);padding:0 2rem 0 0;width:100%}footer ul{text-align:left;font-size:1.1rem;margin:0;padding:0;width:100%}footer ul li:first-of-type{padding:0.35rem 0.75rem}footer ul li{display:block}footer ul li a:hover{text-decoration:none !important}footer ul li.heading{font-weight:bold;border-bottom:3px solid #adb5bd;margin-bottom:0.5rem}@media (min-width: 1200px){footer div.cols>div:last-of-type{min-width:350px}}@media (min-width: 600px) and (max-width: 959px){footer div.cols{flex-wrap:wrap}footer div.cols>div{width:calc(30% - 4rem);padding:0 1rem}}@media (max-width: 599px){footer div.cols{display:block}footer div.cols>div{margin:2rem auto 0;max-width:calc(100% - 4rem)}footer div.cols>div:first-of-type{margin-top:0}} diff --git a/designs/unice/example/public/manifest.json b/designs/unice/example/public/manifest.json new file mode 100644 index 00000000000..578f27ed307 --- /dev/null +++ b/designs/unice/example/public/manifest.json @@ -0,0 +1,15 @@ +{ + "short_name": "unice", + "name": "unice", + "icons": [ + { + "src": "favicon.ico", + "sizes": "64x64 32x32 24x24 16x16", + "type": "image/x-icon" + } + ], + "start_url": ".", + "display": "standalone", + "theme_color": "#000000", + "background_color": "#ffffff" +} diff --git a/designs/unice/example/src/App.js b/designs/unice/example/src/App.js new file mode 100644 index 00000000000..7bb0f0e7112 --- /dev/null +++ b/designs/unice/example/src/App.js @@ -0,0 +1,45 @@ +import React from 'react' +import freesewing from '@freesewing/core' +import Workbench from '@freesewing/components/Workbench' +import '@freesewing/css-theme' +import Pattern from './pattern/src/index.js' +/* + * The following symlink is required to make this import work: + * `root_folder/example/src/pattern => `../../` + * + * Without it, we can't import the pattern as a local file + * since create-react-app does not allow imports outside ./src + * If it's imported as a dependency, webpack will cache the + * build and there will be no hot-reloading of changes + */ + +const App = (props) => { + // You can use this to add translations + /* + let translations = { + JSON: 'JSON', + someOtherString: 'Some other string that needs translation' + } + */ + + // Adds support for loading an external pattern configuration + let recreate = false + if (window) recreate = window.location.pathname.substr(1).split('/') + if (recreate.length === 3 && recreate[0] === 'recreate') { + recreate = { from: recreate[1], id: recreate[2] } + } else { + recreate = false + } + + return ( ++ ) +} + +export default App diff --git a/designs/unice/example/src/index.js b/designs/unice/example/src/index.js new file mode 100644 index 00000000000..24aefad45a1 --- /dev/null +++ b/designs/unice/example/src/index.js @@ -0,0 +1,12 @@ +import React from 'react' +import ReactDOM from 'react-dom' +import App from './App' +import * as serviceWorker from './serviceWorker' +import './layout.css' + +ReactDOM.render( , document.getElementById('root')) + +// If you want your app to work offline and load faster, you can change +// unregister() to register() below. Note this comes with some pitfalls. +// Learn more about service workers: http://bit.ly/CRA-PWA +serviceWorker.unregister() diff --git a/designs/unice/example/src/layout.css b/designs/unice/example/src/layout.css new file mode 100644 index 00000000000..a4963e16e55 --- /dev/null +++ b/designs/unice/example/src/layout.css @@ -0,0 +1,273 @@ +* { + box-sizing: border-box; +} +.MuiToolbar-root { + overflow-y: auto; +} +div.layout-wrapper { + width: 100%; + margin: 0; + padding: 0; + background: #f8f9fa; + background: linear-gradient(90deg, #f1f3f5 0%, #f1f3f5 25%, #f8f9fa 26%, #f8f9fa 100%); +} +div.layout-wrapper div.layout { + display: flex; + max-width: 1600px; + margin: auto; + padding: 0; + flex-direction: row; + flex-wrap: nowrap; + justify-content: space-between; + background-color: #f8f9fa; + min-height: calc(100vh - 64px); +} +div.layout-wrapper div.layout > aside { + width: 33%; + background: #f1f3f5; + border-right: 2px solid #dee2e6; +} +div.layout-wrapper div.layout > section { + margin: 0; + padding: 1rem; +} +div.layout-wrapper div.layout > section > div.content { + max-width: 66ch; + min-width: 340px; +} +div.layout-wrapper div.layout > section > div.content.wide { + max-width: 100%; + margin: auto; +} + +.theme-wrapper.dark header { + background-color: #1a1d21; +} + +.theme-wrapper.dark div.layout-wrapper { + background: #f8f9fa; + background: linear-gradient(90deg, #1a1d21 0%, #1a1d21 25%, #212529 26%, #212529 100%); +} +.theme-wrapper.dark div.layout-wrapper div.layout { + background-color: #212529; +} +.theme-wrapper.dark div.layout-wrapper div.layout > aside { + background-color: #1a1d21; + border-right: 2px solid #343a40; +} + +/* monitor */ +@media (min-width: 1200px) { + div.layout > section { + width: 63%; + } +} + +/* slate */ +@media (max-width: 1199px) and (min-width: 960px) { + div.layout > aside { + width: 298px; + } + div.layout > section { + width: calc(100% - 300px - 4rem); + max-width: none; + margin: 0 1rem 0 3rem; + } +} + +/* tablet */ +@media (max-width: 959px) { + div.layout > aside { + width: 218px; + } + div.layout > section { + width: calc(100% - 220px - 4rem); + max-width: none; + margin: 0; + padding: 0 2rem; + } + div.layout > section div.content { + min-width: inherit; + } +} + +/* mobile */ +@media (max-width: 599px) { + div.layout > aside { + display: none; + } + div.layout > section { + width: calc(100%); + margin: 0 auto; + padding: 0 1.5rem; + max-width: none; + } +} + +div.gatsby-highlight { + margin-bottom: 1rem; +} + +@media (max-width: 599px) { + #mobile-menu { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100vh; + padding: 0 0 1rem; + max-width: 600px; + z-index: -10; + transition: opacity 0.25s ease 0s; + opacity: 0; + overflow: scroll; + } + #mobile-menu > ul, + #mobile-menu > div { + transform: translate(0px, 10px); + transition: transform 0.25s ease 0s; + } + .theme-wrapper.show-menu #mobile-menu { + opacity: 1; + z-index: 10; + } + .theme-wrapper.show-menu #mobile-menu > div { + transform: translate(0px, 0px); + } +} + +.theme-wrapper.light div.draft-ui-menu, +.theme-wrapper.light div.menu { + background: #f1f3f5; +} + +.theme-wrapper.dark div.draft-ui-menu, +.theme-wrapper.dark div.menu { + background: #343a40; +} + +.theme-wrapper.show-menu div.menu { + opacity: 1; + z-index: 10; +} +.theme-wrapper.show-menu div.menu > div { + transform: translate(0px, 0px); +} + +div.spaced-buttons > button { + margin: 0 0.5rem 0.5rem 0; +} + +div.spaced > * { + margin: 0 0.5rem 0.5rem 0; +} + +ul#pre-main-menu { + margin: 0; + padding: 0; +} + +.boldish { + font-weight: 500; +} + +.freesewing.draft { + padding: 1rem; +} + +li.action { + clear: both; +} + +li.action span.MuiSwitch-root { + float: right; +} + +.theme-wrapper.light ul#draft-config li.action.toggle.off, +.theme-wrapper.dark ul#draft-config li.action.toggle.off { + color: #868e96; +} +.theme-wrapper.light ul#draft-config li.action.toggle.off > span svg, +.theme-wrapper.dark ul#draft-config li.action.toggle.off > span svg { + color: #868e96; +} + +footer { + background-color: #1a1d21; + color: #adb5bd; + padding: 3rem 0 6rem; +} +footer a { + color: #dee2e6 !important; + font-weight: 400; +} +footer a:hover { + color: #d0bfff !important; +} +footer div.cols { + display: flex; + flex-direction: row; + justify-content: space-between; + max-width: 1600px; + margin: auto; + padding: 0 1.5rem; +} +footer div.cols > div { + min-width: 150px; + max-width: calc(20% - 4rem); + padding: 0 2rem 0 0; + width: 100%; +} +footer ul { + text-align: left; + font-size: 1.1rem; + margin: 0; + padding: 0; + width: 100%; +} +footer ul li:first-of-type { + padding: 0.35rem 0.75rem; +} +footer ul li { + display: block; +} +footer ul li a:hover { + text-decoration: none !important; +} +footer ul li.heading { + font-weight: bold; + border-bottom: 3px solid #adb5bd; + margin-bottom: 0.5rem; +} + +/* XL screens */ +@media (min-width: 1200px) { + footer div.cols > div:last-of-type { + min-width: 350px; + } +} + +/* SM screens */ +@media (min-width: 600px) and (max-width: 959px) { + footer div.cols { + flex-wrap: wrap; + } + footer div.cols > div { + width: calc(30% - 4rem); + padding: 0 1rem; + } +} + +/* XS screens */ +@media (max-width: 599px) { + footer div.cols { + display: block; + } + footer div.cols > div { + margin: 2rem auto 0; + max-width: calc(100% - 4rem); + } + footer div.cols > div:first-of-type { + margin-top: 0; + } +} diff --git a/designs/unice/example/src/pattern b/designs/unice/example/src/pattern new file mode 100644 index 00000000000..6581736d623 --- /dev/null +++ b/designs/unice/example/src/pattern @@ -0,0 +1 @@ +../../ \ No newline at end of file diff --git a/designs/unice/example/src/serviceWorker.js b/designs/unice/example/src/serviceWorker.js new file mode 100644 index 00000000000..4fe923e7795 --- /dev/null +++ b/designs/unice/example/src/serviceWorker.js @@ -0,0 +1,123 @@ +// In production, we register a service worker to serve assets from local cache. + +// This lets the app load faster on subsequent visits in production, and gives +// it offline capabilities. However, it also means that developers (and users) +// will only see deployed updates on the "N+1" visit to a page, since previously +// cached resources are updated in the background. + +// To learn more about the benefits of this model, read https://goo.gl/KwvDNy. +// This link also includes instructions on opting out of this behavior. + +const isLocalhost = Boolean( + window.location.hostname === 'localhost' || + // [::1] is the IPv6 localhost address. + window.location.hostname === '[::1]' || + // 127.0.0.1/8 is considered localhost for IPv4. + window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/) +) + +export function register(config) { + if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { + // The URL constructor is available in all browsers that support SW. + const publicUrl = new URL(process.env.PUBLIC_URL, window.location) + if (publicUrl.origin !== window.location.origin) { + // Our service worker won't work if PUBLIC_URL is on a different origin + // from what our page is served on. This might happen if a CDN is used to + // serve assets; see https://github.com/facebook/create-react-app/issues/2374 + return + } + + window.addEventListener('load', () => { + const swUrl = `${process.env.PUBLIC_URL}/service-worker.js` + + if (isLocalhost) { + // This is running on localhost. Let's check if a service worker still exists or not. + checkValidServiceWorker(swUrl, config) + + // Add some additional logging to localhost, pointing developers to the + // service worker/PWA documentation. + navigator.serviceWorker.ready.then(() => { + console.log( + 'This web app is being served cache-first by a service ' + + 'worker. To learn more, visit https://goo.gl/SC7cgQ' + ) + }) + } else { + // Is not local host. Just register service worker + registerValidSW(swUrl, config) + } + }) + } +} + +function registerValidSW(swUrl, config) { + navigator.serviceWorker + .register(swUrl) + .then((registration) => { + registration.onupdatefound = () => { + const installingWorker = registration.installing + installingWorker.onstatechange = () => { + if (installingWorker.state === 'installed') { + if (navigator.serviceWorker.controller) { + // At this point, the old content will have been purged and + // the fresh content will have been added to the cache. + // It's the perfect time to display a "New content is + // available; please refresh." message in your web app. + console.log('New content is available; please refresh.') + + // Execute callback + if (config.onUpdate) { + config.onUpdate(registration) + } + } else { + // At this point, everything has been precached. + // It's the perfect time to display a + // "Content is cached for offline use." message. + console.log('Content is cached for offline use.') + + // Execute callback + if (config.onSuccess) { + config.onSuccess(registration) + } + } + } + } + } + }) + .catch((error) => { + console.error('Error during service worker registration:', error) + }) +} + +function checkValidServiceWorker(swUrl, config) { + // Check if the service worker can be found. If it can't reload the page. + fetch(swUrl) + .then((response) => { + // Ensure service worker exists, and that we really are getting a JS file. + if ( + response.status === 404 || + response.headers.get('content-type').indexOf('javascript') === -1 + ) { + // No service worker found. Probably a different app. Reload the page. + navigator.serviceWorker.ready.then((registration) => { + registration.unregister().then(() => { + window.location.reload() + }) + }) + } else { + // Service worker found. Proceed as normal. + registerValidSW(swUrl, config) + } + }) + .catch(() => { + console.log('No internet connection found. App is running in offline mode.') + }) +} + +export function unregister() { + if ('serviceWorker' in navigator) { + navigator.serviceWorker.ready.then((registration) => { + registration.unregister() + }) + } +} diff --git a/designs/unice/package.json b/designs/unice/package.json new file mode 100644 index 00000000000..4c3f21efd5f --- /dev/null +++ b/designs/unice/package.json @@ -0,0 +1,67 @@ +{ + "name": "@freesewing/unice", + "version": "3.0.0-alpha.0", + "description": "A FreeSewing pattern for a basic, highly-customizable underwear pattern", + "author": "Anna Puk (https://github.com/anna-puk)", + "homepage": "https://freesewing.org/", + "repository": "github:freesewing/freesewing", + "license": "MIT", + "bugs": { + "url": "https://github.com/freesewing/freesewing/issues" + }, + "funding": { + "type": "individual", + "url": "https://freesewing.org/patrons/join" + }, + "keywords": [ + "freesewing", + "design", + "diy", + "fashion", + "made to measure", + "parametric design", + "pattern", + "sewing", + "sewing pattern" + ], + "type": "module", + "module": "dist/index.mjs", + "exports": { + ".": "./dist/index.mjs" + }, + "scripts": { + "build": "node build.mjs", + "clean": "rimraf dist", + "mbuild": "NO_MINIFY=1 node build.mjs", + "symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -", + "test": "npx mocha tests/*.test.mjs", + "vbuild": "VERBOSE=1 node build.mjs", + "lab": "cd ../../sites/lab && yarn start", + "tips": "node ../../scripts/help.mjs", + "prettier": "npx prettier --write 'src/*.mjs' 'tests/*.mjs'", + "testci": "npx mocha tests/*.test.mjs --reporter ../../tests/reporters/terse.js", + "cibuild_step5": "node build.mjs" + }, + "peerDependencies": { + "@freesewing/core": "^3.0.0-alpha.0", + "@freesewing/plugin-bundle": "^3.0.0-alpha.0", + "@freesewing/config-helpers": "^3.0.0-alpha.0" + }, + "dependencies": {}, + "devDependencies": { + "mocha": "^10.0.0", + "chai": "^4.2.0" + }, + "files": [ + "dist/*", + "README.md" + ], + "publishConfig": { + "access": "public", + "tag": "next" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=8" + } +} diff --git a/designs/unice/src/back.mjs b/designs/unice/src/back.mjs new file mode 100644 index 00000000000..f2da67d4093 --- /dev/null +++ b/designs/unice/src/back.mjs @@ -0,0 +1,42 @@ +import { pctBasedOn } from '@freesewing/core' +import {back as ursulaBack } from '@freesewing/ursula' + +export const back = { + name: 'unice.back', + measurements: ['waist', 'seat', 'waistToSeat', 'waistToUpperLeg','hips','waistToHips'], + optionalMeasurements: ['crossSeam','crossSeamFront'], + options: { + gussetShift: 0.015, // fraction of seat circumference - could be an advanced option? + gussetWidth: { pct: 7.2, min: 2, max: 12, menu: 'fit' }, // Gusset width in relation to waist-to-upperleg + gussetLength: { pct: 12.7, min: 10, max: 16, menu: 'fit' }, // Gusset length in relation to seat + fabricStretch: { pct: 15, min: 0, max: 100, menu: 'fit' }, // used in Ursula + fabricStretchX: { pct: 15, min: 0, max: 100, menu: 'fit' }, // horizontal stretch (range set wide for beta testing) + fabricStretchY: {pct: 0, min: 0, max: 100, menu: 'fit' }, // vertical stretch (range set wide for beta testing) + rise: { pct: 60, min: 30, max: 100, menu: 'style' }, // extending rise beyond 100% would require adapting paths.sideLeft! + legOpening: { pct: 45, min: 5, max: 85, menu: 'style' }, + frontDip: { pct: 5.0, min: -5, max: 15, menu: 'style' }, + taperToGusset: { pct: 70, min: 5, max: 100, menu: 'style' }, + // booleans + useCrossSeam: { bool: true, menu: 'fit' }, + adjustStretch: {bool: true, menu: 'fit' }, // to not stretch fabric to the limits + }, + draft: ({ + utils, + store, + sa, + Point, + points, + Path, + paths, + Snippet, + snippets, + options, + measurements, + complete, + paperless, + macro, + part, + }) => { + return part + }, +} diff --git a/designs/unice/src/front.mjs b/designs/unice/src/front.mjs new file mode 100644 index 00000000000..c9a160ac812 --- /dev/null +++ b/designs/unice/src/front.mjs @@ -0,0 +1,309 @@ +import { pctBasedOn } from '@freesewing/core' + +export const front = { + name: 'unice.front', + measurements: ['waist', 'seat', 'waistToSeat', 'waistToUpperLeg','hips','waistToHips'], + optionalMeasurements: ['crossSeam','crossSeamFront'], + options: { + gussetShift: 0.015, // fraction of seat circumference - could be an advanced option? + gussetWidth: { pct: 7.2, min: 2, max: 12, menu: 'fit' }, // Gusset width in relation to waist-to-upperleg + gussetLength: { pct: 12.7, min: 10, max: 16, menu: 'fit' }, // Gusset length in relation to seat + fabricStretchX: { pct: 15, min: 0, max: 100, menu: 'fit' }, // horizontal stretch (range set wide for beta testing) + fabricStretchY: {pct: 0, min: 0, max: 100, menu: 'fit' }, // vertical stretch (range set wide for beta testing) + rise: { pct: 60, min: 30, max: 100, menu: 'style' }, // extending rise beyond 100% would require adapting paths.sideLeft! + legOpening: { pct: 45, min: 5, max: 85, menu: 'style' }, + frontDip: { pct: 5.0, min: -5, max: 15, menu: 'style' }, + taperToGusset: { pct: 70, min: 5, max: 100, menu: 'style' }, + // booleans + useCrossSeam: { bool: true, menu: 'fit' }, + adjustStretch: {bool: true, menu: 'fit' }, // to not stretch fabric to the limits + }, + draft: ({ + utils, + store, + sa, + Point, + points, + Path, + paths, + Snippet, + snippets, + options, + measurements, + complete, + paperless, + macro, + part, + }) => { + // Stretch utility method + + // Use stretch inputs to calculate four different scale factors: horizontal/vertical and 'regular'/'reduced', depending on direction of the tension + // xScale: for parts that go across the body (= stretched horizontally) + // xScaleReduced: parts that are not under (horizontal) tension, e.g. the gusset + // yScale: for parts which are stretched vertically but not horizontally (anything below leg opening) + // yScaleReduced: parts which are already under horizontal stretch, which limits vertical stretch + + if (options.adjustStretch) { // roughly 15% of stretch is reserved for comfort + // horizontal: first, 'regular' stretch (for parts that go across the body) + if (options.fabricStretchX < 0.30) { + // subtract 15, but never go below 0 + store.set('xScale', utils.stretchToScale(Math.max(0 , options.fabricStretchX - 0.15))) + } else { + store.set('xScale', utils.stretchToScale(options.fabricStretchX / 2)) + // rough approximation of rule of thumb quoted in Sanne's July 29, 2021 showcase + } + // use half of whatever the regular stretch is (no util available, convert from stretch to fraction manually + store.set('xScaleReduced',(1 + store.get('xScale'))/2) + + // vertical: + if (options.fabricStretchY < 0.30) { + // subtract 15, but never go below 0 + store.set('yScale', utils.stretchToScale(Math.max(0 , options.fabricStretchY - 0.15))) + } else { + store.set('yScale', utils.stretchToScale(options.fabricStretchY / 2)) + // rough approximation of rule of thumb quoted in Sanne's July 29, 2021 showcase + } + // reduced vertical stretch calculated below, same as for non-adjusted case + } else { + // in order: regular, then reduced horizontal stretch, followed by regular vertical stretch + store.set('xScale', utils.stretchToScale(options.fabricStretchX)) + store.set('xScaleReduced', utils.stretchToScale(options.fabricStretchX / 2)) + store.set('yScale', utils.stretchToScale(options.fabricStretchY)) + } + if (options.fabricStretchY < 0.20) { + store.set('yScaleReduced',1) + } else { + // reduced yScale gradually increases from equivalent of stretch 0 to 5%, then cuts off (uses third-order polynomial) + // function to approximate Sanne's guidelines given in Discord (roughly 2.5% for stretch 30-40%, 5% above that) + store.set('yScaleReduced', utils.stretchToScale(Math.min( 0.05, 6.25 * Math.pow(options.fabricStretchY - 0.20, 3)))) + } + + // // temporarily overrule yScale and yScaleReduced + // store.set('yScale',1) + // store.set('yScaleReduced',1) + + + // // Part definition starts here + + // determine height of front part: use cross seam (and cross seam front) if selected and available + // NOTE: neither crossSeam not frontHeight are adjusted for (vertical) stretch + if (options.useCrossSeam && measurements.crossSeam) { + store.set('crossSeam',measurements.crossSeam) + } else { // use original approximation: front and back are roughly waistToUpperLeg high, plus gusset length + store.set('crossSeam',measurements.waistToUpperLeg * (1 + options.backToFrontLength) + options.gussetLength * measurements.seat) + } + // optionally use crossSeamFront to determine relative length of front and back + // this does not account for vertical stretch yet + if (options.useCrossSeam && measurements.crossSeamFront) { // subtract half the gusset length from cross seam front, and an additional 3.5% of the seat circumference to move the gusset upward (to match commercial panties) + store.set('frontHeight',measurements.crossSeamFront - measurements.seat*(0.5*options.gussetLength + options.gussetShift)) + } else { // subtract gusset length, divide by roughly 2 + store.set('frontHeight',(store.get('crossSeam') - options.gussetLength * measurements.seat)/(1 + options.backToFrontLength)) + } + + + // Create points + + // side seam is on a line from upper leg to seat to hips (optional?) to waist + points.frontWaistMid = new Point(measurements.seat / 4, 0) + points.frontWaistLeft = new Point( + measurements.seat / 4 - (measurements.waist / 4) * store.get('xScale'), + 0 + ) + points.frontSeatLeft = new Point( + measurements.seat / 4 - (measurements.seat / 4) * store.get('xScale'), + measurements.waistToSeat * store.get('yScaleReduced') + ) + points.frontUpperLegLeft = new Point( + measurements.seat / 4 - (measurements.seat / 4) * store.get('xScale'), // assume same circ. as seat + measurements.waistToUpperLeg * store.get('yScaleReduced') + ) + points.frontHipLeft = new Point( + measurements.seat / 4 - (measurements.hips / 4) * store.get('xScale'), + measurements.waistToHips * store.get('yScaleReduced') + ) + + // use these points to define an invisible path + paths.sideLeft = new Path() + .move(points.frontUpperLegLeft) + .line(points.frontSeatLeft) + .line(points.frontHipLeft) + .line(points.frontWaistLeft) + .setRender(false) // only show when debugging + + /* Waist band is somewhere on the sideLeft path */ + points.frontWaistBandLeft = paths.sideLeft.shiftFractionAlong(options.rise) + points.frontWaistBandRight = points.frontWaistBandLeft.flipX(points.frontWaistMid) + points.frontWaistBandMid = points.frontWaistBandLeft + .shiftFractionTowards(points.frontWaistBandRight, 0.5) + .shift(270, measurements.waistToUpperLeg * options.frontDip) /* Waist band dip */ + + /* Leg opening is also on the sideLeft path, and cannot be higher than rise */ + /* Minimum side seam length is defined as 3.5% of the sideLeft path (which is at least waistToUpperLeg long) */ + store.set('adjustedLegOpening',Math.min(options.legOpening,options.rise - 0.035)) // TODO: account for rise having a different domain + + points.frontLegOpeningLeft = paths.sideLeft.shiftFractionAlong(store.get('adjustedLegOpening')) + points.frontLegOpeningRight = points.frontLegOpeningLeft.flipX(points.frontWaistMid) // Waist band low point + + // calculate the actual front height, using yScale above and yScaleReduced below leg opening + store.set('frontHeightAbove',points.frontWaistLeft.dy(points.frontLegOpeningLeft)) + + var frontHeightBelow + frontHeightBelow = store.get('yScale')*(store.get('frontHeight') - store.get('frontHeightAbove')/store.get('yScaleReduced')) + + var frontHeightReduced + frontHeightReduced = frontHeightBelow + store.get('frontHeightAbove') + + // gusset width uses modified xScale (barely stretches) and depends on waistToUpperLeg - least sensitive to girth + points.frontGussetLeft = new Point( + measurements.seat / 4 - (measurements.waistToSeat * options.gussetWidth * store.get('xScaleReduced')) * 2.2, + frontHeightReduced + ) + points.frontGussetMid = new Point(measurements.seat / 4, frontHeightReduced) + + /* Flip points to right side */ + points.frontGussetRight = points.frontGussetLeft.flipX(points.frontWaistMid) + points.frontHipRight = points.frontSeatLeft.flipX(points.frontWaistMid) + points.frontWaistRight = points.frontWaistLeft.flipX(points.frontWaistMid) + + /* Middle point for label */ + points.frontMidMid = points.frontLegOpeningLeft.shiftFractionTowards( + points.frontLegOpeningRight, + 0.5 + ) + + // Create control points + + /* Control points for leg opening curves */ + points.frontLegOpeningLeftCp1 = points.frontLegOpeningLeft.shift( + 180, + points.frontGussetLeft.dy(points.frontLegOpeningLeft) / 3 + ) + + /* Control point above gusset moves higher as taperToGusset (= front exposure) increases, but is limited by both the leg opening (allow minimal arching only) and the rise (leg opening must not intersect the waist band) */ + points.frontGussetLeftCp1 = points.frontGussetLeft + .shift(270, Math.max(Math.max(points.frontGussetLeft.dy(points.frontWaistMid) * options.taperToGusset / 2,points.frontGussetLeft.dy(points.frontLegOpeningLeft) * 2),points.frontGussetLeft.dy(points.frontWaistBandMid))) + + /* Control point for waistband dip */ + points.frontWaistBandLeftCp1 = points.frontWaistBandMid.shift(0,points.frontWaistBandMid.dx(points.frontWaistBandLeft) / 3 ) + + + /* Flip control points to right side */ + points.frontGussetRightCp1 = points.frontGussetLeftCp1.flipX(points.frontWaistMid) + points.frontLegOpeningRightCp1 = points.frontLegOpeningLeftCp1.flipX(points.frontWaistMid) + points.frontWaistBandRightCp1 = points.frontWaistBandLeftCp1.flipX(points.frontWaistMid) + + // Draw paths + + paths.seam = new Path() + .move(points.frontWaistBandMid) + .curve(points.frontWaistBandLeftCp1, points.frontWaistBandLeft, points.frontWaistBandLeft) // Waist band dip + .line(points.frontLegOpeningLeft) + .curve(points.frontLegOpeningLeftCp1, points.frontGussetLeftCp1, points.frontGussetLeft) + .line(points.frontGussetMid) + .line(points.frontGussetRight) + .curve(points.frontGussetRightCp1, points.frontLegOpeningRightCp1, points.frontLegOpeningRight) + .line(points.frontWaistBandRight) + .curve(points.frontWaistBandRight, points.frontWaistBandRightCp1, points.frontWaistBandMid) // Waist band dip + .close() + .attr('class', 'fabric') + + // Store points for use in other parts + + /* Store side seam points for use in back */ + + store.set('sideSeamWaist', points.frontWaistBandLeft) + store.set('sideSeamHip', points.frontLegOpeningLeft) + + /* Store gusset points for use in gusset */ + + store.set('frontGussetLeft', points.frontGussetLeft) + store.set('frontGussetRight', points.frontGussetRight) + store.set('frontGussetMid', points.frontGussetMid) + + /* Store lengths for use in elastic */ + + paths.frontLegOpening = new Path() + .move(points.frontGussetRight) + .curve( + points.frontGussetRightCp1, + points.frontLegOpeningRightCp1, + points.frontLegOpeningRight + ) + .setRender(false) + store.set('frontLegOpeningLength',paths.frontLegOpening.length()) + + paths.frontWaistBand = new Path() + .move(points.frontWaistBandRight) + .curve( + points.frontWaistBandRightCp1, + points.frontWaistBandLeftCp1, + points.frontWaistBandLeft + ) + .setRender(false) + store.set('frontWaistBandLength',paths.frontWaistBand.length()) + + // Complete? + if (complete) { + if (sa) { + paths.sa = paths.seam.offset(sa).attr('class', 'fabric sa') + } + } + + macro('title', { + at: points.frontMidMid, + nr: 1, + title: 'front', + }) + + macro('grainline', { + from: points.frontGussetMid, + to: points.frontGussetMid.shiftFractionTowards(points.frontWaistBandMid, 0.5), + }) + + // Paperless? + if (paperless) { + macro('hd', { + from: points.frontWaistBandRight, + to: points.frontWaistBandLeft, + y: points.frontWaistBandRight.y + sa - 15, + }) + macro('hd', { + from: points.frontLegOpeningRight, + to: points.frontLegOpeningLeft, + y: points.frontLegOpeningRight.y + sa - 15, + }) + macro('hd', { + from: points.frontGussetLeft, + to: points.frontGussetRight, + y: points.frontGussetLeft.y + sa + 15, + }) + macro('vd', { + from: points.frontWaistBandMid, + to: points.frontGussetMid, + x: points.frontWaistBandMid.x + sa + 15, + }) + macro('ld', { + from: points.frontWaistBandLeft, + to: points.frontLegOpeningLeft, + d: points.frontWaistBandLeft.y + sa - 15, + }) + macro('pd', { + path: new Path() + .move(points.frontGussetRight) + .curve( + points.frontGussetRightCp1, + points.frontLegOpeningRightCp1, + points.frontLegOpeningRight + ), + d: 15, + }) + /* macro('vd', { + from: points.frontWaistBandLeft, + to: points.frontWaistBandMid, + x: points.frontWaistBandMid.x + sa + 15, + }) */ + } + + return part + }, +} diff --git a/designs/unice/src/gusset.mjs b/designs/unice/src/gusset.mjs new file mode 100644 index 00000000000..39b86acb13d --- /dev/null +++ b/designs/unice/src/gusset.mjs @@ -0,0 +1,4 @@ +const method = part => part + +export default method + diff --git a/designs/unice/src/index.mjs b/designs/unice/src/index.mjs new file mode 100644 index 00000000000..b8c55238e26 --- /dev/null +++ b/designs/unice/src/index.mjs @@ -0,0 +1,14 @@ +import { Design } from '@freesewing/core' +import { front } from './front.mjs' +// import { back } from './back.mjs' +// import { gusset } from './gusset.mjs' +import { data } from '../data.mjs' + +// Setup our new design +const Unice = new Design({ + data, + parts: [front], // parts: [back, front], +}) + +// Named exports +export {front, Unice} // export { back, front, gusset, Unice } \ No newline at end of file diff --git a/designs/unice/tests/shared.test.mjs b/designs/unice/tests/shared.test.mjs new file mode 100644 index 00000000000..13c82f4ee71 --- /dev/null +++ b/designs/unice/tests/shared.test.mjs @@ -0,0 +1,16 @@ +// This file is auto-generated | Any changes you make will be overwritten. +import { Unice } from './dist/index.mjs' + +// Shared tests +import { testPatternConfig } from '../../../tests/designs/config.mjs' +import { testPatternDrafting } from '../../../tests/designs/drafting.mjs' +import { testPatternSampling } from '../../../tests/designs/sampling.mjs' + +// Test config +testPatternConfig(Unice) + +// Test drafting - Change the second parameter to `true` to log errors +testPatternDrafting(Unice, false) + +// Test sampling - Change the second parameter to `true` to log errors +testPatternSampling(Unice, false) From 9e60cf37be5c878ede9082235ab427434e8afcbc Mon Sep 17 00:00:00 2001 From: anna-puk <100537439+anna-puk@users.noreply.github.com> Date: Sat, 24 Sep 2022 16:29:23 +0200 Subject: [PATCH 02/46] restored front, back and gusset elastic and markers for elastic still missing --- designs/unice/src/back.mjs | 275 +++++++++++++++++++++++++++++++++-- designs/unice/src/front.mjs | 9 +- designs/unice/src/gusset.mjs | 117 ++++++++++++++- designs/unice/src/index.mjs | 9 +- 4 files changed, 387 insertions(+), 23 deletions(-) diff --git a/designs/unice/src/back.mjs b/designs/unice/src/back.mjs index f2da67d4093..03aaab2193e 100644 --- a/designs/unice/src/back.mjs +++ b/designs/unice/src/back.mjs @@ -1,25 +1,19 @@ import { pctBasedOn } from '@freesewing/core' -import {back as ursulaBack } from '@freesewing/ursula' +import { back as ursulaBack } from '@freesewing/ursula' +import { front } from './front.mjs' export const back = { name: 'unice.back', measurements: ['waist', 'seat', 'waistToSeat', 'waistToUpperLeg','hips','waistToHips'], optionalMeasurements: ['crossSeam','crossSeamFront'], options: { - gussetShift: 0.015, // fraction of seat circumference - could be an advanced option? - gussetWidth: { pct: 7.2, min: 2, max: 12, menu: 'fit' }, // Gusset width in relation to waist-to-upperleg - gussetLength: { pct: 12.7, min: 10, max: 16, menu: 'fit' }, // Gusset length in relation to seat - fabricStretch: { pct: 15, min: 0, max: 100, menu: 'fit' }, // used in Ursula - fabricStretchX: { pct: 15, min: 0, max: 100, menu: 'fit' }, // horizontal stretch (range set wide for beta testing) - fabricStretchY: {pct: 0, min: 0, max: 100, menu: 'fit' }, // vertical stretch (range set wide for beta testing) - rise: { pct: 60, min: 30, max: 100, menu: 'style' }, // extending rise beyond 100% would require adapting paths.sideLeft! - legOpening: { pct: 45, min: 5, max: 85, menu: 'style' }, - frontDip: { pct: 5.0, min: -5, max: 15, menu: 'style' }, - taperToGusset: { pct: 70, min: 5, max: 100, menu: 'style' }, - // booleans - useCrossSeam: { bool: true, menu: 'fit' }, - adjustStretch: {bool: true, menu: 'fit' }, // to not stretch fabric to the limits + backToFrontLength: 1.15, // Maybe include this in advanced options? + backToFrontWidth: 1.1, // Maybe include this in advanced options? + gussetRatio: 0.7, // Relationship between front and back gusset widths + backDip: { pct: 2.5, min: -5, max: 15, menu: 'style' }, + backExposure: { pct: 20, min: -30, max: 90, menu: 'style' }, }, + after: front, draft: ({ utils, store, @@ -36,7 +30,260 @@ export const back = { paperless, macro, part, + log, }) => { + + // Design pattern here + +log.info('start back') + + // Create points + points.backWaistMid = new Point(measurements.seat / 4, 0) + points.backWaistBandLeft = new Point( + store.get('sideSeamWaist').x / options.backToFrontWidth, + store.get('sideSeamWaist').y + ) + points.backLegOpeningLeft = new Point( + store.get('sideSeamHip').x / options.backToFrontWidth, + store.get('sideSeamHip').y + ) + + // back height is given by (estimated) cross seam, minus front and gusset lengths + // this does not account for vertical stretch yet + const backHeight = store.get('crossSeam') - store.get('frontHeight') - options.gussetLength * measurements.seat + + // calculate the actual back height, using yScale above and yScaleReduced below leg opening + const backHeightAbove = store.get('frontHeightAbove') // part above has same height front and back + + let backHeightBelow + backHeightBelow = store.get('yScale')*(backHeight - backHeightAbove/store.get('yScaleReduced')) + + const backHeightReduced = backHeightBelow + backHeightAbove + + points.backGussetLeft = new Point( + measurements.seat / 4 - + ((measurements.waist * options.gussetWidth * store.get('xScale')) / options.gussetRatio) * + options.backToFrontWidth, + backHeightReduced + ) + points.backGussetMid = new Point( + measurements.seat / 4, + backHeightReduced + ) + + points.backGussetRight = points.backGussetLeft.flipX(points.backWaistMid) + points.backLegOpeningRight = points.backLegOpeningLeft.flipX(points.backWaistMid) + points.backWaistBandRight = points.backWaistBandLeft.flipX(points.backWaistMid) + + points.backWaistBandMid = points.backWaistBandLeft + .shiftFractionTowards(points.backWaistBandRight, 0.5) + .shift(270, measurements.waistToUpperLeg * options.backDip) + + /* Middle point for label */ + points.backMidMid = points.backLegOpeningLeft.shiftFractionTowards( + points.backLegOpeningRight, + 0.5 + ) + + // Create control points + + /* Control point for waistband dip */ + points.backWaistBandLeftCp1 = points.backWaistBandMid.shift(0,points.backWaistBandMid.dx(points.backWaistBandLeft) / 3 ) + + /* Flip points to right side */ + points.backWaistBandRightCp1 = points.backWaistBandLeftCp1.flipX(points.backWaistMid) + + // Shape back coverage + + /* Only have to do this on one side */ + points.backLegOpeningCorner = utils.beamsIntersect( + points.backLegOpeningLeft, + points.backLegOpeningLeft.shift(180, points.backGussetLeft.dy(points.backLegOpeningLeft)), + points.backGussetLeft, + points.backGussetLeft.shift(270, points.backGussetLeft.dy(points.backLegOpeningLeft)) + ) + + if (options.backExposure >= 0) { + /* If back exposure is high, like a thong style */ + /* This controls the hip bit */ + points.backLegOpeningLeftCp1 = points.backLegOpeningLeft.shiftFractionTowards( + points.backLegOpeningCorner, + options.backExposure + ) + /* This controls the center bit */ + points.backGussetLeftCp1 = points.backGussetLeft.shiftFractionTowards( + points.backWaistBandMid, + options.backExposure + ) + points.backGussetLeft = points.backGussetLeft.shiftFractionTowards( + points.backGussetMid, + options.backExposure + ) // This narrows the back of the gusset + points.backGussetRight = points.backGussetLeft.flipX(points.backWaistMid) + } else { + /* If back exposure is low and flares out to cover more */ + store.set('adjustedBackExposure',options.backExposure * store.get('adjustedLegOpening')) // flare depends on leg opening + /* This controls the hip bit */ + points.backLegOpeningLeftCp1 = points.backLegOpeningLeft.shift( + -45,store.get('adjustedBackExposure') * points.backWaistBandMid.dx(points.backWaistBandLeft)) + /* This controls the taper to gusset */ + points.backGussetLeftCp1 = points.backGussetLeft.shift(115, store.get('adjustedBackExposure') * points.backWaistBandMid.dx(points.backWaistBandLeft)) + + /* center of the flare and its control points are on a line parallel to the backGussetLeft to backLegOpeningLeft line + * first, define the points on that line */ + points.backFlare = points.backGussetLeft.shiftFractionTowards(points.backLegOpeningLeft, 0.5) + // points.backFlareCp1 = points.backGussetLeft.shiftFractionTowards(points.backLegOpeningLeft, 0.5 - store.get('adjustedBackExposure')) + points.backFlareCp1 = points.backGussetLeft.shiftFractionTowards(points.backLegOpeningLeft, 0.7) + points.backFlareCp2 = points.backGussetLeft.shiftFractionTowards(points.backLegOpeningLeft, 0.3) + /* then shift all three points outward */ + points.backFlareLeft = points.backFlare.shift( + 215,(points.backWaistBandMid.dx(points.backWaistBandLeft)) * store.get('adjustedBackExposure') * 2 ) + points.backFlareLeftCp1 = points.backFlareCp1.shift( + 215,(points.backWaistBandMid.dx(points.backWaistBandLeft)) * store.get('adjustedBackExposure') * 2 ) + points.backFlareLeftCp2 = points.backFlareCp2.shift( + 215,(points.backWaistBandMid.dx(points.backWaistBandLeft)) * store.get('adjustedBackExposure') * 2 ) + + + /* Flip points to the right */ + + points.backFlareRight = points.backFlareLeft.flipX(points.backWaistBandMid) + points.backFlareRightCp1 = points.backFlareLeftCp1.flipX(points.backWaistMid) + points.backFlareRightCp2 = points.backFlareLeftCp2.flipX(points.backWaistMid) + } + + /* Flip points to the right */ + + points.backLegOpeningRightCp1 = points.backLegOpeningLeftCp1.flipX(points.backWaistMid) + points.backGussetRightCp1 = points.backGussetLeftCp1.flipX(points.backWaistMid) + + // Draw paths + + if (options.backExposure >= 0) { + paths.seam = new Path() + .move(points.backWaistBandMid) + .curve(points.backWaistBandLeftCp1, points.backWaistBandLeft, points.backWaistBandLeft) // Waist band dip + .line(points.backLegOpeningLeft) + .curve(points.backLegOpeningLeftCp1, points.backGussetLeftCp1, points.backGussetLeft) + .line(points.backGussetMid) + .line(points.backGussetRight) + .curve(points.backGussetRightCp1, points.backLegOpeningRightCp1, points.backLegOpeningRight) + .line(points.backWaistBandRight) + .curve(points.backWaistBandRight, points.backWaistBandRightCp1, points.backWaistBandMid) // Waist band dip + .close() + .attr('class', 'fabric') + } else { + paths.seam = new Path() + .move(points.backWaistBandMid) + .curve(points.backWaistBandLeftCp1, points.backWaistBandLeft, points.backWaistBandLeft) // Waist band dip + .line(points.backLegOpeningLeft) + .curve(points.backLegOpeningLeftCp1, points.backFlareLeftCp1, points.backFlareLeft) + .curve(points.backFlareLeftCp2, points.backGussetLeftCp1, points.backGussetLeft) + .line(points.backGussetMid) + .line(points.backGussetRight) + .curve(points.backGussetRightCp1, points.backFlareRightCp2, points.backFlareRight) + .curve(points.backFlareRightCp1, points.backLegOpeningRightCp1, points.backLegOpeningRight) + .line(points.backWaistBandRight) + .curve(points.backWaistBandRight, points.backWaistBandRightCp1, points.backWaistBandMid) // Waist band dip + .close() + .attr('class', 'fabric') + } + + // Store points for use in other parts + + /* Store gusset points for use in gusset */ + + store.set('backGussetLeft', points.backGussetLeft) + store.set('backGussetRight', points.backGussetRight) + + /* Store lengths for use in elastic */ + + paths.backLegOpening = (options.backExposure >= 0) + ? new Path() + .move(points.backGussetRight) + .curve(points.backGussetRightCp1, points.backLegOpeningRightCp1, points.backLegOpeningRight) + .setHidden(true) + : new Path() + .move(points.backGussetRight) + .curve(points.backGussetRightCp1, points.backFlareRightCp2, points.backFlareRight) + .curve(points.backFlareRightCp1, points.backLegOpeningRightCp1, points.backLegOpeningRight) + .setHidden(true) + store.set('backLegOpeningLength',paths.backLegOpening.length()) + + paths.backWaistBand = new Path() + .move(points.backWaistBandRight) + .curve(points.backWaistBandRightCp1, points.backWaistBandLeftCp1, points.backWaistBandLeft) + .setHidden(true) + store.set('backWaistBandLength',paths.backWaistBand.length()) + + // Complete? + if (complete) { + if (sa) { + paths.sa = paths.seam.offset(sa).attr('class', 'fabric sa') + } + } + + macro('title', { + at: points.backMidMid, + nr: 2, + title: 'back', + }) + + macro('grainline', { + from: points.backGussetMid, + to: points.backGussetMid.shiftFractionTowards(points.backWaistBandMid, 0.4), + }) + + points.scaleboxAnchor = points.scalebox = points.backMidMid.shift(90, -50) + macro('miniscale', { at: points.scalebox }) + + // Paperless? + if (paperless) { + macro('hd', { + from: points.backWaistBandRight, + to: points.backWaistBandLeft, + y: points.backWaistBandRight.y + sa - 15, + }) + macro('hd', { + from: points.backLegOpeningRight, + to: points.backLegOpeningLeft, + y: points.backLegOpeningRight.y + sa - 15, + }) + macro('hd', { + from: points.backGussetLeft, + to: points.backGussetRight, + y: points.backGussetLeft.y + sa + 15, + }) + macro('vd', { + from: points.backWaistBandMid, + to: points.backGussetMid, + x: points.backWaistBandMid.x + sa + 15, + }) + if (options.backExposure >= 0) { + macro('pd', { + path: new Path() + .move(points.backGussetRight) + .curve( + points.backGussetRightCp1, + points.backLegOpeningRightCp1, + points.backLegOpeningRight + ), + d: 15, + }) + } else { + macro('pd', { + path: new Path() + .move(points.backGussetRight) + .curve(points.backGussetRightCp1, points.backFlareRightCp2, points.backFlareRight) + .curve( + points.backFlareRightCp1, + points.backLegOpeningRightCp1, + points.backLegOpeningRight + ), + d: 15, + }) + } + } + return part }, } diff --git a/designs/unice/src/front.mjs b/designs/unice/src/front.mjs index c9a160ac812..4dfacef94fe 100644 --- a/designs/unice/src/front.mjs +++ b/designs/unice/src/front.mjs @@ -128,7 +128,7 @@ export const front = { .line(points.frontSeatLeft) .line(points.frontHipLeft) .line(points.frontWaistLeft) - .setRender(false) // only show when debugging + .setHidden(true) // only show when debugging /* Waist band is somewhere on the sideLeft path */ points.frontWaistBandLeft = paths.sideLeft.shiftFractionAlong(options.rise) @@ -165,6 +165,9 @@ export const front = { points.frontHipRight = points.frontSeatLeft.flipX(points.frontWaistMid) points.frontWaistRight = points.frontWaistLeft.flipX(points.frontWaistMid) + console.log('points',points) + + /* Middle point for label */ points.frontMidMid = points.frontLegOpeningLeft.shiftFractionTowards( points.frontLegOpeningRight, @@ -229,7 +232,7 @@ export const front = { points.frontLegOpeningRightCp1, points.frontLegOpeningRight ) - .setRender(false) + .setHidden(true) store.set('frontLegOpeningLength',paths.frontLegOpening.length()) paths.frontWaistBand = new Path() @@ -239,7 +242,7 @@ export const front = { points.frontWaistBandLeftCp1, points.frontWaistBandLeft ) - .setRender(false) + .setHidden(true) store.set('frontWaistBandLength',paths.frontWaistBand.length()) // Complete? diff --git a/designs/unice/src/gusset.mjs b/designs/unice/src/gusset.mjs index 39b86acb13d..54bbeaa0774 100644 --- a/designs/unice/src/gusset.mjs +++ b/designs/unice/src/gusset.mjs @@ -1,4 +1,117 @@ -const method = part => part +import { pctBasedOn } from '@freesewing/core' +import {gusset as ursulaGusset } from '@freesewing/ursula' -export default method +export const gusset = { + name: 'unice.gusset', + measurements: ['waist', 'seat', 'waistToSeat', 'waistToUpperLeg','hips','waistToHips'], + optionalMeasurements: ['crossSeam','crossSeamFront'], + options: { + gussetShift: 0.015, // fraction of seat circumference - could be an advanced option? + gussetWidth: { pct: 7.2, min: 2, max: 12, menu: 'fit' }, // Gusset width in relation to waist-to-upperleg + gussetLength: { pct: 12.7, min: 10, max: 16, menu: 'fit' }, // Gusset length in relation to seat + fabricStretch: { pct: 15, min: 0, max: 100, menu: 'fit' }, // used in Ursula + fabricStretchX: { pct: 15, min: 0, max: 100, menu: 'fit' }, // horizontal stretch (range set wide for beta testing) + fabricStretchY: {pct: 0, min: 0, max: 100, menu: 'fit' }, // vertical stretch (range set wide for beta testing) + rise: { pct: 60, min: 30, max: 100, menu: 'style' }, // extending rise beyond 100% would require adapting paths.sideLeft! + legOpening: { pct: 45, min: 5, max: 85, menu: 'style' }, + frontDip: { pct: 5.0, min: -5, max: 15, menu: 'style' }, + taperToGusset: { pct: 70, min: 5, max: 100, menu: 'style' }, + // booleans + useCrossSeam: { bool: true, menu: 'fit' }, + }, + draft: ({ + utils, + store, + sa, + Point, + points, + Path, + paths, + Snippet, + snippets, + options, + measurements, + complete, + paperless, + macro, + part, + }) => { + // Design pattern here + var yScaleDoubleLayer + yScaleDoubleLayer = (1 + store.get('yScale'))/2 // double layer of fabric stretches half as much + + // Create points + points.frontGussetLeft = new Point(store.get('frontGussetLeft').x, 0) + points.backGussetLeft = new Point( + store.get('backGussetLeft').x, + measurements.seat * options.gussetLength * yScaleDoubleLayer + ) + points.frontGussetRight = new Point(store.get('frontGussetRight').x, 0) + points.backGussetRight = new Point( + store.get('backGussetRight').x, + measurements.seat * options.gussetLength * yScaleDoubleLayer + ) + + // Create control points + points.gussetCp1 = points.frontGussetLeft + .shiftFractionTowards(points.backGussetLeft, 0.5) + .shift(180, points.frontGussetRight.x / -15) + + // Flip points to right side + points.gussetCp2 = points.gussetCp1.flipX(store.get('frontGussetMid')) + + // Create point for title + points.frontMidMid = points.gussetCp1.shiftFractionTowards(points.gussetCp2, 0.5) + + /* Store lengths for use in elastic */ + paths.gussetLegOpening = new Path() + .move(points.backGussetRight) + .curve(points.backGussetRight, points.gussetCp2, points.frontGussetRight) + .setHidden(true) + store.set('gussetSideLength', paths.gussetLegOpening.length()) + + // Draw paths + paths.seam = new Path() + .move(points.frontGussetLeft) + .curve(points.gussetCp1, points.backGussetLeft, points.backGussetLeft) + .line(points.backGussetRight) + .curve(points.backGussetRight, points.gussetCp2, points.frontGussetRight) + .line(points.frontGussetLeft) // Without this, doesn't generate seam allowance + .close() + .attr('class', 'fabric') + + // Complete? + if (complete) { + if (sa) { + paths.sa = paths.seam.offset(sa).attr('class', 'fabric sa') + } + macro('title', { + at: points.frontMidMid, + nr: 3, + title: 'gusset', + }) + } + + // Paperless? + if (paperless) { + macro('hd', { + from: points.frontGussetLeft, + to: points.frontGussetRight, + y: points.frontGussetLeft.y + sa + 15, + }) + macro('hd', { + from: points.backGussetLeft, + to: points.backGussetRight, + y: points.backGussetLeft.y + sa + 15, + }) + macro('vd', { + from: points.frontGussetRight, + to: points.backGussetRight, + x: points.frontGussetRight.x + sa + 15, + }) + } + + return part + }, +} diff --git a/designs/unice/src/index.mjs b/designs/unice/src/index.mjs index b8c55238e26..27909034b88 100644 --- a/designs/unice/src/index.mjs +++ b/designs/unice/src/index.mjs @@ -1,14 +1,15 @@ import { Design } from '@freesewing/core' import { front } from './front.mjs' -// import { back } from './back.mjs' -// import { gusset } from './gusset.mjs' +import { back } from './back.mjs' +import { gusset } from './gusset.mjs' +import { elastic } from '@freesewing/ursula' import { data } from '../data.mjs' // Setup our new design const Unice = new Design({ data, - parts: [front], // parts: [back, front], + parts: [front, back, gusset], }) // Named exports -export {front, Unice} // export { back, front, gusset, Unice } \ No newline at end of file +export {front, back, gusset, Unice} // export { back, front, gusset, Unice } \ No newline at end of file From db44d54efe5ee166a0281e2b19b09415f38f8d71 Mon Sep 17 00:00:00 2001 From: anna-puk <100537439+anna-puk@users.noreply.github.com> Date: Sat, 24 Sep 2022 17:38:02 +0200 Subject: [PATCH 03/46] all four parts are drawn but labels are missing --- designs/unice/src/back.mjs | 1 - designs/unice/src/elastic.mjs | 51 +++++++++++++++++++++++++++++++++++ designs/unice/src/gusset.mjs | 3 ++- designs/unice/src/index.mjs | 6 ++--- 4 files changed, 56 insertions(+), 5 deletions(-) create mode 100644 designs/unice/src/elastic.mjs diff --git a/designs/unice/src/back.mjs b/designs/unice/src/back.mjs index 03aaab2193e..88fe248f125 100644 --- a/designs/unice/src/back.mjs +++ b/designs/unice/src/back.mjs @@ -1,5 +1,4 @@ import { pctBasedOn } from '@freesewing/core' -import { back as ursulaBack } from '@freesewing/ursula' import { front } from './front.mjs' export const back = { diff --git a/designs/unice/src/elastic.mjs b/designs/unice/src/elastic.mjs new file mode 100644 index 00000000000..cba3b134ec6 --- /dev/null +++ b/designs/unice/src/elastic.mjs @@ -0,0 +1,51 @@ +import { gusset } from './gusset.mjs' + +export const elastic = { + name: 'unice.elastic', + options: { + elasticStretch: { pct: 8, min: 5, max: 15, menu: 'fit' }, + }, + after: gusset, + draft: ({ + options, + Point, + points, + store, + utils, + units, + sa, + paperless, + macro, + part, + }) => { + // Stretch utility method + store.set('elasticScale', utils.stretchToScale(options.elasticStretch)) + + // Design pattern here + const legOpeningLength = + store.get('frontLegOpeningLength') + + store.get('backLegOpeningLength') + + store.get('gussetSideLength') + const waistBandLength = store.get('frontWaistBandLength') + store.get('backWaistBandLength') + + points.elasticInfo = new Point(0, 0) + .attr('data-text', 'cutTwoPiecesOfElasticToFinishTheLegOpenings') + .attr('data-text', ':') + .attr('data-text', units(legOpeningLength * store.get('elasticScale') + 2 * sa)) + .attr('data-text', '\n') + .attr('data-text', 'cutOnePieceOfElasticToFinishTheWaistBand') + .attr('data-text', ':') + .attr('data-text', units(waistBandLength * store.get('elasticScale') + 2 * sa)) + + // Paperless? + if (paperless) { + macro('hd', { + from: points.elasticInfo, + to: points.elasticInfo, + y: points.elasticInfo.y + sa + 15, + }) + } + + return part + }, +} diff --git a/designs/unice/src/gusset.mjs b/designs/unice/src/gusset.mjs index 54bbeaa0774..8175482fefb 100644 --- a/designs/unice/src/gusset.mjs +++ b/designs/unice/src/gusset.mjs @@ -1,5 +1,5 @@ import { pctBasedOn } from '@freesewing/core' -import {gusset as ursulaGusset } from '@freesewing/ursula' +import { back } from './back.mjs' export const gusset = { name: 'unice.gusset', @@ -19,6 +19,7 @@ export const gusset = { // booleans useCrossSeam: { bool: true, menu: 'fit' }, }, + after: back, draft: ({ utils, store, diff --git a/designs/unice/src/index.mjs b/designs/unice/src/index.mjs index 27909034b88..7cba0bf4544 100644 --- a/designs/unice/src/index.mjs +++ b/designs/unice/src/index.mjs @@ -2,14 +2,14 @@ import { Design } from '@freesewing/core' import { front } from './front.mjs' import { back } from './back.mjs' import { gusset } from './gusset.mjs' -import { elastic } from '@freesewing/ursula' +import { elastic } from './elastic.mjs' import { data } from '../data.mjs' // Setup our new design const Unice = new Design({ data, - parts: [front, back, gusset], + parts: [front, back, gusset, elastic], }) // Named exports -export {front, back, gusset, Unice} // export { back, front, gusset, Unice } \ No newline at end of file +export {front, back, gusset, elastic, Unice} // export { back, front, gusset, Unice } \ No newline at end of file From 9a0e06890433bb9456ca40ee2e3a4d047af2366b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Sep 2022 04:14:24 +0000 Subject: [PATCH 04/46] chore(deps): bump mongodb-memory-server from 8.9.2 to 8.9.3 Bumps [mongodb-memory-server](https://github.com/nodkz/mongodb-memory-server/tree/HEAD/packages/mongodb-memory-server) from 8.9.2 to 8.9.3. - [Release notes](https://github.com/nodkz/mongodb-memory-server/releases) - [Changelog](https://github.com/nodkz/mongodb-memory-server/blob/master/CHANGELOG.md) - [Commits](https://github.com/nodkz/mongodb-memory-server/commits/v8.9.3/packages/mongodb-memory-server) --- updated-dependencies: - dependency-name: mongodb-memory-server dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- yarn.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/yarn.lock b/yarn.lock index 2a82625508b..1a849c5390c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13455,10 +13455,10 @@ mongodb-connection-string-url@^2.5.3: "@types/whatwg-url" "^8.2.1" whatwg-url "^11.0.0" -mongodb-memory-server-core@8.9.2: - version "8.9.2" - resolved "https://registry.yarnpkg.com/mongodb-memory-server-core/-/mongodb-memory-server-core-8.9.2.tgz#560f8fd358463b606f99164e7557707f6d8d9d52" - integrity sha512-LG8u8QxPGrozy5UBg9YCh8jvvs5Di93zXrusgwgpj+vKxn+Efa6l1pFnCHNy6SYFydFCpMezilsDIXF0tzbJ6A== +mongodb-memory-server-core@8.9.3: + version "8.9.3" + resolved "https://registry.yarnpkg.com/mongodb-memory-server-core/-/mongodb-memory-server-core-8.9.3.tgz#dd9ebf9b8d35c9bb9beacc52fba87e2ca40f3363" + integrity sha512-z/UW/fHTDRA+qvcqBxibTonnwuxRPWsphO9BUGKvFweRxT9uj09/hCK96kjBdF9wQj6k7bj/Tqo9gkGG0XbDng== dependencies: "@types/tmp" "^0.2.3" async-mutex "^0.3.2" @@ -13478,11 +13478,11 @@ mongodb-memory-server-core@8.9.2: yauzl "^2.10.0" mongodb-memory-server@^8.3.0: - version "8.9.2" - resolved "https://registry.yarnpkg.com/mongodb-memory-server/-/mongodb-memory-server-8.9.2.tgz#dc95bc46f7494eae90e757b292300be2d85b4d22" - integrity sha512-h+u+60C/yYZStKqL13O8EerRyt2gdFg9PLyRSBJr5eJfCr+tVMoMrdCw6Dd6PKlCp5hwq27VpjvtSWAT44bHiA== + version "8.9.3" + resolved "https://registry.yarnpkg.com/mongodb-memory-server/-/mongodb-memory-server-8.9.3.tgz#18c23110e0a806ffffcff18e729b35879cd294bb" + integrity sha512-k/1tbGmN6Xegj/XoSA4F/PpKpdRHyT/3HMldhGyiOXx8RNAkJdc/Q9N4+1pCK+HKHMk7BInbo42Bn4OUeAT+hw== dependencies: - mongodb-memory-server-core "8.9.2" + mongodb-memory-server-core "8.9.3" tslib "^2.4.0" mongodb@4.9.1, mongodb@~4.9.0: From 598ed71874797d0e1c01b0c3826d0493b7a8b0b2 Mon Sep 17 00:00:00 2001 From: anna-puk <100537439+anna-puk@users.noreply.github.com> Date: Mon, 26 Sep 2022 23:23:43 +0200 Subject: [PATCH 05/46] updated based on PR feedback --- CHANGELOG.md | 6 + designs/unice/.eslintrc.yml | 18 ++ designs/unice/README.md | 260 ++++++++++---------- designs/unice/build.mjs | 14 -- designs/unice/config/index.js | 62 ----- designs/unice/example/.babelrc | 10 - designs/unice/example/README.md | 96 -------- designs/unice/example/netlify.toml | 9 - designs/unice/example/package.json | 56 ----- designs/unice/example/public/favicon.ico | Bin 12053 -> 0 bytes designs/unice/example/public/index.html | 41 ---- designs/unice/example/public/layout.css | 1 - designs/unice/example/public/manifest.json | 15 -- designs/unice/example/src/App.js | 45 ---- designs/unice/example/src/index.js | 12 - designs/unice/example/src/layout.css | 273 --------------------- designs/unice/example/src/pattern | 1 - designs/unice/example/src/serviceWorker.js | 123 ---------- designs/unice/package.json | 1 + designs/unice/src/back.mjs | 2 - designs/unice/src/elastic.mjs | 17 +- designs/unice/src/front.mjs | 2 + designs/unice/src/index.mjs | 2 +- designs/unice/tests/shared.test.mjs | 6 +- 24 files changed, 173 insertions(+), 899 deletions(-) create mode 100644 designs/unice/.eslintrc.yml delete mode 100644 designs/unice/config/index.js delete mode 100644 designs/unice/example/.babelrc delete mode 100644 designs/unice/example/README.md delete mode 100644 designs/unice/example/netlify.toml delete mode 100644 designs/unice/example/package.json delete mode 100644 designs/unice/example/public/favicon.ico delete mode 100644 designs/unice/example/public/index.html delete mode 100644 designs/unice/example/public/layout.css delete mode 100644 designs/unice/example/public/manifest.json delete mode 100644 designs/unice/example/src/App.js delete mode 100644 designs/unice/example/src/index.js delete mode 100644 designs/unice/example/src/layout.css delete mode 100644 designs/unice/example/src/pattern delete mode 100644 designs/unice/example/src/serviceWorker.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c5c9a62129..105bacdba2e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -649,6 +649,12 @@ - Migrated from Rollup to Esbuild for all builds +### unice + +#### Added + + - Unice is an underwear pattern + ### ursula #### Changed diff --git a/designs/unice/.eslintrc.yml b/designs/unice/.eslintrc.yml new file mode 100644 index 00000000000..b39fd0463e8 --- /dev/null +++ b/designs/unice/.eslintrc.yml @@ -0,0 +1,18 @@ +env: + browser: true + es2021: true +extends: eslint:recommended +overrides: + - files: ["*.yaml", "*.yml"] + plugins: ["yaml"] + extends: ["plugin:yaml/recommended"] +parserOptions: + ecmaVersion: latest + sourceType: module +rules: {} +globals: + it: readonly + describe: readonly + process: readonly + __dirname: readonly + diff --git a/designs/unice/README.md b/designs/unice/README.md index 3c02b12a2d2..6375f82401a 100644 --- a/designs/unice/README.md +++ b/designs/unice/README.md @@ -22,7 +22,7 @@ ![]()
-
--
-FreeSewing v2 -A JavaScript library for made-to-measure sewing patterns
- - -# unice example - -This project was bootstrapped with [Create Freesewing Pattern](https://en.freesewing.dev/create-freesewing-pattern): - -```js -npm init freesewing-pattern -``` - -This example folder is part of the local development environment. -It is **not** part of the pattern's source code. - -To run this example, follow these steps: - - - In the folder above this one, run: `yarn start` (or `npm start`) - - Then, in new terminal, run the same command in this folder: `yarn start` (or `npm start`) - -This will spin up the development environment, similar to [our online demo](https://unice.freesewing.dev/). - -## About FreeSewing π€ - -Where the world of makers and developers collide, that's where you'll find FreeSewing. - -Our [core library](https://freesewing.dev/en/freesewing) is a *batteries-included* toolbox -for parametric design of sewing patterns. It's a modular system (check our list -of [plugins](https://freesewing.dev/en/plugins) and getting started is as simple as: - -```bash -npm init freesewing-pattern -``` - -The [getting started] section on [freesewing.dev](https://freesewing.dev/) is a good -entrypoint to our documentation, but you'll find a lot more there, including -our [API documentation](https://freesewing.dev/en/freesewing/api), -as well as [examples](https://freesewing.dev/en/freesewing/examples), -and [best practices](https://freesewing.dev/en/do). - -If you're a maker, checkout [freesewing.org](https://freesewing/) where you can generate -our sewing patterns adapted to your measurements. - -## Support FreeSewing: Become a patron π₯° - -FreeSewing is an open source project run by a community, -and financially supported by our patrons. - -If you feel what we do is worthwhile, you too -should [become a patron](https://freesewing.org/patrons/join). - -## Links π©βπ» - - - π» Makers website: [freesewing.org](https://freesewing.org) - - π» Developers website: [freesewing.dev](https://freesewing.org) - - π¬ Chat: [gitter.im/freesewing](https://gitter.im/freesewing/freesewing) - - π¦ Twitter: [@freesewing_org](https://twitter.com/freesewing_org) - - π· Instagram: [@freesewing_org](https://instagram.com/freesewing_org) - -## License: MIT π€ - -Β© [Joost De Cock](https://github.com/joostdecock). -See [the license file](https://github.com/freesewing/freesewing/blob/develop/LICENSE) for details. - -## Where to get help π€― - -Our [chatroom on Gitter](https://gitter.im) is the best place to ask questions, -share your feedback, or just hang out. - -If you want to report a problem, please [create an issue](https://github.com/freesewing/freesewing/issues/new). - diff --git a/designs/unice/example/netlify.toml b/designs/unice/example/netlify.toml deleted file mode 100644 index 9890e6c62f2..00000000000 --- a/designs/unice/example/netlify.toml +++ /dev/null @@ -1,9 +0,0 @@ -[build] - base = "designs/unice/example" - publish = "build" - command = "npm run build" - -[[redirects]] - from = "/*" - to = "/index.html" - status = 200 diff --git a/designs/unice/example/package.json b/designs/unice/example/package.json deleted file mode 100644 index 77774ed36a3..00000000000 --- a/designs/unice/example/package.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "name": "unice", - "homepage": "https://unice.freesewing.dev/", - "version": "", - "private": true, - "dependencies": { - "@fontsource/permanent-marker": "latest", - "@fontsource/roboto-mono": "latest", - "@fontsource/ubuntu": "latest", - "@freesewing/components": "latest", - "@freesewing/core": "latest", - "@freesewing/css-theme": "latest", - "@freesewing/i18n": "latest", - "@freesewing/models": "latest", - "@freesewing/mui-theme": "latest", - "@freesewing/pattern-info": "latest", - "@freesewing/plugin-bundle": "latest", - "@freesewing/plugin-theme": "latest", - "@freesewing/plugin-i18n": "latest", - "@freesewing/plugin-svgattr": "latest", - "@freesewing/utils": "latest", - "@material-ui/core": "^4.11.4", - "@material-ui/icons": "^4.11.2", - "@material-ui/lab": "^v4.0.0-alpha.57", - "prismjs": "1.25.0", - "react": "^17.0.2", - "react-dom": "^17.0.2", - "react-intl": "^5.18.0", - "react-scripts": "^4.0.3", - "react-error-overlay": "6.0.9", - "file-saver": "^2.0.5", - "react-markdown": "6.0.2", - "source-map-explorer": "^2.5.2" - }, - "scripts": { - "analyze": "source-map-explorer 'build/static/js/*.js'", - "size": "source-map-explorer 'build/static/js/*.js' --tsv --no-root", - "start": "react-scripts start", - "build": "react-scripts build", - "test": "react-scripts test", - "eject": "react-scripts eject" - }, - "eslintConfig": { - "extends": "react-app" - }, - "browserslist": [ - "defaults" - ], - "devDependencies": { - "babel-plugin-prismjs": "2.0.1", - "react-error-overlay": "6.0.9" - }, - "resolutions": { - "react-error-overlay": "6.0.9" - } -} diff --git a/designs/unice/example/public/favicon.ico b/designs/unice/example/public/favicon.ico deleted file mode 100644 index 95061a260f10f9f0fb6464069a6d65df8dc8a471..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12053 zcmZQzU}Ruq00Bk@1&0563=Con3=EwCe(tgbC?LeQ2nsxfK}sMrrE6L9$cQ!&TshX)29^&uC!fvqkJK9 zLAyhI<7ZYjju^#)tp`GxrgMKezW?O;FCrE(3z+?`yZx}M{FU}gGv~;W^?mp6`ajTY zlxOu)_+kC=zxkt?6(1{)d@Gs46zQK}-)P5V&b>#&AUL7%fK;O{lQoN02gA&TO!Mz* zeb{}VsPR2Z8pj^h4?PF&GF|7G!+TW8_tRe1Zz35A0l}Kx({!W%t(>95vUin(ZevVi z8IwBaotFDwyB%gelibe9bNv0o-UG_h)IP>B?PZk{`yrE7IFpz0yU^4Cu}dQHx*I$m zWH >COxSYZFH^ZghUzajYmPZu2CUEioSWeom;A2j>R~>6xs8@z zpZ@*9(YT#;+wqVOPfZsJKWj2)>%TGMw ydO;KZpPBpMpt28_gV^3ZM-IK= zGEy#@b)fT 3tGCiQYg6o07luMfq{F)x1;@!)yr=ydidO-Pav&!EqF1 ~?X*k&UB=FAssSNz~{(tW} zrf%(I)tfM*-9;yi$;L*!Zf5T{KJgzca+6}dYJ@S_>=F8>b;9%i#8z#Sh!b87?c#^@ zrDI~aqqN1=e28SKk$o_6%Srv)1-2*S{$2RZa>MY%;f)_oADPE5n3UwmWv;T{K~bAg z&hOoC`;8A=xHj=0mRrM65y4qsT5|JmFRR+5lTM2tUVg}X{;~Wa{pv4wyVS&V3@*BG z-db)fYuUg5>&wY^ij{LqHm0`7zrOHq&R<5IKf8^7&+E-RK5s`7pOtCqlc!HN8XURt zCcmTZ` PTJ70WChPq9_}00=E}r#~=ATIpj||VfeD34eXtsvsk?NnD zE1qd5GbV7@^nTFi_TXuWSNj=rbW1D`^V$ggZA^>w{|MFYNMv_zez{6svHt~Ey?W!( zJvSw#rYJK{S=-Q|#ckhjo&0qbP&{T{4oFDrd{tv?_KCoF_?XOV*C9s`x&0j z-?LEiWWux_nU#D2HiwonsQkUmzo%1DPx0`vbZsHQbuv8dAH4P7aopR()4##@L22XU z3-ueM;(43i{;+P++$*7{7`dR{RHQrCJ-*|*qg?Uw0|t$=S=ttaR<66#{OQ&KW!vTZ zO|GhaU`wkA(9*HCi&y{P%M>4^IjLh^;L9VQ3?5CCJ3im!^0rTGX%!9Z2c%SIwp4TR zxQD!~O^~rrdAi^9QMThR(S|i2=O2=u{!nnA$PM3_UzW@=kzS$XUscA#_WX-IE1&ee zJv{mwJhzHI7VKLx-*Zo<^WpRI)6(}&^Zm`hpERpf{Kla}qFiTK1z+zHuvz`(NBTx4 zj=DSlEydPcNZ9F6{lR#T%m=5nt}#k7HLMq+5+u39Rv1WRt7q;!FBBp0KxIMR8iuB~ ze|FDUx!1YfpXJrbug)uc!*chDUnrG1Q`hi7i=ooKx|daJO6m7@A=U|vI=h}T-B_3@ zGr5H&obd^#PGTdMYTgoc?SK3C9azzz*_eO9v8z?Df$Kqq-cMfLd*<7o9h!A&^})%E zyZF|Kzc|6AFys6G*%1?*x}>Ppw$kzZ0?8jT*Dy3m{*yl6BogIu`mM#{ z1i|?ZikAwTKddp|tZY!hrQrS`TWm?dW2w0bg52v@AGpO}^IUrcbHYRJ2}~2zk9dhK z3V1BJd9rBze9Z#qx?i(*oNH>H)T-~mwSas1e>Wxh1>0sO2-Y8PXZ#Q@vVn Fb`~;aa9CwvR!xfjgo>X`;ZDlU^G>{l9+q ?bW=6%-jJg1_l!Y1hp0B z*7To0ta;LD#yLj|hPKTgT$svLtRg%0AD9??TlUy;xumgp 9^ z=%qdEWJ%L3Q<(kwoG#p+ zSUcL8Zrpu-G;Il+{Oz+Flp`0EKl#78KVI<6=j}B$VJkDDHZpOvF`Z!BsKOn%
WPJeWt z{nwv8+i%y#$^FxA@JpDQ=*XqNu0Vou!n}VwXT7&HcjbCu>Bq*^$8^IxL6JK!Lvii) zU|FpOCf^_B*YDb}hBthFE296=qnBw#W)h##p~IXJPXZWamL)b%tG6?;H@&-PU!&+D zCkX-f2a9z)7PhW=oc}6-anAJr=l3=4e)L&$1y@SfhX&0?@5l*G+_z1lT^`;~5AvVT zTrdClv+?Pe2ImMy7I#J&&P{A$D?TJHIV`ZChhb0pL~jM*u4ODI^A8@bXT1>fAYE)( zz$2x0t_7_Jg3f-wGvWXKx{1X>AMVtDVmfgpMebk$OWlb>B33y?lft^U+QkJk#W`JS zcp4$6a=O($OQumdVu4e;{J~GJQ|7+EP;)+rqmE7F)H4yA-zvMma@*9%EU|jS)SEuz zS!e#nAKz0x9b9@o(bi9TX8Q()>l3d2h;>ZTTE&oms3yWI`Jv|Yhnunm&E L2GjcPIV)(yL{^Y!gEqKoqT%lXML%z9d~FZw{3`xUqDlirKFNAdrf6; zVeGHXyL)qXrp`Hj=gu9TfRgL1_npie7be` Yp{ z?fz6GtD^bRZVf}zVuo1{S}yBe {E`urQYmuNqsf_B6O^U0=+yZ~M<4>w@{^pLnLvZh69|{`v2oqr3D@ ze_uCyOGw-CjZ7SUOcTCu-0my(s-pY%;*FtS4H|1%H|;6-G~vS4|4TJOEPYj1R_wIw z6qvVQ;gc|5<0$SsuN7u4yU@sV!YuOs`YD=xSsx|EB-{O~?u5PJDq~?gEm*NT^xCv# zZFA #?j7&x{)5kM`^PnYzZlaNu C8jllE@v&w12i+HC%W zGsr%ixxD*}pw9;xU(S_x0=_R_w8{Hg-($&Y$Cp1Q&b@a2{S%R|f2E@GUOu)EdtWiV z_xavSjZ71+?>6^2)KM+OTCmHLCBf+0j@jH&KV>&4c}?1R?1M)yQ^pEK&RY3r9ak z&+0Sr4cgkUWLoVu|IkwQr2!LPu37u}L;ioS1y6FUFMO!|l(p^Bkw+(0xE`npKfizU z$9H9cbv|iz-UsczZq{S$bT<%b`0~a7!iOE#8y08887-f{U;ZM{?(YBKLt)+JH~bUU zK9pQ{aKGv4?eDJr*8am 7urew{qod%?_?>p{(Y z5r=LOt%g;zE`P9cy7hC@(arl3jz@Z~>2#g-USjb+<{QkX?rnLm@GO01w@|{){#z1@ z1igcnR#e`&J;SQ+K)31NCt=H)uQV>vtzOFzcH3~Z?Y3?23~df8%)UM+Th@Z1I!mVf z>4`08PMkg+JU=^ENbSzm${S9eHxB0S_!eSpB6oA4lAuk~LWWrxb863LYa9t*dbqj! z`Hoxa>Iut3_V{03=35#*(@S* aS~B-F8g14 zkm<@KfeQiikJP?l=jdZPaqY;h{q4dZcs3On#oVx)+WoBfX_BT>&&rzV+`Q_E{FA<< zTw7Kxc&5tw{`^#-f70uXOi!ktb*ka^Tw!q9_4bCN3JcCQEZur1A@#`yCXPPk4~o7@ zCj>Pv-SqNXwD|G@hE2If*Veecb>bBKuyU47d;NrvB~9z&il_c`ZdFXos!#va^Z0ED z!=w%GY|fU)xcSHYsn4IRbJ}#r_SJt{kH=2Yd+#VSSzqc8v->6{jy|Cs0h=4HALiV0 z=!Tcp(eu;Tk58PNCdupZ@3#ua5s&Wql8@cBHXq#`v#i+3>0+Ky=gIgich85_w+?Ji zEIC%X@O{Vmf45aQS442C8<=>qez1KOUwb~YZC8`^PbmQz)`AsnB1uM*8uuyGo7?bK zGN|7=;TFB-k1$8*x!~Dy_4jfd!|$GW|6S3^;LefTbvuvRR>`w-I>efkvT{$=%nN3` zFt1T^2V2;VEeu8*razMkIwuXTLob+eM>g)h&Hdzk+&Am;d&j=Iw6}W-`IIiPSpDh< zo5Jf0fA35Sd17|reY^4pN#~8eVuza7<{4(axf9Jag4|JEKh;k2kAFi~PFd_iVrS zq#j3m?fa|;4V=Rg^0zTHEo4}7Vb9`|Pp3&|bsVe=wr}N95MN%RlqUP~!l{faD<;kq z+IjiW^Y EI81)HDuLE#S>RF8kBV})s!3Z?^Ku& z>;2j7L+o4Lg~z9_ES}_ECEK_?OYEc59FeChb3QoCdzm8r?0 y$7TwTh3g5rZ}XwZb}Q&kJ*=Js5slE z1_-f(f=1|q=n@a6cD@f0mtQz&&09X};jf7ylYE-qSfsxEbK75=;r`ue95Q>;=Py2a zd%Z!`yWD?$i%qhBr0*(R9k#Y-{$1b6vwXa#@+)=yn5ZJ#sI^dMapdN-EB9TLjro_J z5 mEa=dPSvIB z!gsxKC}lD){bciF9dpMfv$rZfU5)cLE@0l>VDr1u^Aoe3Tjs+PQ8vj7+-~=aIvA{D zbmrmPq@2i9H*b}-v7zYOIaZH_?kWmT*%xHrq|c|Bbaqe5kJ|Rb3x92U_N6?gwDbJ- zD+L1I%mW!t{WAFc!QR)a{k#7J|HQWS8NmUcs`*W(Xxq=wdT!KzMA}2J)sHc{S7bx^ z$)vq6r$27Xnefg`WAjtZTgM&y{(R*8@pf6|+_`S|o+mhKZusIZ(>&+*PO15B>n=Z6 zNc(%og{z@vpFrlJv_zY!C&TY6O-gEw4V<=Uk<#NicRZ$?&pIRM&cc+y8q _v&*B z+^hjt7a3+~e(l}yLg7yX*Tt-Lb4*zOithIHul%u^rD&q^d{?87Vp3*q@%pT-M?QS! zxz;AyX7%L6`qp5(z&E>^+us}u4PXdK655-=F~5uJuI-$hwR>FE7bxy}ugsg|w;@5f zDwuQW*%qD6mbr@q8M-FDa~CqTn7p>Zq;H{f`#Yw{C96&O7I?;4p6zg6bz(_(FQ2w! z*uxNuHvt9vy>F%M-1|MArGMAV#c#uAy#1u|=Z5ZGsk--?Z7~hE&)#dD@%^$+m7tb) zfxprkzrxj?8b-_uok|bXERUEK6gdB&^2ao-D^s{u|NbtTCu8pNVfJF{vs~=buPSG( z&udLy?%MTX=c&f2EsJjQM&{2J`ZMpo;O_hGb0^7ZG%y|BTUWxwx w=^_g8Mn?u`+S6WN7)fdgk z-p8A^dM%G-@8r+o>}$4dc4(~AS<@sFqned4+00?bI@?24%z}G=oMD{*@A|1nA2RN4 z;*p(uELzh$iPdN8jQ7STN)>PR`8Jn!b;SHHDirwh;9J4NhiBcg@(<}`i%iPQ;Jn7$ zRK)Y|Ht+J=D;Io`;(1shuI{uc 8nV*_JAB&HuwW;}6e|a!lO$a>3^r z;uA%S*4t0kSm3{=%0l4ioy&)kW^(^OlQ%0yaQBSlt2bxJSpDQUS)_c?#GSd#I)^K& z>9XTOmS<% ;L{k>kBt` z^Id$d9%ap(ZOEN6OT@ueJS3nlskuvhcg6N;oEkeWx3b&z*ab*!z5gcV*2DCuNE7Y5 zP50Pjb+R~w61B?NxZ0UASosbt;5@1B;aBwfwuIn;^4Uv&Fxo^NwoP0&{buH|#1~>I z*H#zUIhE_H{OpVN2x)B9J;1dfcGAlEb%#Txj6BV5**9>#3pe;$RoVNR{eSD_ZAr>P zOX9y5U)=fAv+M(FJmZ#afgO{xDxB1PjUL2t-1z;sQKnM=x}o&b?f#lp1?+Y$nPQSn zm+ZeJPI~{dJG`r}y`F19=d#(kyEa~0HC4PY8l8xiv)>o1byKdEu< p#zS*dXeV>m0p7;X(A~3j#N{xHr1JKHsye?Cq_YwcEN}HFI`t zaM}9qlj5SwVS*)Ae|BEhb!v{^U9ilLyVrPvkDKg~WBzVk>Gcz=WOyfQ3MFzovHwkB z@O|=5Omiu#OQ!AmBGx4@R~IsUYb&?$c>ldmKKJ@bYwKO*lS`gO`%Icurf`10&B w;71=Bz#*&l>NoRtpTdnV>l N z$Ntl$y(X29RaZ=n@A`e7%h&65)RH7ON6rxU6X|XYqK+XSmM${oepILU>4N0%d#k_S zJNiuK$n>{fCzQ82|Gvxfxj5b;` aH6_GZ$|5 zKD)w&y}?oH{QLJRR-b$w-rsaQVC7=8>5$ToS+*B0q-_qfzOkfhLDQz4zZX1sVzyey ztNVRM!h$VY+q`2W7x8XrZ` dKB&mys^Gp><8 zuCMa4UL>I$&*i *8V| 2TV563XL5+^fvW5FR-fG))#hvSCoS^d)cof2--A=0eEU_BdFxr5PMj`3r=(Q# zLlc{o{buYhKbFl=V_($st=V}+NnML5L+;|c5) E7=u{yF=Cl`ac6 zd})$TtvFe&RK}Z;GD+MZx^!D(Qmxq`u7n*2zb9YI`~6QNZ2!bl7xiP$J^tlU%6aU_ z7t <`HnWrx7XREL= zT+6#=S9Iq7FCBZ5 gE!Dla@85pZ7r&~Iua<4wyu|`?+Rl%zJa?JkC1@A3`scn*g(YhYEaXnd=IwjR zw(obS!XXXS@+&c0Hg5Yp_wb`bwe8<+t~}C8`R)}ep~||Ue_7|Dh7QdJGd};%`d3zV z=-GC?*{rD3Ry1Q$>j}&GSp_0b6`uWTY|Q! ->F 0in8CS;Bh=`kOwq2i1sh-ZgidC>)42MI;FI@J4l`?9Hdz=?oVQvkB1E~@@0yg1 z?^VYmJALO~`Ekc>$(OK$#x>lB#HZfeapGCEos{{j>^<)d^=>Y{rqOzDL*n5J{%)ea z2amj2ain#&dH%Y4#S0F*%DIU=S>86~mS2bF^GW-6OY&V=_T;@^%l`z4pSyWJSe&?D zIJNO&rCQ5xhfQX}6E^L&KAC&J _xq%^6Sf51 zTPU^UYl!KL9@e(Fx2G-^vX~X~9co(mlwajp#l~jVe}csU4NDgKcg82g&p6-e((s;< z-7)r4`S-`?Zd_i#Ab05R{U6``n?fthogRD=yV1N_=-%#LjieyIwf7TPdCDhz(vt0{ zKEC!N>&@TmD;*f`YnzCP+zj}A;N=&scfH!CM ? z1u S?jFS3EcVcIfIcUGsltLS@lS6Yd{Z z*%HEaY+3IT^~0A9ZmxHci7H(^v-$F0W);<`2a+PV?>lm4T9#R^lk1<@`$Dbur{kQK z$RGKpG6JCuK3A_REb@9VMJ1crY=OxS?mv<1o>m^Q;#u-RevKio_Cw#eHJ($~9yz)7 zX5*$6N7`cfPd|*FaU|a2fKL02w+!(+d;Twzej35Q-ov-PrMXaOon*el%>7*Lk0J{E z?O2x@3wb@x+rWKt%16Zy$viGQzT}9^_ JUd&E3e3mGZpC9{|hu4LBMlIB{e zmAUHC^cWe2M87oIUk99|+imwV=RRbASQTOWHqptc |bPkULayd ztz$$KOY0?`a~E%^%t{JpG%3Ak{=q89`?C1?JyO@^+4vmy$oBnp`_eL&4kiPx@AqHq z_h>%K)y(w5>tC%yOLwZo!vG!C0F~1PrIUEV`VZ@0=2kBXW#?KTXZUz-Qn+?;P<{}H z`{qq`pPr^SEnxU&lCorF&40lQalaqeMJ5Iag+ILS{?P7}wBgogb((>9x+i*XFmULa zG4GpoK}OEetwqf1CagZuY0rQCg8#%7CX(U(*C&X7lwpZ_cY61OCA)=W`f3I4U77pm zs^X8Ce7X%fF^!Wdzw;}6S@^L+?2wP<^_(revvvolie2%1SH-Es&OM>jT#|3o^#)G4 zghk$a9y=RfeCx62C+p{}%{jl$w&dkX`aCc_Qu&?R>~czo&OesMUA)UXUTNN7oxNvz z+an!G^>-piHo8B|({FvpxJ3Sb>zwvP0jJD&aop<97+f6A9Tp92Q}TC8c@z 1e$0RgP%zfL^P^&oXmv9yKV^JF=xLxF1cpIKNIs UWs2uf z3^-IE?RQb>&rjK!c;`6<$~G1ELIuwC?C4|32`rmA?K|&PnMu>{F-vBZA7uWs)ia~O z((jX}N5D?b!sp6?63U`prYHSm+5#pjS|0ai-5|kqTjqZ}m+R^x{%OHZo@e&2lHSo| z6RvD=q^q#&TMO$(F0Q5ilj2^#n6`P>eeUvI8-DfizLl9I;4S8N)NWSF0>&F#A_cX1 zUcGj%KTx?NY06}?l;*&{+nGYkS3Pt){^$QzuKHPbV%Z-&KRu!3tFYnC{THXms%IaJ z725u%{&B|LU8cVG{mSId_Xc?ui2J%<^;SM5a9hjO?`+ZG&}=E4rqdnD@5NJi-aTgw z?v1r;-1}JPPupIDD@SAQ38 C!C_xY7f2- z6~D`o-@w?$cQWwEcdd`=T}$`stvw(fd*=1}%v{NL%?370Kl*L&s@Ogwif<>=;WpM) zSEc9wyXE{|R=oJPbw{+)Yk`|gyH>84-MEwO*V`2daSv{0UE2MvH0B%Eofe)8CwxvE zowcKMzec{?B9 bUuhAGlycxQ zn v@8+m)huLtHjd#`3VmP$a_IK5lOEra< h7mmvFL*Eq2a} zG55?)ahb*%@*}*-NV~iB{>NK=WtQLfFYGe@GkMX989cmNqI$u9zdkZKF~`Kg_#`jm z?)UX<>LF^}^+DJ7e3uC+oHaG &+C%Pu{Vqh@1-nReCcC?zgPK+0^t>FW^LN6 z|MF{2PR8-P(!IZ~J-J`k5wc9jurgdK?u++@`i(b#h`+tgJZsj!kOd-sH-#Vjy?lBw zs>~^Wzf18xfwKW6|IL(x_= Q^EI#C48}RLA8ba&4bVPGObA8%;s?Q(42J>+r7TH zbv$8tyME{6e;n_s@41?}?=E{gCFpF+r;xc7tA+pE bA6g zxIg)$akA-uJG)75PPs6CQTzLPh3AzCq73~4@89mt{nqk>$4 W+3Y_3w}PT G(ynT7j?6u{w6~Aqxmb|}GdZud&&jZ%ztXb(( zRxj&V!&1?bs;?aWxNi2j{f|42Cg?~+$#N r2y}Y;zW^ r!w#T1|%YW}bdEUb&N8`^+!PAHPuIwupzLAr}TA(W3 zub|bi?Zt!HFTTuQ;#a<4;=%L}C2J&SaHRfFIs0U-gR|hhQk$l )dn7c7^}E1>iJSIn zREKr_k4q9-X!J-opmyd@{vD4eHLpI9suo+U+J2yM4NJw64_>=YwSCZMQ?+>S-LJNP zpJ&m8E-r&c4gUSD_4y__Tb;iY@^SBXZ*F1bzc@i{#W~IIMfa=Z;`kqJJl|@5-%tB1 z`;9%{9l6CtMN=2d4V~F}&367)J$`w=|5X{$`RxzOi tD(L9 z_gb}G-=^FY`1hXku)hC-{%13EX8bsqBA8 )MoBx=Vw>{ z|Nr3nl=eHH)yf=}r!Rb!aYAIJ`8QVAy;pXXX3sN`EBh8=Hly~ @J z ~XH`lNvm0CREv}ymbSN5U4V Yv?IWylr*tef^N~~#ReoHv#oB0j9eXHv1MP4k);;nE=o^VTWCQsR7=E?De zKj$8{)mXHUC5mg$M1?b(dBU5ba(G={U3stcLGInhvetUN@TqS8oF*+h_uD!?KDP0J z!jq%?|EumNT*|z4>gIR08TA!^m3J6saqzgjTz1thg5lgZt385F+mA(NT>aX4IJjQ; zR>{*1%k6JTs|Y{4n $S&B(y|=;j`TAv|5R%qr Rx)K51L?wEN|=m7Kx#oxM66Dqq~2b$GU_LDPI@ zxfAPUo_y5))AX&Vbcecp{*tm4@4Q_8hIH*tjlX)aRn#%++G@L9uYAfUTyS1r_SjN( zPJ3bS$uAeUbDp)G&ORJ+NBZ?gH?NnS^;R19y=1udc`@3@Z+-a8^zp~-zHQcZimwit z-w0tTGM=Y-*zXMI^Vtu~9l3Y-Pqz42uEhAl@k#RssgE8zUTzZ5thoNnQ`!8fPNVk5 zlNMPI>UdW*zIf{PBmUGRfj>zuMSRKp_Wdb-a+T-py&rJTmfpa`=Q^{X#A5cWbI >cYH!(Oo@r7oBo zA35=+;{&V4^EpCAvn(^8o}a&Z$FGWgl@*%;Q)h6LUp&qF%)-D^+aci7q63mA>{m#I zFH1UfFkJTIckcsNw& MNuez@)M pJ(daEwgPWr2jXx`7~9pWuMSK#*-I{b?$$xT#|c0DxmyEGwVCYxJo0r*K2>= zEL^bKitX*$ES6Zs2~ymeJ*)y1k)7X{9eAXY{LL+=*|>~j5%Zg?&jmdcZ*W&K3J16c zyi7W*->Cdi@n$t2kNZy#yH&GZtun1V ig+nB-T6 z6mfBJ-8l1H@Q!0d#;V2MAE&;EdD8lFw +H`U{_N#p7TJ@*`xr-ky>D){|XNk72#Xb+d%!hPJ=Sxje!uuWF5 zcq+$zHZ4MC(&-1@DH^BP#F7iFypvAv4!CI%^B}CzdV!0aScTVvRGa%HEjH5+Snt33 z`1w`UHz!i&t3SAKI#{jl^Ru&+${#uYD?D7EGv`XW^NW3rAHsfVBsd=C3wgYkJO1EB zg|w%W=ee(0)2y{%omI#Kt}Xhr+f^2Ib#PRxiris3@;l%0KAYvHnaPdrZ`zA;4sN{8 zq2u!Wu*rXhd0);d25=b(=i4rloE+Fttk_{W`@sGKOy`^1ng2WTT0FK|te0q^(>jxh z`(ezTX-rQ8I2rFV`5k3l5Ivv4QC_7$DX6OW@q`CQn%%8*TdNADi7Ijx%sg *PWTszBgHdG*SUBl-B>y|3pIg`5|OrH?hm%q5XuS6t{d%tVBg~@E?TLHem%q;}f cZ65z;e6+jU{sPb0%b+Fjp00i_>zopr0KR{Z`2YX_ diff --git a/designs/unice/example/public/index.html b/designs/unice/example/public/index.html deleted file mode 100644 index af182fd3cc0..00000000000 --- a/designs/unice/example/public/index.html +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - - - - unice - - - - - - - diff --git a/designs/unice/example/public/layout.css b/designs/unice/example/public/layout.css deleted file mode 100644 index c62502f9791..00000000000 --- a/designs/unice/example/public/layout.css +++ /dev/null @@ -1 +0,0 @@ -div.layout-wrapper{width:100%;margin:0;padding:0;background-color:red;background:#f8f9fa;background:linear-gradient(90deg, #f1f3f5 0%, #f1f3f5 25%, #f8f9fa 26%, #f8f9fa 100%)}div.layout-wrapper div.layout{display:flex;max-width:1600px;margin:auto;padding:0;flex-direction:row;flex-wrap:nowrap;justify-content:space-between;background-color:#f8f9fa;min-height:calc(100vh - 64px)}div.layout-wrapper div.layout>aside{width:33%;background:#f1f3f5;border-right:2px solid #dee2e6}div.layout-wrapper div.layout>section{margin:0;padding:1rem}div.layout-wrapper div.layout>section>div.content{max-width:66ch;min-width:340px}div.layout-wrapper div.layout>section>div.content.wide{max-width:100%;margin:auto}.theme-wrapper.dark header{background-color:#1a1d21}.theme-wrapper.dark div.layout-wrapper{background:#f8f9fa;background:linear-gradient(90deg, #1a1d21 0%, #1a1d21 25%, #212529 26%, #212529 100%)}.theme-wrapper.dark div.layout-wrapper div.layout{background-color:#212529}.theme-wrapper.dark div.layout-wrapper div.layout>aside{background-color:#1a1d21;border-right:2px solid #343a40}header a svg{color:#ced4da}header a:first-of-type svg{color:#f8f9fa}header a:hover svg{color:#b197fc}header a span,header button span{color:#ced4da}header a span svg,header button span svg{color:#dee2e6}header a:hover span,header button:hover span{color:#f8f9fa}header a:hover span svg,header button:hover span svg{color:#b197fc}header a,header button{padding:0 1vw !important}@media (min-width: 1200px){div.layout>section{width:63%}}@media (max-width: 1199px) and (min-width: 960px){div.layout>aside{width:298px}div.layout>section{width:calc(100% - 300px - 4rem);max-width:none;margin:0 1rem 0 3rem}}@media (max-width: 959px){div.layout>aside{width:218px}div.layout>section{width:calc(100% - 220px - 4rem);max-width:none;margin:0;padding:0 2rem}div.layout>section div.content{min-width:inherit}}@media (max-width: 599px){div.layout>aside{display:none}div.layout>section{width:calc(100%);margin:0 auto;padding:0 1.5rem;max-width:none}}div.gatsby-highlight{margin-bottom:1rem}@media (max-width: 599px){#mobile-menu{position:fixed;top:0;left:0;width:100%;height:100vh;padding:0 0 1rem;max-width:600px;z-index:-10;transition:opacity 0.25s ease 0s;opacity:0;overflow:scroll}#mobile-menu>ul,#mobile-menu>div{transform:translate(0px, 10px);transition:transform 0.25s ease 0s}.theme-wrapper.show-menu #mobile-menu{opacity:1;z-index:10}.theme-wrapper.show-menu #mobile-menu>div{transform:translate(0px, 0px)}}.theme-wrapper.light div.draft-ui-menu,.theme-wrapper.light div.menu{background:#f1f3f5}.theme-wrapper.dark div.draft-ui-menu,.theme-wrapper.dark div.menu{background:#343a40}.theme-wrapper.show-menu div.menu{opacity:1;z-index:10}.theme-wrapper.show-menu div.menu>div{transform:translate(0px, 0px)}div.spaced-buttons>button{margin:0 0.5rem 0.5rem 0}div.spaced>*{margin:0 0.5rem 0.5rem 0}ul#pre-main-menu{margin:0;padding:0}.boldish{font-weight:500}.freesewing.draft{padding:1rem}li.action{clear:both}li.action span.MuiSwitch-root{float:right}.theme-wrapper.light ul#draft-config li.action.toggle.off,.theme-wrapper.dark ul#draft-config li.action.toggle.off{color:#868e96}.theme-wrapper.light ul#draft-config li.action.toggle.off>span svg,.theme-wrapper.dark ul#draft-config li.action.toggle.off>span svg{color:#868e96}footer{background-color:#1a1d21;color:#adb5bd;padding:3rem 0 6rem}footer a{color:#dee2e6 !important;font-weight:400}footer a:hover{color:#d0bfff !important}footer div.cols{display:flex;flex-direction:row;justify-content:space-between;max-width:1600px;margin:auto;padding:0 1.5rem}footer div.cols>div{min-width:150px;max-width:calc(20% - 4rem);padding:0 2rem 0 0;width:100%}footer ul{text-align:left;font-size:1.1rem;margin:0;padding:0;width:100%}footer ul li:first-of-type{padding:0.35rem 0.75rem}footer ul li{display:block}footer ul li a:hover{text-decoration:none !important}footer ul li.heading{font-weight:bold;border-bottom:3px solid #adb5bd;margin-bottom:0.5rem}@media (min-width: 1200px){footer div.cols>div:last-of-type{min-width:350px}}@media (min-width: 600px) and (max-width: 959px){footer div.cols{flex-wrap:wrap}footer div.cols>div{width:calc(30% - 4rem);padding:0 1rem}}@media (max-width: 599px){footer div.cols{display:block}footer div.cols>div{margin:2rem auto 0;max-width:calc(100% - 4rem)}footer div.cols>div:first-of-type{margin-top:0}} diff --git a/designs/unice/example/public/manifest.json b/designs/unice/example/public/manifest.json deleted file mode 100644 index 578f27ed307..00000000000 --- a/designs/unice/example/public/manifest.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "short_name": "unice", - "name": "unice", - "icons": [ - { - "src": "favicon.ico", - "sizes": "64x64 32x32 24x24 16x16", - "type": "image/x-icon" - } - ], - "start_url": ".", - "display": "standalone", - "theme_color": "#000000", - "background_color": "#ffffff" -} diff --git a/designs/unice/example/src/App.js b/designs/unice/example/src/App.js deleted file mode 100644 index 7bb0f0e7112..00000000000 --- a/designs/unice/example/src/App.js +++ /dev/null @@ -1,45 +0,0 @@ -import React from 'react' -import freesewing from '@freesewing/core' -import Workbench from '@freesewing/components/Workbench' -import '@freesewing/css-theme' -import Pattern from './pattern/src/index.js' -/* - * The following symlink is required to make this import work: - * `root_folder/example/src/pattern => `../../` - * - * Without it, we can't import the pattern as a local file - * since create-react-app does not allow imports outside ./src - * If it's imported as a dependency, webpack will cache the - * build and there will be no hot-reloading of changes - */ - -const App = (props) => { - // You can use this to add translations - /* - let translations = { - JSON: 'JSON', - someOtherString: 'Some other string that needs translation' - } - */ - - // Adds support for loading an external pattern configuration - let recreate = false - if (window) recreate = window.location.pathname.substr(1).split('/') - if (recreate.length === 3 && recreate[0] === 'recreate') { - recreate = { from: recreate[1], id: recreate[2] } - } else { - recreate = false - } - - return ( -- ) -} - -export default App diff --git a/designs/unice/example/src/index.js b/designs/unice/example/src/index.js deleted file mode 100644 index 24aefad45a1..00000000000 --- a/designs/unice/example/src/index.js +++ /dev/null @@ -1,12 +0,0 @@ -import React from 'react' -import ReactDOM from 'react-dom' -import App from './App' -import * as serviceWorker from './serviceWorker' -import './layout.css' - -ReactDOM.render( , document.getElementById('root')) - -// If you want your app to work offline and load faster, you can change -// unregister() to register() below. Note this comes with some pitfalls. -// Learn more about service workers: http://bit.ly/CRA-PWA -serviceWorker.unregister() diff --git a/designs/unice/example/src/layout.css b/designs/unice/example/src/layout.css deleted file mode 100644 index a4963e16e55..00000000000 --- a/designs/unice/example/src/layout.css +++ /dev/null @@ -1,273 +0,0 @@ -* { - box-sizing: border-box; -} -.MuiToolbar-root { - overflow-y: auto; -} -div.layout-wrapper { - width: 100%; - margin: 0; - padding: 0; - background: #f8f9fa; - background: linear-gradient(90deg, #f1f3f5 0%, #f1f3f5 25%, #f8f9fa 26%, #f8f9fa 100%); -} -div.layout-wrapper div.layout { - display: flex; - max-width: 1600px; - margin: auto; - padding: 0; - flex-direction: row; - flex-wrap: nowrap; - justify-content: space-between; - background-color: #f8f9fa; - min-height: calc(100vh - 64px); -} -div.layout-wrapper div.layout > aside { - width: 33%; - background: #f1f3f5; - border-right: 2px solid #dee2e6; -} -div.layout-wrapper div.layout > section { - margin: 0; - padding: 1rem; -} -div.layout-wrapper div.layout > section > div.content { - max-width: 66ch; - min-width: 340px; -} -div.layout-wrapper div.layout > section > div.content.wide { - max-width: 100%; - margin: auto; -} - -.theme-wrapper.dark header { - background-color: #1a1d21; -} - -.theme-wrapper.dark div.layout-wrapper { - background: #f8f9fa; - background: linear-gradient(90deg, #1a1d21 0%, #1a1d21 25%, #212529 26%, #212529 100%); -} -.theme-wrapper.dark div.layout-wrapper div.layout { - background-color: #212529; -} -.theme-wrapper.dark div.layout-wrapper div.layout > aside { - background-color: #1a1d21; - border-right: 2px solid #343a40; -} - -/* monitor */ -@media (min-width: 1200px) { - div.layout > section { - width: 63%; - } -} - -/* slate */ -@media (max-width: 1199px) and (min-width: 960px) { - div.layout > aside { - width: 298px; - } - div.layout > section { - width: calc(100% - 300px - 4rem); - max-width: none; - margin: 0 1rem 0 3rem; - } -} - -/* tablet */ -@media (max-width: 959px) { - div.layout > aside { - width: 218px; - } - div.layout > section { - width: calc(100% - 220px - 4rem); - max-width: none; - margin: 0; - padding: 0 2rem; - } - div.layout > section div.content { - min-width: inherit; - } -} - -/* mobile */ -@media (max-width: 599px) { - div.layout > aside { - display: none; - } - div.layout > section { - width: calc(100%); - margin: 0 auto; - padding: 0 1.5rem; - max-width: none; - } -} - -div.gatsby-highlight { - margin-bottom: 1rem; -} - -@media (max-width: 599px) { - #mobile-menu { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100vh; - padding: 0 0 1rem; - max-width: 600px; - z-index: -10; - transition: opacity 0.25s ease 0s; - opacity: 0; - overflow: scroll; - } - #mobile-menu > ul, - #mobile-menu > div { - transform: translate(0px, 10px); - transition: transform 0.25s ease 0s; - } - .theme-wrapper.show-menu #mobile-menu { - opacity: 1; - z-index: 10; - } - .theme-wrapper.show-menu #mobile-menu > div { - transform: translate(0px, 0px); - } -} - -.theme-wrapper.light div.draft-ui-menu, -.theme-wrapper.light div.menu { - background: #f1f3f5; -} - -.theme-wrapper.dark div.draft-ui-menu, -.theme-wrapper.dark div.menu { - background: #343a40; -} - -.theme-wrapper.show-menu div.menu { - opacity: 1; - z-index: 10; -} -.theme-wrapper.show-menu div.menu > div { - transform: translate(0px, 0px); -} - -div.spaced-buttons > button { - margin: 0 0.5rem 0.5rem 0; -} - -div.spaced > * { - margin: 0 0.5rem 0.5rem 0; -} - -ul#pre-main-menu { - margin: 0; - padding: 0; -} - -.boldish { - font-weight: 500; -} - -.freesewing.draft { - padding: 1rem; -} - -li.action { - clear: both; -} - -li.action span.MuiSwitch-root { - float: right; -} - -.theme-wrapper.light ul#draft-config li.action.toggle.off, -.theme-wrapper.dark ul#draft-config li.action.toggle.off { - color: #868e96; -} -.theme-wrapper.light ul#draft-config li.action.toggle.off > span svg, -.theme-wrapper.dark ul#draft-config li.action.toggle.off > span svg { - color: #868e96; -} - -footer { - background-color: #1a1d21; - color: #adb5bd; - padding: 3rem 0 6rem; -} -footer a { - color: #dee2e6 !important; - font-weight: 400; -} -footer a:hover { - color: #d0bfff !important; -} -footer div.cols { - display: flex; - flex-direction: row; - justify-content: space-between; - max-width: 1600px; - margin: auto; - padding: 0 1.5rem; -} -footer div.cols > div { - min-width: 150px; - max-width: calc(20% - 4rem); - padding: 0 2rem 0 0; - width: 100%; -} -footer ul { - text-align: left; - font-size: 1.1rem; - margin: 0; - padding: 0; - width: 100%; -} -footer ul li:first-of-type { - padding: 0.35rem 0.75rem; -} -footer ul li { - display: block; -} -footer ul li a:hover { - text-decoration: none !important; -} -footer ul li.heading { - font-weight: bold; - border-bottom: 3px solid #adb5bd; - margin-bottom: 0.5rem; -} - -/* XL screens */ -@media (min-width: 1200px) { - footer div.cols > div:last-of-type { - min-width: 350px; - } -} - -/* SM screens */ -@media (min-width: 600px) and (max-width: 959px) { - footer div.cols { - flex-wrap: wrap; - } - footer div.cols > div { - width: calc(30% - 4rem); - padding: 0 1rem; - } -} - -/* XS screens */ -@media (max-width: 599px) { - footer div.cols { - display: block; - } - footer div.cols > div { - margin: 2rem auto 0; - max-width: calc(100% - 4rem); - } - footer div.cols > div:first-of-type { - margin-top: 0; - } -} diff --git a/designs/unice/example/src/pattern b/designs/unice/example/src/pattern deleted file mode 100644 index 6581736d623..00000000000 --- a/designs/unice/example/src/pattern +++ /dev/null @@ -1 +0,0 @@ -../../ \ No newline at end of file diff --git a/designs/unice/example/src/serviceWorker.js b/designs/unice/example/src/serviceWorker.js deleted file mode 100644 index 4fe923e7795..00000000000 --- a/designs/unice/example/src/serviceWorker.js +++ /dev/null @@ -1,123 +0,0 @@ -// In production, we register a service worker to serve assets from local cache. - -// This lets the app load faster on subsequent visits in production, and gives -// it offline capabilities. However, it also means that developers (and users) -// will only see deployed updates on the "N+1" visit to a page, since previously -// cached resources are updated in the background. - -// To learn more about the benefits of this model, read https://goo.gl/KwvDNy. -// This link also includes instructions on opting out of this behavior. - -const isLocalhost = Boolean( - window.location.hostname === 'localhost' || - // [::1] is the IPv6 localhost address. - window.location.hostname === '[::1]' || - // 127.0.0.1/8 is considered localhost for IPv4. - window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/) -) - -export function register(config) { - if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { - // The URL constructor is available in all browsers that support SW. - const publicUrl = new URL(process.env.PUBLIC_URL, window.location) - if (publicUrl.origin !== window.location.origin) { - // Our service worker won't work if PUBLIC_URL is on a different origin - // from what our page is served on. This might happen if a CDN is used to - // serve assets; see https://github.com/facebook/create-react-app/issues/2374 - return - } - - window.addEventListener('load', () => { - const swUrl = `${process.env.PUBLIC_URL}/service-worker.js` - - if (isLocalhost) { - // This is running on localhost. Let's check if a service worker still exists or not. - checkValidServiceWorker(swUrl, config) - - // Add some additional logging to localhost, pointing developers to the - // service worker/PWA documentation. - navigator.serviceWorker.ready.then(() => { - console.log( - 'This web app is being served cache-first by a service ' + - 'worker. To learn more, visit https://goo.gl/SC7cgQ' - ) - }) - } else { - // Is not local host. Just register service worker - registerValidSW(swUrl, config) - } - }) - } -} - -function registerValidSW(swUrl, config) { - navigator.serviceWorker - .register(swUrl) - .then((registration) => { - registration.onupdatefound = () => { - const installingWorker = registration.installing - installingWorker.onstatechange = () => { - if (installingWorker.state === 'installed') { - if (navigator.serviceWorker.controller) { - // At this point, the old content will have been purged and - // the fresh content will have been added to the cache. - // It's the perfect time to display a "New content is - // available; please refresh." message in your web app. - console.log('New content is available; please refresh.') - - // Execute callback - if (config.onUpdate) { - config.onUpdate(registration) - } - } else { - // At this point, everything has been precached. - // It's the perfect time to display a - // "Content is cached for offline use." message. - console.log('Content is cached for offline use.') - - // Execute callback - if (config.onSuccess) { - config.onSuccess(registration) - } - } - } - } - } - }) - .catch((error) => { - console.error('Error during service worker registration:', error) - }) -} - -function checkValidServiceWorker(swUrl, config) { - // Check if the service worker can be found. If it can't reload the page. - fetch(swUrl) - .then((response) => { - // Ensure service worker exists, and that we really are getting a JS file. - if ( - response.status === 404 || - response.headers.get('content-type').indexOf('javascript') === -1 - ) { - // No service worker found. Probably a different app. Reload the page. - navigator.serviceWorker.ready.then((registration) => { - registration.unregister().then(() => { - window.location.reload() - }) - }) - } else { - // Service worker found. Proceed as normal. - registerValidSW(swUrl, config) - } - }) - .catch(() => { - console.log('No internet connection found. App is running in offline mode.') - }) -} - -export function unregister() { - if ('serviceWorker' in navigator) { - navigator.serviceWorker.ready.then((registration) => { - registration.unregister() - }) - } -} diff --git a/designs/unice/package.json b/designs/unice/package.json index 4c3f21efd5f..b827b14a8a9 100644 --- a/designs/unice/package.json +++ b/designs/unice/package.json @@ -38,6 +38,7 @@ "vbuild": "VERBOSE=1 node build.mjs", "lab": "cd ../../sites/lab && yarn start", "tips": "node ../../scripts/help.mjs", + "lint": "npx eslint 'src/**' 'tests/*.mjs'", "prettier": "npx prettier --write 'src/*.mjs' 'tests/*.mjs'", "testci": "npx mocha tests/*.test.mjs --reporter ../../tests/reporters/terse.js", "cibuild_step5": "node build.mjs" diff --git a/designs/unice/src/back.mjs b/designs/unice/src/back.mjs index 88fe248f125..d83ca70bda6 100644 --- a/designs/unice/src/back.mjs +++ b/designs/unice/src/back.mjs @@ -34,8 +34,6 @@ export const back = { // Design pattern here -log.info('start back') - // Create points points.backWaistMid = new Point(measurements.seat / 4, 0) points.backWaistBandLeft = new Point( diff --git a/designs/unice/src/elastic.mjs b/designs/unice/src/elastic.mjs index cba3b134ec6..406a4c76a10 100644 --- a/designs/unice/src/elastic.mjs +++ b/designs/unice/src/elastic.mjs @@ -10,6 +10,8 @@ export const elastic = { options, Point, points, + Path, + paths, store, utils, units, @@ -37,14 +39,13 @@ export const elastic = { .attr('data-text', ':') .attr('data-text', units(waistBandLength * store.get('elasticScale') + 2 * sa)) - // Paperless? - if (paperless) { - macro('hd', { - from: points.elasticInfo, - to: points.elasticInfo, - y: points.elasticInfo.y + sa + 15, - }) - } + // Draw a box around the text, so the part shows up correctly. + paths.box = new Path() + .move(new Point(-10,-10)) + .line(new Point(-10,15)) + .line(new Point(200,15)) + .line(new Point(200,-10)) + .close() return part }, diff --git a/designs/unice/src/front.mjs b/designs/unice/src/front.mjs index 4dfacef94fe..79d17a29b96 100644 --- a/designs/unice/src/front.mjs +++ b/designs/unice/src/front.mjs @@ -1,4 +1,5 @@ import { pctBasedOn } from '@freesewing/core' +import {pluginBundle } from '@freesewing/plugin-bundle' export const front = { name: 'unice.front', @@ -18,6 +19,7 @@ export const front = { useCrossSeam: { bool: true, menu: 'fit' }, adjustStretch: {bool: true, menu: 'fit' }, // to not stretch fabric to the limits }, + plugins: [pluginBundle, ], draft: ({ utils, store, diff --git a/designs/unice/src/index.mjs b/designs/unice/src/index.mjs index 7cba0bf4544..1518e7baac3 100644 --- a/designs/unice/src/index.mjs +++ b/designs/unice/src/index.mjs @@ -12,4 +12,4 @@ const Unice = new Design({ }) // Named exports -export {front, back, gusset, elastic, Unice} // export { back, front, gusset, Unice } \ No newline at end of file +export {front, back, gusset, elastic, Unice} \ No newline at end of file diff --git a/designs/unice/tests/shared.test.mjs b/designs/unice/tests/shared.test.mjs index 13c82f4ee71..8ddc94ac54a 100644 --- a/designs/unice/tests/shared.test.mjs +++ b/designs/unice/tests/shared.test.mjs @@ -1,10 +1,10 @@ // This file is auto-generated | Any changes you make will be overwritten. -import { Unice } from './dist/index.mjs' +import { Unice } from '../src/index.mjs' // Shared tests import { testPatternConfig } from '../../../tests/designs/config.mjs' import { testPatternDrafting } from '../../../tests/designs/drafting.mjs' -import { testPatternSampling } from '../../../tests/designs/sampling.mjs' +//import { testPatternSampling } from '../../../tests/designs/sampling.mjs' // Test config testPatternConfig(Unice) @@ -13,4 +13,4 @@ testPatternConfig(Unice) testPatternDrafting(Unice, false) // Test sampling - Change the second parameter to `true` to log errors -testPatternSampling(Unice, false) +//testPatternSampling(Unice, false) From fe61834103aad948b4b6a13e9690ad38a54a5e69 Mon Sep 17 00:00:00 2001 From: Benjamin F Date: Mon, 26 Sep 2022 15:40:13 -0700 Subject: [PATCH 06/46] fix(lunetius): Unhide accidentally-hidden seam. --- designs/lunetius/src/lacerna.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/designs/lunetius/src/lacerna.mjs b/designs/lunetius/src/lacerna.mjs index 499acf28a51..ee171f115d5 100644 --- a/designs/lunetius/src/lacerna.mjs +++ b/designs/lunetius/src/lacerna.mjs @@ -61,7 +61,7 @@ function lunetiusLacerna({ .line(points.bottom) .hide() paths.saBase = new Path().move(points.top).line(points.topLeft).hide() - paths.seam = paths.saBase.join(paths.hem).join(paths.fold).attr('class', 'fabric').hide() + paths.seam = paths.saBase.join(paths.hem).join(paths.fold).attr('class', 'fabric') // Complete? if (complete) { From 1a81df20a5789e0943cf1236c7485df1167955c0 Mon Sep 17 00:00:00 2001 From: Benjamin F Date: Mon, 26 Sep 2022 17:29:38 -0700 Subject: [PATCH 07/46] fix(hi): Unhide accidentally-hidden seam. --- designs/hi/src/body.mjs | 1 - 1 file changed, 1 deletion(-) diff --git a/designs/hi/src/body.mjs b/designs/hi/src/body.mjs index da8b19b5be6..2143b29025c 100644 --- a/designs/hi/src/body.mjs +++ b/designs/hi/src/body.mjs @@ -409,7 +409,6 @@ function draftHiBody({ .curve(points.body02cp1, points.body03cp2, points.body03) .join(paths.allButDart) .close() - .hide() let gillPath = new Path() .move(points.body17) From 0a9779fd2e091860c9f89343f39cdf40767c049c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 27 Sep 2022 04:02:29 +0000 Subject: [PATCH 08/46] chore(deps): bump mongoose from 6.6.1 to 6.6.2 Bumps [mongoose](https://github.com/Automattic/mongoose) from 6.6.1 to 6.6.2. - [Release notes](https://github.com/Automattic/mongoose/releases) - [Changelog](https://github.com/Automattic/mongoose/blob/master/CHANGELOG.md) - [Commits](https://github.com/Automattic/mongoose/compare/6.6.1...6.6.2) --- updated-dependencies: - dependency-name: mongoose dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] ## Notes diff --git a/markdown/dev/reference/api/path/addclass/en.md b/markdown/dev/reference/api/path/addclass/en.md index 750883efb74..d8c0d0bba40 100644 --- a/markdown/dev/reference/api/path/addclass/en.md +++ b/markdown/dev/reference/api/path/addclass/en.md @@ -4,31 +4,17 @@ title: Path.addClass() The `Path.addClass()` method adds a CSS class to the path. +## Signature + ```js Path path.addClass(string className) ``` ---- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 2a82625508b..79e74c9a501 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13520,9 +13520,9 @@ mongoose-encryption@^2.1.0: underscore "^1.5.0" mongoose@^6.1.8, mongoose@^6.5.2: - version "6.6.1" - resolved "https://registry.yarnpkg.com/mongoose/-/mongoose-6.6.1.tgz#8aec30924b1a524924d9de4eb4746951f6aadd26" - integrity sha512-hPDamnn6quL9TjIrOudqUS5sMilENmP/gfxoCIb+rDmlzawtM7+MVCAWrM9930fzD20N7qAema/zE9QIDuifhQ== + version "6.6.2" + resolved "https://registry.yarnpkg.com/mongoose/-/mongoose-6.6.2.tgz#162d651ee830f06c6fd2c8a5886646a5828c0458" + integrity sha512-SrB0DgB1Ime/xh4Tr2yLkFKO5Aa/FrDyAo/ILGDWM5qjhZdhl7HKftiQPibwywC3rTkeU4nc2yuPYKFLBYCBWA== dependencies: bson "^4.6.5" kareem "2.4.1" From f366f1aaee436dbb2d4e2df828627571d00f35ab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 27 Sep 2022 04:09:23 +0000 Subject: [PATCH 09/46] chore(deps-dev): bump @types/node from 18.7.18 to 18.7.23 Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 18.7.18 to 18.7.23. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 2a82625508b..d76b9289bbe 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3541,9 +3541,9 @@ form-data "^3.0.0" "@types/node@*", "@types/node@^18.0.0": - version "18.7.18" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.7.18.tgz#633184f55c322e4fb08612307c274ee6d5ed3154" - integrity sha512-m+6nTEOadJZuTPkKR/SYK3A2d7FZrgElol9UP1Kae90VVU4a6mxnPuLiIW1m4Cq4gZ/nWb9GrdVXJCoCazDAbg== + version "18.7.23" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.7.23.tgz#75c580983846181ebe5f4abc40fe9dfb2d65665f" + integrity sha512-DWNcCHolDq0ZKGizjx2DZjR/PqsYwAcYUJmfMWqtVU2MBMG5Mo+xFZrhGId5r/O5HOuMPyQEcM6KUBp5lBZZBg== "@types/node@^14.0.0": version "14.18.26" From b851e69ec88c5deccfc6064762d7ecef7a591b87 Mon Sep 17 00:00:00 2001 From: Joost De Cock Date: Tue, 27 Sep 2022 11:35:48 +0200 Subject: [PATCH 10/46] chore(plugin-gore): Changes for v3. See #2856 --- plugins/plugin-gore/src/index.mjs | 47 ++++++++++------------- plugins/plugin-gore/tests/plugin.test.mjs | 45 ++++++++++++++-------- 2 files changed, 50 insertions(+), 42 deletions(-) diff --git a/plugins/plugin-gore/src/index.mjs b/plugins/plugin-gore/src/index.mjs index 9cc58b84aa7..8d1efc9ff1c 100644 --- a/plugins/plugin-gore/src/index.mjs +++ b/plugins/plugin-gore/src/index.mjs @@ -4,55 +4,48 @@ export const plugin = { name, version, macros: { - gore: function (so) { + gore: function (so, { points, paths, Path }) { const from = so.from const gores = so.gores const radius = so.radius //radius of the sphere const prefix = so.prefix const extraLength = so.extraLength //the length of the straight section after a complete semisphere - this.points[prefix + 'p1'] = from.shift(0, (radius * Math.PI) / 2 + extraLength) - this.points[prefix + 'Cp1'] = this.points[prefix + 'p1'].shift( + points[prefix + 'p1'] = from.shift(0, (radius * Math.PI) / 2 + extraLength) + points[prefix + 'Cp1'] = points[prefix + 'p1'].shift( 180 - 180 / gores, radius / 2 / Math.cos(Math.PI / gores) ) - this.points[prefix + 'p3'] = from.shift(90, (radius * Math.PI) / gores) - this.points[prefix + 'p2'] = this.points[prefix + 'p3'].shift(0, extraLength) - this.points[prefix + 'Cp2'] = this.points[prefix + 'p2'].shift( - 0, - (radius * (Math.PI - 2)) / 2 - ) + points[prefix + 'p3'] = from.shift(90, (radius * Math.PI) / gores) + points[prefix + 'p2'] = points[prefix + 'p3'].shift(0, extraLength) + points[prefix + 'Cp2'] = points[prefix + 'p2'].shift(0, (radius * (Math.PI - 2)) / 2) if (extraLength < 0) { //top curve used to calculate the new points if extraLength < 0 - this.paths.auxiliaryPath = new this.Path() - .move(this.points[prefix + 'p1']) - .curve( - this.points[prefix + 'Cp1'], - this.points[prefix + 'Cp2'], - this.points[prefix + 'p2'] - ) + paths.auxiliaryPath = new Path() + .move(points[prefix + 'p1']) + .curve(points[prefix + 'Cp1'], points[prefix + 'Cp2'], points[prefix + 'p2']) .hide() - this.points[prefix + 'p2'] = this.paths.auxiliaryPath.intersectsX(0)[0] //the new point p2 is the one in which the auxiliary curve intersects x=0 - this.paths.auxiliaryPath = this.paths.auxiliaryPath.split(this.points[prefix + 'p2'])[0] //the auxiliary curve is split - this.points[prefix + 'Cp1'] = this.paths.auxiliaryPath.ops[1].cp1 //the new control points are those of the new curve - this.points[prefix + 'Cp2'] = this.paths.auxiliaryPath.ops[1].cp2 - this.points[prefix + 'p3'] = this.points[prefix + 'p2'].clone() + points[prefix + 'p2'] = paths.auxiliaryPath.intersectsX(0)[0] //the new point p2 is the one in which the auxiliary curve intersects x=0 + paths.auxiliaryPath = paths.auxiliaryPath.split(points[prefix + 'p2'])[0] //the auxiliary curve is split + points[prefix + 'Cp1'] = paths.auxiliaryPath.ops[1].cp1 //the new control points are those of the new curve + points[prefix + 'Cp2'] = paths.auxiliaryPath.ops[1].cp2 + points[prefix + 'p3'] = points[prefix + 'p2'].clone() } //the seam path is generated - this.paths[prefix + 'seam'] = new this.Path() + paths[prefix + 'seam'] = new Path() .move(from) - .line(this.points[prefix + 'p1']) - .curve(this.points[prefix + 'Cp1'], this.points[prefix + 'Cp2'], this.points[prefix + 'p2']) - .line(this.points[prefix + 'p3']) + .line(points[prefix + 'p1']) + .curve(points[prefix + 'Cp1'], points[prefix + 'Cp2'], points[prefix + 'p2']) + .line(points[prefix + 'p3']) .line(from) .close() .attr('class', so.class ? so.class : '') - if (so?.hidden) this.paths[prefix + 'seam'].hide() - else this.paths[prefix + 'seam'].unhide() + if (so?.hidden) paths[prefix + 'seam'].hide() + else paths[prefix + 'seam'].unhide() }, }, } diff --git a/plugins/plugin-gore/tests/plugin.test.mjs b/plugins/plugin-gore/tests/plugin.test.mjs index 1ff95ff2b0f..2132fb05b69 100644 --- a/plugins/plugin-gore/tests/plugin.test.mjs +++ b/plugins/plugin-gore/tests/plugin.test.mjs @@ -8,7 +8,7 @@ describe('Gore Plugin Tests', () => { it('Should create a default gore', () => { const part = { name: 'test', - draft: ({ Point, points, macro }) => { + draft: ({ Point, points, macro, part }) => { points.anchorPoint = new Point(50, 50) macro('gore', { from: points.anchorPoint, @@ -17,12 +17,15 @@ describe('Gore Plugin Tests', () => { extraLength: 0, prefix: 'gore', }) + + return part }, + plugins: [plugin], } - const Test = new Design({ plugins: [plugin], parts: [part] }) + const Test = new Design({ parts: [part] }) const pattern = new Test() pattern.draft() - let c = pattern.parts.test.points + let c = pattern.parts[0].test.points expect(round(c.gorep1.y)).to.equal(50) expect(round(c.gorep2.x)).to.equal(50) expect(round(c.gorep2.y)).to.equal(30.37) @@ -33,7 +36,7 @@ describe('Gore Plugin Tests', () => { it('Should use a configurable number of gores', () => { const part = { name: 'test', - draft: ({ Point, points, macro }) => { + draft: ({ Point, points, macro, part }) => { points.anchorPoint = new Point(50, 50) macro('gore', { from: points.anchorPoint, @@ -42,12 +45,15 @@ describe('Gore Plugin Tests', () => { extraLength: 0, prefix: 'gore', }) + + return part }, + plugins: [plugin], } - const Test = new Design({ plugins: [plugin], parts: [part] }) + const Test = new Design({ parts: [part] }) const pattern = new Test() pattern.draft() - let c = pattern.parts.test.points + let c = pattern.parts[0].test.points expect(round(c.gorep1.x)).to.equal(89.27) expect(round(c.gorep1.y)).to.equal(50) expect(round(c.gorep2.x)).to.equal(50) @@ -59,7 +65,7 @@ describe('Gore Plugin Tests', () => { it('Should use a configurable extra length', () => { const part = { name: 'test', - draft: ({ Point, points, macro }) => { + draft: ({ Point, points, macro, part }) => { points.anchorPoint = new Point(50, 50) macro('gore', { from: points.anchorPoint, @@ -68,12 +74,15 @@ describe('Gore Plugin Tests', () => { extraLength: 20, prefix: 'gore', }) + + return part }, + plugins: [plugin], } - const Test = new Design({ plugins: [plugin], parts: [part] }) + const Test = new Design({ parts: [part] }) const pattern = new Test() pattern.draft() - let c = pattern.parts.test.points + let c = pattern.parts[0].test.points expect(round(c.gorep1.x)).to.equal(109.27) expect(round(c.gorep1.y)).to.equal(50) expect(round(c.gorep2.x)).to.equal(70) @@ -85,7 +94,7 @@ describe('Gore Plugin Tests', () => { it('Should use a configurable radius', () => { const part = { name: 'test', - draft: ({ Point, points, macro }) => { + draft: ({ Point, points, macro, part }) => { points.anchorPoint = new Point(50, 50) macro('gore', { from: points.anchorPoint, @@ -94,12 +103,15 @@ describe('Gore Plugin Tests', () => { extraLength: 0, prefix: 'gore', }) + + return part }, + plugins: [plugin], } - const Test = new Design({ plugins: [plugin], parts: [part] }) + const Test = new Design({ parts: [part] }) const pattern = new Test() pattern.draft() - let c = pattern.parts.test.points + let c = pattern.parts[0].test.points expect(round(c.gorep1.x)).to.equal(97.12) expect(round(c.gorep1.y)).to.equal(50) expect(round(c.gorep2.x)).to.equal(50) @@ -111,7 +123,7 @@ describe('Gore Plugin Tests', () => { it('Should generate a seam path', () => { const part = { name: 'test', - draft: ({ Point, points, macro }) => { + draft: ({ Point, points, macro, part }) => { points.anchorPoint = new Point(50, 50) macro('gore', { from: points.anchorPoint, @@ -120,12 +132,15 @@ describe('Gore Plugin Tests', () => { extraLength: 0, prefix: 'gore', }) + + return part }, + plugins: [plugin], } - const Test = new Design({ plugins: [plugin], parts: [part] }) + const Test = new Design({ parts: [part] }) const pattern = new Test() pattern.draft() - let c = pattern.parts.test.paths.goreseam.ops + let c = pattern.parts[0].test.paths.goreseam.ops expect(round(c[1].to.x)).to.equal(89.27) expect(round(c[1].to.y)).to.equal(50) expect(round(c[2].to.x)).to.equal(50) From 88e5339b376a79199b0b0b4e74d3d16572c146e2 Mon Sep 17 00:00:00 2001 From: Joost De Cock Date: Tue, 27 Sep 2022 11:42:54 +0200 Subject: [PATCH 11/46] chore(plugin-grainline): Changes for v3. See #2856 --- plugins/plugin-grainline/src/index.mjs | 13 ++++++------- plugins/plugin-grainline/tests/plugin.test.mjs | 9 ++++++--- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/plugins/plugin-grainline/src/index.mjs b/plugins/plugin-grainline/src/index.mjs index 854fc7cdf6a..eb56aebda63 100644 --- a/plugins/plugin-grainline/src/index.mjs +++ b/plugins/plugin-grainline/src/index.mjs @@ -19,19 +19,18 @@ export const plugin = { }, }, macros: { - grainline: function (so = {}) { + grainline: function (so = {}, { points, paths, Path, complete, setGrain }) { if (so === false) { - delete this.points.grainlineFrom - delete this.points.grainlineTo - delete this.paths.grainline - this.setGrain(90) // Restoring default + delete points.grainlineFrom + delete points.grainlineTo + delete paths.grainline + setGrain(90) // Restoring default return true } so = { ...dflts, ...so, } - const { points, complete, setGrain } = this.shorthand() // setGrain relies on plugin-cutlist if (typeof setGrain === 'function') { setGrain(so.from.angle(so.to)) @@ -39,7 +38,7 @@ export const plugin = { if (complete) { points.grainlineFrom = so.from.shiftFractionTowards(so.to, 0.05) points.grainlineTo = so.to.shiftFractionTowards(so.from, 0.05) - this.paths.grainline = new this.Path() + paths.grainline = new Path() .move(points.grainlineFrom) .line(points.grainlineTo) .attr('class', 'note') diff --git a/plugins/plugin-grainline/tests/plugin.test.mjs b/plugins/plugin-grainline/tests/plugin.test.mjs index 32650f516cc..f8061011dbf 100644 --- a/plugins/plugin-grainline/tests/plugin.test.mjs +++ b/plugins/plugin-grainline/tests/plugin.test.mjs @@ -8,19 +8,22 @@ describe('Grainline Plugin Tests', () => { it('Should run the default grainline macro', () => { const part = { name: 'test', - draft: ({ points, Point, macro }) => { + draft: ({ points, Point, macro, part }) => { points.from = new Point(10, 20) points.to = new Point(10, 230) macro('grainline', { from: points.from, to: points.to, }) + + return part }, + plugins: [plugin], } - const Pattern = new Design({ plugins: [plugin], parts: [part] }) + const Pattern = new Design({ parts: [part] }) const pattern = new Pattern() pattern.draft() - const c = pattern.parts.test.paths.grainline + const c = pattern.parts[0].test.paths.grainline expect(c.attributes.get('class')).to.equal('note') expect(c.attributes.get('marker-start')).to.equal('url(#grainlineFrom)') expect(c.attributes.get('marker-end')).to.equal('url(#grainlineTo)') From 3212e5eedcbae6c8df49d8806f2644d417f74ff1 Mon Sep 17 00:00:00 2001 From: Joost De Cock Date: Tue, 27 Sep 2022 11:55:44 +0200 Subject: [PATCH 12/46] chore(plugin-measurements): Changes for v3. See #2856 --- plugins/plugin-measurements/src/index.mjs | 50 ++++++++-------- .../plugin-measurements/tests/plugin.test.mjs | 57 +++++++------------ 2 files changed, 46 insertions(+), 61 deletions(-) diff --git a/plugins/plugin-measurements/src/index.mjs b/plugins/plugin-measurements/src/index.mjs index c25950326a9..5e2ac7a8d1c 100644 --- a/plugins/plugin-measurements/src/index.mjs +++ b/plugins/plugin-measurements/src/index.mjs @@ -5,31 +5,31 @@ export const plugin = { version, hooks: { preDraft: function ({ settings }) { - if (settings.measurements) { - if ( - typeof settings.measurements.seatBack !== 'undefined' && - typeof settings.measurements.seat !== 'undefined' - ) { - settings.measurements.seatFront = - settings.measurements.seat - settings.measurements.seatBack - settings.measurements.seatBackArc = settings.measurements.seatBack / 2 - settings.measurements.seatFrontArc = settings.measurements.seatFront / 2 - } - if ( - typeof settings.measurements.waist !== 'undefined' && - typeof settings.measurements.waistBack !== 'undefined' - ) { - settings.measurements.waistFront = - settings.measurements.waist - settings.measurements.waistBack - settings.measurements.waistBackArc = settings.measurements.waistBack / 2 - settings.measurements.waistFrontArc = settings.measurements.waistFront / 2 - } - if ( - typeof settings.measurements.crossSeam !== 'undefined' && - typeof settings.measurements.crossSeamFront !== 'undefined' - ) { - settings.measurements.crossSeamBack = - settings.measurements.crossSeam - settings.measurements.crossSeamFront + for (const set of settings) { + if (set.measurements) { + if ( + typeof set.measurements.seatBack !== 'undefined' && + typeof set.measurements.seat !== 'undefined' + ) { + set.measurements.seatFront = set.measurements.seat - set.measurements.seatBack + set.measurements.seatBackArc = set.measurements.seatBack / 2 + set.measurements.seatFrontArc = set.measurements.seatFront / 2 + } + if ( + typeof set.measurements.waist !== 'undefined' && + typeof set.measurements.waistBack !== 'undefined' + ) { + set.measurements.waistFront = set.measurements.waist - set.measurements.waistBack + set.measurements.waistBackArc = set.measurements.waistBack / 2 + set.measurements.waistFrontArc = set.measurements.waistFront / 2 + } + if ( + typeof set.measurements.crossSeam !== 'undefined' && + typeof set.measurements.crossSeamFront !== 'undefined' + ) { + set.measurements.crossSeamBack = + set.measurements.crossSeam - set.measurements.crossSeamFront + } } } }, diff --git a/plugins/plugin-measurements/tests/plugin.test.mjs b/plugins/plugin-measurements/tests/plugin.test.mjs index 2d558136917..005a5e57df9 100644 --- a/plugins/plugin-measurements/tests/plugin.test.mjs +++ b/plugins/plugin-measurements/tests/plugin.test.mjs @@ -12,62 +12,47 @@ const measurements = { crossSeam: 100, crossSeamFront: 42, } - const part = { name: 'test', - draft: ({ points, Point }) => { + draft: ({ points, Point, part }) => { points.from = new Point(10, 20) points.to = new Point(10, 230) + + return part }, + measurements: Object.keys(measurements), + plugins: [plugin], } -const Pattern = new Design({ plugins: [plugin], parts: [part] }) -const pattern = new Pattern({ measurements }) -pattern.draft() +const Pattern = new Design({ parts: [part] }) describe('Measurements Plugin Tests', () => { it('Should set the extra measurements', () => { - expect(pattern.settings.measurements.seatFront).to.equal(40) - expect(pattern.settings.measurements.seatFrontArc).to.equal(20) - expect(pattern.settings.measurements.seatBackArc).to.equal(30) - expect(pattern.settings.measurements.waistFront).to.equal(55) - expect(pattern.settings.measurements.waistFrontArc).to.equal(27.5) - expect(pattern.settings.measurements.crossSeamBack).to.equal(58) + const pattern = new Pattern({ measurements }) + pattern.draft() + expect(pattern.settings[0].measurements.seatFront).to.equal(40) + expect(pattern.settings[0].measurements.seatFrontArc).to.equal(20) + expect(pattern.settings[0].measurements.seatBackArc).to.equal(30) + expect(pattern.settings[0].measurements.waistFront).to.equal(55) + expect(pattern.settings[0].measurements.waistFrontArc).to.equal(27.5) + expect(pattern.settings[0].measurements.crossSeamBack).to.equal(58) }) it('Should calculate seatFront from seat and seatBack', function () { - const testPattern = new Design({ - measurements: {}, - plugins: [plugin], - }) - const pattern = new testPattern() - const userMeasurements = { seat: 50, seatBack: 20 } - pattern.settings.measurements = userMeasurements + const pattern = new Pattern({ measurements: { seat: 50, seatBack: 20 } }) pattern.draft() - expect(pattern.settings.measurements.seatFront).to.equal(30) + expect(pattern.settings[0].measurements.seatFront).to.equal(30) }) it('Should calculate waistFrontArc and waistBackArc from waist and waistBack', function () { - const testPattern = new Design({ - measurements: {}, - plugins: [plugin], - }) - const pattern = new testPattern() - const userMeasurements = { waist: 50, waistBack: 20 } - pattern.settings.measurements = userMeasurements + const pattern = new Pattern({ measurements: { waist: 50, waistBack: 20 } }) pattern.draft() - expect(pattern.settings.measurements.waistFrontArc).to.equal(15) - expect(pattern.settings.measurements.waistBackArc).to.equal(10) + expect(pattern.settings[0].measurements.waistFrontArc).to.equal(15) + expect(pattern.settings[0].measurements.waistBackArc).to.equal(10) }) it('Should calculate crossSeamBack from crossSeam and crossSeamFront', function () { - const testPattern = new Design({ - measurements: {}, - plugins: [plugin], - }) - const pattern = new testPattern() - const userMeasurements = { crossSeam: 50, crossSeamFront: 20 } - pattern.settings.measurements = userMeasurements + const pattern = new Pattern({ measurements: { crossSeam: 50, crossSeamFront: 20 } }) pattern.draft() - expect(pattern.settings.measurements.crossSeamBack).to.equal(30) + expect(pattern.settings[0].measurements.crossSeamBack).to.equal(30) }) }) From 026d090351e1740648b718d0e6d25dff13241e76 Mon Sep 17 00:00:00 2001 From: Joost De Cock Date: Tue, 27 Sep 2022 11:57:31 +0200 Subject: [PATCH 13/46] chore(plugin-mirror): Changes for v3. See #2856 --- plugins/plugin-mirror/tests/plugin.test.mjs | 79 +++++++++++---------- 1 file changed, 41 insertions(+), 38 deletions(-) diff --git a/plugins/plugin-mirror/tests/plugin.test.mjs b/plugins/plugin-mirror/tests/plugin.test.mjs index 1a6b755410a..3dbee0a1de5 100644 --- a/plugins/plugin-mirror/tests/plugin.test.mjs +++ b/plugins/plugin-mirror/tests/plugin.test.mjs @@ -7,7 +7,7 @@ const expect = chai.expect describe('Mirror Plugin Tests', () => { const part = { name: 'test', - draft: ({ points, Point, macro, paths, Path }) => { + draft: ({ points, Point, macro, paths, Path, part }) => { points.mirrorA = new Point(-100, -100) points.mirrorB = new Point(100, 100) points.a = new Point(10, 20) @@ -23,58 +23,61 @@ describe('Mirror Plugin Tests', () => { macro('mirror', settings) macro('mirror', { ...settings, prefix: 'test' }) macro('mirror', { ...settings, clone: false }) + + return part }, + plugins: [plugin], } - const Pattern = new Design({ plugins: [plugin], parts: [part] }) + const Pattern = new Design({ parts: [part] }) const pattern = new Pattern() pattern.draft() it('Should mirror points', () => { - expect(pattern.parts.test.points.mirroredA.x).to.equal(20) - expect(pattern.parts.test.points.mirroredA.y).to.equal(10) - expect(pattern.parts.test.points.mirroredB.x).to.equal(40) - expect(pattern.parts.test.points.mirroredB.y).to.equal(30) + expect(pattern.parts[0].test.points.mirroredA.x).to.equal(20) + expect(pattern.parts[0].test.points.mirroredA.y).to.equal(10) + expect(pattern.parts[0].test.points.mirroredB.x).to.equal(40) + expect(pattern.parts[0].test.points.mirroredB.y).to.equal(30) }) it('Should mirror points with custom prefix', () => { - expect(pattern.parts.test.points.testA.x).to.equal(20) - expect(pattern.parts.test.points.testA.y).to.equal(10) - expect(pattern.parts.test.points.testB.x).to.equal(40) - expect(pattern.parts.test.points.testB.y).to.equal(30) + expect(pattern.parts[0].test.points.testA.x).to.equal(20) + expect(pattern.parts[0].test.points.testA.y).to.equal(10) + expect(pattern.parts[0].test.points.testB.x).to.equal(40) + expect(pattern.parts[0].test.points.testB.y).to.equal(30) }) it('Should mirror points without cloning them', () => { - expect(pattern.parts.test.points.a.x).to.equal(20) - expect(pattern.parts.test.points.a.y).to.equal(10) - expect(pattern.parts.test.points.b.x).to.equal(40) - expect(pattern.parts.test.points.b.y).to.equal(30) + expect(pattern.parts[0].test.points.a.x).to.equal(20) + expect(pattern.parts[0].test.points.a.y).to.equal(10) + expect(pattern.parts[0].test.points.b.x).to.equal(40) + expect(pattern.parts[0].test.points.b.y).to.equal(30) }) it('Should mirror paths', () => { - expect(pattern.parts.test.paths.mirroredTest.ops[0].to.x).to.equal(2) - expect(pattern.parts.test.paths.mirroredTest.ops[0].to.y).to.equal(1) - expect(pattern.parts.test.paths.mirroredTest.ops[1].cp1.x).to.equal(20) - expect(pattern.parts.test.paths.mirroredTest.ops[1].cp1.y).to.equal(10) - expect(pattern.parts.test.paths.mirroredTest.ops[1].cp2.x).to.equal(40) - expect(pattern.parts.test.paths.mirroredTest.ops[1].cp2.y).to.equal(30) - expect(pattern.parts.test.paths.mirroredTest.ops[1].to.x).to.equal(60) - expect(pattern.parts.test.paths.mirroredTest.ops[1].to.y).to.equal(50) + expect(pattern.parts[0].test.paths.mirroredTest.ops[0].to.x).to.equal(2) + expect(pattern.parts[0].test.paths.mirroredTest.ops[0].to.y).to.equal(1) + expect(pattern.parts[0].test.paths.mirroredTest.ops[1].cp1.x).to.equal(20) + expect(pattern.parts[0].test.paths.mirroredTest.ops[1].cp1.y).to.equal(10) + expect(pattern.parts[0].test.paths.mirroredTest.ops[1].cp2.x).to.equal(40) + expect(pattern.parts[0].test.paths.mirroredTest.ops[1].cp2.y).to.equal(30) + expect(pattern.parts[0].test.paths.mirroredTest.ops[1].to.x).to.equal(60) + expect(pattern.parts[0].test.paths.mirroredTest.ops[1].to.y).to.equal(50) }) it('Should mirror paths with custom prefix', () => { - expect(pattern.parts.test.paths.testTest.ops[0].to.x).to.equal(2) - expect(pattern.parts.test.paths.testTest.ops[0].to.y).to.equal(1) - expect(pattern.parts.test.paths.testTest.ops[1].cp1.x).to.equal(20) - expect(pattern.parts.test.paths.testTest.ops[1].cp1.y).to.equal(10) - expect(pattern.parts.test.paths.testTest.ops[1].cp2.x).to.equal(40) - expect(pattern.parts.test.paths.testTest.ops[1].cp2.y).to.equal(30) - expect(pattern.parts.test.paths.testTest.ops[1].to.x).to.equal(60) - expect(pattern.parts.test.paths.testTest.ops[1].to.y).to.equal(50) + expect(pattern.parts[0].test.paths.testTest.ops[0].to.x).to.equal(2) + expect(pattern.parts[0].test.paths.testTest.ops[0].to.y).to.equal(1) + expect(pattern.parts[0].test.paths.testTest.ops[1].cp1.x).to.equal(20) + expect(pattern.parts[0].test.paths.testTest.ops[1].cp1.y).to.equal(10) + expect(pattern.parts[0].test.paths.testTest.ops[1].cp2.x).to.equal(40) + expect(pattern.parts[0].test.paths.testTest.ops[1].cp2.y).to.equal(30) + expect(pattern.parts[0].test.paths.testTest.ops[1].to.x).to.equal(60) + expect(pattern.parts[0].test.paths.testTest.ops[1].to.y).to.equal(50) }) it('Should mirror paths without cloning them', () => { - expect(pattern.parts.test.paths.test.ops[0].to.x).to.equal(2) - expect(pattern.parts.test.paths.test.ops[0].to.y).to.equal(1) - expect(pattern.parts.test.paths.test.ops[1].cp1.x).to.equal(20) - expect(pattern.parts.test.paths.test.ops[1].cp1.y).to.equal(10) - expect(pattern.parts.test.paths.test.ops[1].cp2.x).to.equal(40) - expect(pattern.parts.test.paths.test.ops[1].cp2.y).to.equal(30) - expect(pattern.parts.test.paths.test.ops[1].to.x).to.equal(60) - expect(pattern.parts.test.paths.test.ops[1].to.y).to.equal(50) + expect(pattern.parts[0].test.paths.test.ops[0].to.x).to.equal(2) + expect(pattern.parts[0].test.paths.test.ops[0].to.y).to.equal(1) + expect(pattern.parts[0].test.paths.test.ops[1].cp1.x).to.equal(20) + expect(pattern.parts[0].test.paths.test.ops[1].cp1.y).to.equal(10) + expect(pattern.parts[0].test.paths.test.ops[1].cp2.x).to.equal(40) + expect(pattern.parts[0].test.paths.test.ops[1].cp2.y).to.equal(30) + expect(pattern.parts[0].test.paths.test.ops[1].to.x).to.equal(60) + expect(pattern.parts[0].test.paths.test.ops[1].to.y).to.equal(50) }) }) From 11e45c30dbc3d4fd4a154432b0c181453c772b2a Mon Sep 17 00:00:00 2001 From: Joost De Cock Date: Tue, 27 Sep 2022 11:59:35 +0200 Subject: [PATCH 14/46] chore(plugin-notches): Changes for v3. See #2856 --- plugins/plugin-notches/tests/plugin.test.mjs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/plugins/plugin-notches/tests/plugin.test.mjs b/plugins/plugin-notches/tests/plugin.test.mjs index 2a6c27d1bde..5f9553532b7 100644 --- a/plugins/plugin-notches/tests/plugin.test.mjs +++ b/plugins/plugin-notches/tests/plugin.test.mjs @@ -9,8 +9,9 @@ const part = { draft: ({ Point, snippets, Snippet }) => { snippets.button = new Snippet('notch', new Point(10, 20)) }, + plugins: [plugin], } -const Pattern = new Design({ plugins: [plugin], parts: [part] }) +const Pattern = new Design({ parts: [part] }) const pattern = new Pattern() pattern.draft().render() @@ -26,11 +27,14 @@ describe('Notches Plugin Test', () => { it('Draws a notch on an anchor point', () => { const part = { name: 'test', - draft: ({ Point, snippets, Snippet }) => { + draft: ({ Point, snippets, Snippet, part }) => { snippets.button = new Snippet('notch', new Point(10, 20)) + + return part }, + plugins: [plugin], } - const Pattern = new Design({ plugins: [plugin], parts: [part] }) + const Pattern = new Design({ parts: [part] }) const pattern = new Pattern() pattern.draft().render() const c = pattern.svg From f5f5968f3b5ae8fe27792522e3eaf065e92a6aac Mon Sep 17 00:00:00 2001 From: Joost De Cock Date: Tue, 27 Sep 2022 12:31:07 +0200 Subject: [PATCH 15/46] fix(shared): Issue with boolean options --- .../workbench/menu/design-options/option.js | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/sites/shared/components/workbench/menu/design-options/option.js b/sites/shared/components/workbench/menu/design-options/option.js index 69a06fe4ef6..1b6bfdf02d4 100644 --- a/sites/shared/components/workbench/menu/design-options/option.js +++ b/sites/shared/components/workbench/menu/design-options/option.js @@ -2,31 +2,30 @@ import { Chevron } from 'shared/components/navigation/primary' import { optionType } from 'shared/utils' import { Li, Details, Summary, SumButton, SumDiv, Deg } from 'shared/components/workbench/menu' import { useTranslation } from 'next-i18next' -import {values} from 'shared/components/workbench/menu/design-options/option-value' -import {inputs} from 'shared/components/workbench/menu/design-options/option-input' +import { values } from 'shared/components/workbench/menu/design-options/option-value' +import { inputs } from 'shared/components/workbench/menu/design-options/option-input' -const Option = props => { +const Option = (props) => { const { t } = useTranslation([`o_${props.design.designConfig.data.name}`]) - const opt = props.design.patternConfig.options[props.option]; + const opt = props.design.patternConfig.options[props.option] const type = optionType(opt) const Input = inputs[type] const Value = values[type] try { - const hide = opt.hide && opt.hide(props.draft.settings); + const hide = opt.hide && opt.hide(props.draft.settings) if (hide) return null - } catch(e) { - console.warn(`error occurred in hide method for ${ props.option}, so we'll just show it`, e) + } catch (e) { + console.warn(`error occurred in hide method for ${props.option}, so we'll just show it`, e) } if (type === 'bool') { const toggleBoolean = () => { const dflt = opt.bool const current = props.gist?.options?.[props.option] - if (typeof current === 'undefined') - props.updateGist(['options', props.option], !dflt) - else props.unsetGist(['options', props.option]) + const newVal = typeof current === 'undefined' ? !dflt : !current + props.updateGist(['options', props.option], newVal) } return ( @@ -34,7 +33,7 @@ const Option = props => { @@ -51,7 +50,7 @@ const Option = props => { {t(`${props.option}.t`)} - {t(`${props.option}.t`) } + {t(`${props.option}.t`)} - + From 07d7f2defc61fb88302c508aa9fc9a699bcdd539 Mon Sep 17 00:00:00 2001 From: Joost De Cock Date: Tue, 27 Sep 2022 12:35:35 +0200 Subject: [PATCH 16/46] fix(plugintest): Force radius to number --- designs/plugintest/src/plugin-round.mjs | 2 +- plugins/plugin-round/src/index.mjs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/designs/plugintest/src/plugin-round.mjs b/designs/plugintest/src/plugin-round.mjs index 82e33b18e9e..abb5046cce7 100644 --- a/designs/plugintest/src/plugin-round.mjs +++ b/designs/plugintest/src/plugin-round.mjs @@ -17,7 +17,7 @@ const pluginRound = ({ Point, points, Path, paths, macro, options, part }) => { .attr('class', 'note dashed') const opts = { - radius: options.roundRadius, + radius: Number(options.roundRadius), hide: options.roundHide, } diff --git a/plugins/plugin-round/src/index.mjs b/plugins/plugin-round/src/index.mjs index 567217a725d..be7f0a02ee6 100644 --- a/plugins/plugin-round/src/index.mjs +++ b/plugins/plugin-round/src/index.mjs @@ -31,7 +31,7 @@ export const plugin = { this.points[prefix + 'End'] ) .attr('class', so.class ? so.class : '') - if (so?.hidden) this.paths[prefix + 'Rounded'].hide() + if (so?.hide) this.paths[prefix + 'Rounded'].hide() else this.paths[prefix + 'Rounded'].unhide() }, }, From b4da96da0712ab9ecf83ed5aee2c88f32ded5da0 Mon Sep 17 00:00:00 2001 From: Joost De Cock Date: Tue, 27 Sep 2022 13:41:44 +0200 Subject: [PATCH 17/46] chore(plugin-scalebox): Changes for v3. See #2856 --- plugins/plugin-scalebox/src/miniscale.mjs | 67 +++++++------ plugins/plugin-scalebox/src/scalebox.mjs | 99 +++++++++---------- plugins/plugin-scalebox/tests/plugin.test.mjs | 56 +++++++---- 3 files changed, 114 insertions(+), 108 deletions(-) diff --git a/plugins/plugin-scalebox/src/miniscale.mjs b/plugins/plugin-scalebox/src/miniscale.mjs index 533beeb5645..b7876518fd0 100644 --- a/plugins/plugin-scalebox/src/miniscale.mjs +++ b/plugins/plugin-scalebox/src/miniscale.mjs @@ -1,7 +1,7 @@ -export function miniscale(so) { +export function miniscale(so, { points, paths, Point, Path, scale }) { // Passing `false` will remove the miniscale if (so === false) { - for (let id of [ + for (const id of [ '__miniscaleMetricTopLeft', '__miniscaleMetricTopRight', '__miniscaleMetricBottomRight', @@ -13,15 +13,13 @@ export function miniscale(so) { '__miniscaleMetric', '__miniscaleImperial', ]) - delete this.points[id] - for (let id of ['__miniscaleMetric', '__miniscaleImperial']) delete this.paths[id] + delete points[id] + for (const id of ['__miniscaleMetric', '__miniscaleImperial']) delete paths[id] return true } - const scale = this.context.settings.scale - // Convert scale to a value between 0 and 5, inclusive. - const scaleIndex = Math.ceil(6 * Math.max(0.1, Math.min(1, this.context.settings.scale))) - 1 + const scaleIndex = Math.ceil(6 * Math.max(0.1, Math.min(1, scale))) - 1 // Metric size in mm / display value and imperial size in mm / display value for each scale index. const sizes = [ @@ -37,20 +35,21 @@ export function miniscale(so) { const metricDisplaySize = sizes[scaleIndex][1] const imperialDisplaySize = sizes[scaleIndex][3] // Box points - this.points.__miniscaleMetricTopLeft = new this.Point(so.at.x - m, so.at.y - m) - this.points.__miniscaleMetricTopRight = new this.Point(so.at.x + m, so.at.y - m) - this.points.__miniscaleMetricBottomLeft = new this.Point(so.at.x - m, so.at.y + m) - this.points.__miniscaleMetricBottomRight = new this.Point(so.at.x + m, so.at.y + m) - this.points.__miniscaleImperialTopLeft = new this.Point(so.at.x - i, so.at.y - i) - this.points.__miniscaleImperialTopRight = new this.Point(so.at.x + i, so.at.y - i) - this.points.__miniscaleImperialBottomLeft = new this.Point(so.at.x - i, so.at.y + i) - this.points.__miniscaleImperialBottomRight = new this.Point(so.at.x + i, so.at.y + i) + points.__miniscaleMetricTopLeft = new Point(so.at.x - m, so.at.y - m) + points.__miniscaleMetricTopRight = new Point(so.at.x + m, so.at.y - m) + points.__miniscaleMetricBottomLeft = new Point(so.at.x - m, so.at.y + m) + points.__miniscaleMetricBottomRight = new Point(so.at.x + m, so.at.y + m) + points.__miniscaleImperialTopLeft = new Point(so.at.x - i, so.at.y - i) + points.__miniscaleImperialTopRight = new Point(so.at.x + i, so.at.y - i) + points.__miniscaleImperialBottomLeft = new Point(so.at.x - i, so.at.y + i) + points.__miniscaleImperialBottomRight = new Point(so.at.x + i, so.at.y + i) // Text anchor points - this.points.__miniscaleMetric = new this.Point(so.at.x, so.at.y - 2 * scale) - this.points.__miniscaleImperial = new this.Point(so.at.x, so.at.y + 8 * scale) + points.__miniscaleMetric = new Point(so.at.x, so.at.y - 2 * scale) + points.__miniscaleImperial = new Point(so.at.x, so.at.y + 8 * scale) // Rotation if (so.rotate) { - let points = [ + so.rotate = Number(so.rotate) + let toRotate = [ '__miniscaleMetricTopLeft', '__miniscaleMetricTopRight', '__miniscaleMetricBottomLeft', @@ -62,34 +61,34 @@ export function miniscale(so) { '__miniscaleMetric', '__miniscaleImperial', ] - for (let pid of points) this.points[pid] = this.points[pid].rotate(so.rotate, so.at) - for (let pid of points.slice(8)) { - this.points[pid].attributes.set( + for (const pid of toRotate) points[pid] = points[pid].rotate(so.rotate, so.at) + for (const pid of toRotate.slice(8)) { + points[pid].attributes.set( 'data-text-transform', - `rotate(${so.rotate * -1}, ${this.points[pid].x}, ${this.points[pid].y})` + `rotate(${so.rotate * -1}, ${points[pid].x}, ${points[pid].y})` ) } } // Paths - this.paths.__miniscaleImperial = new this.Path() + paths.__miniscaleImperial = new Path() .attr('class', 'scalebox imperial fill-current') - .move(this.points.__miniscaleImperialTopLeft) - .line(this.points.__miniscaleImperialBottomLeft) - .line(this.points.__miniscaleImperialBottomRight) - .line(this.points.__miniscaleImperialTopRight) + .move(points.__miniscaleImperialTopLeft) + .line(points.__miniscaleImperialBottomLeft) + .line(points.__miniscaleImperialBottomRight) + .line(points.__miniscaleImperialTopRight) .close() - this.paths.__miniscaleMetric = new this.Path() + paths.__miniscaleMetric = new Path() .attr('class', 'scalebox metric fill-bg') - .move(this.points.__miniscaleMetricTopLeft) - .line(this.points.__miniscaleMetricBottomLeft) - .line(this.points.__miniscaleMetricBottomRight) - .line(this.points.__miniscaleMetricTopRight) + .move(points.__miniscaleMetricTopLeft) + .line(points.__miniscaleMetricBottomLeft) + .line(points.__miniscaleMetricBottomRight) + .line(points.__miniscaleMetricTopRight) .close() // Text - this.points.__miniscaleMetric = this.points.__miniscaleMetric + points.__miniscaleMetric = points.__miniscaleMetric .attr('data-text', `${metricDisplaySize} x ${metricDisplaySize}`) .attr('data-text-class', 'text-xs center') - this.points.__miniscaleImperial = this.points.__miniscaleImperial + points.__miniscaleImperial = points.__miniscaleImperial .attr('data-text', `${imperialDisplaySize} x ${imperialDisplaySize}`) .attr('data-text-class', 'text-xs center ') } diff --git a/plugins/plugin-scalebox/src/scalebox.mjs b/plugins/plugin-scalebox/src/scalebox.mjs index 35fec755fcf..55a343f102b 100644 --- a/plugins/plugin-scalebox/src/scalebox.mjs +++ b/plugins/plugin-scalebox/src/scalebox.mjs @@ -1,4 +1,4 @@ -export function scalebox(so) { +export function scalebox(so, { store, points, paths, scale, Point, Path }) { // Passing `false` will remove the scalebox if (so === false) { for (let id of [ @@ -17,15 +17,13 @@ export function scalebox(so) { '__scaleboxMetric', '__scaleboxImperial', ]) - delete this.points[id] - for (let id of ['__scaleboxMetric', '__scaleboxImperial']) delete this.paths[id] + delete points[id] + for (let id of ['__scaleboxMetric', '__scaleboxImperial']) delete paths[id] return true } - const scale = this.context.settings.scale - // Convert scale to a value between 0 and 9, inclusive. - const scaleIndex = Math.round(10 * Math.max(0.1, Math.min(1, this.context.settings.scale))) - 1 + const scaleIndex = Math.round(10 * Math.max(0.1, Math.min(1, scale))) - 1 // Metric width and height in mm and display width and height for each scale index. const metricSizes = [ @@ -66,48 +64,43 @@ export function scalebox(so) { const imperialDisplayHeight = imperialSizes[scaleIndex][3] // Box points - this.points.__scaleboxMetricTopLeft = new this.Point( - so.at.x - metricWidth / 2, - so.at.y - metricHeight / 2 - ) - this.points.__scaleboxMetricTopRight = new this.Point( - so.at.x + metricWidth / 2, - so.at.y - metricHeight / 2 - ) - this.points.__scaleboxMetricBottomLeft = new this.Point( + points.__scaleboxMetricTopLeft = new Point(so.at.x - metricWidth / 2, so.at.y - metricHeight / 2) + points.__scaleboxMetricTopRight = new Point(so.at.x + metricWidth / 2, so.at.y - metricHeight / 2) + points.__scaleboxMetricBottomLeft = new Point( so.at.x - metricWidth / 2, so.at.y + metricHeight / 2 ) - this.points.__scaleboxMetricBottomRight = new this.Point( + points.__scaleboxMetricBottomRight = new Point( so.at.x + metricWidth / 2, so.at.y + metricHeight / 2 ) - this.points.__scaleboxImperialTopLeft = new this.Point( + points.__scaleboxImperialTopLeft = new Point( so.at.x - imperialWidth / 2, so.at.y - imperialHeight / 2 ) - this.points.__scaleboxImperialTopRight = new this.Point( + points.__scaleboxImperialTopRight = new Point( so.at.x + imperialWidth / 2, so.at.y - imperialHeight / 2 ) - this.points.__scaleboxImperialBottomLeft = new this.Point( + points.__scaleboxImperialBottomLeft = new Point( so.at.x - imperialWidth / 2, so.at.y + imperialHeight / 2 ) - this.points.__scaleboxImperialBottomRight = new this.Point( + points.__scaleboxImperialBottomRight = new Point( so.at.x + imperialWidth / 2, so.at.y + imperialHeight / 2 ) // Text anchor points - this.points.__scaleboxLead = new this.Point(so.at.x - 45 * scale, so.at.y - 15 * scale) - this.points.__scaleboxTitle = this.points.__scaleboxLead.shift(-90, 10 * scale) - this.points.__scaleboxText = this.points.__scaleboxTitle.shift(-90, 12 * scale) - this.points.__scaleboxLink = this.points.__scaleboxText.shift(-90, 5 * scale) - this.points.__scaleboxMetric = new this.Point(so.at.x, so.at.y + 20 * scale) - this.points.__scaleboxImperial = new this.Point(so.at.x, so.at.y + 24 * scale) + points.__scaleboxLead = new Point(so.at.x - 45 * scale, so.at.y - 15 * scale) + points.__scaleboxTitle = points.__scaleboxLead.shift(-90, 10 * scale) + points.__scaleboxText = points.__scaleboxTitle.shift(-90, 12 * scale) + points.__scaleboxLink = points.__scaleboxText.shift(-90, 5 * scale) + points.__scaleboxMetric = new Point(so.at.x, so.at.y + 20 * scale) + points.__scaleboxImperial = new Point(so.at.x, so.at.y + 24 * scale) // Rotation if (so.rotate) { - let points = [ + so.rotate = Number(so.rotate) + let toRotate = [ '__scaleboxMetricTopLeft', '__scaleboxMetricTopRight', '__scaleboxMetricBottomLeft', @@ -123,61 +116,61 @@ export function scalebox(so) { '__scaleboxMetric', '__scaleboxImperial', ] - for (let pid of points) this.points[pid] = this.points[pid].rotate(so.rotate, so.at) - for (let pid of points.slice(8)) { - this.points[pid].attributes.set( + for (let pid of toRotate) points[pid] = points[pid].rotate(so.rotate, so.at) + for (let pid of toRotate.slice(8)) { + points[pid].attributes.set( 'data-text-transform', - `rotate(${so.rotate * -1}, ${this.points[pid].x}, ${this.points[pid].y})` + `rotate(${so.rotate * -1}, ${points[pid].x}, ${points[pid].y})` ) } } // Paths - this.paths.__scaleboxImperial = new this.Path() + paths.__scaleboxImperial = new Path() .attr('class', 'scalebox imperial fill-current') - .move(this.points.__scaleboxImperialTopLeft) - .line(this.points.__scaleboxImperialBottomLeft) - .line(this.points.__scaleboxImperialBottomRight) - .line(this.points.__scaleboxImperialTopRight) + .move(points.__scaleboxImperialTopLeft) + .line(points.__scaleboxImperialBottomLeft) + .line(points.__scaleboxImperialBottomRight) + .line(points.__scaleboxImperialTopRight) .close() - this.paths.__scaleboxMetric = new this.Path() + paths.__scaleboxMetric = new Path() .attr('class', 'scalebox metric fill-bg') - .move(this.points.__scaleboxMetricTopLeft) - .line(this.points.__scaleboxMetricBottomLeft) - .line(this.points.__scaleboxMetricBottomRight) - .line(this.points.__scaleboxMetricTopRight) + .move(points.__scaleboxMetricTopLeft) + .line(points.__scaleboxMetricBottomLeft) + .line(points.__scaleboxMetricBottomRight) + .line(points.__scaleboxMetricTopRight) .close() // Lead - this.points.__scaleboxLead = this.points.__scaleboxLead + points.__scaleboxLead = points.__scaleboxLead .attr('data-text', so.lead || 'FreeSewing') .attr('data-text-class', 'text-sm') // Title - if (so.title) this.points.__scaleboxTitle.attributes.set('data-text', so.title) + if (so.title) points.__scaleboxTitle.attributes.set('data-text', so.title) else { - let name = this.context.config?.data?.name || 'No Name' + let name = store.data?.name || 'No Name' if (name.indexOf('@freesewing/') !== -1) name = name.replace('@freesewing/', '') - this.points.__scaleboxTitle = this.points.__scaleboxTitle + points.__scaleboxTitle = points.__scaleboxTitle .attr('data-text', name) - .attr('data-text', 'v' + (this.context.config?.data?.version || 'No Version')) + .attr('data-text', 'v' + (store.data?.version || 'No Version')) } - this.points.__scaleboxTitle.attributes.add('data-text-class', 'text-lg') + points.__scaleboxTitle.attributes.add('data-text-class', 'text-lg') // Text if (typeof so.text === 'string') { - this.points.__scaleboxText.attr('data-text', so.text) + points.__scaleboxText.attr('data-text', so.text) } else { - this.points.__scaleboxText.attr('data-text', 'supportFreesewingBecomeAPatron') - this.points.__scaleboxLink = this.points.__scaleboxLink + points.__scaleboxText.attr('data-text', 'supportFreesewingBecomeAPatron') + points.__scaleboxLink = points.__scaleboxLink .attr('data-text', 'freesewing.org/patrons/join') .attr('data-text-class', 'text-sm fill-note') } - this.points.__scaleboxText.attr('data-text-class', 'text-xs').attr('data-text-lineheight', 4) + points.__scaleboxText.attr('data-text-class', 'text-xs').attr('data-text-lineheight', 4) // Instructions - this.points.__scaleboxMetric = this.points.__scaleboxMetric + points.__scaleboxMetric = points.__scaleboxMetric .attr('data-text', 'theWhiteInsideOfThisBoxShouldMeasure') .attr('data-text', `${metricDisplayWidth}`) .attr('data-text', 'x') .attr('data-text', `${metricDisplayHeight}`) .attr('data-text-class', 'text-xs center') - this.points.__scaleboxImperial = this.points.__scaleboxImperial + points.__scaleboxImperial = points.__scaleboxImperial .attr('data-text', 'theBlackOutsideOfThisBoxShouldMeasure') .attr('data-text', `${imperialDisplayWidth}`) .attr('data-text', 'x') diff --git a/plugins/plugin-scalebox/tests/plugin.test.mjs b/plugins/plugin-scalebox/tests/plugin.test.mjs index 1c77708efa4..57cf10d1842 100644 --- a/plugins/plugin-scalebox/tests/plugin.test.mjs +++ b/plugins/plugin-scalebox/tests/plugin.test.mjs @@ -8,17 +8,20 @@ describe('Scalebox Plugin Tests', () => { it('Should run the default scalebox macro', () => { const part = { name: 'test', - draft: ({ points, Point, macro }) => { + draft: ({ points, Point, macro, part }) => { points.anchor = new Point(100, 200) macro('scalebox', { at: points.anchor, }) + + return part }, + plugins: [plugin], } - const Pattern = new Design({ parts: [part], plugins: [plugin] }) + const Pattern = new Design({ parts: [part] }) const pattern = new Pattern() pattern.draft() - let p = pattern.parts.test.points + let p = pattern.parts[0].test.points expect(p.__scaleboxMetricTopLeft.x).to.equal(50) expect(p.__scaleboxMetricTopLeft.y).to.equal(175) expect(p.__scaleboxMetricTopRight.x).to.equal(150) @@ -47,7 +50,7 @@ describe('Scalebox Plugin Tests', () => { expect(p.__scaleboxMetric.y).to.equal(220) expect(p.__scaleboxImperial.x).to.equal(100) expect(p.__scaleboxImperial.y).to.equal(224) - p = pattern.parts.test.paths.__scaleboxMetric + p = pattern.parts[0].test.paths.__scaleboxMetric expect(p.ops[0].type).to.equal('move') expect(p.ops[1].type).to.equal('line') expect(p.ops[2].type).to.equal('line') @@ -61,7 +64,7 @@ describe('Scalebox Plugin Tests', () => { expect(p.ops[2].to.y).to.equal(225) expect(p.ops[3].to.x).to.equal(150) expect(p.ops[3].to.y).to.equal(175) - p = pattern.parts.test.paths.__scaleboxImperial + p = pattern.parts[0].test.paths.__scaleboxImperial expect(p.ops[0].type).to.equal('move') expect(p.ops[1].type).to.equal('line') expect(p.ops[2].type).to.equal('line') @@ -87,11 +90,12 @@ describe('Scalebox Plugin Tests', () => { rotate: 90, }) }, + plugins: [plugin], } - const Pattern = new Design({ parts: [part], plugins: [plugin] }) + const Pattern = new Design({ parts: [part] }) const pattern = new Pattern() pattern.draft() - const p = pattern.parts.test.points + const p = pattern.parts[0].test.points expect(round(p.__scaleboxMetricTopLeft.x)).to.equal(75) expect(round(p.__scaleboxMetricTopLeft.y)).to.equal(250) expect(round(p.__scaleboxMetricTopRight.x)).to.equal(75) @@ -125,27 +129,29 @@ describe('Scalebox Plugin Tests', () => { it('Should run the scalebox macro with default text', () => { const part = { name: 'test', - draft: ({ points, Point, macro }) => { + draft: ({ points, Point, macro, part }) => { points.anchor = new Point(100, 200) macro('scalebox', { at: points.anchor, }) + + return part }, + plugins: [plugin], } const Pattern = new Design({ parts: [part], - plugins: [plugin], data: { name: 'test', version: '1.2.3' }, }) const pattern = new Pattern() pattern.draft() - let p = pattern.parts.test.points.__scaleboxLead.attributes + let p = pattern.parts[0].test.points.__scaleboxLead.attributes expect(p.get('data-text')).to.equal('FreeSewing') expect(p.get('data-text-class')).to.equal('text-sm') - p = pattern.parts.test.points.__scaleboxTitle.attributes + p = pattern.parts[0].test.points.__scaleboxTitle.attributes expect(p.get('data-text')).to.equal('test v1.2.3') expect(p.get('data-text-class')).to.equal('text-lg') - p = pattern.parts.test.points.__scaleboxText.attributes + p = pattern.parts[0].test.points.__scaleboxText.attributes expect(p.get('data-text-class')).to.equal('text-xs') expect(p.get('data-text-lineheight')).to.equal('4') expect(p.list['data-text'][0]).to.equal('supportFreesewingBecomeAPatron') @@ -154,7 +160,7 @@ describe('Scalebox Plugin Tests', () => { it('Should run the scalebox macro with custom text', () => { const part = { name: 'test', - draft: ({ points, Point, macro }) => { + draft: ({ points, Point, macro, part }) => { points.anchor = new Point(100, 200) macro('scalebox', { at: points.anchor, @@ -162,22 +168,24 @@ describe('Scalebox Plugin Tests', () => { title: 'theTitle', text: 'theText', }) + + return part }, + plugins: [plugin], } const Pattern = new Design({ parts: [part], - plugins: [plugin], data: { name: 'test', version: '1.2.3' }, }) const pattern = new Pattern() pattern.draft() - let p = pattern.parts.test.points.__scaleboxLead.attributes + let p = pattern.parts[0].test.points.__scaleboxLead.attributes expect(p.get('data-text')).to.equal('theLead') expect(p.get('data-text-class')).to.equal('text-sm') - p = pattern.parts.test.points.__scaleboxTitle.attributes + p = pattern.parts[0].test.points.__scaleboxTitle.attributes expect(p.get('data-text')).to.equal('theTitle') expect(p.get('data-text-class')).to.equal('text-lg') - p = pattern.parts.test.points.__scaleboxText.attributes + p = pattern.parts[0].test.points.__scaleboxText.attributes expect(p.get('data-text')).to.equal('theText') expect(p.get('data-text-class')).to.equal('text-xs') expect(p.get('data-text-lineheight')).to.equal('4') @@ -186,7 +194,7 @@ describe('Scalebox Plugin Tests', () => { it('Should apply scale to the scalebox macro', () => { const part = { name: 'test', - draft: ({ points, Point, macro }) => { + draft: ({ points, Point, macro, part }) => { points.anchor = new Point(100, 200) macro('scalebox', { at: points.anchor, @@ -194,7 +202,10 @@ describe('Scalebox Plugin Tests', () => { title: 'theTitle', text: 'theText', }) + + return part }, + plugins: [plugin], } const Pattern = new Design({ parts: [part], @@ -203,7 +214,7 @@ describe('Scalebox Plugin Tests', () => { }) const pattern = new Pattern({ scale: 0.5 }) pattern.draft() - let p = pattern.parts.test.points + let p = pattern.parts[0].test.points expect(p.__scaleboxMetricTopLeft.x).to.equal(75) expect(p.__scaleboxMetricTopLeft.y).to.equal(187.5) expect(p.__scaleboxMetricTopRight.x).to.equal(125) @@ -231,12 +242,15 @@ describe('Scalebox Plugin Tests', () => { it('Should apply scale to the miniscale macro', () => { const part = { name: 'test', - draft: ({ points, Point, macro }) => { + draft: ({ points, Point, macro, part }) => { points.anchor = new Point(100, 200) macro('miniscale', { at: points.anchor, }) + + return part }, + plugins: [plugin], } const Pattern = new Design({ parts: [part], @@ -245,7 +259,7 @@ describe('Scalebox Plugin Tests', () => { }) const pattern = new Pattern({ scale: 0.5 }) pattern.draft() - let p = pattern.parts.test.points + let p = pattern.parts[0].test.points expect(p.__miniscaleMetricTopLeft.x).to.equal(92) expect(p.__miniscaleMetricTopLeft.y).to.equal(192) expect(p.__miniscaleMetricTopRight.x).to.equal(108) From ddd5b296b3a44f768c08d152c07b6d9e24fa1993 Mon Sep 17 00:00:00 2001 From: Joost De Cock Date: Tue, 27 Sep 2022 13:43:38 +0200 Subject: [PATCH 18/46] chore(plugin-sprinkle): Changes for v3. See #2856 --- plugins/plugin-sprinkle/src/index.mjs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/plugin-sprinkle/src/index.mjs b/plugins/plugin-sprinkle/src/index.mjs index 16e29577838..59595bd9216 100644 --- a/plugins/plugin-sprinkle/src/index.mjs +++ b/plugins/plugin-sprinkle/src/index.mjs @@ -4,11 +4,11 @@ export const plugin = { name, version, macros: { - sprinkle: function (so) { + sprinkle: function (so, { snippets, Snippet, points }) { for (let pid of so.on) { - this.snippets[pid + '-' + so.snippet] = new this.Snippet(so.snippet, this.points[pid]) - if (so.scale) this.snippets[pid + '-' + so.snippet].attr('data-scale', so.scale) - if (so.rotate) this.snippets[pid + '-' + so.snippet].attr('data-rotate', so.rotate) + snippets[pid + '-' + so.snippet] = new Snippet(so.snippet, points[pid]) + if (so.scale) snippets[pid + '-' + so.snippet].attr('data-scale', so.scale) + if (so.rotate) snippets[pid + '-' + so.snippet].attr('data-rotate', so.rotate) } }, }, From 3e445a8401910b84532b4c1086b76d7e4ea76e38 Mon Sep 17 00:00:00 2001 From: Joost De Cock Date: Tue, 27 Sep 2022 14:01:25 +0200 Subject: [PATCH 19/46] chore(plugin-theme): Changes for v3. See #2856 --- plugins/plugin-theme/src/css.mjs | 4 ++-- plugins/plugin-theme/src/index.mjs | 19 ++++++++++--------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/plugins/plugin-theme/src/css.mjs b/plugins/plugin-theme/src/css.mjs index d77bdc8d33d..326dd01c47a 100644 --- a/plugins/plugin-theme/src/css.mjs +++ b/plugins/plugin-theme/src/css.mjs @@ -1,4 +1,4 @@ -export const paperless = ` +export const paperlessStyle = ` /* Paperless grid */ svg.freesewing path.grid { fill: none; @@ -26,7 +26,7 @@ svg.freesewing path.gridline-xs { svg.freesewing path.gridbox { fill: url(#grid); }` -export const sample = ` +export const sampleStyle = ` /* Sample classes */ svg.freesewing path.sample { stroke-width: 0.75 diff --git a/plugins/plugin-theme/src/index.mjs b/plugins/plugin-theme/src/index.mjs index 18813f91156..bfb6a70d367 100644 --- a/plugins/plugin-theme/src/index.mjs +++ b/plugins/plugin-theme/src/index.mjs @@ -1,5 +1,5 @@ import { name, version } from '../data.mjs' -import { sample, paperless, buildStylesheet } from './css.mjs' +import { sampleStyle, paperlessStyle, buildStylesheet } from './css.mjs' const grid = { metric: ` @@ -28,16 +28,18 @@ export const plugin = { const current = svg.attributes.get('class') if (!current || current.indexOf('freesewing') !== -1) { svg.attributes.set('class', 'freesewing') - svg.style += sample - svg.style += paperless + svg.style += sampleStyle + svg.style += paperlessStyle svg.style += buildStylesheet(svg.pattern.settings.scale, data.stripped) - // FIXME : Re-implement this for v3 - /* - if (svg.pattern.settings[0].paperless) { - svg.pattern.settings.units === 'imperial' + let paperless = false + for (const set of svg.pattern.settings) { + if (set.paperless) paperless = true + } + if (paperless) { + svg.pattern.settings[0].units === 'imperial' ? (svg.defs += grid.imperial) : (svg.defs += grid.metric) - for (const key in svg.pattern.parts) { + for (const key in svg.pattern.parts[0]) { const part = svg.pattern.parts[key] if (!part.hidden && svg.pattern.__needs(key)) { let anchor = new svg.pattern.Point(0, 0) @@ -57,7 +59,6 @@ export const plugin = { } } } - */ } }, }, From f56e67d0071d9f4df14543a16dd92672fcb42fb5 Mon Sep 17 00:00:00 2001 From: Joost De Cock Date: Tue, 27 Sep 2022 14:08:32 +0200 Subject: [PATCH 20/46] chore(plugin-title): Changes for v3. See #2856 --- plugins/plugin-title/src/index.mjs | 26 +++++++++--------- plugins/plugin-title/tests/plugin.test.mjs | 32 +++++++++++++--------- 2 files changed, 32 insertions(+), 26 deletions(-) diff --git a/plugins/plugin-title/src/index.mjs b/plugins/plugin-title/src/index.mjs index f644744b8d4..f6a43442013 100644 --- a/plugins/plugin-title/src/index.mjs +++ b/plugins/plugin-title/src/index.mjs @@ -31,7 +31,7 @@ export const plugin = { }, }, macros: { - title: function (so) { + title: function (so, { points, scale, locale, store }) { const prefix = so.prefix || '' // Passing `false` will remove the title @@ -43,7 +43,7 @@ export const plugin = { `_${prefix}_titleFor`, `_${prefix}_exportDate`, ]) - delete this.points[id] + delete points[id] return true } @@ -59,36 +59,36 @@ export const plugin = { } so = { ...defaults, ...so } - so.scale = so.scale * this.context.settings.scale + so.scale = so.scale * scale let overwrite = true if (so.append) overwrite = false - this.points[`_${prefix}_titleNr`] = so.at + points[`_${prefix}_titleNr`] = so.at .clone() .attr('data-text', so.nr, overwrite) .attr('data-text-class', 'text-4xl fill-note font-bold') .attr('data-text-transform', transform(so.at)) let shift = 8 if (so.title) { - this.points[`_${prefix}_titleName`] = so.at + points[`_${prefix}_titleName`] = so.at .shift(-90 - so.rotation, shift * so.scale) .attr('data-text', so.title) .attr('data-text-class', 'text-lg fill-current font-bold') .attr('data-text-transform', transform(so.at.shift(-90 - so.rotation, 13 * so.scale))) shift += 8 } - let name = this.context.config?.data?.name || 'No Name' + let name = store.data?.name || 'No Name' name = name.replace('@freesewing/', '') - this.points[`_${prefix}_titlePattern`] = so.at + points[`_${prefix}_titlePattern`] = so.at .shift(-90 - so.rotation, shift * so.scale) .attr('data-text', name) - .attr('data-text', 'v' + (this.context.config?.data?.version || 'No Version')) + .attr('data-text', 'v' + (store.data?.version || 'No Version')) .attr('data-text-class', 'fill-note') .attr('data-text-transform', transform(so.at.shift(-90 - so.rotation, shift * so.scale))) - if (this.context.settings.metadata && this.context.settings.metadata.for) { + if (store.data.for) { shift += 8 - this.points[`_${prefix}_titleFor`] = so.at + points[`_${prefix}_titleFor`] = so.at .shift(-90 - so.rotation, shift * so.scale) - .attr('data-text', '( ' + this.context.settings.metadata.for + ' )') + .attr('data-text', '( ' + store.data.for + ' )') .attr('data-text-class', 'fill-current font-bold') .attr('data-text-transform', transform(so.at.shift(-90 - so.rotation, shift * so.scale))) } @@ -98,11 +98,11 @@ export const plugin = { let mins = now.getMinutes() if (hours < 10) hours = `0${hours}` if (mins < 10) mins = `0${mins}` - this.points[`_${prefix}_exportDate`] = so.at + points[`_${prefix}_exportDate`] = so.at .shift(-90 - so.rotation, shift * so.scale) .attr( 'data-text', - now.toLocaleDateString(this.context.settings.locale || 'en', { + now.toLocaleDateString(locale || 'en', { weekday: 'long', year: 'numeric', month: 'short', diff --git a/plugins/plugin-title/tests/plugin.test.mjs b/plugins/plugin-title/tests/plugin.test.mjs index a51e5126bc4..c4e801efd24 100644 --- a/plugins/plugin-title/tests/plugin.test.mjs +++ b/plugins/plugin-title/tests/plugin.test.mjs @@ -8,35 +8,37 @@ describe('Title Plugin Tests', () => { it('Should run the title macro', () => { const part = { name: 'test', - draft: ({ points, Point, macro }) => { + draft: ({ points, Point, macro, part }) => { points.anchor = new Point(-12, -34) macro('title', { at: points.anchor, nr: 3, title: 'unitTest', }) + + return part }, + plugins: [plugin], } const Pattern = new Design({ data: { name: 'testPattern', version: 99 }, parts: [part], - plugins: [plugin], }) const pattern = new Pattern() pattern.draft().render() - let p = pattern.parts.test.points.__titleNr + let p = pattern.parts[0].test.points.__titleNr expect(p.x).to.equal(-12) expect(p.y).to.equal(-34) expect(p.attributes.get('data-text')).to.equal('3') expect(p.attributes.get('data-text-class')).to.equal('text-4xl fill-note font-bold') expect(p.attributes.get('data-text-x')).to.equal('-12') expect(p.attributes.get('data-text-y')).to.equal('-34') - p = pattern.parts.test.points.__titleName + p = pattern.parts[0].test.points.__titleName expect(p.attributes.get('data-text')).to.equal('unitTest') expect(p.attributes.get('data-text-class')).to.equal('text-lg fill-current font-bold') expect(p.attributes.get('data-text-x')).to.equal('-12') expect(p.attributes.get('data-text-y')).to.equal('-26') - p = pattern.parts.test.points.__titlePattern + p = pattern.parts[0].test.points.__titlePattern expect(p.attributes.get('data-text')).to.equal('testPattern v99') expect(p.attributes.get('data-text-class')).to.equal('fill-note') expect(p.attributes.get('data-text-x')).to.equal('-12') @@ -46,7 +48,7 @@ describe('Title Plugin Tests', () => { it('Should run the title macro with append flag', () => { const part = { name: 'test', - draft: ({ points, Point, macro }) => { + draft: ({ points, Point, macro, part }) => { points.anchor = new Point(-12, -34).attr('data-text', '#') macro('title', { at: points.anchor, @@ -54,16 +56,18 @@ describe('Title Plugin Tests', () => { title: 'unitTest', append: true, }) + + return part }, + plugins: [plugin], } const Pattern = new Design({ data: { name: 'testPattern', version: 99 }, parts: [part], - plugins: [plugin], }) const pattern = new Pattern() pattern.draft().render() - let p = pattern.parts.test.points.__titleNr + let p = pattern.parts[0].test.points.__titleNr expect(p.x).to.equal(-12) expect(p.y).to.equal(-34) expect(p.attributes.get('data-text')).to.equal('# 3') @@ -75,7 +79,7 @@ describe('Title Plugin Tests', () => { it('Should run the title macro with point prefix', () => { const part = { name: 'test', - draft: ({ points, Point, macro }) => { + draft: ({ points, Point, macro, part }) => { points.anchor = new Point(-12, -34).attr('data-text', '#') macro('title', { at: points.anchor, @@ -83,28 +87,30 @@ describe('Title Plugin Tests', () => { title: 'unitTest', prefix: 'foo', }) + + return part }, + plugins: [plugin], } const Pattern = new Design({ data: { name: 'testPattern', version: 99 }, parts: [part], - plugins: [plugin], }) const pattern = new Pattern() pattern.draft().render() - let p = pattern.parts.test.points._foo_titleNr + let p = pattern.parts[0].test.points._foo_titleNr expect(p.x).to.equal(-12) expect(p.y).to.equal(-34) expect(p.attributes.get('data-text')).to.equal('3') expect(p.attributes.get('data-text-class')).to.equal('text-4xl fill-note font-bold') expect(p.attributes.get('data-text-x')).to.equal('-12') expect(p.attributes.get('data-text-y')).to.equal('-34') - p = pattern.parts.test.points._foo_titleName + p = pattern.parts[0].test.points._foo_titleName expect(p.attributes.get('data-text')).to.equal('unitTest') expect(p.attributes.get('data-text-class')).to.equal('text-lg fill-current font-bold') expect(p.attributes.get('data-text-x')).to.equal('-12') expect(p.attributes.get('data-text-y')).to.equal('-26') - p = pattern.parts.test.points._foo_titlePattern + p = pattern.parts[0].test.points._foo_titlePattern expect(p.attributes.get('data-text')).to.equal('testPattern v99') expect(p.attributes.get('data-text-class')).to.equal('fill-note') expect(p.attributes.get('data-text-x')).to.equal('-12') From 920fe39d97a4b906ad2ae188dd4da047e3eebfd2 Mon Sep 17 00:00:00 2001 From: Joost De Cock Date: Tue, 27 Sep 2022 14:13:25 +0200 Subject: [PATCH 21/46] feat(plugintest): Added rotation option for scalebox --- designs/plugintest/src/plugin-scalebox.mjs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/designs/plugintest/src/plugin-scalebox.mjs b/designs/plugintest/src/plugin-scalebox.mjs index 92750aeb2c1..df125f1ac63 100644 --- a/designs/plugintest/src/plugin-scalebox.mjs +++ b/designs/plugintest/src/plugin-scalebox.mjs @@ -7,6 +7,7 @@ const pluginScalebox = ({ Point, points, macro, options, part }) => { macro(options.scaleboxType, { at: points.a, + rotate: options.scaleboxRotation, }) } @@ -19,6 +20,7 @@ export const scalebox = { after: base, options: { scaleboxType: { dflt: 'scalebox', list: ['scalebox', 'miniscale'], menu: 'scalebox' }, + scaleboxRotation: { deg: 0, min: 0, max: 360, menu: 'scalebox' }, }, draft: pluginScalebox, } From ba2eef45fff1cfac70c96034325cafa77e2395bf Mon Sep 17 00:00:00 2001 From: Joost De Cock Date: Tue, 27 Sep 2022 18:20:46 +0200 Subject: [PATCH 22/46] feat(shared): Example component now runs example code --- sites/shared/components/mdx/example/index.js | 82 +++++++++++++++---- sites/shared/components/mdx/example/tabbed.js | 34 -------- sites/shared/components/mdx/index.js | 33 ++++---- 3 files changed, 81 insertions(+), 68 deletions(-) delete mode 100644 sites/shared/components/mdx/example/tabbed.js diff --git a/sites/shared/components/mdx/example/index.js b/sites/shared/components/mdx/example/index.js index 75848cca293..474e35ad990 100644 --- a/sites/shared/components/mdx/example/index.js +++ b/sites/shared/components/mdx/example/index.js @@ -1,33 +1,41 @@ -import React, { useState } from 'react' -import { Examples } from '@freesewing/examples' -import { Rendertest } from '@freesewing/rendertest' -import { Tutorial } from '@freesewing/tutorial' +import { Tab, Tabs } from '../tabs.js' +import Md from 'react-markdown' +import { plugin } from '@freesewing/plugin-bundle' +import { Design } from '@freesewing/core' import Svg from '../../workbench/draft/svg' import Defs from '../../workbench/draft/defs' import Stack from '../../workbench/draft/stack' import { useGist } from 'shared/hooks/useGist' -export const examplePatterns = { - examples: Examples, - //rendertest: Rendertest, - //tutorial: Tutorial, +// Get code from children +const asText = (reactEl) => { + if (typeof reactEl.props.children === 'string') return reactEl.props.children + if (Array.isArray(reactEl.props.children)) { + return reactEl.props.children.map((el) => (typeof el === 'string' ? el : asText(el))).join('') + } + if (typeof reactEl.props.children === 'object') return asText(reactEl.props.children) + + return '' } -const Example = ({ app, part, pattern='examples', xray=false }) => { - const Pattern = examplePatterns[pattern] +// The actual example +const Example = ({ app, draft, xray = false }) => { // State for gist - const { gist, setGist, unsetGist, updateGist, gistReady, undoGist, resetGist } = useGist( - 'example-mdx', - app - ) + const { gist, unsetGist, updateGist } = useGist('example-mdx', app) if (xray) { gist._state.xray = { enabled: true } gist.margin = 20 } - if (part !== '') gist.only = [ "examples."+part] - const draft = new Pattern(gist) const patternProps = draft.draft().getRenderProps() + console.log(draft) + if (draft.store.logs.error.length > 0 || draft.setStores[0].logs.error.length > 0) + return ( + ++ ) return ({draft.store.logs.error.join('\n')}+{draft.setStores[0].logs.error.join('\n')}+This method is chainable as it returns the `Path` object +This method is chainable as it returns the `Path` object -- -###### This method exists to save you some typing - -Note that the two following calls yield the same result: - -```js -path.attr('class', 'fabric') -path.addClass('fabric') -``` - -So the only purpose of this method is to save your some typing. - - - --Example of the Path.addClass() method - +## Example +```js ({ Point, points, Path, paths, part }) => { @@ -43,3 +29,15 @@ Example of the Path.addClass() method return part } ``` + + +## Notes + +The main purpose of this method is to save your some typing, +as the two following calls yield the same result: + +```js +path.attr('class', 'fabric') +path.addClass('fabric') +``` + diff --git a/markdown/dev/reference/api/path/addtext/en.md b/markdown/dev/reference/api/path/addtext/en.md new file mode 100644 index 00000000000..92d455612f7 --- /dev/null +++ b/markdown/dev/reference/api/path/addtext/en.md @@ -0,0 +1,47 @@ +--- +title: Path.addText() +--- + +The `Path.addText()` method adds text to the path. + +## Signature + +```js +Path path.addText(string text, string className) +``` + +The second argument will optionally be used to set the CSS class for the text. + +This method is chainable as it returns the `Path` object + +## Example + ++```js +({ Point, points, Path, paths, part }) => { + 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') + + return part +} +``` + + +## Notes + +The main purpose of this method is to save your some typing, +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 +existing text on the path, diff --git a/markdown/dev/reference/api/path/aspathstring/en.md b/markdown/dev/reference/api/path/aspathstring/en.md index 17a4d0412c9..047ecb05f4b 100644 --- a/markdown/dev/reference/api/path/aspathstring/en.md +++ b/markdown/dev/reference/api/path/aspathstring/en.md @@ -5,13 +5,13 @@ title: Path.asPathString() This `Path.asPathString()` returs the path as a string that can be used as the `d` attribute for an SVG `path` element. +## Signature + ```js string path.asPathString() ``` -+## Notes This method is mostly aimed at people looking to implement their own rendering methods, or integrate with SVG processing tools. - - diff --git a/markdown/dev/reference/api/path/attr/en.md b/markdown/dev/reference/api/path/attr/en.md index 9e3e087e97c..eba65e00d89 100644 --- a/markdown/dev/reference/api/path/attr/en.md +++ b/markdown/dev/reference/api/path/attr/en.md @@ -8,6 +8,8 @@ It calls `this.attributes.add()` under the hood, and returns the Path object. If the third parameter is set to `true` it will call `this.attributes.set()` instead, thereby overwriting the value of the attribute. +## Signature + ```js Path path.attr( string name, @@ -18,31 +20,35 @@ Path path.attr(This method is chainable as it returns the `Path` object --Example of the Path.attr() method - +## Example +```js ({ Point, points, Path, paths, part }) => { - points.from = new Point(10, 50); - points.cp1 = new Point(40, 10); - points.cp2 = new Point(90, 30); - points.to = new Point(50, 90); + 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) - .addClass("canvas") - .attr("data-text", "freesewingIsMadeByJoostDeCockAndContributors") - .attr("data-text-class", "text-xs center"); + .setClass("canvas") + .setText("FreeSewing rocks", "text-xs center") return part +} ``` + --Methods like `addClass`, `setClass`, `addCircle`, `setCircle`, `adddText`, and `setText` +## Notes + +Methods like +[`Path.addClass`](/reference/api/path/addclass), +[`Path.setClass`](/reference/api/path/setclass), +[`Path.adddText`](/reference/api/path/addtext), and +[`Path.setText`](/reference/api/path/settext) all call this method under the hood. - diff --git a/markdown/dev/reference/api/path/bbox/en.md b/markdown/dev/reference/api/path/bbox/en.md index 1b16ac663a7..3c2cf3241ab 100644 --- a/markdown/dev/reference/api/path/bbox/en.md +++ b/markdown/dev/reference/api/path/bbox/en.md @@ -5,6 +5,8 @@ title: Path.bbox() The `Path.bbox()` method returns an object describing the bounding box of a path. In other words, it gives you a rectangle the Path fits in. +## Signature + ```js object path.bbox() ``` @@ -18,8 +20,6 @@ It returns an object with a signature like this: } ``` -+## Notes This method is mostly aimed at people looking to implement their own layout solution. - - diff --git a/markdown/dev/reference/api/path/clone/en.md b/markdown/dev/reference/api/path/clone/en.md index 1c750154139..158935ef4d0 100644 --- a/markdown/dev/reference/api/path/clone/en.md +++ b/markdown/dev/reference/api/path/clone/en.md @@ -4,30 +4,36 @@ title: Path.clone() The `Path.clone()` method returns a new `Path` object that is a deep copy of this path. +## Signature + ```js Path path.clone() ``` --Example of the Path.clone() method +## Example + + +```js +({ Point, points, Path, paths, 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); + + paths.example = new Path() + .move(points.A) + .line(points.B) + .curve(points.BCp2, points.CCp1, points.C); + + paths.clone = paths.example + .clone() + .setClass("note lashed stroke-xl") + .attr("style", "stroke-opacity: 0.5"); + + return part +} +``` -```js -let { Point, points, Path, paths } = part.shorthand(); - -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.example = new Path() - .move(points.A) - .line(points.B) - .curve(points.BCp2, points.CCp1, points.C); - -paths.clone = paths.example - .clone() - .attr("class", "note lashed stroke-l") - .attr("style", "stroke-opacity: 0.5"); -``` diff --git a/markdown/dev/reference/api/path/close/en.md b/markdown/dev/reference/api/path/close/en.md index db3e3b7a738..3cddea95219 100644 --- a/markdown/dev/reference/api/path/close/en.md +++ b/markdown/dev/reference/api/path/close/en.md @@ -1,29 +1,36 @@ --- -title: close() +title: Path.close() --- +The `Path.close()` method closes a path by drawing a straight line from the current position to the path's start. + +## Signature + ```js Path path.close() ``` -Closes a path by drawing a straight line from the current position to the path's start. +This method is chainable as it returns the `Path` object --Example of the Path.close() method +## Example + + +```js +({ Point, points, Path, paths, part }) => { + + 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') + + return part +} +``` -```js -let { Point, points, Path, paths } = part.shorthand(); - -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 - .attr("data-text", "Path._close()") - .attr("data-text-class", "text-sm right fill-note"); -``` diff --git a/markdown/dev/reference/api/path/curve/en.md b/markdown/dev/reference/api/path/curve/en.md index 22ce7ba5485..825450ebd22 100644 --- a/markdown/dev/reference/api/path/curve/en.md +++ b/markdown/dev/reference/api/path/curve/en.md @@ -1,28 +1,36 @@ --- -title: curve() +title: Path.curve() --- +The `Path.curve()` method draws a cubic Bezier curve from the current position +via two control points to a given endpoint. + +## Signature + ```js Path path.curve(Point cp1, Point cp2, Point to) ``` -Draws a cubic Bezier curve from the current position via two control points to a given endpoint. +This method is chainable as it returns the `Path` object --Example of the Path.curve() method +## Example + + + +## Notes + +The main purpose of this method is to save your some typing, +as the two following calls yield the same result: + +```js +.curve(point1, point2, point2) +.curve_(point1, point2) ``` diff --git a/markdown/dev/reference/api/path/divide/en.md b/markdown/dev/reference/api/path/divide/en.md index 522d7b4bd2c..5bfee5e418f 100644 --- a/markdown/dev/reference/api/path/divide/en.md +++ b/markdown/dev/reference/api/path/divide/en.md @@ -1,42 +1,49 @@ --- -title: divide() +title: Path.divide() --- +The `Path.divide()` method breaks a path apart in an array of atomic paths. An +atomic path is a path that can't be divided further and is always made up of +one move + one drawing operation. + +## Signature + ```js array path.divide() ``` -Breaks a path apart in an array of atomic paths. An atomic path is a path that can't be divided further and is -always made up of one move + one drawing operation. - -+```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); + + paths.line = new Path() + .move(points.from) + .curve(points.cp1, points.cp2, points.to) + .setText("Path.curve()", "text-sm center fill-note") + + return part +} +``` -```js -let { Point, points, Path, paths } = part.shorthand(); - -points.from = new Point(10, 20); -points.cp1 = new Point(40, 0); -points.cp2 = new Point(60, 30); -points.to = new Point(90, 20); - -paths.line = new Path() - .move(points.from) - .curve(points.cp1, points.cp2, points.to) - .attr("data-text", "Path.curve()") - .attr("data-text-class", "text-sm center fill-note"); -``` diff --git a/markdown/dev/reference/api/path/curve_/en.md b/markdown/dev/reference/api/path/curve_/en.md index 5499d61726a..c74865423cb 100644 --- a/markdown/dev/reference/api/path/curve_/en.md +++ b/markdown/dev/reference/api/path/curve_/en.md @@ -1,35 +1,26 @@ --- -title: "curve_()" +title: Path.curve_() --- +The `Path.curve_()` method draws a cubic Bezier curve from the current position +via two control points to a given endpoint. However, the end control point is +identical to the end point. + +## Signature + ```js Path path.curve_(Point cp1, Point to) ``` -Draws a cubic Bezier curve from the current position via two control points to a given endpoint. -However, the end control point is identical to the end point. +This method is chainable as it returns the `Path` object -+## Example -###### This method exists to save you some typing -Note that the two following calls yield the same result: + - -```js -.curve(point1, point2, point2) -.curve_(point1, point2) -``` - -So the only purpose of this method is to save your some typing; - - -Example of the Path.curve\_() method - - -```js - let { Point, points, Path, paths } = part.shorthand(); +({ Point, points, Path, paths, part }) => { points.from = new Point(10, 20); points.cp1 = new Point(40, 0); @@ -38,6 +29,20 @@ Example of the Path.curve\_() method paths.line = new Path() .move(points.from) .curve_(points.cp1, points.to) - .attr("data-text", "Path.curve_()") - .attr("data-text-class", "text-sm center fill-note"); + .setText("Path.curve_()", "text-sm center fill-note") + .attr("data-text-dy", -1) + + return part +} +``` +-Example of the Path.divide() method - +## Example +```js -let { Point, points, Path, paths } = part.shorthand(); +({ Point, points, Path, paths, part }) => { -points.A = new Point(55, 40); -points.B = new Point(10, 70); -points.BCp2 = new Point(40, 20); -points.C = new Point(90, 60); -points.CCp1 = new Point(50, -30); -points.D = new Point(50, 80); -points.DCp1 = new Point(140, 50); + points.A = new Point(55, 40); + points.B = new Point(10, 70); + points.BCp2 = new Point(40, 20); + points.C = new Point(90, 60); + points.CCp1 = new Point(50, -30); + points.D = new Point(50, 80); + points.DCp1 = new Point(140, 50); + + paths.example = new Path() + .move(points.A) + .line(points.B) + .curve(points.BCp2, points.CCp1, points.C) + .curve(points.DCp1, points.DCp1, points.D) + .close(); + + let style = "stroke-width: 4; stroke-opacity: 0.5;"; + let i = 0; + for (let p of paths.example.divide()) { + i++; + paths[i] = p + .attr("style", style) + .attr('style', `stroke: hsl(${i * 70}, 100%, 50%)`) + } -paths.example = new Path() - .move(points.A) - .line(points.B) - .curve(points.BCp2, points.CCp1, points.C) - .curve(points.DCp1, points.DCp1, points.D) - .close(); - -let style = "stroke-width: 4; stroke-opacity: 0.5;"; -let i = 0; -for (let p of paths.example.divide()) { - i++; - paths[i] = p - .attr("style", style) - .attr("style", `stroke: hsl(${i * 70}, 100%, 50%)`); + return part } ``` + + diff --git a/markdown/dev/reference/api/path/edge/en.md b/markdown/dev/reference/api/path/edge/en.md index b229c539d13..d2b0d6663ee 100644 --- a/markdown/dev/reference/api/path/edge/en.md +++ b/markdown/dev/reference/api/path/edge/en.md @@ -1,5 +1,5 @@ --- -title: edge() +title: Path.edge() --- ```js @@ -17,36 +17,37 @@ Returns the Point object at the edge of the path you specify. Edge must be one o - `bottomLeft` - `bottomRight` --Example of the Path.edge() method - - +```js -let { Point, points, Path, paths, Snippet, snippets } = part.shorthand(); +({ 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(-60, 90); -points.E = new Point(90, 190); + 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(-60, 90) + points.E = new Point(90, 190) + + paths.demo = new Path() + .move(points.A) + .line(points.B) + .curve(points.BCp2, points.CCp1, points.C) + .curve(points.E, points.D, points.A) + .close() + + for (let i of [ + "topLeft", + "topRight", + "bottomLeft", + "bottomRight", + "top", + "left", + "bottom", + "right" + ]) snippets[i] = new Snippet("notch", paths.demo.edge(i)) -paths.demo = new Path() - .move(points.A) - .line(points.B) - .curve(points.BCp2, points.CCp1, points.C) - .curve(points.E, points.D, points.A) - .close(); - -for (let i of [ - "topLeft", - "topRight", - "bottomLeft", - "bottomRight", - "top", - "left", - "bottom", - "right" -]) snippets[i] = new Snippet("notch", paths.demo.edge(i)); + return part +} ``` + diff --git a/markdown/dev/reference/api/path/en.md b/markdown/dev/reference/api/path/en.md index f797e50c045..6c079467db1 100644 --- a/markdown/dev/reference/api/path/en.md +++ b/markdown/dev/reference/api/path/en.md @@ -13,8 +13,13 @@ Path new Path(); A Path objects comes with the following properties: -- `render` : Set this to `false` to not render the path (exclude it from the output) -- `attributes` : An [Attributes](/reference/api/attributes) instance holding the path's attributes +- `attributes` : An [Attributes](/reference/api/attributes) instance holding + the path's attributes +- `hidden` : When this is `true` the path will be hidden (excluded it from the + output). See [Path.hide()](/reference/api/path/hide), + [Path.unhide()](/reference/api/path/unhide), and + [Path.setHidden()](/reference/api/path/sethidden) for various methods that + allow setting this in a chainable way. In addition, a Path object exposes the following methods: diff --git a/markdown/dev/reference/api/path/end/en.md b/markdown/dev/reference/api/path/end/en.md index 278791d8373..ba128d42b92 100644 --- a/markdown/dev/reference/api/path/end/en.md +++ b/markdown/dev/reference/api/path/end/en.md @@ -1,30 +1,38 @@ --- -title: end() +title: Path.end() --- +The `Path.end()` method returns the Point object at the end of the path. + +## Signature + ```js Point path.end() ``` -Returns the Point object at the end of the path. +This method is chainable as it returns the `Path` object --Example of the Path.end() method +## Example + + +```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) + + 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()) + + return part +} +``` -```js -let { Point, points, Path, paths, Snippet, snippets } = part.shorthand(); - -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); - -snippets.end = new Snippet("notch", paths.demo.end()); -``` diff --git a/markdown/dev/reference/api/path/hide/en.md b/markdown/dev/reference/api/path/hide/en.md index ed231b36511..e0f9b535b1e 100644 --- a/markdown/dev/reference/api/path/hide/en.md +++ b/markdown/dev/reference/api/path/hide/en.md @@ -1,37 +1,33 @@ --- -title: hide() +title: Path.hide() --- +The `Path.hide()` hides the path so it does not appear in the output. + +## Signature + ```js -Path path.attr( - string name, - mixed value, - bool overwrite = false -) +Path path.hide() ``` -This `Path.attr()` method calls `this.attributes.add()` under the hood, but returns the Path object. +This method is chainable as it returns the `Path` object -This allows you to chain different calls together as in the example below. +## Example -If the third parameter is set to `true` it will call `this.attributes.set()` instead, thereby overwriting the value of the attribute. ++```js +({ Point, points, Path, paths, part }) => { - -Example of the Path.attr() method + 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') + + return part +} +``` -```js -let { Point, points, Path, paths } = part.shorthand(); - -points.B = new Point(10, 50); -points.BCp2 = new Point(40, 10); -points.C = new Point(90, 30); -points.CCp1 = new Point(50, 90); - -paths.example = new Path() - .move(points.B) - .curve(points.BCp2, points.CCp1, points.C) - .attr("class", "canvas") - .attr("data-text", "freesewingIsMadeByJoostDeCockAndContributors") - .attr("data-text-class", "text-xs center"); -``` diff --git a/markdown/dev/reference/api/path/insop/en.md b/markdown/dev/reference/api/path/insop/en.md index f6b18f2378c..b9a430453f8 100644 --- a/markdown/dev/reference/api/path/insop/en.md +++ b/markdown/dev/reference/api/path/insop/en.md @@ -1,38 +1,51 @@ --- -title: insop() +title: Path.insop() --- +The `Path.insop()` method injects a Path into the [`noop` +operation](/reference/api/path/noop) with id `id`. + +## Signature + ```js Path path.insop(string id, Path path) ``` -Injects a Path into the [`noop` operation](/reference/api/path/noop) with id `id`. +This method is chainable as it returns the `Path` object -This is often used to insert darts into a path --Example of the Path.noop() method + +```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) + + 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;') + + return part +} +``` -```js -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) +## Notes -paths.withoutDart = new Path() - .move(points.left) - .line(points.dartLeft) - .noop('dart') - .line(points.right) +This is often used to insert darts into a path. -paths.withDart = paths.without - .insop( - 'dart', - new Path() - .line(points.dartTip) - .line(points.dartRight) - ) - .attr('style', 'stroke-width: 2px; stroke-opacity: 0.5; stroke: orange;') -``` diff --git a/markdown/dev/reference/api/path/intersects/en.md b/markdown/dev/reference/api/path/intersects/en.md index 8eed5092151..ddb4171dc32 100644 --- a/markdown/dev/reference/api/path/intersects/en.md +++ b/markdown/dev/reference/api/path/intersects/en.md @@ -1,59 +1,61 @@ --- -title: intersects() +title: Path.intersects() --- - ``` - array|false path.intersects(Path path) - ``` +The `Path.intersects()` method returns the Point object(s) where the path +intersects with a path you pass it. -Returns the Point object(s) where the path intersects with a path you pass it. +## Signature -+``` +array|false path.intersects(Path path) +``` -###### Use the intersection methods in Utils whenever possible + + - -+```js +({ 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); + points.C = new Point(90, 30); + points.CCp1 = new Point(50, -30); + points.D = new Point(50, 130); + points.DCp1 = new Point(150, 30); + + points._A = new Point(55, 40); + points._B = new Point(0, 55); + points._BCp2 = new Point(40, -20); + points._C = new Point(90, 40); + points._CCp1 = new Point(50, -30); + points._D = new Point(40, 120); + points._DCp1 = new Point(180, 40); + + paths.demo1 = new Path() + .move(points.A) + .line(points.B) + .curve(points.BCp2, points.CCp1, points.C) + .curve(points.DCp1, points.DCp1, points.D); + paths.demo2 = new Path() + .move(points._A) + .line(points._B) + .curve(points._BCp2, points._CCp1, points._C) + .curve(points._DCp1, points._DCp1, points._D); + + for (let p of paths.demo1.intersects(paths.demo2)) { + snippets[getId()] = new Snippet('notch', p) + } + + return part +} +``` + + + +## Notes This is an expensive (read: slow) method that you should only use when you don't know in advance in what segment of your path the intersection will occur. If you do know, use one of the intersection methods in [Utils](/reference/api/utils). - --Example of the Path.intersects() method - - - ```js - let { Point, points, Path, paths, Snippet, snippets } = part.shorthand(); - - 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, 130); - points.DCp1 = new Point(150, 30); - - points._A = new Point(55, 40); - points._B = new Point(0, 55); - points._BCp2 = new Point(40, -20); - points._C = new Point(90, 40); - points._CCp1 = new Point(50, -30); - points._D = new Point(40, 120); - points._DCp1 = new Point(180, 40); - - paths.demo1 = new Path() - .move(points.A) - .line(points.B) - .curve(points.BCp2, points.CCp1, points.C) - .curve(points.DCp1, points.DCp1, points.D); - paths.demo2 = new Path() - .move(points._A) - .line(points._B) - .curve(points._BCp2, points._CCp1, points._C) - .curve(points._DCp1, points._DCp1, points._D); - - for (let p of paths.demo1.intersects(paths.demo2)) { - snippets[part.getId()] = new Snippet("notch", p); - } - ``` diff --git a/markdown/dev/reference/api/path/intersectsx/en.md b/markdown/dev/reference/api/path/intersectsx/en.md index 858b6edab96..9a38ef9c416 100644 --- a/markdown/dev/reference/api/path/intersectsx/en.md +++ b/markdown/dev/reference/api/path/intersectsx/en.md @@ -1,43 +1,50 @@ --- -title: intersectsX() +title: Path.intersectsX() --- +The `Path.intersectsX()` method returns the Point object(s) where the path +intersects with a given X-value. + +## Signature + ```js array|false path.intersectsX(float x) ``` -Returns the Point object(s) where the path intersects with a given X-value. - --Example of the Path.intersectsX() method - +## Example +```js -let { Point, points, Path, paths, Snippet, snippets } = part.shorthand(); +({ Point, points, Path, paths, snippets, Snippet, getId, part }) => { -points.A = new Point(95, 50); -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, 130); -points.DCp1 = new Point(150, 30); + points.A = new Point(95, 50); + 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, 130); + points.DCp1 = new Point(150, 30); + + points.top = new Point(60, -10); + points.bot = new Point(60, 140); + + paths.line = new Path() + .move(points.top) + .line(points.bot) + .attr("class", "lining dashed"); + + paths.demo = new Path() + .move(points.A) + .line(points.B) + .curve(points.BCp2, points.CCp1, points.C) + .curve(points.DCp1, points.DCp1, points.D); + + for (let p of paths.demo.intersectsX(60)) { + snippets[getId()] = new Snippet("notch", p); + } -points.top = new Point(60, -10); -points.bot = new Point(60, 140); - -paths.line = new Path() - .move(points.top) - .line(points.bot) - .attr("class", "lining dashed"); - -paths.demo = new Path() - .move(points.A) - .line(points.B) - .curve(points.BCp2, points.CCp1, points.C) - .curve(points.DCp1, points.DCp1, points.D); - -for (let p of paths.demo.intersectsX(60)) { - snippets[part.getId()] = new Snippet("notch", p); + return part } ``` + + diff --git a/markdown/dev/reference/api/path/intersectsy/en.md b/markdown/dev/reference/api/path/intersectsy/en.md index df06a59385b..b825ec0e77a 100644 --- a/markdown/dev/reference/api/path/intersectsy/en.md +++ b/markdown/dev/reference/api/path/intersectsy/en.md @@ -1,43 +1,50 @@ --- -title: intersectsY() +title: Path.intersectsY() --- +The `Path.intersectsY()` method returns the Point object(s) where the path +intersects with a given Y-value. + +## Signature + ```js array|false path.intersectsY(float y) ``` -Returns the Point object(s) where the path intersects with a given Y-value. - --Example of the Path.intersectsY() method - +## Example +```js -let { Point, points, Path, paths, Snippet, snippets } = part.shorthand(); +({ Point, points, Path, paths, snippets, Snippet, getId, part }) => { -points.A = new Point(55, 40); -points.B = new Point(10, 70); -points.BCp2 = new Point(40, 20); -points.C = new Point(90, 60); -points.CCp1 = new Point(50, -30); -points.D = new Point(50, 80); -points.DCp1 = new Point(140, 50); + points.A = new Point(55, 40); + points.B = new Point(10, 70); + points.BCp2 = new Point(40, 20); + points.C = new Point(90, 60); + points.CCp1 = new Point(50, -30); + points.D = new Point(50, 80); + points.DCp1 = new Point(140, 50); -points.top = new Point(10, 58); -points.bot = new Point(130, 58); + points.top = new Point(10, 58); + points.bot = new Point(130, 58); -paths.line = new Path() - .move(points.top) - .line(points.bot) - .attr("class", "lining dashed"); + paths.line = new Path() + .move(points.top) + .line(points.bot) + .attr("class", "lining dashed"); -paths.demo = new Path() - .move(points.A) - .line(points.B) - .curve(points.BCp2, points.CCp1, points.C) - .curve(points.DCp1, points.DCp1, points.D); + paths.demo = new Path() + .move(points.A) + .line(points.B) + .curve(points.BCp2, points.CCp1, points.C) + .curve(points.DCp1, points.DCp1, points.D); -for (let p of paths.demo.intersectsY(58)) { - snippets[part.getId()] = new Snippet("notch", p); + for (let p of paths.demo.intersectsY(58)) { + snippets[getId()] = new Snippet("notch", p); + } + + return part } ``` + + diff --git a/markdown/dev/reference/api/path/join/en.md b/markdown/dev/reference/api/path/join/en.md index 32a2e1ab4a0..17bbb31abd5 100644 --- a/markdown/dev/reference/api/path/join/en.md +++ b/markdown/dev/reference/api/path/join/en.md @@ -1,44 +1,49 @@ --- -title: join() +title: Path.join() --- +The `Path.join()` method joins this path with another path. + + +## Signature + ```js Path path.join(path other) ``` -Joins this path with another path. +## Examples -+ - -+```js +({ Point, points, Path, paths, 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) + + paths.path1 = new Path() + .move(points.A) + .line(points.B) + .setClass("various") + + paths.path2 = new Path() + .move(points.B) + .curve(points.BCp2, points.CCp1, points.C) + .setClass("note") + + paths.joint = paths.path1 + .join(paths.path2) + .setClass("lining dotted") + + return part +} +``` + + + +## Notes You cannot join a closed path to another path --Example of the Path.join() method - - -```js -let { Point, points, Path, paths } = part.shorthand(); - -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.path1 = new Path() - .move(points.A) - .line(points.B) - .attr("class", "various"); - -paths.path2 = new Path() - .move(points.B) - .curve(points.BCp2, points.CCp1, points.C) - .attr("class", "canvas"); - -paths.joint = paths.path1 - .join(paths.path2) - .attr("class", "note lashed stroke-l") - .attr("style", "stoke-opacity: 0.5"); -``` diff --git a/markdown/dev/reference/api/path/length/en.md b/markdown/dev/reference/api/path/length/en.md index ca15197e6f7..e58a5e4cdb9 100644 --- a/markdown/dev/reference/api/path/length/en.md +++ b/markdown/dev/reference/api/path/length/en.md @@ -1,43 +1,49 @@ --- -title: length() +title: Path.length() --- +The `Path.length()` method returns the length of the path. + +## Signature + ```js float path.length() ``` -Returns the length of the path. +## Example --Example of the Path.length() method + +```js +({ Point, points, Path, paths, macro, 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); + + paths.example = new Path() + .move(points.A) + .line(points.B) + .curve(points.BCp2, points.CCp1, points.C); + + macro("pd", { + path: paths.example, + d: -20 + }); + + macro("pd", { + path: new Path().move(points.B).line(points.A), + d: 10 + }); + + macro("pd", { + path: new Path().move(points.B).curve(points.BCp2, points.CCp1, points.C), + d: -10 + }); + + return part +} +``` -```js -let { Point, points, Path, paths, macro } = part.shorthand(); - -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.example = new Path() - .move(points.A) - .line(points.B) - .curve(points.BCp2, points.CCp1, points.C); - -macro("pd", { - path: paths.example, - d: -20 -}); - -macro("pd", { - path: new Path().move(points.B).line(points.A), - d: 10 -}); - -macro("pd", { - path: new Path().move(points.B).curve(points.BCp2, points.CCp1, points.C), - d: -10 -}); -``` diff --git a/markdown/dev/reference/api/path/line/en.md b/markdown/dev/reference/api/path/line/en.md index 2cf569eb77e..906ec3d2974 100644 --- a/markdown/dev/reference/api/path/line/en.md +++ b/markdown/dev/reference/api/path/line/en.md @@ -1,26 +1,34 @@ --- -title: line() +title: Path.line() --- +The `Path.line()` method draws a straight line from the current position to a +given point. + +## Signature + ```js Path path.line(Point to) ``` -Draws a straight line from the current position to a given point. +This method is chainable as it returns the `Path` object --Example of the Path.line() method +## Example + + +```js +({ Point, points, Path, paths, part }) => { + + 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") + + return part +} +``` -```js -let { Point, points, Path, paths } = part.shorthand(); - -points.from = new Point(10, 10); -points.to = new Point(90, 10); - -paths.line = new Path() - .move(points.from) - .line(points.to) - .attr("data-text", "Path.line()") - .attr("data-text-class", "text-sm center fill-note"); -``` diff --git a/markdown/dev/reference/api/path/move/en.md b/markdown/dev/reference/api/path/move/en.md index 7fb24ec2aee..f80354c7f19 100644 --- a/markdown/dev/reference/api/path/move/en.md +++ b/markdown/dev/reference/api/path/move/en.md @@ -1,18 +1,36 @@ --- -title: move() +title: Path.move() --- +The `Path.move()` method moves to a given point without drawing a line. + +## Signature + ```js Path path.move(Point to) ``` -Moves to a given point without drawing a line. +## Example --###### Always start your path with a move + - -+```js +({ Point, points, Path, paths, part }) => { -When drawing a path, you must always start with a `move()` call, + points.to = new Point(50, 20) + .setText("Path.move()", "text-xs fill-note center") + + paths.noline = new Path().move(points.to) + + return part +} +``` + + + +## Notes + +When drawing a path, **you must always start with a `move()` call**, followed by your `line()` and/or `curve()` calls and an optional `close()` call. @@ -23,21 +41,5 @@ paths.example = new Path() .move(points.a) .curve(points.b, points.c, points.d) .line(points.e) - .close(); -``` - --Example of the Path.move() method - - -```js -let { Point, points, Path, paths } = part.shorthand(); - -points.to = new Point(50, 20) - .attr("data-text", "Path.move()") - .attr("data-text-class", "text-xs fill-note"); - -paths.noline = new Path().move(points.to); + .close() ``` diff --git a/markdown/dev/reference/api/path/noop/en.md b/markdown/dev/reference/api/path/noop/en.md index 88fad6961ff..38fa85198ed 100644 --- a/markdown/dev/reference/api/path/noop/en.md +++ b/markdown/dev/reference/api/path/noop/en.md @@ -1,41 +1,49 @@ --- -title: noop() +title: Path.noop() --- +The `Path.noop()` method adds a placeholder path operation. +A `noop` operation does nothing, but is intended to be replaced later +with [`Path.insop()`](/reference/api/path/insop). + +## Signature + ```js Path path.noop(string id) ``` -Adds a placeholder path operation. +This method is chainable as it returns the `Path` object -A `noop` operation does nothing, but is intended to be replaced later -with [`Path.insop()`](/reference/api/path/insop). +## Example -This is often used to insert darts into a path ++```js +({ Point, points, Path, paths, part }) => { - -Example of the Path.noop() method + 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.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 +} +``` -```js -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.withDart = paths.without - .insop( - 'dart', - new Path() - .line(points.dartTip) - .line(points.dartRight) - ) - .attr('style', 'stroke-width: 2px; stroke-opacity: 0.5; stroke: orange;') -``` diff --git a/markdown/dev/reference/api/path/offset/en.md b/markdown/dev/reference/api/path/offset/en.md index c5ce02fae6d..c52d43fcf5f 100644 --- a/markdown/dev/reference/api/path/offset/en.md +++ b/markdown/dev/reference/api/path/offset/en.md @@ -1,46 +1,53 @@ --- -title: offset() +title: Path.offset() --- +The `Path.offset()` method returns a new Path that is offset by distance from +the original path. + +## Signature + ```js Path path.offset(float distance) ``` -Returns a new Path that is offset by distance from the original path. +## Example --Example of the Path.offset() method + +```js +({ Point, points, Path, paths, 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); + + paths.example = new Path() + .move(points.A) + .line(points.B) + .curve(points.BCp2, points.CCp1, points.C) + .line(points.A) + .close(); + + paths.offset = paths.example + .offset(-10) + .attr("class", "interfacing"); + + paths.lineOffset = new Path() + .move(points.A) + .line(points.B) + .offset(-5) + .attr("class", "various"); + + paths.curveOffset = new Path() + .move(points.B) + .curve(points.BCp2, points.CCp1, points.C) + .offset(-5) + .attr("class", "canvas"); + + return part +} +``` -```js -let { Point, points, Path, paths } = part.shorthand(); - -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.example = new Path() - .move(points.A) - .line(points.B) - .curve(points.BCp2, points.CCp1, points.C) - .line(points.A) - .close(); - -paths.offset = paths.example - .offset(-10) - .attr("class", "interfacing"); - -paths.lineOffset = new Path() - .move(points.A) - .line(points.B) - .offset(-5) - .attr("class", "various"); - -paths.curveOffset = new Path() - .move(points.B) - .curve(points.BCp2, points.CCp1, points.C) - .offset(-5) - .attr("class", "canvas"); -``` diff --git a/markdown/dev/reference/api/path/reverse/en.md b/markdown/dev/reference/api/path/reverse/en.md index 55f8f102fc9..d9952973e0b 100644 --- a/markdown/dev/reference/api/path/reverse/en.md +++ b/markdown/dev/reference/api/path/reverse/en.md @@ -1,42 +1,49 @@ --- -title: reverse() +title: Path.reverse() --- +The `Path.reverse()` returns a path that is the reversed version of this path. +As in, start becomes end, and end becomes start. + +## Signature + ```js -Path path.reverse() +Path path.reverse(bool cloneAttributes=false) ``` -Returns a path that is the reversed version of this path. As in, start becomes end, and end becomes start. +If you pass a truthy value to this method, it will return a deep clone of the +path, including its attributes. By default, it will return a shallow +copy, whithout the attributes. -+## Example + + + -+```js +({ Point, points, Path, paths, part }) => { + + 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.example = new Path() + .move(points.B) + .curve(points.BCp2, points.CCp1, points.C) + .setText("FreeSewing rocks", "text-xs fill-note center") + + paths.reverse = paths.example.reverse(true) + + return part +} +``` + + +## Notes The reversed path is a shallow copy. It will in other words not inherit the attributes of the original path. -If you want a deep copy, including the attributes, use `Path.clone().reverse()`. +If you want a deep copy, including the attributes, use `Path.reverse(true)`. --Example of the Path.reverse() method - - -```js -let { Point, points, Path, paths } = part.shorthand(); - -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.example = new Path() - .move(points.B) - .curve(points.BCp2, points.CCp1, points.C) - .attr("data-text", "freesewingIsMadeByJoostDeCockAndContributors") - .attr("data-text-class", "text-xs fill-note"); - -paths.reverse = paths.example - .reverse() - .attr("data-text", "freesewingIsMadeByJoostDeCockAndContributors") - .attr("data-text-class", "text-xs fill-lining"); -``` diff --git a/markdown/dev/reference/api/path/roughlength/en.md b/markdown/dev/reference/api/path/roughlength/en.md index 5280edae521..de51a13fdce 100644 --- a/markdown/dev/reference/api/path/roughlength/en.md +++ b/markdown/dev/reference/api/path/roughlength/en.md @@ -1,37 +1,50 @@ --- -title: roughLength() +title: Path.roughLength() --- +The `Path.roughLength()` method returns a (very) rough estimate of the path's length. + +## Signature + ```js -Path path.attr( - string name, - mixed value, - bool overwrite = false -) +Number path.roughLength() ``` -This `Path.attr()` method calls `this.attributes.add()` under the hood, but returns the Path object. +## Example -This allows you to chain different calls together as in the example below. ++```js +({ Point, points, Path, paths, macro, units, part }) => { -If the third parameter is set to `true` it will call `this.attributes.set()` instead, thereby overwriting the value of the attribute. + points.B = new Point(10, 30); + points.BCp2 = new Point(40, 20); + points.C = new Point(120, 30); + points.CCp1 = new Point(50, -30); + + paths.example = new Path() + .move(points.B) + .curve(points.BCp2, points.CCp1, points.C); + + macro("pd", { + path: paths.example, + d: -10, + text: `Path.roughLength() = ${units(paths.example.roughLength())}` + }) + macro("pd", { + path: paths.example, + d: 10, + text: `Path.length() = ${units(paths.example.length())}` + }); + - -Example of the Path.attr() method + return part +} +``` -```js -let { Point, points, Path, paths } = part.shorthand(); +## Notes -points.B = new Point(10, 50); -points.BCp2 = new Point(40, 10); -points.C = new Point(90, 30); -points.CCp1 = new Point(50, 90); +The `Path.roughLength()` is not intended to give an estimate that is accurate, but rather differentiatate between paths that are a few millimeter long, or meters long. -paths.example = new Path() - .move(points.B) - .curve(points.BCp2, points.CCp1, points.C) - .attr("class", "canvas") - .attr("data-text", "freesewingIsMadeByJoostDeCockAndContributors") - .attr("data-text-class", "text-xs center"); -``` +It calculates the length without *walking the (cubic) Bezier curve* making it very fast and very inaccurate (for curves). +It is typically used to determine how much precision to apply when walking a curve. diff --git a/markdown/dev/reference/api/path/setclass/en.md b/markdown/dev/reference/api/path/setclass/en.md index b4c4f8f5471..28a3407faf2 100644 --- a/markdown/dev/reference/api/path/setclass/en.md +++ b/markdown/dev/reference/api/path/setclass/en.md @@ -1,37 +1,43 @@ --- -title: setClass() +title: Path.setClass() --- +The `Path.setClass()` method sets the CSS class(es) of the path. + +## Signature + ```js -Path path.attr( - string name, - mixed value, - bool overwrite = false -) +Path path.setClass(string className) ``` -This `Path.attr()` method calls `this.attributes.add()` under the hood, but returns the Path object. +This method is chainable as it returns the `Path` object -This allows you to chain different calls together as in the example below. +## Example -If the third parameter is set to `true` it will call `this.attributes.set()` instead, thereby overwriting the value of the attribute. ++```js +({ Point, points, Path, paths, part }) => { - -Example of the Path.attr() method + 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') + + return part +} +``` +## Notes + +The main purpose of this method is to save your some typing, +as the two following calls yield the same result: + ```js -let { Point, points, Path, paths } = part.shorthand(); - -points.B = new Point(10, 50); -points.BCp2 = new Point(40, 10); -points.C = new Point(90, 30); -points.CCp1 = new Point(50, 90); - -paths.example = new Path() - .move(points.B) - .curve(points.BCp2, points.CCp1, points.C) - .attr("class", "canvas") - .attr("data-text", "freesewingIsMadeByJoostDeCockAndContributors") - .attr("data-text-class", "text-xs center"); +path.attr('class', 'fabric', true) +path.addClass('fabric') ``` + diff --git a/markdown/dev/reference/api/path/sethidden/en.md b/markdown/dev/reference/api/path/sethidden/en.md index 4ff2a979132..31fb5df586c 100644 --- a/markdown/dev/reference/api/path/sethidden/en.md +++ b/markdown/dev/reference/api/path/sethidden/en.md @@ -1,37 +1,34 @@ --- -title: setHidden() +title: Path.setHidden() --- +The `Path.setHidden()` method either hides or unhides the path depending on the +value you pass it. + +## Signature + ```js -Path path.attr( - string name, - mixed value, - bool overwrite = false -) +Path path.setHidden(bool hidden = false) ``` -This `Path.attr()` method calls `this.attributes.add()` under the hood, but returns the Path object. +This method is chainable as it returns the `Path` object -This allows you to chain different calls together as in the example below. +## Example -If the third parameter is set to `true` it will call `this.attributes.set()` instead, thereby overwriting the value of the attribute. ++```js +({ Point, points, Path, paths, part }) => { - -Example of the Path.attr() method + 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') + + return part +} +``` -```js -let { Point, points, Path, paths } = part.shorthand(); - -points.B = new Point(10, 50); -points.BCp2 = new Point(40, 10); -points.C = new Point(90, 30); -points.CCp1 = new Point(50, 90); - -paths.example = new Path() - .move(points.B) - .curve(points.BCp2, points.CCp1, points.C) - .attr("class", "canvas") - .attr("data-text", "freesewingIsMadeByJoostDeCockAndContributors") - .attr("data-text-class", "text-xs center"); -``` diff --git a/markdown/dev/reference/api/path/setrender/en.md b/markdown/dev/reference/api/path/setrender/en.md deleted file mode 100644 index 8e809bd146d..00000000000 --- a/markdown/dev/reference/api/path/setrender/en.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: setRender() ---- - -```js -Path path.setRender(bool render) -``` - -This is a chainable method to sets the `path.render` property. -If you set it to `false` your path will not be rendered. - -Add example diff --git a/markdown/dev/reference/api/path/settext/en.md b/markdown/dev/reference/api/path/settext/en.md new file mode 100644 index 00000000000..578b3c08908 --- /dev/null +++ b/markdown/dev/reference/api/path/settext/en.md @@ -0,0 +1,48 @@ +--- +title: Path.setText() +--- + +The `Path.addText()` method set text on the path. + +## Signature + +```js +Path path.setText(string text, string className) +``` + +The second argument will optionally be used to set the CSS class for the text. + +This method is chainable as it returns the `Path` object + +## Example + ++```js +({ Point, points, Path, paths, part }) => { + 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') + + return part +} +``` + + +## Notes + +The main purpose of this method is to save your some typing, +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 +add to the existing text. + diff --git a/markdown/dev/reference/api/path/shiftalong/en.md b/markdown/dev/reference/api/path/shiftalong/en.md index bda434d566f..c31b402bcc8 100644 --- a/markdown/dev/reference/api/path/shiftalong/en.md +++ b/markdown/dev/reference/api/path/shiftalong/en.md @@ -1,54 +1,55 @@ --- -title: shiftAlong() +title: Path.shiftAlong() --- -```js -Point path.shiftAlong(float distance[, int stepsPerMm=25]) -``` +The `Path.shiftAlong()` method returns a point that lies at distance travelled +along the path. -Returns a point that lies at distance travelled along the path. - --Example of the Path.shiftAlong() method - +## Signature ```js -let { Point, points, Path, paths, Snippet, snippets } = part.shorthand(); - -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.example = new Path() - .move(points.A) - .line(points.B) - .curve(points.BCp2, points.CCp1, points.C); - -points.x1 = paths.example - .shiftAlong(20) - .attr("data-text", "2cm") - .attr("data-text-class", "center fill-note") - .attr("data-text-lineheight", 6); -points.x2 = paths.example - .shiftAlong(90) - .attr("data-text", "9cm") - .attr("data-text-class", "center fill-note") - .attr("data-text-lineheight", 6); - -snippets.x1 = new Snippet("notch", points.x1); -snippets.x2 = new Snippet("notch", points.x2); +Point path.shiftAlong(float distance[, int stepsPerMm=10]) ``` -- -##### The second parameter is optional - The second parameter controls the precision by which the path will be _walked_. -By default, we'll divide it into 25 steps per mm. +By default, we'll divide it into 10 steps per mm. If you don't need that precision, you can pass a lower number. -But for most cases, you can just ignore it. +If you need more precision, you can pass a higher number. +For most cases, the default will be fine. - +## Example + ++```js +({ Point, points, Path, paths, Snippet, snippets, 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); + + paths.example = new Path() + .move(points.A) + .line(points.B) + .curve(points.BCp2, points.CCp1, points.C); + + points.x1 = paths.example + .shiftAlong(20) + .attr("data-text", "2cm") + .attr("data-text-class", "center fill-note") + .attr("data-text-lineheight", 6); + points.x2 = paths.example + .shiftAlong(90) + .attr("data-text", "9cm") + .attr("data-text-class", "center fill-note") + .attr("data-text-lineheight", 6); + + snippets.x1 = new Snippet("notch", points.x1); + snippets.x2 = new Snippet("notch", points.x2); + + return part +} +``` + diff --git a/markdown/dev/reference/api/path/shiftfractionalong/en.md b/markdown/dev/reference/api/path/shiftfractionalong/en.md index 1672c60cc41..490dc0047fe 100644 --- a/markdown/dev/reference/api/path/shiftfractionalong/en.md +++ b/markdown/dev/reference/api/path/shiftfractionalong/en.md @@ -1,54 +1,52 @@ --- -title: shiftFractionAlong() +title: Path.shiftFractionAlong() --- +The `Path.shiftFractionAlong()` returns a point that lies at fraction of the +length of the path travelled along the path. + +## Signature + ```js Point path.shiftFractionAlong(float fraction[, int stepsPerMm=25]) ``` -Returns a point that lies at fraction of the length of the path travelled along the path. - --Example of the Path.shiftFractionAlong() method - - -```js -let { Point, points, Path, paths, Snippet, snippets } = part.shorthand(); - -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.example = new Path() - .move(points.A) - .line(points.B) - .curve(points.BCp2, points.CCp1, points.C); - -points.x1 = paths.example - .shiftFractionAlong(0.2) - .attr("data-text", "msg_20") - .attr("data-text-class", "center") - .attr("data-text-lineheight", 6); -points.x2 = paths.example - .shiftFractionAlong(0.9) - .attr("data-text", "msg_90") - .attr("data-text-class", "center") - .attr("data-text-lineheight", 6); - -snippets.xl = new Snippet("notch", points.x1); -snippets.x2 = new Snippet("notch", points.x2); -``` - -- -##### The second parameter is optional - The second parameter controls the precision by which the path will be _walked_. -By default, we'll divide it into 25 steps per mm. +By default, we'll divide it into 10 steps per mm. If you don't need that precision, you can pass a lower number. -But for most cases, you can just ignore it. +If you need more precision, you can pass a higher number. +For most cases, the default will be fine. + +## Example + + diff --git a/markdown/dev/reference/api/path/smurve/en.md b/markdown/dev/reference/api/path/smurve/en.md index 3189c37f7ee..75b967474f1 100644 --- a/markdown/dev/reference/api/path/smurve/en.md +++ b/markdown/dev/reference/api/path/smurve/en.md @@ -1,37 +1,41 @@ --- -title: smurve() +title: Path.smurve() --- +The `Path.smurve()` method draws a smooth curve from the current point via a control point to an endpoint. +A smooth curve means it will use the reflection of the end control point of the previous curve. + +## Signature + ```js -Path path.attr( - string name, - mixed value, - bool overwrite = false -) +Path path.smurve(Point cp2, Point end) ``` -This `Path.attr()` method calls `this.attributes.add()` under the hood, but returns the Path object. ++```js +({ Point, points, Path, paths, Snippet, snippets, 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); + + paths.example = new Path() + .move(points.A) + .line(points.B) + .curve(points.BCp2, points.CCp1, points.C); + + points.x1 = paths.example + .shiftFractionAlong(0.2) + .setText("0.2", "center") + points.x2 = paths.example + .shiftFractionAlong(0.9) + .setText("0.9", "center") + + snippets.xl = new Snippet("notch", points.x1); + snippets.x2 = new Snippet("notch", points.x2); + + return part +} +``` + -This method is chainable as it returns the `Path` object -This allows you to chain different calls together as in the example below. +## Example -If the third parameter is set to `true` it will call `this.attributes.set()` instead, thereby overwriting the value of the attribute. ++```js +({ Point, points, Path, paths, part }) => { - -Example of the Path.attr() method + 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) + + 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 +} +``` -```js -let { Point, points, Path, paths } = part.shorthand(); - -points.B = new Point(10, 50); -points.BCp2 = new Point(40, 10); -points.C = new Point(90, 30); -points.CCp1 = new Point(50, 90); - -paths.example = new Path() - .move(points.B) - .curve(points.BCp2, points.CCp1, points.C) - .attr("class", "canvas") - .attr("data-text", "freesewingIsMadeByJoostDeCockAndContributors") - .attr("data-text-class", "text-xs center"); -``` diff --git a/markdown/dev/reference/api/path/smurve_/en.md b/markdown/dev/reference/api/path/smurve_/en.md index 202b3036809..ed785005404 100644 --- a/markdown/dev/reference/api/path/smurve_/en.md +++ b/markdown/dev/reference/api/path/smurve_/en.md @@ -1,37 +1,42 @@ --- -title: smurve_() +title: Path.smurve_() --- +The `Path.smurve_()` method draws a smooth curve from the current point an endpoint. +In addition, the end point's control point lies on top of the end point. + +A smooth curve means it will use the reflection of the end control point of the previous curve. + +## Signature + ```js -Path path.attr( - string name, - mixed value, - bool overwrite = false -) +Path path.smurve_(Point cp2, Point end) ``` -This `Path.attr()` method calls `this.attributes.add()` under the hood, but returns the Path object. +This method is chainable as it returns the `Path` object -This allows you to chain different calls together as in the example below. +## Example -If the third parameter is set to `true` it will call `this.attributes.set()` instead, thereby overwriting the value of the attribute. ++```js +({ Point, points, Path, paths, part }) => { - -Example of the Path.attr() method + 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) + + 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 +} +``` -```js -let { Point, points, Path, paths } = part.shorthand(); - -points.B = new Point(10, 50); -points.BCp2 = new Point(40, 10); -points.C = new Point(90, 30); -points.CCp1 = new Point(50, 90); - -paths.example = new Path() - .move(points.B) - .curve(points.BCp2, points.CCp1, points.C) - .attr("class", "canvas") - .attr("data-text", "freesewingIsMadeByJoostDeCockAndContributors") - .attr("data-text-class", "text-xs center"); -``` diff --git a/markdown/dev/reference/api/path/split/en.md b/markdown/dev/reference/api/path/split/en.md index c1d5d2117ca..644a5c91c7e 100644 --- a/markdown/dev/reference/api/path/split/en.md +++ b/markdown/dev/reference/api/path/split/en.md @@ -1,42 +1,49 @@ --- -title: split +title: Path.split() --- +The `Path.split()` method splits a path in two halves, on a point along that +path that you pass it. + +## Signature + ```js array path.split(Point splitPoint) ``` -Splits a path in two halves, on a point along that path that you pass it. - --Example of the Path.split() method - +## Example +```js -let { Point, points, Path, paths, Snippet, snippets } = part.shorthand(); +({ 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, 130); -points.DCp1 = new Point(150, 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, 130); + points.DCp1 = new Point(150, 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); + + points.split = paths.demo.shiftFractionAlong(0.75); + snippets.split = new Snippet("notch", points.split); + + let style = "stroke-width: 3; stroke-opacity: 0.5;"; + let halves = paths.demo.split(points.split); + for (let i in halves) { + paths[i] = halves[i] + .attr("style", style) + .attr("style", `stroke: hsl(${i * 70}, 100%, 50%)`); + } -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.split = paths.demo.shiftFractionAlong(0.75); -snippets.split = new Snippet("notch", points.split); - -let style = "stroke-width: 3; stroke-opacity: 0.5;"; -let halves = paths.demo.split(points.split); -for (let i in halves) { - paths[i] = halves[i] - .attr("style", style) - .attr("style", `stroke: hsl(${i * 70}, 100%, 50%)`); + return part } ``` + + diff --git a/markdown/dev/reference/api/path/start/en.md b/markdown/dev/reference/api/path/start/en.md index 5c07bbce771..8403460cc0e 100644 --- a/markdown/dev/reference/api/path/start/en.md +++ b/markdown/dev/reference/api/path/start/en.md @@ -1,30 +1,38 @@ --- -title: start() +title: Path.start() --- +The `Path.start()` method returns the Point object at the start of the path. + +## Signature + ```js Point path.start() ``` -Returns the Point object at the start of the path. +This method is chainable as it returns the `Path` object --Example of the Path.start() method +## Example + + +```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) + + 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()) + + return part +} +``` -```js -let { Point, points, Path, paths, Snippet, snippets } = part.shorthand(); - -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.example = new Path() - .move(points.A) - .line(points.B) - .curve(points.BCp2, points.CCp1, points.C); - -snippets.start = new Snippet("notch", paths.example.start()); -``` diff --git a/markdown/dev/reference/api/path/translate/en.md b/markdown/dev/reference/api/path/translate/en.md index 6bfbcc1385c..909d038d246 100644 --- a/markdown/dev/reference/api/path/translate/en.md +++ b/markdown/dev/reference/api/path/translate/en.md @@ -1,45 +1,51 @@ --- -title: translate() +title: Path.translate() --- +The `Path.translate()` method returns a path with +[a translate transform](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform#Translate) +applied. + +## Example + ```js Path path.translate(float deltaX, float deltaY) ``` -Returns a path with -[a translate transform](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform#Translate) -applied. +## Example --Example of the Path.translate() method + +```js +({ Point, points, Path, paths, part, macro }) => { + + 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.A = new Path() + .move(points.A) + .line(points.B) + .curve(points.BCp2, points.CCp1, points.C) + + paths.B = paths.A.translate(60, 30) + + points.step1 = points.B.shift(0, 60) + points.step2 = points.step1.shift(-90, 30) + macro("ld", { + from: points.B, + to: points.step1, + noStartMarker: true + }) + macro("ld", { + from: points.step1, + to: points.step2, + noStartMarker: true + }) + + return part +} +``` -```js -let { Point, points, Path, paths, macro } = part.shorthand(); - -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.A = new Path() - .move(points.A) - .line(points.B) - .curve(points.BCp2, points.CCp1, points.C); - -paths.B = paths.A.translate(60, 30); - -points.step1 = points.B.shift(0, 60); -points.step2 = points.step1.shift(-90, 30); -macro("ld", { - from: points.B, - to: points.step1, - noStartMarker: true -}); -macro("ld", { - from: points.step1, - to: points.step2, - noStartMarker: true -}); -``` diff --git a/markdown/dev/reference/api/path/trim/en.md b/markdown/dev/reference/api/path/trim/en.md index 495a67047a7..e4ca44c638a 100644 --- a/markdown/dev/reference/api/path/trim/en.md +++ b/markdown/dev/reference/api/path/trim/en.md @@ -1,18 +1,68 @@ --- -title: trim() +title: Path.trim() --- +The `Path.trim()` method Returns a new Path that is this path with overlapping +parts removed. + ```js Path path.trim() ``` -Returns a new Path that is this path with overlapping parts removed. + + ++```js +({ Point, points, Path, paths, part }) => { + + points.center = new Point(0, 0) + points.base = new Point(0, 10) + points.tip = new Point(0, 50) + points.tipCpRight = new Point(30, 50) + points.tipCpLeft = new Point(-30, 50) + paths.example = new Path().move(points.base) + for (let i = 0; i < 4; i++) { + points["base" + i] = points.base.rotate(60 * i, points.center) + points["tip" + i] = points.tip.rotate(60 * i, points.center) + points["tipCpRight" + i] = points.tipCpRight.rotate(60 * i, points.center) + points["tipCpLeft" + i] = points.tipCpLeft.rotate(60 * i, points.center) + if (i < 2) { + paths.example + .line(points["base" + i]) + .curve(points["base" + i], points["tipCpLeft" + i], points["tip" + i]) + .curve( + points["tipCpRight" + i], + points["base" + i], + points["base" + i] + ); + } else { + paths.example + .line(points["base" + i]) + .line(points["tip" + i]) + .line(points["tipCpRight" + i]) + .line(points["base" + i]) + } + } + + paths.offset = paths.example + .offset(10) + .setClass("lining dotted stroke-sm") + + paths.trimmed = paths.offset + .trim() + .setClass("various stroke-xl") + .attr("style", "stroke-opacity: 0.5;") + + return part +} +``` + + + +## Notes This method is typically used when [Path.offset()](/reference/api/path/offset) caused some overlap. - -- -###### Use sparsely or performance will suffer +However, use this sparsely or performance will suffer. This method is recursive and complex, and the performance penalty for using it on a long/complex path will be significant. @@ -22,54 +72,3 @@ To limit the impact of path.trim(), follow this approach: - construct a minimal path that contains the overlap - trim it - now join it to the rest of your path - -You can see an example of this -[in the front part of the Bruce pattern](https://github.com/freesewing/freesewing/blob/3ca5d0edfe54c7ac20aaf3af2f3544aee72f9b99/designs/bruce/src/front.js#L158). - - - --Example of the Path.trim() method - - -```js -let { Point, points, Path, paths } = part.shorthand(); - -points.center = new Point(0, 0); -points.base = new Point(0, 10); -points.tip = new Point(0, 50); -points.tipCpRight = new Point(30, 50); -points.tipCpLeft = new Point(-30, 50); -paths.example = new Path().move(points.base); -for (let i = 0; i < 4; i++) { - points["base" + i] = points.base.rotate(60 * i, points.center); - points["tip" + i] = points.tip.rotate(60 * i, points.center); - points["tipCpRight" + i] = points.tipCpRight.rotate(60 * i, points.center); - points["tipCpLeft" + i] = points.tipCpLeft.rotate(60 * i, points.center); - if (i < 2) { - paths.example - .line(points["base" + i]) - .curve(points["base" + i], points["tipCpLeft" + i], points["tip" + i]) - .curve( - points["tipCpRight" + i], - points["base" + i], - points["base" + i] - ); - } else { - paths.example - .line(points["base" + i]) - .line(points["tip" + i]) - .line(points["tipCpRight" + i]) - .line(points["base" + i]); - } -} - -paths.offset = paths.example - .offset(10) - .attr("class", "lining dotted stroke-sm"); - -paths.trimmed = paths.offset - .trim() - .attr("class", "various stroke-xl") - .attr("style", "stroke-opacity: 0.5;"); -``` diff --git a/markdown/dev/reference/api/path/unhide/en.md b/markdown/dev/reference/api/path/unhide/en.md index 11909d5870c..8b7ae18915e 100644 --- a/markdown/dev/reference/api/path/unhide/en.md +++ b/markdown/dev/reference/api/path/unhide/en.md @@ -1,37 +1,35 @@ --- -title: unhide() +title: Path.unhide() --- +The `Path.unhide()` method unhides the path so it does appears in the output. + +By default, paths are not hidden. So you should only call this on path previously hidden via `Path.hide()`. + +## Signature + ```js -Path path.attr( - string name, - mixed value, - bool overwrite = false -) +Path path.unhide() ``` -This `Path.attr()` method calls `this.attributes.add()` under the hood, but returns the Path object. +This method is chainable as it returns the `Path` object -This allows you to chain different calls together as in the example below. +## Example -If the third parameter is set to `true` it will call `this.attributes.set()` instead, thereby overwriting the value of the attribute. ++```js +({ Point, points, Path, paths, part }) => { - -Example of the Path.attr() method + 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') + + return part +} +``` -```js -let { Point, points, Path, paths } = part.shorthand(); - -points.B = new Point(10, 50); -points.BCp2 = new Point(40, 10); -points.C = new Point(90, 30); -points.CCp1 = new Point(50, 90); - -paths.example = new Path() - .move(points.B) - .curve(points.BCp2, points.CCp1, points.C) - .attr("class", "canvas") - .attr("data-text", "freesewingIsMadeByJoostDeCockAndContributors") - .attr("data-text-class", "text-xs center"); -``` From 8955cdeec85989f5f63bceb95d1a0a23665e939b Mon Sep 17 00:00:00 2001 From: Joost De CockDate: Tue, 27 Sep 2022 18:24:55 +0200 Subject: [PATCH 25/46] feat(examples): Added two more examples --- designs/examples/src/index.mjs | 3 +++ designs/examples/src/path.mjs | 25 ++++++++++++++++--------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/designs/examples/src/index.mjs b/designs/examples/src/index.mjs index 487893757d1..73e2d676f09 100644 --- a/designs/examples/src/index.mjs +++ b/designs/examples/src/index.mjs @@ -7,6 +7,7 @@ import { data } from '../data.mjs' import { path__curve, path_addclass, + path_addtext, path_attr, path_move, path_line, @@ -140,6 +141,7 @@ const Examples = new Design({ // Path API path__curve, path_addclass, + path_addtext, path_attr, path_move, path_line, @@ -266,6 +268,7 @@ export { // Path API path__curve, path_addclass, + path_addtext, path_attr, path_move, path_line, diff --git a/designs/examples/src/path.mjs b/designs/examples/src/path.mjs index ad951583e72..d3ce4366009 100644 --- a/designs/examples/src/path.mjs +++ b/designs/examples/src/path.mjs @@ -23,10 +23,19 @@ export const path_addclass = { 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 box(part, 100, 20) + }, +} + +export const path_addtext = { + name: 'examples.path_addtext', + draft: ({ Point, points, Path, paths, part }) => { + 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') return box(part, 100, 20) }, @@ -67,7 +76,7 @@ export const path_clone = { paths.clone = paths.example .clone() - .attr('class', 'note lashed stroke-l') + .setClass('note lashed stroke-xl') .attr('style', 'stroke-opacity: 0.5') return part @@ -86,8 +95,7 @@ export const path_close = { ._curve(points.cp2, points.to) .close() .reverse() // To keep text from being upside-down - .attr('data-text', 'Path._close()') - .attr('data-text-class', 'text-sm right fill-note') + .setText('Path._close()', 'text-sm right fill-note') return box(part, 100, 25) }, @@ -104,8 +112,7 @@ export const path_curve = { paths.line = new Path() .move(points.from) .curve(points.cp1, points.cp2, points.to) - .attr('data-text', 'Path.curve()') - .attr('data-text-class', 'text-sm center fill-note') + .setText('Path.curve()', 'text-sm center fill-note') return box(part, 100, 25) }, From b57b31056b6e80541cb32954028ec9cd09967d9f Mon Sep 17 00:00:00 2001 From: Joost De Cock Date: Tue, 27 Sep 2022 19:15:42 +0200 Subject: [PATCH 26/46] chore(markdown): Updated Design api docs for v3 --- markdown/dev/reference/api/design/en.md | 41 +++++++++++++++++++------ 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/markdown/dev/reference/api/design/en.md b/markdown/dev/reference/api/design/en.md index 7922913be70..2856f0f9946 100644 --- a/markdown/dev/reference/api/design/en.md +++ b/markdown/dev/reference/api/design/en.md @@ -3,14 +3,21 @@ title: Design order: 10 --- -The `Design` named export in FreeSewing's core library serves a single purpose: -To create new pattern designs. +The `Design` named export in FreeSewing's core library is a contructor that +creates new pattern designs. -## Design constructor +## Signature ```js -import { Design } from "@freesewing/core" +Pattern Design({ + array parts, + object data +}) +``` +## Example + +```js const Sorcha = new Design({ // design configuration here }) @@ -21,9 +28,8 @@ It takes a single argument, an object holding the design's configuration. ## Design configuration - Since a design's configuration is managed at the part level, -the Design constructor only expects a `parts` attribute that should +the Design configuration object only requires a `parts` property that should hold an array of parts to include in the Design. ```js @@ -44,14 +50,29 @@ to [the Store](/reference/api/store). const Sorcha = new Design({ parts: [ front, back, sleeve ], data: { - // Your custom data here + version: 3, + price: 12, + currency: 'euro' } }) ``` - +## Notes -This Design constructor is a _super-constructor_. + +The Design constructor is a _super-constructor_. It will return a constructor method that will a pattern based on your design. - +## Properties + +In addition to the returned constructor method, an instantiated Design object +also provides the following properties: + +### Design.designConfig + +This holds the design configuration as passed to the Design constructor. + +### Design.patternConfig + +Holds the resolved pattern configuration based on the configuration passed to the Design constructor. + From f2cef46eb01b516ba0834661eb68cc4506c5f207 Mon Sep 17 00:00:00 2001 From: Joost De CockDate: Tue, 27 Sep 2022 19:15:57 +0200 Subject: [PATCH 27/46] chore(markdown): Updated Point api docs for v3 (wip) --- .../dev/reference/api/point/addcircle/en.md | 17 +++---- .../dev/reference/api/point/addtext/en.md | 33 +++++++----- markdown/dev/reference/api/point/angle/en.md | 45 +++++++++-------- markdown/dev/reference/api/point/attr/en.md | 41 +++++++++------ markdown/dev/reference/api/point/clone/en.md | 50 +++++++++++-------- markdown/dev/reference/api/point/copy/en.md | 48 ++++++++++-------- markdown/dev/reference/api/point/dist/en.md | 46 ++++++++--------- 7 files changed, 156 insertions(+), 124 deletions(-) diff --git a/markdown/dev/reference/api/point/addcircle/en.md b/markdown/dev/reference/api/point/addcircle/en.md index c6c5626a6b0..99142ffdf17 100644 --- a/markdown/dev/reference/api/point/addcircle/en.md +++ b/markdown/dev/reference/api/point/addcircle/en.md @@ -2,11 +2,11 @@ title: Point.addCircle() --- -Adds a circle to a Point. Under the hood, this will call `Point.attr()` as circles -are added by setting attributes. Refer to [Drawing circles](/howtos/code/drawing-circles) for -more details. +The `Point.addCircle()` method adds a circle to a Point. Under the hood, this +will call `Point.attr()` as circles are added by setting attributes. Refer to +[Drawing circles](/howtos/code/drawing-circles) for more details. -## Point.addCircle() signature +## Signature ```js Point point.addCircle( @@ -15,12 +15,9 @@ Point point.addCircle( ) ``` -## Point.addCircle() example - - -Examples of Point.addCircle(), compare this to [Point.setCircle](/reference/api/point/setcircle) - +## Example +```js ({ Point, points, part }) => { points.a = new Point(30, 10) @@ -41,4 +38,6 @@ Examples of Point.addCircle(), compare this to [Point.setCircle](/reference/api/ return part } ``` + + diff --git a/markdown/dev/reference/api/point/addtext/en.md b/markdown/dev/reference/api/point/addtext/en.md index 887c4242e2a..21d590cf2ed 100644 --- a/markdown/dev/reference/api/point/addtext/en.md +++ b/markdown/dev/reference/api/point/addtext/en.md @@ -2,11 +2,11 @@ title: Point.addText() --- -Adds text on a Point. Under the hood, this will call `Point.attr()` as text -is added by setting attributes. Refer to [Adding text](/howtos/code/adding-text) for -more details. +The `Point.addText()` method adds text on a Point. Under the hood, this will +call `Point.attr()` as text is added by setting attributes. Refer to [Adding +text](/howtos/code/adding-text) for more details. -## Point.addText() signature +## Signature ```js Point point.addText( @@ -15,21 +15,28 @@ Point point.addText( ) ``` -## Point.addText() example - --Examples of Point.addText(), compare this to [Point.setText](/reference/api/point/settext) - +## Example +```js -({ Point, points, part }) => { +({ Point, points, Path, paths, part }) => { points.anchor = new Point(100, 25) - .addText('supportFreesewingBecomeAPatron', 'center') - .addText('please?') + .addText('FreeSewing') + .addText('rocks') + + // Avoid the text getting cropped + paths.hidden = new Path() + .move(points.anchor) + .line(points.anchor.shift(0, 80)) + .addClass('hidden') + return part } ``` + -Remember to [use translation keys, not text](/guides/best-practices/use-translation-keys) +## Notes + +Remember to [use translation keys, not text](/guides/best-practices/use-translation-keys) diff --git a/markdown/dev/reference/api/point/angle/en.md b/markdown/dev/reference/api/point/angle/en.md index 493432026e9..199a006ecc0 100644 --- a/markdown/dev/reference/api/point/angle/en.md +++ b/markdown/dev/reference/api/point/angle/en.md @@ -2,33 +2,36 @@ title: Point.angle() --- -A point's `angle()` method returns the angle (in degrees) between this point and -the point passed into the method. An angle of 0Β° points to the right, and the angle increases counterclockwise. +The `Point.angle()` method returns the angle (in degrees) between this point +and the point passed into the method. An angle of 0Β° points to the right, and +the angle increases counterclockwise. -## Point.angle() signature +## Signature ```js float point.angle(Point pointB) ``` -## Point.angle() Example +## Example --An example of the Point.angle() method + +```js +({ Point, points, Path, paths, part }) => { + + points.sun = new Point(10, 5); + points.moon = points.sun.shift(-15, 70); + points.text = points.sun + .shiftFractionTowards(points.moon, 0.8) + .attr("data-text", points.sun.angle(points.moon)+"Β°") + .attr("data-text-class", "text-sm fill-note center"); + + paths.line = new Path() + .move(points.sun) + .line(points.moon) + .attr("class", "dashed"); + + return part +} +``` -```js -let { Point, points, Path, paths } = part.shorthand(); - -points.sun = new Point(10, 5); -points.moon = points.sun.shift(-15, 70); -points.text = points.sun - .shiftFractionTowards(points.moon, 0.8) - .attr("data-text", points.sun.angle(points.moon)+"Β°") - .attr("data-text-class", "text-sm fill-note center"); - -paths.line = new Path() - .move(points.sun) - .line(points.moon) - .attr("class", "dashed"); -``` diff --git a/markdown/dev/reference/api/point/attr/en.md b/markdown/dev/reference/api/point/attr/en.md index 1f0de570cd2..92843e0927e 100644 --- a/markdown/dev/reference/api/point/attr/en.md +++ b/markdown/dev/reference/api/point/attr/en.md @@ -2,10 +2,11 @@ title: Point.attr() --- -Adds an attribute to the point, and returns the original point. Setting the third parameter -to `true` will replace the value of the attribute instead of adding it. +The `Point.attr()` method adds an attribute to the point, and returns the +original point. Setting the third parameter to `true` will replace the value of +the attribute instead of adding it. -## Point.attr() signature +## Signature ```js Point point.attr( @@ -15,21 +16,29 @@ Point point.attr( ) ``` -The `Point.attr()` method calls [`this.attributes.add()`](/reference/api/attributes/add/) under the hood, but returns the `Point` object. -This allows you to chain different calls together as in the example below. - 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. -## Point.attr() example --An example of the Point.attr() method + This method is chainable as it returns the `Path` object + +## Example + ++```js +({ Point, points, Path, paths, part }) => { + + 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') + + return part +} +``` -```js -let { Point, points } = part.shorthand(); - -points.anchor = new Point(100, 25) - .attr("data-text", "freesewingIsMadeByJoostDeCockAndContributors") - .attr("data-text-class", "center"); -``` diff --git a/markdown/dev/reference/api/point/clone/en.md b/markdown/dev/reference/api/point/clone/en.md index 91cec6088b8..10cc77cae88 100644 --- a/markdown/dev/reference/api/point/clone/en.md +++ b/markdown/dev/reference/api/point/clone/en.md @@ -2,37 +2,45 @@ title: Point.clone() --- -Returns a new `Point` with the same coordinates and attributes as the original point. +The `Point.clone()` method returns a new `Point` with the same coordinates and +attributes as the original point. -## Point.clone() signature +## Signature ```js Point point.clone() ``` -+ - -## Point.clone() example - -This method is chainable as it returns the `Point` object -###### Copy vs clone - -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. - --An example of the Point.clone() method - +## Example +```js - let { Point, points, Snippet, snippets } = part.shorthand(); +({ Point, points, Path, paths, Snippet, snippets, part }) => { points.A = new Point(25, 25) - .attr("data-text", "Point A") - .attr("data-text-class", "text-xl") - .attr("data-text-fill-opacity", "0.5"); - points.B = points.A.clone().attr("data-text", "Point B"); + .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') + + return part +} ``` + + + +## Notes + +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/markdown/dev/reference/api/point/copy/en.md b/markdown/dev/reference/api/point/copy/en.md index 41f80e76887..ea95531f2d7 100644 --- a/markdown/dev/reference/api/point/copy/en.md +++ b/markdown/dev/reference/api/point/copy/en.md @@ -2,37 +2,43 @@ title: Point.copy() --- -A point's `copy()` method returns a new point with the same coordinates as the original point. -This method does _not_ copy any attributes the original point may have. +The `Point.copy()` method returns a new point with the same coordinates as the +original point. This method does _not_ copy any attributes the original point +may have. -## Point.copy() signature +## Signature ```js Point point.copy() ``` -- -###### Copy vs clone - -this `Point.copy()` method will only copy the point's coordinates. -To also copy the attributes, use [`Point.clone()`](/reference/api/point/clone/) instead. - - ## Point.copy() example --An example of the Point.copy() method + +```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") + + 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') + + return part +} +``` -```js -let { Point, points, Snippet, snippets } = part.shorthand(); -points.A = new Point(50, 25) - .attr("data-text", "Point A") - .attr("data-text-class", "text-xl"); -points.B = points.A.copy().attr("data-text", "Point B"); +## Notes -snippets.x = new Snippet("notch", points.A); -``` +The `Point.copy()` method will only copy the point's coordinates. +To also copy the attributes, use [`Point.clone()`](/reference/api/point/clone/) instead. diff --git a/markdown/dev/reference/api/point/dist/en.md b/markdown/dev/reference/api/point/dist/en.md index aeee3e00553..724b297e2ae 100644 --- a/markdown/dev/reference/api/point/dist/en.md +++ b/markdown/dev/reference/api/point/dist/en.md @@ -2,35 +2,35 @@ title: Point.dist() --- -A point's `dist()` method returns the distance (in mm) between this point and the point you pass it. +The `Point.dist()` method returns the distance (in mm) between this point and +the point you pass it. -## Point.dist() signature +## Signature ```js float point.dist(Point point) ``` -## Point.dist() example +## Example --An example of the Point.dist() method + +```js +({ Point, points, Path, paths, units, part }) => { + + points.from = new Point(10, 10) + points.to = new Point(80, 70) + + points.text = points.from + .shiftFractionTowards(points.to, 0.6) + .setText(units(points.from.dist(points.to)), 'text-sm fill-note center') + + paths.line = new Path() + .move(points.from) + .line(points.to) + .attr('class', 'dashed') + + return part +} +``` -```js -let { Point, points, Path, paths } = part.shorthand() - -points.from = new Point(10, 10) -points.to = new Point(80, 70) - -points.text = points.from - .shiftFractionTowards(points.to, 0.6) - .attr('data-text', points.from.dist(points.to) + 'mm') - .attr('data-text-class', 'text-sm fill-note center') - -paths.line = new Path() - .move(points.from) - .line(points.to) - .attr('class', 'dashed') - -return part -``` From 8896e04d4f10772f6def69378d8aaab96f9d0ed5 Mon Sep 17 00:00:00 2001 From: anna-puk <100537439+anna-puk@users.noreply.github.com> Date: Tue, 27 Sep 2022 22:29:09 +0200 Subject: [PATCH 28/46] used lint to clean up code --- designs/unice/src/back.mjs | 4 ---- designs/unice/src/elastic.mjs | 2 -- designs/unice/src/front.mjs | 3 --- designs/unice/src/gusset.mjs | 4 ---- 4 files changed, 13 deletions(-) diff --git a/designs/unice/src/back.mjs b/designs/unice/src/back.mjs index d83ca70bda6..97555b4e5fb 100644 --- a/designs/unice/src/back.mjs +++ b/designs/unice/src/back.mjs @@ -1,4 +1,3 @@ -import { pctBasedOn } from '@freesewing/core' import { front } from './front.mjs' export const back = { @@ -21,15 +20,12 @@ export const back = { points, Path, paths, - Snippet, - snippets, options, measurements, complete, paperless, macro, part, - log, }) => { // Design pattern here diff --git a/designs/unice/src/elastic.mjs b/designs/unice/src/elastic.mjs index 406a4c76a10..1965b5ae859 100644 --- a/designs/unice/src/elastic.mjs +++ b/designs/unice/src/elastic.mjs @@ -16,8 +16,6 @@ export const elastic = { utils, units, sa, - paperless, - macro, part, }) => { // Stretch utility method diff --git a/designs/unice/src/front.mjs b/designs/unice/src/front.mjs index 79d17a29b96..6ee8c5592ea 100644 --- a/designs/unice/src/front.mjs +++ b/designs/unice/src/front.mjs @@ -1,4 +1,3 @@ -import { pctBasedOn } from '@freesewing/core' import {pluginBundle } from '@freesewing/plugin-bundle' export const front = { @@ -28,8 +27,6 @@ export const front = { points, Path, paths, - Snippet, - snippets, options, measurements, complete, diff --git a/designs/unice/src/gusset.mjs b/designs/unice/src/gusset.mjs index 8175482fefb..3a06bc94c24 100644 --- a/designs/unice/src/gusset.mjs +++ b/designs/unice/src/gusset.mjs @@ -1,4 +1,3 @@ -import { pctBasedOn } from '@freesewing/core' import { back } from './back.mjs' export const gusset = { @@ -21,15 +20,12 @@ export const gusset = { }, after: back, draft: ({ - utils, store, sa, Point, points, Path, paths, - Snippet, - snippets, options, measurements, complete, From 995849cd72d6da2d5984779dddb108a195a337da Mon Sep 17 00:00:00 2001 From: anna-puk <100537439+anna-puk@users.noreply.github.com> Date: Tue, 27 Sep 2022 22:33:45 +0200 Subject: [PATCH 29/46] used prettier to clean up formatting --- designs/unice/src/back.mjs | 474 ++++++++++++++++++---------------- designs/unice/src/elastic.mjs | 61 ++--- designs/unice/src/front.mjs | 471 +++++++++++++++++---------------- designs/unice/src/gusset.mjs | 141 +++++----- designs/unice/src/index.mjs | 2 +- 5 files changed, 596 insertions(+), 553 deletions(-) diff --git a/designs/unice/src/back.mjs b/designs/unice/src/back.mjs index 97555b4e5fb..afefabe8fbf 100644 --- a/designs/unice/src/back.mjs +++ b/designs/unice/src/back.mjs @@ -2,8 +2,8 @@ import { front } from './front.mjs' export const back = { name: 'unice.back', - measurements: ['waist', 'seat', 'waistToSeat', 'waistToUpperLeg','hips','waistToHips'], - optionalMeasurements: ['crossSeam','crossSeamFront'], + measurements: ['waist', 'seat', 'waistToSeat', 'waistToUpperLeg', 'hips', 'waistToHips'], + optionalMeasurements: ['crossSeam', 'crossSeamFront'], options: { backToFrontLength: 1.15, // Maybe include this in advanced options? backToFrontWidth: 1.1, // Maybe include this in advanced options? @@ -27,255 +27,281 @@ export const back = { macro, part, }) => { + // Design pattern here - // Design pattern here - - // Create points - points.backWaistMid = new Point(measurements.seat / 4, 0) - points.backWaistBandLeft = new Point( - store.get('sideSeamWaist').x / options.backToFrontWidth, - store.get('sideSeamWaist').y - ) - points.backLegOpeningLeft = new Point( - store.get('sideSeamHip').x / options.backToFrontWidth, - store.get('sideSeamHip').y - ) - - // back height is given by (estimated) cross seam, minus front and gusset lengths - // this does not account for vertical stretch yet - const backHeight = store.get('crossSeam') - store.get('frontHeight') - options.gussetLength * measurements.seat - - // calculate the actual back height, using yScale above and yScaleReduced below leg opening - const backHeightAbove = store.get('frontHeightAbove') // part above has same height front and back - - let backHeightBelow - backHeightBelow = store.get('yScale')*(backHeight - backHeightAbove/store.get('yScaleReduced')) - - const backHeightReduced = backHeightBelow + backHeightAbove - - points.backGussetLeft = new Point( - measurements.seat / 4 - - ((measurements.waist * options.gussetWidth * store.get('xScale')) / options.gussetRatio) * - options.backToFrontWidth, - backHeightReduced - ) - points.backGussetMid = new Point( - measurements.seat / 4, - backHeightReduced - ) - - points.backGussetRight = points.backGussetLeft.flipX(points.backWaistMid) - points.backLegOpeningRight = points.backLegOpeningLeft.flipX(points.backWaistMid) - points.backWaistBandRight = points.backWaistBandLeft.flipX(points.backWaistMid) - - points.backWaistBandMid = points.backWaistBandLeft - .shiftFractionTowards(points.backWaistBandRight, 0.5) - .shift(270, measurements.waistToUpperLeg * options.backDip) - - /* Middle point for label */ - points.backMidMid = points.backLegOpeningLeft.shiftFractionTowards( - points.backLegOpeningRight, - 0.5 - ) - - // Create control points - - /* Control point for waistband dip */ - points.backWaistBandLeftCp1 = points.backWaistBandMid.shift(0,points.backWaistBandMid.dx(points.backWaistBandLeft) / 3 ) - - /* Flip points to right side */ - points.backWaistBandRightCp1 = points.backWaistBandLeftCp1.flipX(points.backWaistMid) - - // Shape back coverage - - /* Only have to do this on one side */ - points.backLegOpeningCorner = utils.beamsIntersect( - points.backLegOpeningLeft, - points.backLegOpeningLeft.shift(180, points.backGussetLeft.dy(points.backLegOpeningLeft)), - points.backGussetLeft, - points.backGussetLeft.shift(270, points.backGussetLeft.dy(points.backLegOpeningLeft)) - ) - - if (options.backExposure >= 0) { - /* If back exposure is high, like a thong style */ - /* This controls the hip bit */ - points.backLegOpeningLeftCp1 = points.backLegOpeningLeft.shiftFractionTowards( - points.backLegOpeningCorner, - options.backExposure + // Create points + points.backWaistMid = new Point(measurements.seat / 4, 0) + points.backWaistBandLeft = new Point( + store.get('sideSeamWaist').x / options.backToFrontWidth, + store.get('sideSeamWaist').y ) - /* This controls the center bit */ - points.backGussetLeftCp1 = points.backGussetLeft.shiftFractionTowards( - points.backWaistBandMid, - options.backExposure + points.backLegOpeningLeft = new Point( + store.get('sideSeamHip').x / options.backToFrontWidth, + store.get('sideSeamHip').y ) - points.backGussetLeft = points.backGussetLeft.shiftFractionTowards( - points.backGussetMid, - options.backExposure - ) // This narrows the back of the gusset + + // back height is given by (estimated) cross seam, minus front and gusset lengths + // this does not account for vertical stretch yet + const backHeight = + store.get('crossSeam') - store.get('frontHeight') - options.gussetLength * measurements.seat + + // calculate the actual back height, using yScale above and yScaleReduced below leg opening + const backHeightAbove = store.get('frontHeightAbove') // part above has same height front and back + + let backHeightBelow + backHeightBelow = + store.get('yScale') * (backHeight - backHeightAbove / store.get('yScaleReduced')) + + const backHeightReduced = backHeightBelow + backHeightAbove + + points.backGussetLeft = new Point( + measurements.seat / 4 - + ((measurements.waist * options.gussetWidth * store.get('xScale')) / options.gussetRatio) * + options.backToFrontWidth, + backHeightReduced + ) + points.backGussetMid = new Point(measurements.seat / 4, backHeightReduced) + points.backGussetRight = points.backGussetLeft.flipX(points.backWaistMid) - } else { - /* If back exposure is low and flares out to cover more */ - store.set('adjustedBackExposure',options.backExposure * store.get('adjustedLegOpening')) // flare depends on leg opening - /* This controls the hip bit */ - points.backLegOpeningLeftCp1 = points.backLegOpeningLeft.shift( - -45,store.get('adjustedBackExposure') * points.backWaistBandMid.dx(points.backWaistBandLeft)) - /* This controls the taper to gusset */ - points.backGussetLeftCp1 = points.backGussetLeft.shift(115, store.get('adjustedBackExposure') * points.backWaistBandMid.dx(points.backWaistBandLeft)) + points.backLegOpeningRight = points.backLegOpeningLeft.flipX(points.backWaistMid) + points.backWaistBandRight = points.backWaistBandLeft.flipX(points.backWaistMid) - /* center of the flare and its control points are on a line parallel to the backGussetLeft to backLegOpeningLeft line - * first, define the points on that line */ - points.backFlare = points.backGussetLeft.shiftFractionTowards(points.backLegOpeningLeft, 0.5) - // points.backFlareCp1 = points.backGussetLeft.shiftFractionTowards(points.backLegOpeningLeft, 0.5 - store.get('adjustedBackExposure')) - points.backFlareCp1 = points.backGussetLeft.shiftFractionTowards(points.backLegOpeningLeft, 0.7) - points.backFlareCp2 = points.backGussetLeft.shiftFractionTowards(points.backLegOpeningLeft, 0.3) - /* then shift all three points outward */ - points.backFlareLeft = points.backFlare.shift( - 215,(points.backWaistBandMid.dx(points.backWaistBandLeft)) * store.get('adjustedBackExposure') * 2 ) - points.backFlareLeftCp1 = points.backFlareCp1.shift( - 215,(points.backWaistBandMid.dx(points.backWaistBandLeft)) * store.get('adjustedBackExposure') * 2 ) - points.backFlareLeftCp2 = points.backFlareCp2.shift( - 215,(points.backWaistBandMid.dx(points.backWaistBandLeft)) * store.get('adjustedBackExposure') * 2 ) + points.backWaistBandMid = points.backWaistBandLeft + .shiftFractionTowards(points.backWaistBandRight, 0.5) + .shift(270, measurements.waistToUpperLeg * options.backDip) + /* Middle point for label */ + points.backMidMid = points.backLegOpeningLeft.shiftFractionTowards( + points.backLegOpeningRight, + 0.5 + ) + + // Create control points + + /* Control point for waistband dip */ + points.backWaistBandLeftCp1 = points.backWaistBandMid.shift( + 0, + points.backWaistBandMid.dx(points.backWaistBandLeft) / 3 + ) + + /* Flip points to right side */ + points.backWaistBandRightCp1 = points.backWaistBandLeftCp1.flipX(points.backWaistMid) + + // Shape back coverage + + /* Only have to do this on one side */ + points.backLegOpeningCorner = utils.beamsIntersect( + points.backLegOpeningLeft, + points.backLegOpeningLeft.shift(180, points.backGussetLeft.dy(points.backLegOpeningLeft)), + points.backGussetLeft, + points.backGussetLeft.shift(270, points.backGussetLeft.dy(points.backLegOpeningLeft)) + ) + + if (options.backExposure >= 0) { + /* If back exposure is high, like a thong style */ + /* This controls the hip bit */ + points.backLegOpeningLeftCp1 = points.backLegOpeningLeft.shiftFractionTowards( + points.backLegOpeningCorner, + options.backExposure + ) + /* This controls the center bit */ + points.backGussetLeftCp1 = points.backGussetLeft.shiftFractionTowards( + points.backWaistBandMid, + options.backExposure + ) + points.backGussetLeft = points.backGussetLeft.shiftFractionTowards( + points.backGussetMid, + options.backExposure + ) // This narrows the back of the gusset + points.backGussetRight = points.backGussetLeft.flipX(points.backWaistMid) + } else { + /* If back exposure is low and flares out to cover more */ + store.set('adjustedBackExposure', options.backExposure * store.get('adjustedLegOpening')) // flare depends on leg opening + /* This controls the hip bit */ + points.backLegOpeningLeftCp1 = points.backLegOpeningLeft.shift( + -45, + store.get('adjustedBackExposure') * points.backWaistBandMid.dx(points.backWaistBandLeft) + ) + /* This controls the taper to gusset */ + points.backGussetLeftCp1 = points.backGussetLeft.shift( + 115, + store.get('adjustedBackExposure') * points.backWaistBandMid.dx(points.backWaistBandLeft) + ) + + /* center of the flare and its control points are on a line parallel to the backGussetLeft to backLegOpeningLeft line + * first, define the points on that line */ + points.backFlare = points.backGussetLeft.shiftFractionTowards(points.backLegOpeningLeft, 0.5) + // points.backFlareCp1 = points.backGussetLeft.shiftFractionTowards(points.backLegOpeningLeft, 0.5 - store.get('adjustedBackExposure')) + points.backFlareCp1 = points.backGussetLeft.shiftFractionTowards( + points.backLegOpeningLeft, + 0.7 + ) + points.backFlareCp2 = points.backGussetLeft.shiftFractionTowards( + points.backLegOpeningLeft, + 0.3 + ) + /* then shift all three points outward */ + points.backFlareLeft = points.backFlare.shift( + 215, + points.backWaistBandMid.dx(points.backWaistBandLeft) * store.get('adjustedBackExposure') * 2 + ) + points.backFlareLeftCp1 = points.backFlareCp1.shift( + 215, + points.backWaistBandMid.dx(points.backWaistBandLeft) * store.get('adjustedBackExposure') * 2 + ) + points.backFlareLeftCp2 = points.backFlareCp2.shift( + 215, + points.backWaistBandMid.dx(points.backWaistBandLeft) * store.get('adjustedBackExposure') * 2 + ) + + /* Flip points to the right */ + + points.backFlareRight = points.backFlareLeft.flipX(points.backWaistBandMid) + points.backFlareRightCp1 = points.backFlareLeftCp1.flipX(points.backWaistMid) + points.backFlareRightCp2 = points.backFlareLeftCp2.flipX(points.backWaistMid) + } /* Flip points to the right */ - points.backFlareRight = points.backFlareLeft.flipX(points.backWaistBandMid) - points.backFlareRightCp1 = points.backFlareLeftCp1.flipX(points.backWaistMid) - points.backFlareRightCp2 = points.backFlareLeftCp2.flipX(points.backWaistMid) - } + points.backLegOpeningRightCp1 = points.backLegOpeningLeftCp1.flipX(points.backWaistMid) + points.backGussetRightCp1 = points.backGussetLeftCp1.flipX(points.backWaistMid) - /* Flip points to the right */ + // Draw paths - points.backLegOpeningRightCp1 = points.backLegOpeningLeftCp1.flipX(points.backWaistMid) - points.backGussetRightCp1 = points.backGussetLeftCp1.flipX(points.backWaistMid) - - // Draw paths - - if (options.backExposure >= 0) { - paths.seam = new Path() - .move(points.backWaistBandMid) - .curve(points.backWaistBandLeftCp1, points.backWaistBandLeft, points.backWaistBandLeft) // Waist band dip - .line(points.backLegOpeningLeft) - .curve(points.backLegOpeningLeftCp1, points.backGussetLeftCp1, points.backGussetLeft) - .line(points.backGussetMid) - .line(points.backGussetRight) - .curve(points.backGussetRightCp1, points.backLegOpeningRightCp1, points.backLegOpeningRight) - .line(points.backWaistBandRight) - .curve(points.backWaistBandRight, points.backWaistBandRightCp1, points.backWaistBandMid) // Waist band dip - .close() - .attr('class', 'fabric') - } else { - paths.seam = new Path() - .move(points.backWaistBandMid) - .curve(points.backWaistBandLeftCp1, points.backWaistBandLeft, points.backWaistBandLeft) // Waist band dip - .line(points.backLegOpeningLeft) - .curve(points.backLegOpeningLeftCp1, points.backFlareLeftCp1, points.backFlareLeft) - .curve(points.backFlareLeftCp2, points.backGussetLeftCp1, points.backGussetLeft) - .line(points.backGussetMid) - .line(points.backGussetRight) - .curve(points.backGussetRightCp1, points.backFlareRightCp2, points.backFlareRight) - .curve(points.backFlareRightCp1, points.backLegOpeningRightCp1, points.backLegOpeningRight) - .line(points.backWaistBandRight) - .curve(points.backWaistBandRight, points.backWaistBandRightCp1, points.backWaistBandMid) // Waist band dip - .close() - .attr('class', 'fabric') - } - - // Store points for use in other parts - - /* Store gusset points for use in gusset */ - - store.set('backGussetLeft', points.backGussetLeft) - store.set('backGussetRight', points.backGussetRight) - - /* Store lengths for use in elastic */ - - paths.backLegOpening = (options.backExposure >= 0) - ? new Path() - .move(points.backGussetRight) + if (options.backExposure >= 0) { + paths.seam = new Path() + .move(points.backWaistBandMid) + .curve(points.backWaistBandLeftCp1, points.backWaistBandLeft, points.backWaistBandLeft) // Waist band dip + .line(points.backLegOpeningLeft) + .curve(points.backLegOpeningLeftCp1, points.backGussetLeftCp1, points.backGussetLeft) + .line(points.backGussetMid) + .line(points.backGussetRight) .curve(points.backGussetRightCp1, points.backLegOpeningRightCp1, points.backLegOpeningRight) - .setHidden(true) - : new Path() - .move(points.backGussetRight) + .line(points.backWaistBandRight) + .curve(points.backWaistBandRight, points.backWaistBandRightCp1, points.backWaistBandMid) // Waist band dip + .close() + .attr('class', 'fabric') + } else { + paths.seam = new Path() + .move(points.backWaistBandMid) + .curve(points.backWaistBandLeftCp1, points.backWaistBandLeft, points.backWaistBandLeft) // Waist band dip + .line(points.backLegOpeningLeft) + .curve(points.backLegOpeningLeftCp1, points.backFlareLeftCp1, points.backFlareLeft) + .curve(points.backFlareLeftCp2, points.backGussetLeftCp1, points.backGussetLeft) + .line(points.backGussetMid) + .line(points.backGussetRight) .curve(points.backGussetRightCp1, points.backFlareRightCp2, points.backFlareRight) .curve(points.backFlareRightCp1, points.backLegOpeningRightCp1, points.backLegOpeningRight) - .setHidden(true) - store.set('backLegOpeningLength',paths.backLegOpening.length()) + .line(points.backWaistBandRight) + .curve(points.backWaistBandRight, points.backWaistBandRightCp1, points.backWaistBandMid) // Waist band dip + .close() + .attr('class', 'fabric') + } - paths.backWaistBand = new Path() + // Store points for use in other parts + + /* Store gusset points for use in gusset */ + + store.set('backGussetLeft', points.backGussetLeft) + store.set('backGussetRight', points.backGussetRight) + + /* Store lengths for use in elastic */ + + paths.backLegOpening = + options.backExposure >= 0 + ? new Path() + .move(points.backGussetRight) + .curve( + points.backGussetRightCp1, + points.backLegOpeningRightCp1, + points.backLegOpeningRight + ) + .setHidden(true) + : new Path() + .move(points.backGussetRight) + .curve(points.backGussetRightCp1, points.backFlareRightCp2, points.backFlareRight) + .curve( + points.backFlareRightCp1, + points.backLegOpeningRightCp1, + points.backLegOpeningRight + ) + .setHidden(true) + store.set('backLegOpeningLength', paths.backLegOpening.length()) + + paths.backWaistBand = new Path() .move(points.backWaistBandRight) .curve(points.backWaistBandRightCp1, points.backWaistBandLeftCp1, points.backWaistBandLeft) .setHidden(true) - store.set('backWaistBandLength',paths.backWaistBand.length()) + store.set('backWaistBandLength', paths.backWaistBand.length()) - // Complete? - if (complete) { - if (sa) { - paths.sa = paths.seam.offset(sa).attr('class', 'fabric sa') + // Complete? + if (complete) { + if (sa) { + paths.sa = paths.seam.offset(sa).attr('class', 'fabric sa') + } } - } - macro('title', { - at: points.backMidMid, - nr: 2, - title: 'back', - }) + macro('title', { + at: points.backMidMid, + nr: 2, + title: 'back', + }) - macro('grainline', { - from: points.backGussetMid, - to: points.backGussetMid.shiftFractionTowards(points.backWaistBandMid, 0.4), - }) + macro('grainline', { + from: points.backGussetMid, + to: points.backGussetMid.shiftFractionTowards(points.backWaistBandMid, 0.4), + }) - points.scaleboxAnchor = points.scalebox = points.backMidMid.shift(90, -50) - macro('miniscale', { at: points.scalebox }) + points.scaleboxAnchor = points.scalebox = points.backMidMid.shift(90, -50) + macro('miniscale', { at: points.scalebox }) - // Paperless? - if (paperless) { - macro('hd', { - from: points.backWaistBandRight, - to: points.backWaistBandLeft, - y: points.backWaistBandRight.y + sa - 15, - }) - macro('hd', { - from: points.backLegOpeningRight, - to: points.backLegOpeningLeft, - y: points.backLegOpeningRight.y + sa - 15, - }) - macro('hd', { - from: points.backGussetLeft, - to: points.backGussetRight, - y: points.backGussetLeft.y + sa + 15, - }) - macro('vd', { - from: points.backWaistBandMid, - to: points.backGussetMid, - x: points.backWaistBandMid.x + sa + 15, - }) - if (options.backExposure >= 0) { - macro('pd', { - path: new Path() - .move(points.backGussetRight) - .curve( - points.backGussetRightCp1, - points.backLegOpeningRightCp1, - points.backLegOpeningRight - ), - d: 15, + // Paperless? + if (paperless) { + macro('hd', { + from: points.backWaistBandRight, + to: points.backWaistBandLeft, + y: points.backWaistBandRight.y + sa - 15, }) - } else { - macro('pd', { - path: new Path() - .move(points.backGussetRight) - .curve(points.backGussetRightCp1, points.backFlareRightCp2, points.backFlareRight) - .curve( - points.backFlareRightCp1, - points.backLegOpeningRightCp1, - points.backLegOpeningRight - ), - d: 15, + macro('hd', { + from: points.backLegOpeningRight, + to: points.backLegOpeningLeft, + y: points.backLegOpeningRight.y + sa - 15, }) + macro('hd', { + from: points.backGussetLeft, + to: points.backGussetRight, + y: points.backGussetLeft.y + sa + 15, + }) + macro('vd', { + from: points.backWaistBandMid, + to: points.backGussetMid, + x: points.backWaistBandMid.x + sa + 15, + }) + if (options.backExposure >= 0) { + macro('pd', { + path: new Path() + .move(points.backGussetRight) + .curve( + points.backGussetRightCp1, + points.backLegOpeningRightCp1, + points.backLegOpeningRight + ), + d: 15, + }) + } else { + macro('pd', { + path: new Path() + .move(points.backGussetRight) + .curve(points.backGussetRightCp1, points.backFlareRightCp2, points.backFlareRight) + .curve( + points.backFlareRightCp1, + points.backLegOpeningRightCp1, + points.backLegOpeningRight + ), + d: 15, + }) + } } - } return part }, diff --git a/designs/unice/src/elastic.mjs b/designs/unice/src/elastic.mjs index 1965b5ae859..ead702d83ae 100644 --- a/designs/unice/src/elastic.mjs +++ b/designs/unice/src/elastic.mjs @@ -6,45 +6,34 @@ export const elastic = { elasticStretch: { pct: 8, min: 5, max: 15, menu: 'fit' }, }, after: gusset, - draft: ({ - options, - Point, - points, - Path, - paths, - store, - utils, - units, - sa, - part, - }) => { - // Stretch utility method - store.set('elasticScale', utils.stretchToScale(options.elasticStretch)) + draft: ({ options, Point, points, Path, paths, store, utils, units, sa, part }) => { + // Stretch utility method + store.set('elasticScale', utils.stretchToScale(options.elasticStretch)) - // Design pattern here - const legOpeningLength = - store.get('frontLegOpeningLength') + - store.get('backLegOpeningLength') + - store.get('gussetSideLength') - const waistBandLength = store.get('frontWaistBandLength') + store.get('backWaistBandLength') + // Design pattern here + const legOpeningLength = + store.get('frontLegOpeningLength') + + store.get('backLegOpeningLength') + + store.get('gussetSideLength') + const waistBandLength = store.get('frontWaistBandLength') + store.get('backWaistBandLength') - points.elasticInfo = new Point(0, 0) - .attr('data-text', 'cutTwoPiecesOfElasticToFinishTheLegOpenings') - .attr('data-text', ':') - .attr('data-text', units(legOpeningLength * store.get('elasticScale') + 2 * sa)) - .attr('data-text', '\n') - .attr('data-text', 'cutOnePieceOfElasticToFinishTheWaistBand') - .attr('data-text', ':') - .attr('data-text', units(waistBandLength * store.get('elasticScale') + 2 * sa)) + points.elasticInfo = new Point(0, 0) + .attr('data-text', 'cutTwoPiecesOfElasticToFinishTheLegOpenings') + .attr('data-text', ':') + .attr('data-text', units(legOpeningLength * store.get('elasticScale') + 2 * sa)) + .attr('data-text', '\n') + .attr('data-text', 'cutOnePieceOfElasticToFinishTheWaistBand') + .attr('data-text', ':') + .attr('data-text', units(waistBandLength * store.get('elasticScale') + 2 * sa)) - // Draw a box around the text, so the part shows up correctly. - paths.box = new Path() - .move(new Point(-10,-10)) - .line(new Point(-10,15)) - .line(new Point(200,15)) - .line(new Point(200,-10)) - .close() + // Draw a box around the text, so the part shows up correctly. + paths.box = new Path() + .move(new Point(-10, -10)) + .line(new Point(-10, 15)) + .line(new Point(200, 15)) + .line(new Point(200, -10)) + .close() - return part + return part }, } diff --git a/designs/unice/src/front.mjs b/designs/unice/src/front.mjs index 6ee8c5592ea..fd4250b08f7 100644 --- a/designs/unice/src/front.mjs +++ b/designs/unice/src/front.mjs @@ -1,24 +1,24 @@ -import {pluginBundle } from '@freesewing/plugin-bundle' +import { pluginBundle } from '@freesewing/plugin-bundle' export const front = { name: 'unice.front', - measurements: ['waist', 'seat', 'waistToSeat', 'waistToUpperLeg','hips','waistToHips'], - optionalMeasurements: ['crossSeam','crossSeamFront'], + measurements: ['waist', 'seat', 'waistToSeat', 'waistToUpperLeg', 'hips', 'waistToHips'], + optionalMeasurements: ['crossSeam', 'crossSeamFront'], options: { gussetShift: 0.015, // fraction of seat circumference - could be an advanced option? gussetWidth: { pct: 7.2, min: 2, max: 12, menu: 'fit' }, // Gusset width in relation to waist-to-upperleg gussetLength: { pct: 12.7, min: 10, max: 16, menu: 'fit' }, // Gusset length in relation to seat fabricStretchX: { pct: 15, min: 0, max: 100, menu: 'fit' }, // horizontal stretch (range set wide for beta testing) - fabricStretchY: {pct: 0, min: 0, max: 100, menu: 'fit' }, // vertical stretch (range set wide for beta testing) + fabricStretchY: { pct: 0, min: 0, max: 100, menu: 'fit' }, // vertical stretch (range set wide for beta testing) rise: { pct: 60, min: 30, max: 100, menu: 'style' }, // extending rise beyond 100% would require adapting paths.sideLeft! legOpening: { pct: 45, min: 5, max: 85, menu: 'style' }, frontDip: { pct: 5.0, min: -5, max: 15, menu: 'style' }, taperToGusset: { pct: 70, min: 5, max: 100, menu: 'style' }, // booleans useCrossSeam: { bool: true, menu: 'fit' }, - adjustStretch: {bool: true, menu: 'fit' }, // to not stretch fabric to the limits + adjustStretch: { bool: true, menu: 'fit' }, // to not stretch fabric to the limits }, - plugins: [pluginBundle, ], + plugins: [pluginBundle], draft: ({ utils, store, @@ -34,197 +34,230 @@ export const front = { macro, part, }) => { - // Stretch utility method + // Stretch utility method - // Use stretch inputs to calculate four different scale factors: horizontal/vertical and 'regular'/'reduced', depending on direction of the tension - // xScale: for parts that go across the body (= stretched horizontally) - // xScaleReduced: parts that are not under (horizontal) tension, e.g. the gusset - // yScale: for parts which are stretched vertically but not horizontally (anything below leg opening) - // yScaleReduced: parts which are already under horizontal stretch, which limits vertical stretch + // Use stretch inputs to calculate four different scale factors: horizontal/vertical and 'regular'/'reduced', depending on direction of the tension + // xScale: for parts that go across the body (= stretched horizontally) + // xScaleReduced: parts that are not under (horizontal) tension, e.g. the gusset + // yScale: for parts which are stretched vertically but not horizontally (anything below leg opening) + // yScaleReduced: parts which are already under horizontal stretch, which limits vertical stretch - if (options.adjustStretch) { // roughly 15% of stretch is reserved for comfort - // horizontal: first, 'regular' stretch (for parts that go across the body) - if (options.fabricStretchX < 0.30) { - // subtract 15, but never go below 0 - store.set('xScale', utils.stretchToScale(Math.max(0 , options.fabricStretchX - 0.15))) + if (options.adjustStretch) { + // roughly 15% of stretch is reserved for comfort + // horizontal: first, 'regular' stretch (for parts that go across the body) + if (options.fabricStretchX < 0.30) { + // subtract 15, but never go below 0 + store.set('xScale', utils.stretchToScale(Math.max(0, options.fabricStretchX - 0.15))) + } else { + store.set('xScale', utils.stretchToScale(options.fabricStretchX / 2)) + // rough approximation of rule of thumb quoted in Sanne's July 29, 2021 showcase + } + // use half of whatever the regular stretch is (no util available, convert from stretch to fraction manually + store.set('xScaleReduced', (1 + store.get('xScale')) / 2) + + // vertical: + if (options.fabricStretchY < 0.30) { + // subtract 15, but never go below 0 + store.set('yScale', utils.stretchToScale(Math.max(0, options.fabricStretchY - 0.15))) + } else { + store.set('yScale', utils.stretchToScale(options.fabricStretchY / 2)) + // rough approximation of rule of thumb quoted in Sanne's July 29, 2021 showcase + } + // reduced vertical stretch calculated below, same as for non-adjusted case } else { - store.set('xScale', utils.stretchToScale(options.fabricStretchX / 2)) - // rough approximation of rule of thumb quoted in Sanne's July 29, 2021 showcase + // in order: regular, then reduced horizontal stretch, followed by regular vertical stretch + store.set('xScale', utils.stretchToScale(options.fabricStretchX)) + store.set('xScaleReduced', utils.stretchToScale(options.fabricStretchX / 2)) + store.set('yScale', utils.stretchToScale(options.fabricStretchY)) } - // use half of whatever the regular stretch is (no util available, convert from stretch to fraction manually - store.set('xScaleReduced',(1 + store.get('xScale'))/2) - - // vertical: - if (options.fabricStretchY < 0.30) { - // subtract 15, but never go below 0 - store.set('yScale', utils.stretchToScale(Math.max(0 , options.fabricStretchY - 0.15))) + if (options.fabricStretchY < 0.20) { + store.set('yScaleReduced', 1) } else { - store.set('yScale', utils.stretchToScale(options.fabricStretchY / 2)) - // rough approximation of rule of thumb quoted in Sanne's July 29, 2021 showcase + // reduced yScale gradually increases from equivalent of stretch 0 to 5%, then cuts off (uses third-order polynomial) + // function to approximate Sanne's guidelines given in Discord (roughly 2.5% for stretch 30-40%, 5% above that) + store.set( + 'yScaleReduced', + utils.stretchToScale(Math.min(0.05, 6.25 * Math.pow(options.fabricStretchY - 0.2, 3))) + ) } - // reduced vertical stretch calculated below, same as for non-adjusted case - } else { - // in order: regular, then reduced horizontal stretch, followed by regular vertical stretch - store.set('xScale', utils.stretchToScale(options.fabricStretchX)) - store.set('xScaleReduced', utils.stretchToScale(options.fabricStretchX / 2)) - store.set('yScale', utils.stretchToScale(options.fabricStretchY)) - } - if (options.fabricStretchY < 0.20) { - store.set('yScaleReduced',1) - } else { - // reduced yScale gradually increases from equivalent of stretch 0 to 5%, then cuts off (uses third-order polynomial) - // function to approximate Sanne's guidelines given in Discord (roughly 2.5% for stretch 30-40%, 5% above that) - store.set('yScaleReduced', utils.stretchToScale(Math.min( 0.05, 6.25 * Math.pow(options.fabricStretchY - 0.20, 3)))) - } - // // temporarily overrule yScale and yScaleReduced - // store.set('yScale',1) - // store.set('yScaleReduced',1) + // // temporarily overrule yScale and yScaleReduced + // store.set('yScale',1) + // store.set('yScaleReduced',1) + // // Part definition starts here - // // Part definition starts here + // determine height of front part: use cross seam (and cross seam front) if selected and available + // NOTE: neither crossSeam not frontHeight are adjusted for (vertical) stretch + if (options.useCrossSeam && measurements.crossSeam) { + store.set('crossSeam', measurements.crossSeam) + } else { + // use original approximation: front and back are roughly waistToUpperLeg high, plus gusset length + store.set( + 'crossSeam', + measurements.waistToUpperLeg * (1 + options.backToFrontLength) + + options.gussetLength * measurements.seat + ) + } + // optionally use crossSeamFront to determine relative length of front and back + // this does not account for vertical stretch yet + if (options.useCrossSeam && measurements.crossSeamFront) { + // subtract half the gusset length from cross seam front, and an additional 3.5% of the seat circumference to move the gusset upward (to match commercial panties) + store.set( + 'frontHeight', + measurements.crossSeamFront - + measurements.seat * (0.5 * options.gussetLength + options.gussetShift) + ) + } else { + // subtract gusset length, divide by roughly 2 + store.set( + 'frontHeight', + (store.get('crossSeam') - options.gussetLength * measurements.seat) / + (1 + options.backToFrontLength) + ) + } - // determine height of front part: use cross seam (and cross seam front) if selected and available - // NOTE: neither crossSeam not frontHeight are adjusted for (vertical) stretch - if (options.useCrossSeam && measurements.crossSeam) { - store.set('crossSeam',measurements.crossSeam) - } else { // use original approximation: front and back are roughly waistToUpperLeg high, plus gusset length - store.set('crossSeam',measurements.waistToUpperLeg * (1 + options.backToFrontLength) + options.gussetLength * measurements.seat) - } - // optionally use crossSeamFront to determine relative length of front and back - // this does not account for vertical stretch yet - if (options.useCrossSeam && measurements.crossSeamFront) { // subtract half the gusset length from cross seam front, and an additional 3.5% of the seat circumference to move the gusset upward (to match commercial panties) - store.set('frontHeight',measurements.crossSeamFront - measurements.seat*(0.5*options.gussetLength + options.gussetShift)) - } else { // subtract gusset length, divide by roughly 2 - store.set('frontHeight',(store.get('crossSeam') - options.gussetLength * measurements.seat)/(1 + options.backToFrontLength)) - } + // Create points - - // Create points - - // side seam is on a line from upper leg to seat to hips (optional?) to waist - points.frontWaistMid = new Point(measurements.seat / 4, 0) - points.frontWaistLeft = new Point( - measurements.seat / 4 - (measurements.waist / 4) * store.get('xScale'), - 0 - ) - points.frontSeatLeft = new Point( - measurements.seat / 4 - (measurements.seat / 4) * store.get('xScale'), - measurements.waistToSeat * store.get('yScaleReduced') - ) - points.frontUpperLegLeft = new Point( - measurements.seat / 4 - (measurements.seat / 4) * store.get('xScale'), // assume same circ. as seat - measurements.waistToUpperLeg * store.get('yScaleReduced') + // side seam is on a line from upper leg to seat to hips (optional?) to waist + points.frontWaistMid = new Point(measurements.seat / 4, 0) + points.frontWaistLeft = new Point( + measurements.seat / 4 - (measurements.waist / 4) * store.get('xScale'), + 0 ) - points.frontHipLeft = new Point( - measurements.seat / 4 - (measurements.hips / 4) * store.get('xScale'), - measurements.waistToHips * store.get('yScaleReduced') + points.frontSeatLeft = new Point( + measurements.seat / 4 - (measurements.seat / 4) * store.get('xScale'), + measurements.waistToSeat * store.get('yScaleReduced') + ) + points.frontUpperLegLeft = new Point( + measurements.seat / 4 - (measurements.seat / 4) * store.get('xScale'), // assume same circ. as seat + measurements.waistToUpperLeg * store.get('yScaleReduced') + ) + points.frontHipLeft = new Point( + measurements.seat / 4 - (measurements.hips / 4) * store.get('xScale'), + measurements.waistToHips * store.get('yScaleReduced') ) - // use these points to define an invisible path - paths.sideLeft = new Path() - .move(points.frontUpperLegLeft) - .line(points.frontSeatLeft) - .line(points.frontHipLeft) - .line(points.frontWaistLeft) - .setHidden(true) // only show when debugging + // use these points to define an invisible path + paths.sideLeft = new Path() + .move(points.frontUpperLegLeft) + .line(points.frontSeatLeft) + .line(points.frontHipLeft) + .line(points.frontWaistLeft) + .setHidden(true) // only show when debugging - /* Waist band is somewhere on the sideLeft path */ - points.frontWaistBandLeft = paths.sideLeft.shiftFractionAlong(options.rise) - points.frontWaistBandRight = points.frontWaistBandLeft.flipX(points.frontWaistMid) - points.frontWaistBandMid = points.frontWaistBandLeft - .shiftFractionTowards(points.frontWaistBandRight, 0.5) - .shift(270, measurements.waistToUpperLeg * options.frontDip) /* Waist band dip */ + /* Waist band is somewhere on the sideLeft path */ + points.frontWaistBandLeft = paths.sideLeft.shiftFractionAlong(options.rise) + points.frontWaistBandRight = points.frontWaistBandLeft.flipX(points.frontWaistMid) + points.frontWaistBandMid = points.frontWaistBandLeft + .shiftFractionTowards(points.frontWaistBandRight, 0.5) + .shift(270, measurements.waistToUpperLeg * options.frontDip) /* Waist band dip */ - /* Leg opening is also on the sideLeft path, and cannot be higher than rise */ - /* Minimum side seam length is defined as 3.5% of the sideLeft path (which is at least waistToUpperLeg long) */ - store.set('adjustedLegOpening',Math.min(options.legOpening,options.rise - 0.035)) // TODO: account for rise having a different domain + /* Leg opening is also on the sideLeft path, and cannot be higher than rise */ + /* Minimum side seam length is defined as 3.5% of the sideLeft path (which is at least waistToUpperLeg long) */ + store.set('adjustedLegOpening', Math.min(options.legOpening, options.rise - 0.035)) // TODO: account for rise having a different domain - points.frontLegOpeningLeft = paths.sideLeft.shiftFractionAlong(store.get('adjustedLegOpening')) - points.frontLegOpeningRight = points.frontLegOpeningLeft.flipX(points.frontWaistMid) // Waist band low point + points.frontLegOpeningLeft = paths.sideLeft.shiftFractionAlong(store.get('adjustedLegOpening')) + points.frontLegOpeningRight = points.frontLegOpeningLeft.flipX(points.frontWaistMid) // Waist band low point - // calculate the actual front height, using yScale above and yScaleReduced below leg opening - store.set('frontHeightAbove',points.frontWaistLeft.dy(points.frontLegOpeningLeft)) + // calculate the actual front height, using yScale above and yScaleReduced below leg opening + store.set('frontHeightAbove', points.frontWaistLeft.dy(points.frontLegOpeningLeft)) - var frontHeightBelow - frontHeightBelow = store.get('yScale')*(store.get('frontHeight') - store.get('frontHeightAbove')/store.get('yScaleReduced')) + var frontHeightBelow + frontHeightBelow = + store.get('yScale') * + (store.get('frontHeight') - store.get('frontHeightAbove') / store.get('yScaleReduced')) - var frontHeightReduced - frontHeightReduced = frontHeightBelow + store.get('frontHeightAbove') + var frontHeightReduced + frontHeightReduced = frontHeightBelow + store.get('frontHeightAbove') - // gusset width uses modified xScale (barely stretches) and depends on waistToUpperLeg - least sensitive to girth - points.frontGussetLeft = new Point( - measurements.seat / 4 - (measurements.waistToSeat * options.gussetWidth * store.get('xScaleReduced')) * 2.2, - frontHeightReduced - ) - points.frontGussetMid = new Point(measurements.seat / 4, frontHeightReduced) + // gusset width uses modified xScale (barely stretches) and depends on waistToUpperLeg - least sensitive to girth + points.frontGussetLeft = new Point( + measurements.seat / 4 - + measurements.waistToSeat * options.gussetWidth * store.get('xScaleReduced') * 2.2, + frontHeightReduced + ) + points.frontGussetMid = new Point(measurements.seat / 4, frontHeightReduced) - /* Flip points to right side */ - points.frontGussetRight = points.frontGussetLeft.flipX(points.frontWaistMid) - points.frontHipRight = points.frontSeatLeft.flipX(points.frontWaistMid) - points.frontWaistRight = points.frontWaistLeft.flipX(points.frontWaistMid) + /* Flip points to right side */ + points.frontGussetRight = points.frontGussetLeft.flipX(points.frontWaistMid) + points.frontHipRight = points.frontSeatLeft.flipX(points.frontWaistMid) + points.frontWaistRight = points.frontWaistLeft.flipX(points.frontWaistMid) - console.log('points',points) + console.log('points', points) + /* Middle point for label */ + points.frontMidMid = points.frontLegOpeningLeft.shiftFractionTowards( + points.frontLegOpeningRight, + 0.5 + ) - /* Middle point for label */ - points.frontMidMid = points.frontLegOpeningLeft.shiftFractionTowards( - points.frontLegOpeningRight, - 0.5 - ) + // Create control points - // Create control points + /* Control points for leg opening curves */ + points.frontLegOpeningLeftCp1 = points.frontLegOpeningLeft.shift( + 180, + points.frontGussetLeft.dy(points.frontLegOpeningLeft) / 3 + ) - /* Control points for leg opening curves */ - points.frontLegOpeningLeftCp1 = points.frontLegOpeningLeft.shift( - 180, - points.frontGussetLeft.dy(points.frontLegOpeningLeft) / 3 - ) + /* Control point above gusset moves higher as taperToGusset (= front exposure) increases, but is limited by both the leg opening (allow minimal arching only) and the rise (leg opening must not intersect the waist band) */ + points.frontGussetLeftCp1 = points.frontGussetLeft.shift( + 270, + Math.max( + Math.max( + (points.frontGussetLeft.dy(points.frontWaistMid) * options.taperToGusset) / 2, + points.frontGussetLeft.dy(points.frontLegOpeningLeft) * 2 + ), + points.frontGussetLeft.dy(points.frontWaistBandMid) + ) + ) - /* Control point above gusset moves higher as taperToGusset (= front exposure) increases, but is limited by both the leg opening (allow minimal arching only) and the rise (leg opening must not intersect the waist band) */ - points.frontGussetLeftCp1 = points.frontGussetLeft - .shift(270, Math.max(Math.max(points.frontGussetLeft.dy(points.frontWaistMid) * options.taperToGusset / 2,points.frontGussetLeft.dy(points.frontLegOpeningLeft) * 2),points.frontGussetLeft.dy(points.frontWaistBandMid))) + /* Control point for waistband dip */ + points.frontWaistBandLeftCp1 = points.frontWaistBandMid.shift( + 0, + points.frontWaistBandMid.dx(points.frontWaistBandLeft) / 3 + ) - /* Control point for waistband dip */ - points.frontWaistBandLeftCp1 = points.frontWaistBandMid.shift(0,points.frontWaistBandMid.dx(points.frontWaistBandLeft) / 3 ) + /* Flip control points to right side */ + points.frontGussetRightCp1 = points.frontGussetLeftCp1.flipX(points.frontWaistMid) + points.frontLegOpeningRightCp1 = points.frontLegOpeningLeftCp1.flipX(points.frontWaistMid) + points.frontWaistBandRightCp1 = points.frontWaistBandLeftCp1.flipX(points.frontWaistMid) + // Draw paths - /* Flip control points to right side */ - points.frontGussetRightCp1 = points.frontGussetLeftCp1.flipX(points.frontWaistMid) - points.frontLegOpeningRightCp1 = points.frontLegOpeningLeftCp1.flipX(points.frontWaistMid) - points.frontWaistBandRightCp1 = points.frontWaistBandLeftCp1.flipX(points.frontWaistMid) + paths.seam = new Path() + .move(points.frontWaistBandMid) + .curve(points.frontWaistBandLeftCp1, points.frontWaistBandLeft, points.frontWaistBandLeft) // Waist band dip + .line(points.frontLegOpeningLeft) + .curve(points.frontLegOpeningLeftCp1, points.frontGussetLeftCp1, points.frontGussetLeft) + .line(points.frontGussetMid) + .line(points.frontGussetRight) + .curve( + points.frontGussetRightCp1, + points.frontLegOpeningRightCp1, + points.frontLegOpeningRight + ) + .line(points.frontWaistBandRight) + .curve(points.frontWaistBandRight, points.frontWaistBandRightCp1, points.frontWaistBandMid) // Waist band dip + .close() + .attr('class', 'fabric') - // Draw paths + // Store points for use in other parts - paths.seam = new Path() - .move(points.frontWaistBandMid) - .curve(points.frontWaistBandLeftCp1, points.frontWaistBandLeft, points.frontWaistBandLeft) // Waist band dip - .line(points.frontLegOpeningLeft) - .curve(points.frontLegOpeningLeftCp1, points.frontGussetLeftCp1, points.frontGussetLeft) - .line(points.frontGussetMid) - .line(points.frontGussetRight) - .curve(points.frontGussetRightCp1, points.frontLegOpeningRightCp1, points.frontLegOpeningRight) - .line(points.frontWaistBandRight) - .curve(points.frontWaistBandRight, points.frontWaistBandRightCp1, points.frontWaistBandMid) // Waist band dip - .close() - .attr('class', 'fabric') + /* Store side seam points for use in back */ - // Store points for use in other parts + store.set('sideSeamWaist', points.frontWaistBandLeft) + store.set('sideSeamHip', points.frontLegOpeningLeft) - /* Store side seam points for use in back */ + /* Store gusset points for use in gusset */ - store.set('sideSeamWaist', points.frontWaistBandLeft) - store.set('sideSeamHip', points.frontLegOpeningLeft) + store.set('frontGussetLeft', points.frontGussetLeft) + store.set('frontGussetRight', points.frontGussetRight) + store.set('frontGussetMid', points.frontGussetMid) - /* Store gusset points for use in gusset */ + /* Store lengths for use in elastic */ - store.set('frontGussetLeft', points.frontGussetLeft) - store.set('frontGussetRight', points.frontGussetRight) - store.set('frontGussetMid', points.frontGussetMid) - - /* Store lengths for use in elastic */ - - paths.frontLegOpening = new Path() + paths.frontLegOpening = new Path() .move(points.frontGussetRight) .curve( points.frontGussetRightCp1, @@ -232,79 +265,75 @@ export const front = { points.frontLegOpeningRight ) .setHidden(true) - store.set('frontLegOpeningLength',paths.frontLegOpening.length()) - - paths.frontWaistBand = new Path() + store.set('frontLegOpeningLength', paths.frontLegOpening.length()) + + paths.frontWaistBand = new Path() .move(points.frontWaistBandRight) - .curve( - points.frontWaistBandRightCp1, - points.frontWaistBandLeftCp1, - points.frontWaistBandLeft - ) + .curve(points.frontWaistBandRightCp1, points.frontWaistBandLeftCp1, points.frontWaistBandLeft) .setHidden(true) - store.set('frontWaistBandLength',paths.frontWaistBand.length()) + store.set('frontWaistBandLength', paths.frontWaistBand.length()) - // Complete? - if (complete) { - if (sa) { - paths.sa = paths.seam.offset(sa).attr('class', 'fabric sa') + // Complete? + if (complete) { + if (sa) { + paths.sa = paths.seam.offset(sa).attr('class', 'fabric sa') + } } - } - macro('title', { - at: points.frontMidMid, - nr: 1, - title: 'front', - }) + macro('title', { + at: points.frontMidMid, + nr: 1, + title: 'front', + }) - macro('grainline', { - from: points.frontGussetMid, - to: points.frontGussetMid.shiftFractionTowards(points.frontWaistBandMid, 0.5), - }) + macro('grainline', { + from: points.frontGussetMid, + to: points.frontGussetMid.shiftFractionTowards(points.frontWaistBandMid, 0.5), + }) - // Paperless? - if (paperless) { - macro('hd', { - from: points.frontWaistBandRight, - to: points.frontWaistBandLeft, - y: points.frontWaistBandRight.y + sa - 15, - }) - macro('hd', { - from: points.frontLegOpeningRight, - to: points.frontLegOpeningLeft, - y: points.frontLegOpeningRight.y + sa - 15, - }) - macro('hd', { - from: points.frontGussetLeft, - to: points.frontGussetRight, - y: points.frontGussetLeft.y + sa + 15, - }) - macro('vd', { - from: points.frontWaistBandMid, - to: points.frontGussetMid, - x: points.frontWaistBandMid.x + sa + 15, - }) - macro('ld', { - from: points.frontWaistBandLeft, - to: points.frontLegOpeningLeft, - d: points.frontWaistBandLeft.y + sa - 15, - }) - macro('pd', { - path: new Path() - .move(points.frontGussetRight) - .curve( - points.frontGussetRightCp1, - points.frontLegOpeningRightCp1, - points.frontLegOpeningRight - ), - d: 15, - }) - /* macro('vd', { + // Paperless? + if (paperless) { + macro('hd', { + from: points.frontWaistBandRight, + to: points.frontWaistBandLeft, + y: points.frontWaistBandRight.y + sa - 15, + }) + macro('hd', { + from: points.frontLegOpeningRight, + to: points.frontLegOpeningLeft, + y: points.frontLegOpeningRight.y + sa - 15, + }) + macro('hd', { + from: points.frontGussetLeft, + to: points.frontGussetRight, + y: points.frontGussetLeft.y + sa + 15, + }) + macro('vd', { + from: points.frontWaistBandMid, + to: points.frontGussetMid, + x: points.frontWaistBandMid.x + sa + 15, + }) + macro('ld', { + from: points.frontWaistBandLeft, + to: points.frontLegOpeningLeft, + d: points.frontWaistBandLeft.y + sa - 15, + }) + macro('pd', { + path: new Path() + .move(points.frontGussetRight) + .curve( + points.frontGussetRightCp1, + points.frontLegOpeningRightCp1, + points.frontLegOpeningRight + ), + d: 15, + }) + /* macro('vd', { from: points.frontWaistBandLeft, to: points.frontWaistBandMid, x: points.frontWaistBandMid.x + sa + 15, }) */ - } + } return part }, diff --git a/designs/unice/src/gusset.mjs b/designs/unice/src/gusset.mjs index 3a06bc94c24..d620c8f9607 100644 --- a/designs/unice/src/gusset.mjs +++ b/designs/unice/src/gusset.mjs @@ -2,15 +2,15 @@ import { back } from './back.mjs' export const gusset = { name: 'unice.gusset', - measurements: ['waist', 'seat', 'waistToSeat', 'waistToUpperLeg','hips','waistToHips'], - optionalMeasurements: ['crossSeam','crossSeamFront'], + measurements: ['waist', 'seat', 'waistToSeat', 'waistToUpperLeg', 'hips', 'waistToHips'], + optionalMeasurements: ['crossSeam', 'crossSeamFront'], options: { gussetShift: 0.015, // fraction of seat circumference - could be an advanced option? gussetWidth: { pct: 7.2, min: 2, max: 12, menu: 'fit' }, // Gusset width in relation to waist-to-upperleg gussetLength: { pct: 12.7, min: 10, max: 16, menu: 'fit' }, // Gusset length in relation to seat - fabricStretch: { pct: 15, min: 0, max: 100, menu: 'fit' }, // used in Ursula + fabricStretch: { pct: 15, min: 0, max: 100, menu: 'fit' }, // used in Ursula fabricStretchX: { pct: 15, min: 0, max: 100, menu: 'fit' }, // horizontal stretch (range set wide for beta testing) - fabricStretchY: {pct: 0, min: 0, max: 100, menu: 'fit' }, // vertical stretch (range set wide for beta testing) + fabricStretchY: { pct: 0, min: 0, max: 100, menu: 'fit' }, // vertical stretch (range set wide for beta testing) rise: { pct: 60, min: 30, max: 100, menu: 'style' }, // extending rise beyond 100% would require adapting paths.sideLeft! legOpening: { pct: 45, min: 5, max: 85, menu: 'style' }, frontDip: { pct: 5.0, min: -5, max: 15, menu: 'style' }, @@ -33,82 +33,81 @@ export const gusset = { macro, part, }) => { + // Design pattern here + var yScaleDoubleLayer + yScaleDoubleLayer = (1 + store.get('yScale')) / 2 // double layer of fabric stretches half as much - // Design pattern here - var yScaleDoubleLayer - yScaleDoubleLayer = (1 + store.get('yScale'))/2 // double layer of fabric stretches half as much + // Create points + points.frontGussetLeft = new Point(store.get('frontGussetLeft').x, 0) + points.backGussetLeft = new Point( + store.get('backGussetLeft').x, + measurements.seat * options.gussetLength * yScaleDoubleLayer + ) + points.frontGussetRight = new Point(store.get('frontGussetRight').x, 0) + points.backGussetRight = new Point( + store.get('backGussetRight').x, + measurements.seat * options.gussetLength * yScaleDoubleLayer + ) - // Create points - points.frontGussetLeft = new Point(store.get('frontGussetLeft').x, 0) - points.backGussetLeft = new Point( - store.get('backGussetLeft').x, - measurements.seat * options.gussetLength * yScaleDoubleLayer - ) - points.frontGussetRight = new Point(store.get('frontGussetRight').x, 0) - points.backGussetRight = new Point( - store.get('backGussetRight').x, - measurements.seat * options.gussetLength * yScaleDoubleLayer - ) + // Create control points + points.gussetCp1 = points.frontGussetLeft + .shiftFractionTowards(points.backGussetLeft, 0.5) + .shift(180, points.frontGussetRight.x / -15) - // Create control points - points.gussetCp1 = points.frontGussetLeft - .shiftFractionTowards(points.backGussetLeft, 0.5) - .shift(180, points.frontGussetRight.x / -15) + // Flip points to right side + points.gussetCp2 = points.gussetCp1.flipX(store.get('frontGussetMid')) - // Flip points to right side - points.gussetCp2 = points.gussetCp1.flipX(store.get('frontGussetMid')) + // Create point for title + points.frontMidMid = points.gussetCp1.shiftFractionTowards(points.gussetCp2, 0.5) - // Create point for title - points.frontMidMid = points.gussetCp1.shiftFractionTowards(points.gussetCp2, 0.5) + /* Store lengths for use in elastic */ + paths.gussetLegOpening = new Path() + .move(points.backGussetRight) + .curve(points.backGussetRight, points.gussetCp2, points.frontGussetRight) + .setHidden(true) + store.set('gussetSideLength', paths.gussetLegOpening.length()) - /* Store lengths for use in elastic */ - paths.gussetLegOpening = new Path() - .move(points.backGussetRight) - .curve(points.backGussetRight, points.gussetCp2, points.frontGussetRight) - .setHidden(true) - store.set('gussetSideLength', paths.gussetLegOpening.length()) + // Draw paths + paths.seam = new Path() + .move(points.frontGussetLeft) + .curve(points.gussetCp1, points.backGussetLeft, points.backGussetLeft) + .line(points.backGussetRight) + .curve(points.backGussetRight, points.gussetCp2, points.frontGussetRight) + .line(points.frontGussetLeft) // Without this, doesn't generate seam allowance + .close() + .attr('class', 'fabric') - // Draw paths - paths.seam = new Path() - .move(points.frontGussetLeft) - .curve(points.gussetCp1, points.backGussetLeft, points.backGussetLeft) - .line(points.backGussetRight) - .curve(points.backGussetRight, points.gussetCp2, points.frontGussetRight) - .line(points.frontGussetLeft) // Without this, doesn't generate seam allowance - .close() - .attr('class', 'fabric') - - // Complete? - if (complete) { - if (sa) { - paths.sa = paths.seam.offset(sa).attr('class', 'fabric sa') + // Complete? + if (complete) { + if (sa) { + paths.sa = paths.seam.offset(sa).attr('class', 'fabric sa') + } + macro('title', { + at: points.frontMidMid, + nr: 3, + title: 'gusset', + }) } - macro('title', { - at: points.frontMidMid, - nr: 3, - title: 'gusset', - }) - } - // Paperless? - if (paperless) { - macro('hd', { - from: points.frontGussetLeft, - to: points.frontGussetRight, - y: points.frontGussetLeft.y + sa + 15, - }) - macro('hd', { - from: points.backGussetLeft, - to: points.backGussetRight, - y: points.backGussetLeft.y + sa + 15, - }) - macro('vd', { - from: points.frontGussetRight, - to: points.backGussetRight, - x: points.frontGussetRight.x + sa + 15, - }) - } + // Paperless? + if (paperless) { + macro('hd', { + from: points.frontGussetLeft, + to: points.frontGussetRight, + y: points.frontGussetLeft.y + sa + 15, + }) + macro('hd', { + from: points.backGussetLeft, + to: points.backGussetRight, + y: points.backGussetLeft.y + sa + 15, + }) + macro('vd', { + from: points.frontGussetRight, + to: points.backGussetRight, + x: points.frontGussetRight.x + sa + 15, + }) + } - return part + return part }, } diff --git a/designs/unice/src/index.mjs b/designs/unice/src/index.mjs index 1518e7baac3..035a9359450 100644 --- a/designs/unice/src/index.mjs +++ b/designs/unice/src/index.mjs @@ -12,4 +12,4 @@ const Unice = new Design({ }) // Named exports -export {front, back, gusset, elastic, Unice} \ No newline at end of file +export { front, back, gusset, elastic, Unice } From 71904f240c188c91af39b954ef8a23af91869aa8 Mon Sep 17 00:00:00 2001 From: Joost De CockDate: Tue, 27 Sep 2022 23:59:52 +0200 Subject: [PATCH 30/46] fix(plugin-round): Hide path by default --- plugins/plugin-round/src/index.mjs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/plugin-round/src/index.mjs b/plugins/plugin-round/src/index.mjs index be7f0a02ee6..b9cce3edffe 100644 --- a/plugins/plugin-round/src/index.mjs +++ b/plugins/plugin-round/src/index.mjs @@ -6,6 +6,7 @@ export const plugin = { macros: { round: function (so) { const C = 0.55191502449 + const { hide = true } = so // Find angle between points let from = so.from let to = so.to @@ -31,7 +32,7 @@ export const plugin = { this.points[prefix + 'End'] ) .attr('class', so.class ? so.class : '') - if (so?.hide) this.paths[prefix + 'Rounded'].hide() + if (hide) this.paths[prefix + 'Rounded'].hide() else this.paths[prefix + 'Rounded'].unhide() }, }, From 9273b3300303642db291e1edbd9a41513f299cd3 Mon Sep 17 00:00:00 2001 From: Benjamin F Date: Tue, 27 Sep 2022 18:07:03 -0700 Subject: [PATCH 31/46] fix(charlie): Unhide accidentally-hidden seam for Fly Extension part. --- designs/charlie/src/fly-extension.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/designs/charlie/src/fly-extension.mjs b/designs/charlie/src/fly-extension.mjs index b45f7ea5005..cb3a19bebb4 100644 --- a/designs/charlie/src/fly-extension.mjs +++ b/designs/charlie/src/fly-extension.mjs @@ -27,7 +27,7 @@ function draftCharlieFlyExtension({ points, paths, Path, complete, macro, sa, pa .line(points.styleWaistIn) .line(points.flyTop) .hide() - paths.seam = paths.saBase.clone().line(points.flyCorner).close().hide().attr('class', 'fabric') + paths.seam = paths.saBase.clone().line(points.flyCorner).close().unhide().attr('class', 'fabric') if (complete) { macro('cutonfold', { From 55ab9e27359f3a412eb3796529fe81214417c876 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 28 Sep 2022 04:08:09 +0000 Subject: [PATCH 32/46] chore(deps-dev): bump all-contributors-cli from 6.20.4 to 6.21.0 Bumps [all-contributors-cli](https://github.com/all-contributors/all-contributors-cli) from 6.20.4 to 6.21.0. - [Release notes](https://github.com/all-contributors/all-contributors-cli/releases) - [Commits](https://github.com/all-contributors/all-contributors-cli/compare/v6.20.4...v6.21.0) --- updated-dependencies: - dependency-name: all-contributors-cli dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 2a82625508b..16b7010d8ba 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4070,9 +4070,9 @@ algoliasearch@^4.11.0: "@algolia/transporter" "4.14.2" all-contributors-cli@^6.20.0: - version "6.20.4" - resolved "https://registry.yarnpkg.com/all-contributors-cli/-/all-contributors-cli-6.20.4.tgz#de69d243206cb821f8c33ef0b57e9f511ceb7e25" - integrity sha512-oLOrCGh1LjR/EkaESbLe7faTX1tq8TP4pcR6CvkKED5O9E7Yahk5DiexR8roghluljwI20m2JX2I6UTYV7/tLg== + version "6.21.0" + resolved "https://registry.yarnpkg.com/all-contributors-cli/-/all-contributors-cli-6.21.0.tgz#0d7dbd754da74a82e17510b0a3a643e53fba8fc6" + integrity sha512-THdHBp6XJG6I/rpfNIJKV8UiXh25Hg3EwJ4LaxEaetCplVrf9XvqVRbI5hR7sjbyM6+PqPpTG/ELX88PX1uAkw== dependencies: "@babel/runtime" "^7.7.6" async "^3.1.0" From 36448809631684435f89fdc6ad8417ac2b67241f Mon Sep 17 00:00:00 2001 From: Joost De Cock Date: Wed, 28 Sep 2022 16:35:26 +0200 Subject: [PATCH 33/46] fix(tests): Check both stores for errors --- tests/designs/drafting.mjs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/designs/drafting.mjs b/tests/designs/drafting.mjs index e8d161efad6..241c5382c40 100644 --- a/tests/designs/drafting.mjs +++ b/tests/designs/drafting.mjs @@ -13,8 +13,6 @@ const expect = chai.expect * @param boolean log: Set to true to log errors */ export const testPatternDrafting = (Pattern, log = false) => { - const pattern = new Pattern() - const config = Pattern.patternConfig const design = getShortName(Pattern.designConfig.data.name) const family = getFamily(design) @@ -26,8 +24,8 @@ export const testPatternDrafting = (Pattern, log = false) => { console.log(pattern.store.logs) console.log(pattern.setStores[0].logs) } - if (pattern.store.logs.error.length < 1) return true - if (pattern.setStores[0].logs.error.length < 1) return true + if (pattern.store.logs.error.length < 1 && pattern.setStores[0].logs.error.length < 1) + return true return false } catch (err) { if (log) console.log(err) From 3af542c592f33b24318b9c17fb417e7b01a1488c Mon Sep 17 00:00:00 2001 From: Joost De Cock Date: Wed, 28 Sep 2022 16:36:35 +0200 Subject: [PATCH 34/46] fix(plugin-buttons): Reference settings directly --- plugins/plugin-bust/src/index.mjs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/plugins/plugin-bust/src/index.mjs b/plugins/plugin-bust/src/index.mjs index 1c0599f7cb4..0e6cd5ac18f 100644 --- a/plugins/plugin-bust/src/index.mjs +++ b/plugins/plugin-bust/src/index.mjs @@ -4,12 +4,12 @@ export const plugin = { name, version, hooks: { - preDraft: ({ settings }) => { - for (const set of settings) { - if (set.measurements) { - if (typeof set.measurements.bust === 'undefined') { - set.measurements.bust = set.measurements.chest - set.measurements.chest = set.measurements.highBust + preDraft: function ({ settings }) { + for (const i in settings) { + if (settings[i].measurements) { + if (typeof settings[i].measurements.bust === 'undefined') { + settings[i].measurements.bust = settings[i].measurements.chest + settings[i].measurements.chest = settings[i].measurements.highBust } } } From 6ce5937fb9044e77104dd3af9ac4ff07d7e42275 Mon Sep 17 00:00:00 2001 From: Joost De Cock Date: Wed, 28 Sep 2022 16:47:45 +0200 Subject: [PATCH 35/46] wip(core): More tweaks to plugin discovery --- packages/core/src/pattern.mjs | 50 +++++++++++++---------- packages/core/tests/pattern-init.test.mjs | 4 ++ 2 files changed, 33 insertions(+), 21 deletions(-) diff --git a/packages/core/src/pattern.mjs b/packages/core/src/pattern.mjs index a9846e2aee8..ed423bb8fdf 100644 --- a/packages/core/src/pattern.mjs +++ b/packages/core/src/pattern.mjs @@ -501,40 +501,48 @@ function getPluginName(plugin) { * @return {Pattern} this - The Pattern instance */ Pattern.prototype.__addPartPlugins = function (part) { + if (!part.plugins) return this if (!this.config.plugins) this.config.plugins = {} const plugins = { ...this.config.plugins } - if (!part.plugins) return this // Side-step immutability of the part object to ensure plugins is an array let partPlugins = part.plugins if (!Array.isArray(partPlugins)) partPlugins = [partPlugins] - for (const plugin of partPlugins) plugins[getPluginName(plugin)] = plugin + // Go through list of part plugins for (let plugin of partPlugins) { const name = getPluginName(plugin) + this.store.log.debug( + plugin.plugin + ? `π Resolved __${name}__ conditional plugin in \`${part.name}\`` + : `π Resolved __${name}__ plugin in \`${part.name}\`` + ) // Handle [plugin, data] scenario if (Array.isArray(plugin)) { const pluginObj = { ...plugin[0], data: plugin[1] } plugin = pluginObj } - if (plugin.plugin) - this.store.log.debug(`π Resolved __${name}__ conditional plugin in \`${part.name}\``) - else this.store.log.debug(`π Resolved __${name}__ plugin in \`${part.name}\``) - // Do not overwrite an existing plugin with a conditional plugin unless it is also conditional - if (plugin.plugin && plugin.condition) { - if (!plugins[name]) { - plugins[name] = plugin - this.store.log.info(`Plugin \`${name}\` was conditionally added.`) - } else if (plugins[name]?.condition) { - plugins[name + '_'] = plugin - this.store.log.info( - `Plugin \`${name}\` was conditionally added again. Renaming to ${name}_.` - ) - } else - this.store.log.info( - `Plugin \`${name}\` was requested conditionally, but is already added explicitly. Not loading.` - ) - } else { + if (!plugins[name]) { + // New plugin, so we load it plugins[name] = plugin - this.store.log.info(`Plugin \`${name}\` was added.`) + this.store.log.info( + plugin.condition + ? `New plugin conditionally added: \`${name}\`` + : `New plugin added: \`${name}\`` + ) + } else { + // Existing plugin, takes some more work + if (plugin.plugin && plugin.condition) { + // Multiple instances of the same plugin with different conditions + // will all be added, so we need to change the name. + if (plugins[name]?.condition) { + plugins[name + '_'] = plugin + this.store.log.info( + `Plugin \`${name}\` was conditionally added again. Renaming to ${name}_.` + ) + } else + this.store.log.info( + `Plugin \`${name}\` was requested conditionally, but is already added explicitly. Not loading.` + ) + } } } diff --git a/packages/core/tests/pattern-init.test.mjs b/packages/core/tests/pattern-init.test.mjs index 27116f877c2..7af41d5e2d9 100644 --- a/packages/core/tests/pattern-init.test.mjs +++ b/packages/core/tests/pattern-init.test.mjs @@ -702,6 +702,9 @@ describe('Pattern', () => { it('Should check whether created parts get the pattern context', () => { let partContext + const plugin = { + name: 'example', + } const part = { name: 'test', draft: ({ Point, paths, Path, part, context }) => { @@ -710,6 +713,7 @@ describe('Pattern', () => { return part }, + plugins: [plugin], } const Pattern = new Design({ parts: [part], data: { name: 'test', version: '1' } }) const pattern = new Pattern() From 8a39e43300f1e16b9a3f5a599c2c9fc09155324d Mon Sep 17 00:00:00 2001 From: Joost De Cock Date: Wed, 28 Sep 2022 16:50:08 +0200 Subject: [PATCH 36/46] fix(albert): Ported crossbox plugin to v3 --- designs/albert/src/front.mjs | 62 ++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/designs/albert/src/front.mjs b/designs/albert/src/front.mjs index 060bfff42c0..c35c2af6e1a 100644 --- a/designs/albert/src/front.mjs +++ b/designs/albert/src/front.mjs @@ -6,52 +6,52 @@ const crossBox = { name: 'crossbox', version, macros: { - crossBox: function (so) { - let id = this.getId() + crossBox: function (so, { points, Point, paths, Path, getId }) { + let id = getId() let shiftFraction = 0.1 - this.points[id + '_boxTopLeft'] = so.from.copy() - this.points[id + '_boxBottomRight'] = so.to.copy() - this.points[id + '_boxTopRight'] = new this.Point(so.to.x, so.from.y) - this.points[id + '_boxBottomLeft'] = new this.Point(so.from.x, so.to.y) + points[id + '_boxTopLeft'] = so.from.copy() + points[id + '_boxBottomRight'] = so.to.copy() + points[id + '_boxTopRight'] = new Point(so.to.x, so.from.y) + points[id + '_boxBottomLeft'] = new Point(so.from.x, so.to.y) - this.points[id + '_topCrossTL'] = this.points[id + '_boxTopLeft'].shiftFractionTowards( - this.points[id + '_boxBottomRight'], + points[id + '_topCrossTL'] = points[id + '_boxTopLeft'].shiftFractionTowards( + points[id + '_boxBottomRight'], shiftFraction ) - this.points[id + '_topCrossTR'] = this.points[id + '_boxTopRight'].shiftFractionTowards( - this.points[id + '_boxBottomLeft'], + points[id + '_topCrossTR'] = points[id + '_boxTopRight'].shiftFractionTowards( + points[id + '_boxBottomLeft'], shiftFraction ) - this.points[id + '_topCrossBL'] = this.points[id + '_boxBottomLeft'].shiftFractionTowards( - this.points[id + '_boxTopRight'], + points[id + '_topCrossBL'] = points[id + '_boxBottomLeft'].shiftFractionTowards( + points[id + '_boxTopRight'], shiftFraction ) - this.points[id + '_topCrossBR'] = this.points[id + '_boxBottomRight'].shiftFractionTowards( - this.points[id + '_boxTopLeft'], + points[id + '_topCrossBR'] = points[id + '_boxBottomRight'].shiftFractionTowards( + points[id + '_boxTopLeft'], shiftFraction ) - this.paths[id + 'crossBox'] = new this.Path() - .move(this.points[id + '_boxTopLeft']) - .line(this.points[id + '_boxTopRight']) - .line(this.points[id + '_boxBottomRight']) - .line(this.points[id + '_boxBottomLeft']) - .line(this.points[id + '_boxTopLeft']) + paths[id + 'crossBox'] = new Path() + .move(points[id + '_boxTopLeft']) + .line(points[id + '_boxTopRight']) + .line(points[id + '_boxBottomRight']) + .line(points[id + '_boxBottomLeft']) + .line(points[id + '_boxTopLeft']) .close() .attr('class', 'lining dotted stroke-sm') - this.paths[id + '_topCross'] = new this.Path() - .move(this.points[id + '_topCrossTL']) - .line(this.points[id + '_topCrossBR']) - .line(this.points[id + '_topCrossTR']) - .line(this.points[id + '_topCrossBL']) - .line(this.points[id + '_topCrossTL']) - .line(this.points[id + '_topCrossTR']) - .move(this.points[id + '_topCrossBR']) - .line(this.points[id + '_topCrossBL']) + paths[id + '_topCross'] = new Path() + .move(points[id + '_topCrossTL']) + .line(points[id + '_topCrossBR']) + .line(points[id + '_topCrossTR']) + .line(points[id + '_topCrossBL']) + .line(points[id + '_topCrossTL']) + .line(points[id + '_topCrossTR']) + .move(points[id + '_topCrossBR']) + .line(points[id + '_topCrossBL']) .attr('class', 'lining dotted stroke-sm') if (typeof so.text === 'string') { - this.points.textAnchor = this.points[id + '_boxTopLeft'] - .shiftFractionTowards(this.points[id + '_boxBottomRight'], 0.5) + points.textAnchor = points[id + '_boxTopLeft'] + .shiftFractionTowards(points[id + '_boxBottomRight'], 0.5) .attr('data-text', so.text) .attr('data-text-class', 'center') } From c4937602c58e38583ef90f8a39303c24248ce936 Mon Sep 17 00:00:00 2001 From: Joost De Cock Date: Wed, 28 Sep 2022 17:01:00 +0200 Subject: [PATCH 37/46] chore: Removed examples as it's no longer needed We no longer need a dedicated examples design. It was used to showcase examples in the dev docs. But the new dev site Example component will use the actual example code to generate the example. Which is much better since we don't have to keep the example code and code of the the example design in sync. --- CHANGELOG.md | 29 - config/dependencies.yaml | 4 - config/keywords.yaml | 4 - config/software/designs.json | 4 - designs/examples/.eslintrc.yml | 18 - designs/examples/CHANGELOG.md | 38 -- designs/examples/README.md | 290 ---------- designs/examples/build.mjs | 36 -- designs/examples/config/index.js | 122 ---- designs/examples/data.mjs | 4 - designs/examples/package.json | 65 --- designs/examples/src/docs.mjs | 321 ----------- designs/examples/src/index.mjs | 387 ------------- designs/examples/src/path.mjs | 752 ------------------------- designs/examples/src/plugins.mjs | 342 ----------- designs/examples/src/point.mjs | 457 --------------- designs/examples/src/settings.mjs | 22 - designs/examples/src/shared.mjs | 13 - designs/examples/src/snippet.mjs | 39 -- designs/examples/src/snippets.mjs | 91 --- designs/examples/src/stacks.mjs | 128 ----- designs/examples/src/utils.mjs | 445 --------------- designs/examples/tests/shared.test.mjs | 16 - 23 files changed, 3627 deletions(-) delete mode 100644 designs/examples/.eslintrc.yml delete mode 100644 designs/examples/CHANGELOG.md delete mode 100644 designs/examples/README.md delete mode 100644 designs/examples/build.mjs delete mode 100644 designs/examples/config/index.js delete mode 100644 designs/examples/data.mjs delete mode 100644 designs/examples/package.json delete mode 100644 designs/examples/src/docs.mjs delete mode 100644 designs/examples/src/index.mjs delete mode 100644 designs/examples/src/path.mjs delete mode 100644 designs/examples/src/plugins.mjs delete mode 100644 designs/examples/src/point.mjs delete mode 100644 designs/examples/src/settings.mjs delete mode 100644 designs/examples/src/shared.mjs delete mode 100644 designs/examples/src/snippet.mjs delete mode 100644 designs/examples/src/snippets.mjs delete mode 100644 designs/examples/src/stacks.mjs delete mode 100644 designs/examples/src/utils.mjs delete mode 100644 designs/examples/tests/shared.test.mjs diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c5c9a62129..272c4677fba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -679,12 +679,6 @@ ### yuri -#### Changed - - - Migrated from Rollup to Esbuild for all builds - -### examples - #### Changed - Migrated from Rollup to Esbuild for all builds @@ -1272,16 +1266,6 @@ ### yuri -#### Changed - - - Switched to default import for version from package.json - -### examples - -#### Added - - - Added plugin_gore example - #### Changed - Switched to default import for version from package.json @@ -2537,13 +2521,6 @@ - Added the (disabled) waistbandHeight option from Titan - Changed to Titan's waistbandWidth option -### examples - -#### Added - - - Added examples for bartack plugin - - Added examples for new buttonhole-start/end snippets - ### plugin-buttons #### Added @@ -4029,12 +4006,6 @@ ### wahid -#### Added - - - Initial release - -### examples - #### Added - Initial release diff --git a/config/dependencies.yaml b/config/dependencies.yaml index e85429c6203..cdd3832178f 100644 --- a/config/dependencies.yaml +++ b/config/dependencies.yaml @@ -65,10 +65,6 @@ diana: peer: '@freesewing/brian': *freesewing '@freesewing/plugin-bust': *freesewing -examples: - peer: - '@freesewing/plugin-mirror': *freesewing - '@freesewing/plugin-gore': *freesewing holmes: _: '@freesewing/plugin-gore': *freesewing diff --git a/config/keywords.yaml b/config/keywords.yaml index f6b93f28536..7b04674c8cf 100644 --- a/config/keywords.yaml +++ b/config/keywords.yaml @@ -24,10 +24,6 @@ design: - pattern - sewing - sewing pattern -examples: - - documentation - - example - - parametric design i18n: - i18n - internationalisation diff --git a/config/software/designs.json b/config/software/designs.json index 75abc902887..5f5eab831e5 100644 --- a/config/software/designs.json +++ b/config/software/designs.json @@ -321,10 +321,6 @@ } }, "utilities": { - "examples": { - "description": "A FreeSewing pattern holding examples for our documentation", - "code": "Joost De Cock" - }, "legend": { "description": "A FreeSewing pattern to document pattern notation", "code": "Joost De Cock" diff --git a/designs/examples/.eslintrc.yml b/designs/examples/.eslintrc.yml deleted file mode 100644 index b39fd0463e8..00000000000 --- a/designs/examples/.eslintrc.yml +++ /dev/null @@ -1,18 +0,0 @@ -env: - browser: true - es2021: true -extends: eslint:recommended -overrides: - - files: ["*.yaml", "*.yml"] - plugins: ["yaml"] - extends: ["plugin:yaml/recommended"] -parserOptions: - ecmaVersion: latest - sourceType: module -rules: {} -globals: - it: readonly - describe: readonly - process: readonly - __dirname: readonly - diff --git a/designs/examples/CHANGELOG.md b/designs/examples/CHANGELOG.md deleted file mode 100644 index 0173d7207ac..00000000000 --- a/designs/examples/CHANGELOG.md +++ /dev/null @@ -1,38 +0,0 @@ -# Change log for: @freesewing/examples - - -## 2.21.0 (2022-06-27) - -### Changed - - - Migrated from Rollup to Esbuild for all builds - -## 2.20.0 (2022-01-24) - -### Added - - - Added plugin_gore example - -### Changed - - - Switched to default import for version from package.json - -## 2.15.0 (2021-04-15) - -### Added - - - Added examples for bartack plugin - - Added examples for new buttonhole-start/end snippets - -## 2.0.0 (2019-08-25) - -### Added - - - Initial release - - -This is the **initial release**, and the start of this change log. - -> Prior to version 2, FreeSewing was not a JavaScript project. -> As such, that history is out of scope for this change log. - diff --git a/designs/examples/README.md b/designs/examples/README.md deleted file mode 100644 index 31fba58bc1f..00000000000 --- a/designs/examples/README.md +++ /dev/null @@ -1,290 +0,0 @@ - - - -# @freesewing/examples - -A FreeSewing pattern holding examples for our documentation - - - - -> #### Note: Version 3 is a work in progress -> -> We are working on a new major version (v3) but it is not ready for prime-time. -> For production use, please refer to our v2 packages (the `latest` on NPM) -> or [the `v2` branch in our monorepo](https://github.com/freesewing/freesewing/tree/v2). - -## What am I looking at? π€ - -This repository is our *monorepo* holding all our NPM designs, plugins, other NPM packages, and (web)sites. - -This folder holds: @freesewing/examples - -If you're not entirely sure what to do or how to start, type this command: - -``` -npm run tips -``` - -> If you don't want to set up a dev environment, you can run it in your browser: -> -> [](https://gitpod.io/#https://github.com/freesewing/freesewing) -> -> We recommend that you fork our repository and then -> put `gitpod.io/# to start up a browser-based dev environment of your own. - -## About FreeSewing π - -Where the world of makers and developers collide, that's where you'll find FreeSewing. - -If you're a maker, checkout [freesewing.org](https://freesewing.org/) where you can generate -our sewing patterns adapted to your measurements. - -If you're a developer, our documentation is on [freesewing.dev](https://freesewing.dev/). -Our [core library](https://freesewing.dev/reference/api/) is a *batteries-included* toolbox -for parametric design of sewing patterns. But we also provide a range -of [plugins](https://freesewing.dev/reference/plugins/) that further extend the -functionality of the platform. - -If you have NodeJS installed, you can try it right now by running: - -```bash -npx create-freesewing-pattern -``` - -Or, consult our getting started guides -for [Linux](https://freesewing.dev/tutorials/getting-started-linux/), -[MacOS](https://freesewing.dev/tutorials/getting-started-mac/), -or [Windows](https://freesewing.dev/tutorials/getting-started-windows/). - -We also have a [pattern design tutorial](https://freesewing.dev/tutorials/pattern-design/) that -walks you through your first parametric design, -and [a friendly community](https://freesewing.org/community/where/) with -people who can help you when you get stuck. - -## Support FreeSewing: Become a patron π₯° - -FreeSewing is an open source project run by a community, -and financially supported by our patrons. - -If you feel what we do is worthwhile, and you can spend a few coind without -hardship, then you should [join us and become a patron](https://freesewing.org/community/join). - -## Links π©βπ» - - - π» Makers website: [freesewing.org](https://freesewing.org) - - π» Developers website: [freesewing.dev](https://freesewing.dev) - - π¬ Chat: On Discord via [discord.freesewing.org](https://discord.freesewing.org/) - - β Todo list/Kanban board: On Github via [todo.freesewing.org](https://todo.freesewing.org/) - - π¦ Twitter: [@freesewing_org](https://twitter.com/freesewing_org) - - π· Instagram: [@freesewing_org](https://instagram.com/freesewing_org) - -## License: MIT π€ - -Β© [Joost De Cock](https://github.com/joostdecock). -See [the license file](https://github.com/freesewing/freesewing/blob/develop/LICENSE) for details. - -## Where to get help π€― - -Our [chatrooms on Discord](https://chat.freesewing.org/) are the best place to ask questions, -share your feedback, or just hang out. - -If you want to report a problem, please [create an issue](https://github.com/freesewing/freesewing/issues/new). - - - -## Contributors β¨ - -Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)): - - - - - (https://github.com/joostdecock)", - "homepage": "https://freesewing.org/", - "repository": "github:freesewing/freesewing", - "license": "MIT", - "bugs": { - "url": "https://github.com/freesewing/freesewing/issues" - }, - "funding": { - "type": "individual", - "url": "https://freesewing.org/patrons/join" - }, - "keywords": [ - "freesewing", - "documentation", - "example", - "parametric design" - ], - "type": "module", - "module": "dist/index.mjs", - "exports": { - ".": "./dist/index.mjs" - }, - "scripts": { - "build": "node build.mjs", - "clean": "rimraf dist", - "mbuild": "NO_MINIFY=1 node build.mjs", - "symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -", - "test": "npx mocha tests/*.test.mjs", - "vbuild": "VERBOSE=1 node build.mjs", - "lab": "cd ../../sites/lab && yarn start", - "tips": "node ../../scripts/help.mjs", - "lint": "npx eslint 'src/**' 'tests/*.mjs'", - "prettier": "npx prettier --write 'src/*.mjs' 'tests/*.mjs'", - "testci": "npx mocha tests/*.test.mjs --reporter ../../tests/reporters/terse.js", - "cibuild_step5": "node build.mjs" - }, - "peerDependencies": { - "@freesewing/core": "^3.0.0-alpha.0", - "@freesewing/plugin-bundle": "^3.0.0-alpha.0", - "@freesewing/config-helpers": "^3.0.0-alpha.0", - "@freesewing/plugin-mirror": "^3.0.0-alpha.0", - "@freesewing/plugin-gore": "^3.0.0-alpha.0" - }, - "dependencies": {}, - "devDependencies": { - "mocha": "^10.0.0", - "chai": "^4.2.0" - }, - "files": [ - "dist/*", - "README.md" - ], - "publishConfig": { - "access": "public", - "tag": "next" - }, - "engines": { - "node": ">=16.0.0", - "npm": ">=8" - } -} diff --git a/designs/examples/src/docs.mjs b/designs/examples/src/docs.mjs deleted file mode 100644 index e00000a3d42..00000000000 --- a/designs/examples/src/docs.mjs +++ /dev/null @@ -1,321 +0,0 @@ -import { box } from './shared.mjs' - -export const docs_coords = { - name: 'examples.box_coords', - draft: ({ Point, points, paths, Path, part }) => { - points.origin = new Point(10, 10) - points.x = new Point(100, 10) - points.y = new Point(10, 50) - points.textX = points.x.shift(135, 2).attr('data-text', 'X') - points.textY = points.y.shift(180, 5).attr('data-text', 'Y') - paths.coords = new Path() - .move(points.y) - .line(points.origin) - .line(points.x) - .attr('class', 'mark') - .attr('marker-start', 'url(#dimensionFrom)') - .attr('marker-end', 'url(#dimensionTo)') - - return box(part, 100, 50) - }, -} - -export const docs_overview = { - name: 'examples.docs_overview', - draft: ({ Point, points, Path, paths, options, part }) => { - /** - * Returs the value passed to it randomized with a given tolerance - */ - const about = (value, tolerance = 5) => { - let randomized = (tolerance / 100) * Math.random() * value - let fixed = (1 - tolerance / 100) * value - - return fixed + randomized - } - - /** - * like about, but also randomly makes value negative - * This is for degrees - */ - const nabout = (value, tolerance = 5) => { - if (Math.random() > 0.5) return about(value, tolerance) - else return -1 * about(value, tolerance) - } - - /** - * Draws a w*h box that's randomized by tolerance to give it - * that hand-drawn look. - * - * Returns a Path object - */ - const box = (name, origin, width, height, tolerance = 10) => { - let base = height - if (width < height) base = width - let t = base * (tolerance / 100) - points[name + 'TopLeft'] = new Point(about(origin.x, t), about(origin.y, t)) - points[name + 'BottomLeft'] = new Point(about(origin.x, t), about(origin.y + height, t)) - points[name + 'BottomRight'] = new Point( - about(origin.x + width, t), - about(origin.y + height, t) - ) - points[name + 'TopRight'] = new Point(about(origin.x + width, t), about(origin.y, t)) - points[name + 'Mid'] = points[name + 'TopLeft'].shiftFractionTowards( - points[name + 'BottomRight'], - 0.5 - ) - points[name + 'Mid'].y += 3 - - let f = 0.3 - let r = tolerance / 2 - points[name + 'TopLeftCp1'] = points[name + 'TopLeft'] - .shiftFractionTowards(points[name + 'BottomLeft'], about(f)) - .rotate(nabout(r), points[name + 'TopLeft']) - points[name + 'TopLeftCp2'] = points[name + 'TopLeft'] - .shiftFractionTowards(points[name + 'TopRight'], about(f)) - .rotate(nabout(r), points[name + 'TopLeft']) - points[name + 'BottomLeftCp1'] = points[name + 'BottomLeft'] - .shiftFractionTowards(points[name + 'TopLeft'], about(f)) - .rotate(nabout(r), points[name + 'BottomLeft']) - points[name + 'BottomLeftCp2'] = points[name + 'BottomLeft'] - .shiftFractionTowards(points[name + 'BottomRight'], about(f)) - .rotate(nabout(r), points[name + 'BottomLeft']) - points[name + 'BottomRightCp1'] = points[name + 'BottomRight'] - .shiftFractionTowards(points[name + 'BottomLeft'], about(f)) - .rotate(nabout(r), points[name + 'BottomRight']) - points[name + 'BottomRightCp2'] = points[name + 'BottomRight'] - .shiftFractionTowards(points[name + 'TopRight'], about(f)) - .rotate(nabout(r), points[name + 'BottomRight']) - points[name + 'TopRightCp1'] = points[name + 'TopRight'] - .shiftFractionTowards(points[name + 'BottomRight'], about(f)) - .rotate(nabout(r), points[name + 'TopRight']) - points[name + 'TopRightCp2'] = points[name + 'TopRight'] - .shiftFractionTowards(points[name + 'TopLeft'], about(f)) - .rotate(nabout(r), points[name + 'TopRight']) - - return new Path() - .move(points[name + 'TopLeft']) - .curve( - points[name + 'TopLeftCp1'], - points[name + 'BottomLeftCp1'], - points[name + 'BottomLeft'] - ) - .curve( - points[name + 'BottomLeftCp2'], - points[name + 'BottomRightCp1'], - points[name + 'BottomRight'] - ) - .curve( - points[name + 'BottomRightCp2'], - points[name + 'TopRightCp1'], - points[name + 'TopRight'] - ) - .curve(points[name + 'TopRightCp2'], points[name + 'TopLeftCp2'], points[name + 'TopLeft']) - .close() - .attr('class', options.focus === name ? 'note' : 'fabric') - } - - /** - * Draws an arrow from to - * Returns a Path object - */ - const arrow = (name, text = '', tolerance = 10) => { - let from = points[name + 'From'] - let to = points[name + 'To'] - from = from.shiftTowards(to, 3) - to = to.shiftTowards(from, 3) - let base = from.dist(to) - let t = base * (tolerance / 100) - from.x = about(from.x, t) - from.x = about(from.x, t) - to.x = about(to.x, t) - to.x = about(to.x, t) - let f = 0.3 - let r = tolerance / 2 - points[name + 'FromCp'] = from.shiftFractionTowards(to, about(f)).rotate(nabout(r), from) - points[name + 'ToCp'] = to.shiftFractionTowards(from, about(f)).rotate(nabout(r), to) - points[name + 'Tip1'] = to.shiftTowards(from, about(3.8)).rotate(about(15), to) - points[name + 'Tip2'] = to.shiftTowards(from, about(3.5)).rotate(about(-15), to) - let path = new Path() - .move(from) - .curve(points[name + 'FromCp'], points[name + 'ToCp'], to) - .move(points[name + 'Tip1']) - .line(to) - .line(points[name + 'Tip2']) - .attr('class', 'fabric') - if (options.focus === name) path = path.attr('class', 'note') - if (text) - return path - .attr('data-text', ' ' + text) - .attr('data-text-class', 'scribble') - .attr('data-text-class', options.focus === name ? 'fill-note' : '') - else return path - } - - const drawBox = (name, x, y, width, height, tolerance = 5, text = true) => { - points[name + 'Origin'] = new Point(x, y) - paths[name] = box(name, points[name + 'Origin'], width, height, tolerance) - if (text) { - points[name + 'Mid'].attr('data-text', name).attr('data-text-class', 'center scribble') - if (options.focus === name) points[name + 'Mid'].attr('data-text-class', 'fill-note') - } - } - - const svgLogo = (anchor, size = 1) => { - points.svg15 = anchor - .shift(45, 4 * size) - .attr('data-circle', 1.2 * size) - .attr('data-circle-class', 'fill-fabric') - points.svg3 = anchor - .shift(0, 4 * size) - .attr('data-circle', 1.2 * size) - .attr('data-circle-class', 'fill-fabric') - points.svg45 = anchor - .shift(-45, 4 * size) - .attr('data-circle', 1.2 * size) - .attr('data-circle-class', 'fill-fabric') - points.svg6 = anchor - .shift(-90, 4 * size) - .attr('data-circle', 1.2 * size) - .attr('data-circle-class', 'fill-fabric') - points.svg75 = anchor - .shift(-135, 4 * size) - .attr('data-circle', 1.2 * size) - .attr('data-circle-class', 'fill-fabric') - points.svg9 = anchor - .shift(180, 4 * size) - .attr('data-circle', 1.2 * size) - .attr('data-circle-class', 'fill-fabric') - points.svg105 = anchor - .shift(135, 4 * size) - .attr('data-circle', 1.2 * size) - .attr('data-circle-class', 'fill-fabric') - points.svg12 = anchor - .shift(90, 4 * size) - .attr('data-circle', 1.2 * size) - .attr('data-circle-class', 'fill-fabric') - points.svgText = anchor - .clone() - .attr('data-text', 'SVG') - .attr('data-text-class', 'text-xl scribble') - points.svgText.x += size * 7 - points.svgText.y += 6 - paths.svgLogo = new Path() - .move(points.svg15) - .line(points.svg75) - .move(points.svg3) - .line(points.svg9) - .move(points.svg45) - .line(points.svg105) - .move(points.svg6) - .line(points.svg12) - .attr('class', 'stroke-l') - } - const reactLogo = (anchor, size = 1) => { - h = 3 * size - w = 6 * size - points.reactTop1 = anchor.shift(45, w) - points.reactBottom1 = anchor.shift(-135, w) - points.reactTop1Cp1 = points.reactTop1.shift(135, h) - points.reactTop1Cp2 = points.reactTop1.shift(-45, h) - points.reactBottom1Cp1 = points.reactBottom1.shift(135, h) - points.reactBottom1Cp2 = points.reactBottom1.shift(-45, h) - points.reactTop2 = points.reactTop1.rotate(60, anchor) - points.reactBottom2 = points.reactBottom1.rotate(60, anchor) - points.reactTop2Cp1 = points.reactTop1Cp1.rotate(60, anchor) - points.reactTop2Cp2 = points.reactTop1Cp2.rotate(60, anchor) - points.reactBottom2Cp1 = points.reactBottom1Cp1.rotate(60, anchor) - points.reactBottom2Cp2 = points.reactBottom1Cp2.rotate(60, anchor) - points.reactTop3 = points.reactTop1.rotate(-60, anchor) - points.reactBottom3 = points.reactBottom1.rotate(-60, anchor) - points.reactTop3Cp1 = points.reactTop1Cp1.rotate(-60, anchor) - points.reactTop3Cp2 = points.reactTop1Cp2.rotate(-60, anchor) - points.reactBottom3Cp1 = points.reactBottom1Cp1.rotate(-60, anchor) - points.reactBottom3Cp2 = points.reactBottom1Cp2.rotate(-60, anchor) - points.svgLogo = anchor - .clone() - .attr('data-circle', 1 * size) - .attr('data-circle-class', 'fill-fabric') - points.reactText = anchor - .clone() - .attr('data-text', 'React') - .attr('data-text-class', 'text-xl scribble') - points.reactText.x += size * 7 - points.reactText.y += 6 - - paths.reactLogo = new Path() - .move(points.reactTop1) - .curve(points.reactTop1Cp1, points.reactBottom1Cp1, points.reactBottom1) - .curve(points.reactBottom1Cp2, points.reactTop1Cp2, points.reactTop1) - .close() - .move(points.reactTop2) - .curve(points.reactTop2Cp1, points.reactBottom2Cp1, points.reactBottom2) - .curve(points.reactBottom2Cp2, points.reactTop2Cp2, points.reactTop2) - .close() - .move(points.reactTop3) - .curve(points.reactTop3Cp1, points.reactBottom3Cp1, points.reactBottom3) - .curve(points.reactBottom3Cp2, points.reactTop3Cp2, points.reactTop3) - .close() - } - - // Other parts first so they're behind - drawBox('Part4', 4, -19, 40, 65, 5, false) - drawBox('Part3', 1, -16, 40, 65, 5, false) - drawBox('Part2', -2, -13, 40, 65, 5, false) - drawBox('Part', -5, -10, 40, 65, 5) - paths.Part4.attr('class', 'fill-bg') - paths.Part3.attr('class', 'fill-bg') - paths.Part2.attr('class', 'fill-bg') - paths.Part.attr('class', 'fill-bg') - points.PartMid.y = points.PartTopLeft.y + 9 - let x = 0 - let y = 0 - let w = 30 - let h = 15 - drawBox('Points', x, y, w, h) - y += 18 - drawBox('Paths', x, y, w, h) - y += 18 - drawBox('Snippets', x, y, w, h) - x = -35 - y = -3 - w = 25 - h = 20 - drawBox('config', x, y, w, h) - y += 23 - drawBox('Store', x, y, w, h) - x = -40 - y = -30 - drawBox('Pattern', x, y, 90, 90) - points.PatternMid.y = points.PatternTopLeft.y + 9 - - drawBox('settings', -100, 6, 40, 20) - drawBox('draft', 80, 3, 20, 25) - - points.arrow1From = points.settingsTopRight.shiftFractionTowards( - points.settingsBottomRight, - 0.5 - ) - points.arrow1To = points.PatternTopLeft.shiftFractionTowards(points.PatternBottomLeft, 0.5) - paths.arrow1 = arrow('arrow1') - points.arrow2From = points.PatternTopRight.shiftFractionTowards(points.PatternBottomRight, 0.5) - points.arrow2To = points.draftTopLeft.shiftFractionTowards(points.draftBottomLeft, 0.5) - paths.arrow2 = arrow('arrow2', 'draft()') - - svgLogo(points.draftMid.shift(70, 50)) - reactLogo(points.draftMid.shift(-80, 36)) - - points.arrow3From = points.draftTopLeft.shiftFractionTowards(points.draftTopRight, 0.5) - points.arrow3To = points.svgText.clone() - paths.arrow3 = arrow('arrow3', 'render()') - points.arrow4From = points.draftBottomLeft.shiftFractionTowards(points.draftBottomRight, 0.5) - points.arrow4To = points.reactText.clone().shift(40, 15) - paths.arrow4 = arrow('arrow4') - - paths.extend = new Path() - .move(points.draftTopRight) - .line(points.draftTopRight.shift(0, 40)) - .attr('class', 'hidden') - - return part - }, -} diff --git a/designs/examples/src/index.mjs b/designs/examples/src/index.mjs deleted file mode 100644 index 73e2d676f09..00000000000 --- a/designs/examples/src/index.mjs +++ /dev/null @@ -1,387 +0,0 @@ -import { Design } from '@freesewing/core' -import { pluginBundle } from '@freesewing/plugin-bundle' -import { gorePlugin } from '@freesewing/plugin-gore' -import { data } from '../data.mjs' - -// Path API -import { - path__curve, - path_addclass, - path_addtext, - path_attr, - path_move, - path_line, - path_curve, - path_curve_, - path_close, - path_ops, - path_clone, - path_divide, - path_edge, - path_end, - path_intersects, - path_intersectsx, - path_intersectsy, - path_join, - path_length, - path_noop, - path_offset, - path_reverse, - path_shiftalong, - path_shiftfractionalong, - path_smurve, - path_smurve_, - path_split, - path_start, - path_translate, - path_trim, -} from './path.mjs' - -// Point API -import { - point_addcircle, - point_addtext, - point_angle, - point_attr, - point_clone, - point_copy, - point_dist, - point_dx, - point_dy, - point_flipx, - point_flipy, - point_setcircle, - point_settext, - point_shift, - point_shiftfractiontowards, - point_shifttowards, - point_shiftoutwards, - point_sitson, - point_sitsroughlyon, - point_rotate, - point_translate, -} from './point.mjs' - -// Snippet API -import { snippet, snippet_attr, snippet_clone } from './snippet.mjs' - -// Utils API -import { - utils_linesintersect, - utils_beamsintersect, - utils_beamintersectsx, - utils_beamintersectsy, - utils_lineintersectscurve, - utils_curvesintersect, - utils_pointonbeam, - utils_pointonline, - utils_pointoncurve, - utils_circlesintersect, - utils_beamintersectscircle, - utils_lineintersectscircle, - utils_curveintersectsx, - utils_curveintersectsy, - utils_splitcurve, -} from './utils.mjs' - -// Plugins -import { - plugin_banner, - plugin_bartack, - plugin_bartackalong, - plugin_bartackfractionalong, - plugin_buttons, - plugin_cutonfold, - plugin_dimension, - plugin_gore, - plugin_grainline, - plugin_logo, - plugin_mirror, - plugin_notches, - plugin_round, - plugin_sprinkle, - plugin_scalebox, - plugin_title, -} from './plugins.mjs' - -// Snippets -import { - snippet_bnotch, - snippet_notch, - snippet_button, - snippet_buttonhole, - snippet_buttonholestart, - snippet_buttonholeend, - snippet_snapsocket, - snippet_snapstud, - snippet_logo, -} from './snippets.mjs' - -// Stacks -import { - stacks_top, - stacks_left, - stacks_right, - stacks_bottom, - stacks_leftEye, - stacks_rightEye, - stacks_mouth, -} from './stacks.mjs' - -// Settings -import { settings_sa } from './settings.mjs' - -// Docs illustrations -import { docs_coords, docs_overview } from './docs.mjs' - -// Setup our new design -const Examples = new Design({ - data, - parts: [ - // Path API - path__curve, - path_addclass, - path_addtext, - path_attr, - path_move, - path_line, - path_curve, - path_curve_, - path_close, - path_ops, - path_clone, - path_divide, - path_edge, - path_end, - path_intersects, - path_intersectsx, - path_intersectsy, - path_join, - path_length, - path_noop, - path_offset, - path_reverse, - path_shiftalong, - path_shiftfractionalong, - path_smurve, - path_smurve_, - path_split, - path_start, - path_translate, - path_trim, - - // Point API - point_addcircle, - point_addtext, - point_angle, - point_attr, - point_clone, - point_copy, - point_dist, - point_dx, - point_dy, - point_flipx, - point_flipy, - point_setcircle, - point_settext, - point_shift, - point_shiftfractiontowards, - point_shifttowards, - point_shiftoutwards, - point_sitson, - point_sitsroughlyon, - point_rotate, - point_translate, - - // Snippet API - snippet, - snippet_attr, - snippet_clone, - - // Utils API - utils_linesintersect, - utils_beamsintersect, - utils_beamintersectsx, - utils_beamintersectsy, - utils_lineintersectscurve, - utils_curvesintersect, - utils_pointonbeam, - utils_pointonline, - utils_pointoncurve, - utils_circlesintersect, - utils_beamintersectscircle, - utils_lineintersectscircle, - utils_curveintersectsx, - utils_curveintersectsy, - utils_splitcurve, - - // Plugins - plugin_banner, - plugin_bartack, - plugin_bartackalong, - plugin_bartackfractionalong, - plugin_buttons, - plugin_cutonfold, - plugin_dimension, - plugin_gore, - plugin_grainline, - plugin_logo, - plugin_mirror, - plugin_notches, - plugin_round, - plugin_sprinkle, - plugin_scalebox, - plugin_title, - - // Snippets - snippet_bnotch, - snippet_notch, - snippet_button, - snippet_buttonhole, - snippet_buttonholestart, - snippet_buttonholeend, - snippet_snapsocket, - snippet_snapstud, - snippet_logo, - - // Stacks - stacks_top, - stacks_left, - stacks_right, - stacks_bottom, - stacks_leftEye, - stacks_rightEye, - stacks_mouth, - - // Settings - settings_sa, - - // Docs - docs_coords, - docs_overview, - ], - plugins: [pluginBundle, gorePlugin], -}) - -// Named exports -export { - // Path API - path__curve, - path_addclass, - path_addtext, - path_attr, - path_move, - path_line, - path_curve, - path_curve_, - path_close, - path_ops, - path_clone, - path_divide, - path_edge, - path_end, - path_intersects, - path_intersectsx, - path_intersectsy, - path_join, - path_length, - path_noop, - path_offset, - path_reverse, - path_shiftalong, - path_shiftfractionalong, - path_smurve, - path_smurve_, - path_split, - path_start, - path_translate, - path_trim, - - // Point API - point_addcircle, - point_addtext, - point_angle, - point_attr, - point_clone, - point_copy, - point_dist, - point_dx, - point_dy, - point_flipx, - point_flipy, - point_setcircle, - point_settext, - point_shift, - point_shiftfractiontowards, - point_shifttowards, - point_shiftoutwards, - point_sitson, - point_sitsroughlyon, - point_rotate, - point_translate, - - // Snippet API - snippet, - snippet_attr, - snippet_clone, - - // Utils API - utils_linesintersect, - utils_beamsintersect, - utils_beamintersectsx, - utils_beamintersectsy, - utils_lineintersectscurve, - utils_curvesintersect, - utils_pointonbeam, - utils_pointonline, - utils_pointoncurve, - utils_circlesintersect, - utils_beamintersectscircle, - utils_lineintersectscircle, - utils_curveintersectsx, - utils_curveintersectsy, - utils_splitcurve, - - // Plugins - plugin_banner, - plugin_bartack, - plugin_bartackalong, - plugin_bartackfractionalong, - plugin_buttons, - plugin_cutonfold, - plugin_dimension, - plugin_gore, - plugin_grainline, - plugin_logo, - plugin_mirror, - plugin_notches, - plugin_round, - plugin_sprinkle, - plugin_scalebox, - plugin_title, - - // Snippets - snippet_bnotch, - snippet_notch, - snippet_button, - snippet_buttonhole, - snippet_buttonholestart, - snippet_buttonholeend, - snippet_snapsocket, - snippet_snapstud, - snippet_logo, - - // Stacks - stacks_top, - stacks_left, - stacks_right, - stacks_bottom, - stacks_leftEye, - stacks_rightEye, - stacks_mouth, - - // Docs - docs_coords, - docs_overview, - Examples, -} diff --git a/designs/examples/src/path.mjs b/designs/examples/src/path.mjs deleted file mode 100644 index d3ce4366009..00000000000 --- a/designs/examples/src/path.mjs +++ /dev/null @@ -1,752 +0,0 @@ -import { box } from './shared.mjs' - -export const path__curve = { - name: 'examples.path__curve', - draft: ({ Point, points, Path, paths, part }) => { - points.from = new Point(5, 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) - .attr('data-text', 'Path._curve()') - .attr('data-text-class', 'text-sm center fill-note') - - return box(part, 100, 25) - }, -} - -export const path_addclass = { - name: 'examples.path_addclass', - draft: ({ Point, points, Path, paths, part }) => { - 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') - - return box(part, 100, 20) - }, -} - -export const path_addtext = { - name: 'examples.path_addtext', - draft: ({ Point, points, Path, paths, part }) => { - 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') - - return box(part, 100, 20) - }, -} - -export const path_attr = { - name: 'examples.path_attr', - draft: ({ Point, points, Path, paths, part }) => { - points.B = new Point(10, 50) - points.BCp2 = new Point(40, 10) - points.C = new Point(90, 30) - points.CCp1 = new Point(50, 90) - - paths.example = new Path() - .move(points.B) - .curve(points.BCp2, points.CCp1, points.C) - .attr('class', 'canvas') - .attr('data-text', 'supportFreesewingBecomeAPatron') - .attr('data-text-class', 'text-xs center') - - return part - }, -} - -export const path_clone = { - name: 'examples.path_clone', - draft: ({ Point, points, Path, paths, 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) - - paths.example = new Path() - .move(points.A) - .line(points.B) - .curve(points.BCp2, points.CCp1, points.C) - - paths.clone = paths.example - .clone() - .setClass('note lashed stroke-xl') - .attr('style', 'stroke-opacity: 0.5') - - return part - }, -} - -export const path_close = { - name: 'examples.path_close', - draft: ({ Point, points, Path, paths, part }) => { - 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') - - return box(part, 100, 25) - }, -} - -export const path_curve = { - name: 'examples.path_curve', - draft: ({ Point, points, Path, paths, part }) => { - points.from = new Point(10, 20) - points.cp1 = new Point(40, 0) - points.cp2 = new Point(60, 30) - 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') - - return box(part, 100, 25) - }, -} - -export const path_curve_ = { - name: 'examples.path_curve_', - draft: ({ Point, points, Path, paths, part }) => { - points.from = new Point(10, 20) - points.cp1 = new Point(40, 0) - points.to = new Point(90, 20) - - paths.line = new Path() - .move(points.from) - .curve_(points.cp1, points.to) - .attr('data-text', 'Path.curve_()') - .attr('data-text-class', 'text-sm center fill-note') - - return box(part, 100, 25) - }, -} - -export const path_divide = { - name: 'examples.path_divide', - draft: ({ Point, points, Path, paths, part }) => { - points.A = new Point(55, 40) - points.B = new Point(10, 70) - points.BCp2 = new Point(40, 20) - points.C = new Point(90, 60) - points.CCp1 = new Point(50, -30) - points.D = new Point(50, 80) - points.DCp1 = new Point(140, 50) - - paths.example = new Path() - .move(points.A) - .line(points.B) - .curve(points.BCp2, points.CCp1, points.C) - .curve(points.DCp1, points.DCp1, points.D) - .close() - - let style = 'stroke-width: 4; stroke-opacity: 0.5;' - let i = 0 - for (let p of paths.example.divide()) { - i++ - paths[i] = p.attr('style', style).attr('style', `stroke: hsl(${i * 70}, 100%, 50%)`) - } - - return part - }, -} - -export const path_edge = { - name: 'examples.path_edge', - draft: ({ Point, points, Path, paths, Snippet, snippets, 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(-60, 90) - points.E = new Point(90, 190) - - paths.demo = new Path() - .move(points.A) - .line(points.B) - .curve(points.BCp2, points.CCp1, points.C) - .curve(points.E, points.D, points.A) - .close() - - for (let i of [ - 'topLeft', - 'topRight', - 'bottomLeft', - 'bottomRight', - 'top', - 'left', - 'bottom', - 'right', - ]) - snippets[i] = new Snippet('notch', paths.demo.edge(i)) - - return part - }, -} - -export const path_end = { - name: 'examples.path_end', - draft: ({ Point, points, Path, paths, Snippet, snippets, 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) - - 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()) - - return part - }, -} - -export const path_intersects = { - name: 'examples.path_intersects', - draft: ({ Point, points, Path, paths, Snippet, snippets, 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, 130) - points.DCp1 = new Point(150, 30) - - points._A = new Point(55, 40) - points._B = new Point(0, 55) - points._BCp2 = new Point(40, -20) - points._C = new Point(90, 40) - points._CCp1 = new Point(50, -30) - points._D = new Point(40, 120) - points._DCp1 = new Point(180, 40) - - paths.demo1 = new Path() - .move(points.A) - .line(points.B) - .curve(points.BCp2, points.CCp1, points.C) - .curve(points.DCp1, points.DCp1, points.D) - paths.demo2 = new Path() - .move(points._A) - .line(points._B) - .curve(points._BCp2, points._CCp1, points._C) - .curve(points._DCp1, points._DCp1, points._D) - - for (let p of paths.demo1.intersects(paths.demo2)) { - snippets[part.getId()] = new Snippet('notch', p) - } - - return part - }, -} - -export const path_intersectsx = { - name: 'examples.path_intersectsx', - draft: ({ Point, points, Path, paths, Snippet, snippets, part }) => { - points.A = new Point(95, 50) - 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, 130) - points.DCp1 = new Point(150, 30) - - points.top = new Point(60, -10) - points.bot = new Point(60, 140) - - paths.line = new Path().move(points.top).line(points.bot).attr('class', 'lining dashed') - - paths.demo = new Path() - .move(points.A) - .line(points.B) - .curve(points.BCp2, points.CCp1, points.C) - .curve(points.DCp1, points.DCp1, points.D) - - for (let p of paths.demo.intersectsX(60)) { - snippets[part.getId()] = new Snippet('notch', p) - } - - return part - }, -} - -export const path_intersectsy = { - name: 'examples.path_intersectsy', - draft: ({ Point, points, Path, paths, Snippet, snippets, part }) => { - points.A = new Point(55, 40) - points.B = new Point(10, 70) - points.BCp2 = new Point(40, 20) - points.C = new Point(90, 60) - points.CCp1 = new Point(50, -30) - points.D = new Point(50, 80) - points.DCp1 = new Point(140, 50) - - points.top = new Point(10, 58) - points.bot = new Point(130, 58) - - paths.line = new Path().move(points.top).line(points.bot).attr('class', 'lining dashed') - - paths.demo = new Path() - .move(points.A) - .line(points.B) - .curve(points.BCp2, points.CCp1, points.C) - .curve(points.DCp1, points.DCp1, points.D) - for (let p of paths.demo.intersectsY(58)) { - snippets[part.getId()] = new Snippet('notch', p) - } - - return part - }, -} - -export const path_join = { - name: 'examples.path_join', - draft: ({ Point, points, Path, paths, 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) - - paths.path1 = new Path().move(points.A).line(points.B).attr('class', 'various') - - paths.path2 = new Path() - .move(points.B) - .curve(points.BCp2, points.CCp1, points.C) - .attr('class', 'canvas') - - paths.joint = paths.path1 - .join(paths.path2) - .attr('class', 'note lashed stroke-l') - .attr('style', 'stroke-opacity: 0.5') - - return part - }, -} - -export const path_length = { - name: 'examples.path_length', - draft: ({ Point, points, Path, paths, macro, 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) - - paths.example = new Path() - .move(points.A) - .line(points.B) - .curve(points.BCp2, points.CCp1, points.C) - - macro('pd', { - path: paths.example, - d: -20, - }) - - macro('pd', { - path: new Path().move(points.B).line(points.A), - d: 10, - }) - - macro('pd', { - path: new Path().move(points.B).curve(points.BCp2, points.CCp1, points.C), - d: -10, - }) - - return part - }, -} - -export const path_line = { - name: 'examples.path_line', - draft: ({ Point, points, Path, paths, part }) => { - points.from = new Point(10, 10) - points.to = new Point(90, 10) - - paths.line = new Path() - .move(points.from) - .line(points.to) - .attr('data-text', 'Path.line()') - .attr('data-text-class', 'text-sm center fill-note') - - return box(part, 100, 15) - }, -} - -export const path_move = { - name: 'examples.path_move', - draft: ({ Point, points, Path, paths, part }) => { - points.to = new Point(50, 10) - .attr('data-text', 'Path.move()') - .attr('data-text-class', 'fill-note center') - - paths.noline = new Path().move(points.to) - - return box(part, 100, 15) - }, -} - -export const path_noop = { - name: 'examples.path_noop', - draft: ({ 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) - - paths.without = new Path() - .move(points.left) - .line(points.dartLeft) - .noop('dart') - .line(points.right) - - paths.withDart = paths.without - .insop('dart', new Path().line(points.dartTip).line(points.dartRight)) - .attr('style', 'stroke-width: 2px; stroke-opacity: 0.5; stroke: orange;') - - return part - }, -} - -export const path_offset = { - name: 'examples.path_offset', - draft: ({ Point, points, Path, paths, 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) - - paths.example = new Path() - .move(points.A) - .line(points.B) - .curve(points.BCp2, points.CCp1, points.C) - .line(points.A) - .close() - - paths.offset = paths.example.offset(-10).attr('class', 'interfacing') - - paths.lineOffset = new Path().move(points.A).line(points.B).offset(-5).attr('class', 'various') - - paths.curveOffset = new Path() - .move(points.B) - .curve(points.BCp2, points.CCp1, points.C) - .offset(-5) - .attr('class', 'canvas') - - return part - }, -} - -export const path_ops = { - name: 'examples.path_ops', - draft: ({ Point, points, Path, paths, options, part }) => { - const textClasses = (label) => - options.focus === label ? 'center text-xs fill-note' : 'center text-xs' - - points.A = new Point(10, 10) - .attr('data-text', 'Path.move()') - .attr('data-text-class', textClasses('move')) - points.B = new Point(70, 30) - points.BCp2 = new Point(40, 10) - points.C = new Point(90, -50) - points.CCp1 = new Point(125, -30) - points.D = new Point(20, -50) - points.DCp = new Point(40, 0) - points.E = new Point(-20, -20) - points.ECp = new Point(-20, -50) - - paths.line = new Path() - .move(points.A) - .line(points.B) - .attr('data-text', 'Path.line()') - .attr('data-text-class', textClasses('line')) - - paths.curve = new Path() - .move(points.B) - .curve(points.BCp2, points.CCp1, points.C) - .attr('data-text', 'Path.curve()') - .attr('data-text-class', textClasses('curve')) - - paths._curve = new Path() - .move(points.C) - ._curve(points.DCp, points.D) - .attr('data-text', 'Path._curve()') - .attr('data-text-class', textClasses('_curve')) - - paths.curve_ = new Path() - .move(points.D) - .curve_(points.ECp, points.E) - .attr('data-text', 'Path.curve_()') - .attr('data-text-class', textClasses('curve_')) - - paths.close = new Path() - .move(points.E) - .line(points.A) - .attr('data-text', 'Path.close()') - .attr('data-text-class', textClasses('close')) - - paths.example = paths.line.join(paths.curve).join(paths._curve).join(paths.curve_).close() - - return part - }, -} - -export const path_reverse = { - name: 'examples.path_reverse', - draft: ({ Point, points, Path, paths, part }) => { - 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.example = new Path() - .move(points.B) - .curve(points.BCp2, points.CCp1, points.C) - .attr('data-text', 'freesewingIsMadeByJoostDeCockAndContributors') - .attr('data-text-class', 'text-xs fill-note') - - paths.reverse = paths.example - .reverse() - .attr('data-text', 'freesewingIsMadeByJoostDeCockAndContributors') - .attr('data-text-class', 'text-xs fill-lining') - - return part - }, -} - -export const path_shiftalong = { - name: 'examples.path_shiftalong', - draft: ({ Point, points, Path, paths, Snippet, snippets, 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) - - paths.example = new Path() - .move(points.A) - .line(points.B) - .curve(points.BCp2, points.CCp1, points.C) - - points.x1 = paths.example - .shiftAlong(20) - .attr('data-text', '2cm') - .attr('data-text-class', 'center fill-note') - .attr('data-text-lineheight', 6) - points.x2 = paths.example - .shiftAlong(90) - .attr('data-text', '9cm') - .attr('data-text-class', 'center fill-note') - .attr('data-text-lineheight', 6) - - snippets.x1 = new Snippet('notch', points.x1) - snippets.x2 = new Snippet('notch', points.x2) - - return part - }, -} - -export const path_shiftfractionalong = { - name: 'examples.path_shiftfractionalong', - draft: ({ Point, points, Path, paths, Snippet, snippets, 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) - - paths.example = new Path() - .move(points.A) - .line(points.B) - .curve(points.BCp2, points.CCp1, points.C) - - points.x1 = paths.example - .shiftFractionAlong(0.2) - .attr('data-text', '20%') - .attr('data-text-class', 'center fill-note') - .attr('data-text-lineheight', 6) - points.x2 = paths.example - .shiftFractionAlong(0.9) - .attr('data-text', '90%') - .attr('data-text-class', 'center fill-note') - .attr('data-text-lineheight', 6) - - snippets.xl = new Snippet('notch', points.x1) - snippets.x2 = new Snippet('notch', points.x2) - - return part - }, -} - -export const path_smurve = { - name: 'examples.path_smurve', - draft: ({ Point, points, Path, paths, part }) => { - points.from = new Point(10, 20) - points.cp1 = new Point(40, 10) - points.cp2 = new Point(60, 30) - points.to = new Point(90, 20) - points.scp2 = new Point(140, 30) - points.sto = new Point(170, 20) - - paths.line = new Path() - .move(points.from) - .curve(points.cp1, points.cp2, points.to) - .smurve(points.scp2, points.sto) - .attr('data-text', 'Path.smurve()') - .attr('data-text-class', 'text-sm center fill-note') - - return box(part, 180, 40) - }, -} - -export const path_smurve_ = { - name: 'examples.path_smurve_', - draft: ({ Point, points, Path, paths, part }) => { - points.from = new Point(10, 20) - points.cp1 = new Point(40, 10) - points.cp2 = new Point(60, 30) - points.to = new Point(90, 20) - points.sto = new Point(170, 20) - - paths.line = new Path() - .move(points.from) - .curve(points.cp1, points.cp2, points.to) - .smurve_(points.sto) - .attr('data-text', 'Path.smurve_()') - .attr('data-text-class', 'text-sm center fill-note') - - return box(part, 180, 40) - }, -} - -export const path_split = { - name: 'examples.path_split', - draft: ({ Point, points, Path, paths, Snippet, snippets, 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, 130) - points.DCp1 = new Point(150, 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) - - points.split = paths.demo.shiftFractionAlong(0.75) - snippets.x = new Snippet('x', points.split) - - let style = 'stroke-width: 3; stroke-opacity: 0.5;' - let halves = paths.demo.split(points.split) - for (let i in halves) { - paths[i] = halves[i].attr('style', style).attr('style', `stroke: hsl(${i * 70}, 100%, 50%)`) - } - - return part - }, -} - -export const path_start = { - name: 'examples.path_start', - draft: ({ Point, points, Path, paths, Snippet, snippets, 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) - - paths.example = new Path() - .move(points.A) - .line(points.B) - .curve(points.BCp2, points.CCp1, points.C) - - snippets.start = new Snippet('notch', paths.example.start()) - return part - }, -} - -export const path_translate = { - name: 'examples.path_translate', - draft: ({ Point, points, Path, paths, macro, 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) - - paths.A = new Path().move(points.A).line(points.B).curve(points.BCp2, points.CCp1, points.C) - - paths.B = paths.A.translate(60, 30) - - points.step1 = points.B.shift(0, 60) - points.step2 = points.step1.shift(-90, 30) - macro('ld', { - from: points.B, - to: points.step1, - noStartMarker: true, - }) - macro('ld', { - from: points.step1, - to: points.step2, - noStartMarker: true, - }) - - return part - }, -} - -export const path_trim = { - name: 'examples.path_trim', - draft: ({ Point, points, Path, paths, part }) => { - points.center = new Point(0, 0) - points.base = new Point(0, 10) - points.tip = new Point(0, 50) - points.tipCpRight = new Point(30, 50) - points.tipCpLeft = new Point(-30, 50) - paths.example = new Path().move(points.base) - for (let i = 0; i < 4; i++) { - points['base' + i] = points.base.rotate(60 * i, points.center) - points['tip' + i] = points.tip.rotate(60 * i, points.center) - points['tipCpRight' + i] = points.tipCpRight.rotate(60 * i, points.center) - points['tipCpLeft' + i] = points.tipCpLeft.rotate(60 * i, points.center) - if (i < 2) { - paths.example - .line(points['base' + i]) - .curve(points['base' + i], points['tipCpLeft' + i], points['tip' + i]) - .curve(points['tipCpRight' + i], points['base' + i], points['base' + i]) - } else { - paths.example - .line(points['base' + i]) - .line(points['tip' + i]) - .line(points['tipCpRight' + i]) - .line(points['base' + i]) - } - } - - paths.offset = paths.example.offset(10).attr('class', 'lining dotted stroke-sm') - - paths.trimmed = paths.offset - .trim() - .attr('class', 'various stroke-xl') - .attr('style', 'stroke-opacity: 0.5;') - return part - }, -} diff --git a/designs/examples/src/plugins.mjs b/designs/examples/src/plugins.mjs deleted file mode 100644 index e8f436e8f94..00000000000 --- a/designs/examples/src/plugins.mjs +++ /dev/null @@ -1,342 +0,0 @@ -import { box } from './shared.mjs' - -export const plugin_banner = { - name: 'examples.plugin_banner', - draft: ({ points, Point, paths, Path, macro, part }) => { - points.from = new Point(0, 0) - points.to = new Point(320, 0) - - paths.banner = new Path().move(points.from).line(points.to) - - macro('banner', { - path: paths.banner, - text: 'banner plugin', - }) - - // Prevent clipping of text - paths.box = new Path().move(new Point(0, -20)).line(new Point(0, 20)).attr('class', 'hidden') - - return part - }, -} - -export const plugin_bartack = { - name: 'examples.plugin_bartack', - draft: ({ Point, points, macro, part }) => { - points.a = new Point(15, 15) - - macro('bartack', { - anchor: points.a, - angle: 30, - length: 15, - }) - - return box(part, 60, 30) - }, -} - -export const plugin_bartackalong = { - name: 'examples.plugin_bartackalong', - draft: ({ Point, Path, points, paths, macro, part }) => { - points.a = new Point(15, 15) - points.b = new Point(20, 20) - points.c = new Point(30, 20) - points.d = new Point(35, 15) - points.e = new Point(20, 10) - points.f = new Point(30, 10) - - paths.a = new Path().move(points.a).curve(points.b, points.c, points.d).hide() - - macro('bartackAlong', { - path: paths.a, - }) - - macro('sprinkle', { - snippet: 'notch', - on: ['e', 'f'], - }) - - return box(part, 60, 30) - }, -} - -export const plugin_bartackfractionalong = { - name: 'examples.plugin_bartackfractionalong', - draft: ({ Point, Path, points, paths, macro, part }) => { - points.a = new Point(15, 15) - points.b = new Point(20, 20) - points.c = new Point(30, 20) - points.d = new Point(35, 15) - points.e = new Point(20, 10) - points.f = new Point(30, 10) - - paths.a = new Path().move(points.a).curve(points.b, points.c, points.d).hide() - - macro('bartackFractionAlong', { - path: paths.a, - start: 0.2, - end: 0.8, - }) - - macro('sprinkle', { - snippet: 'notch', - on: ['e', 'f'], - }) - - return box(part, 60, 30) - }, -} - -export const plugin_buttons = { - name: 'examples.plugin_buttons', - draft: ({ Point, snippets, Snippet, part }) => { - snippets.button = new Snippet('button', new Point(20, 10)) - snippets.buttonhole = new Snippet('buttonhole', new Point(40, 10)) - snippets.buttonholeStart = new Snippet('buttonhole-start', new Point(60, 10)) - snippets.buttonholeEnd = new Snippet('buttonhole-end', new Point(80, 10)) - snippets.snapMale = new Snippet('snap-stud', new Point(100, 10)) - snippets.snapFemale = new Snippet('snap-socket', new Point(120, 10)) - - return box(part, 140, 20) - }, -} - -export const plugin_cutonfold = { - name: 'examples.plugin_cutonfold', - draft: ({ Point, points, Path, paths, macro, part }) => { - points.topLeft = new Point(0, 0) - points.topRight = new Point(150, 0) - points.bottomRight = new Point(150, 30) - points.bottomLeft = new Point(0, 30) - - paths.box = new Path() - .move(points.topLeft) - .line(points.topRight) - .line(points.bottomRight) - .line(points.bottomLeft) - .close() - - macro('cutonfold', { - from: points.bottomLeft, - to: points.bottomRight, - grainline: true, - }) - - return part - }, -} - -export const plugin_dimension = { - name: 'examples.plugin_dimension', - draft: ({ Point, points, Path, paths, macro, part }) => { - points.A = new Point(0, 0) - points.B = new Point(0, 100) - points.C = new Point(50, 100) - points.D = new Point(100, 50) - points.DCp1 = new Point(100, 0) - - paths.box = new Path() - .move(points.A) - .line(points.B) - .line(points.C) - .line(points.D) - .curve(points.DCp1, points.A, points.A) - .close() - - macro('vd', { - from: points.A, - to: points.B, - x: points.A.x - 15, - }) - - macro('hd', { - from: points.B, - to: points.C, - y: points.B.y + 15, - }) - - macro('ld', { - from: points.C, - to: points.D, - d: -15, - }) - - macro('ld', { - from: points.C, - to: points.D, - d: -30, - text: 'Custom text', - }) - - macro('pd', { - path: new Path().move(points.A).curve(points.A, points.DCp1, points.D), - d: -15, - }) - - return part - }, -} - -export const plugin_gore = { - name: 'examples.plugin_gore', - draft: ({ Point, points, macro, part }) => { - points.anchor = new Point(0, 0) - - macro('gore', { - from: points.anchor, - radius: 60, - gores: 5, - extraLength: 20, - }) - - return part - }, -} - -export const plugin_grainline = { - name: 'examples.plugin_grainline', - draft: ({ Point, points, macro, part }) => { - points.grainlineFrom = new Point(10, 10) - points.grainlineTo = new Point(100, 10) - - macro('grainline', { - from: points.grainlineFrom, - to: points.grainlineTo, - }) - - return box(part, 110, 15) - }, -} - -export const plugin_logo = { - name: 'examples.plugin_logo', - draft: ({ points, Point, snippets, Snippet, part }) => { - points.anchor = new Point(50, 25) - - snippets.logo = new Snippet('logo', points.anchor).attr('data-scale', 0.666) - - return box(part, 100, 35) - }, -} - -export const plugin_mirror = { - name: 'examples.plugin_mirror', - draft: ({ Point, Path, points, paths, macro, part }) => { - points.a = new Point(5, 5) - points.b = new Point(45, 30) - points.c = new Point(5, 30) - points.d = new Point(45, 5) - points.mid = new Point(25, 15) - - paths.a = new Path().move(points.a).curve(points.b, points.c, points.d) - - macro('mirror', { - mirror: [points.b, points.d], - points: [points.mid], - paths: [paths.a], - }) - - macro('sprinkle', { - snippet: 'notch', - on: ['mid', 'mirroredMid'], - }) - - return box(part, 100, 40) - }, -} - -export const plugin_notches = { - name: 'examples.plugin_notches', - draft: ({ Point, snippets, Snippet, part }) => { - snippets.notch = new Snippet('notch', new Point(60, 10)) - snippets.bnotch = new Snippet('bnotch', new Point(80, 10)) - - return box(part, 140, 20) - }, -} - -export const plugin_round = { - name: 'examples.plugin_round', - draft: ({ Point, points, Path, paths, macro, part }) => { - points.topLeft = new Point(0, 0) - points.bottomLeft = new Point(0, 30) - points.topRight = new Point(100, 0) - points.bottomRight = new Point(100, 30) - - paths.demo = new Path() - .move(points.topLeft) - .line(points.bottomLeft) - .line(points.bottomRight) - .line(points.topRight) - .close() - .attr('class', 'note dashed') - - macro('round', { - from: points.topLeft, - to: points.bottomRight, - via: points.bottomLeft, - radius: 10, - prefix: 'bl', - }) - macro('round', { - from: points.bottomRight, - to: points.topLeft, - via: points.topRight, - radius: 20, - prefix: 'tr', - }) - - return part - }, -} - -export const plugin_scalebox = { - name: 'examples.plugin_scalebox', - draft: ({ Point, points, macro, part }) => { - points.anchor1 = new Point(0, 0) - points.anchor2 = new Point(70, 0) - - macro('scalebox', { at: points.anchor1 }) - macro('miniscale', { at: points.anchor2 }) - - return part - }, -} - -export const plugin_sprinkle = { - name: 'examples.plugin_sprinkle', - draft: ({ Point, points, macro, part }) => { - points.a = new Point(10, 10) - points.b = new Point(20, 15) - points.c = new Point(30, 10) - points.d = new Point(40, 15) - points.e = new Point(50, 10) - points.f = new Point(60, 15) - points.g = new Point(70, 10) - points.h = new Point(80, 15) - points.i = new Point(90, 10) - - macro('sprinkle', { - snippet: 'button', - on: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'], - }) - - return box(part, 100, 25) - }, -} - -export const plugin_title = { - name: 'examples.plugin_title', - draft: ({ Point, points, macro, part }) => { - points.title = new Point(90, 45) - - macro('title', { - at: points.title, - nr: 4, - title: 'sleeve', - prefix: 'test', - }) - - return box(part, 200, 70) - }, -} diff --git a/designs/examples/src/point.mjs b/designs/examples/src/point.mjs deleted file mode 100644 index ef299c4d345..00000000000 --- a/designs/examples/src/point.mjs +++ /dev/null @@ -1,457 +0,0 @@ -import { box } from './shared.mjs' - -export const point_addcircle = { - name: 'examples.point_addcircle', - draft: ({ Point, points, part }) => { - points.a = new Point(30, 10).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.c = new Point(70, 10).addCircle(3, 'interfacing').addCircle(7, 'mark lashed') - return box(part, 100, 20) - }, -} - -export const point_addtext = { - name: 'examples.point_addtext', - draft: ({ Point, points, part }) => { - points.anchor = new Point(100, 25) - .addText('supportFreesewingBecomeAPatron', 'center') - .addText('please?') - - return box(part, 200, 50) - }, -} - -export const point_angle = { - name: 'examples.point_angle', - draft: ({ Point, points, Path, paths, part }) => { - points.sun = new Point(10, 5) - points.moon = points.sun.shift(-15, 70) - points.text = points.sun - .shiftFractionTowards(points.moon, 0.8) - .attr('data-text', points.sun.angle(points.moon) + 'Β°') - .attr('data-text-class', 'text-sm fill-note center') - - paths.line = new Path().move(points.sun).line(points.moon).attr('class', 'dashed') - - return part - }, -} - -export const point_attr = { - name: 'examples.point_attr', - draft: ({ Point, points, part }) => { - points.anchor = new Point(100, 25) - .attr('data-text', 'supportFreesewingBecomeAPatron') - .attr('data-text-class', 'center') - - return box(part, 200, 50) - }, -} - -export const point_clone = { - name: 'examples.point_clone', - draft: ({ Point, points, Snippet, snippets, part }) => { - points.A = new Point(25, 25) - .attr('data-text', 'Point A') - .attr('data-text-class', 'text-xl') - .attr('data-text-fill-opacity', '0.5') - points.B = points.A.clone().attr('data-text', 'Point B') - - snippets.x = new Snippet('notch', points.A) - - return box(part) - }, -} - -export const point_copy = { - name: 'examples.point_copy', - draft: ({ Point, points, Snippet, snippets, part }) => { - points.A = new Point(50, 25).attr('data-text', 'Point A').attr('data-text-class', 'text-xl') - points.B = points.A.copy().attr('data-text', 'Point B') - - snippets.x = new Snippet('notch', points.A) - - return box(part) - }, -} - -export const point_dist = { - name: 'examples.point_dist', - draft: ({ Point, points, Path, paths, part }) => { - points.from = new Point(10, 10) - points.to = new Point(80, 70) - - points.text = points.from - .shiftFractionTowards(points.to, 0.6) - .attr('data-text', points.from.dist(points.to) + 'mm') - .attr('data-text-class', 'text-sm fill-note center') - - paths.line = new Path().move(points.from).line(points.to).attr('class', 'dashed') - - return part - }, -} - -export const point_dx = { - name: 'examples.point_dx', - draft: ({ Point, points, Path, paths, part }) => { - points.from = new Point(10, 10) - points.to = new Point(80, 70) - - paths.line = new Path().move(points.from).line(points.to).attr('class', 'dashed') - - points.totop = points.from.shift(0, points.from.dx(points.to)) - - points.text_dx = points.from - .shiftFractionTowards(points.totop, 0.6) - .shiftFractionTowards(points.to, 0.1) - .attr('data-text', points.from.dx(points.to) + 'mm') - .attr('data-text-class', 'text-sm fill-note center') - - paths.line_dx = new Path().move(points.from).line(points.totop).attr('class', 'dashed') - - paths.line_dy = new Path().move(points.to).line(points.totop).attr('class', 'dashed') - - return part - }, -} - -export const point_dy = { - name: 'examples.point_dy', - draft: ({ Point, points, Path, paths, part }) => { - points.from = new Point(10, 10) - points.to = new Point(80, 70) - - paths.line = new Path().move(points.from).line(points.to).attr('class', 'dashed') - - points.totop = points.from.shift(0, points.from.dx(points.to)) - - paths.line_dx = new Path().move(points.from).line(points.totop).attr('class', 'dashed') - - points.text_dy = points.totop - .shiftFractionTowards(points.to, 0.4) - .attr('data-text', points.from.dy(points.to) + 'mm') - .attr('data-text-class', 'text-sm fill-note right') - - paths.line_dy = new Path().move(points.to).line(points.totop).attr('class', 'dashed') - - return part - }, -} - -export const point_flipx = { - name: 'examples.point_flipy', - draft: ({ Point, points, Path, paths, part }) => { - points.top = new Point(50, 10) - points.out1 = new Point(70, 30) - points.in1 = new Point(55, 35) - points.out2 = new Point(75, 50) - points.in2 = new Point(60, 55) - points.out3 = new Point(80, 70) - points.in3 = new Point(55, 70) - points.trunkOut = new Point(55, 80) - points.trunkIn = new Point(50, 80) - - points._out1 = points.out1.flipX(points.top) - points._in1 = points.in1.flipX(points.top) - points._out2 = points.out2.flipX(points.top) - points._in2 = points.in2.flipX(points.top) - points._out3 = points.out3.flipX(points.top) - points._in3 = points.in3.flipX(points.top) - points._trunkOut = points.trunkOut.flipX(points.top) - - points.bottom = new Point(50, 80) - - paths.tree = new Path() - .move(points.top) - .line(points.out1) - .line(points.in1) - .line(points.out2) - .line(points.in2) - .line(points.out3) - .line(points.in3) - .line(points.trunkOut) - .line(points._trunkOut) - .line(points._in3) - .line(points._out3) - .line(points._in2) - .line(points._out2) - .line(points._in1) - .line(points._out1) - .close() - - paths.mirror = new Path().move(points.top).line(points.bottom).attr('class', 'note dashed') - - return part - }, -} - -export const point_flipy = { - name: 'examples.point_flipy', - draft: ({ Point, points, Path, paths, part }) => { - points.start = new Point(0, 50) - points.churchTowerWallLeft = new Point(10, 50) - points.churchTowerRoofLeft = new Point(10, 30) - points.churchTowerTop = new Point(15, 10) - points.churchTowerRoofRight = new Point(20, 30) - points.churchRoofRight = new Point(50, 30) - points.churchWallRight = new Point(50, 50) - points.houseWallLeft = new Point(65, 50) - points.houseRoofLeft = new Point(65, 35) - points.houseRoofTop = new Point(75, 25) - points.houseRoofRight = new Point(85, 35) - points.houseWallRight = new Point(85, 50) - points.end = new Point(95, 50) - - points.mirror = new Point(0, 60) - points.mirrorLineEnd = new Point(95, 60) - - points._start = points.start.flipY(points.mirror) - points._churchTowerWallLeft = points.churchTowerWallLeft.flipY(points.mirror) - points._churchTowerRoofLeft = points.churchTowerRoofLeft.flipY(points.mirror) - points._churchTowerTop = points.churchTowerTop.flipY(points.mirror) - points._churchTowerRoofRight = points.churchTowerRoofRight.flipY(points.mirror) - points._churchRoofRight = points.churchRoofRight.flipY(points.mirror) - points._churchWallRight = points.churchWallRight.flipY(points.mirror) - points._houseWallLeft = points.houseWallLeft.flipY(points.mirror) - points._houseRoofLeft = points.houseRoofLeft.flipY(points.mirror) - points._houseRoofTop = points.houseRoofTop.flipY(points.mirror) - points._houseRoofRight = points.houseRoofRight.flipY(points.mirror) - points._houseWallRight = points.houseWallRight.flipY(points.mirror) - points._end = points.end.flipY(points.mirror) - - paths.skylineTop = 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.skylineBottom = 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.mirrorLine = new Path() - .move(points.mirror) - .line(points.mirrorLineEnd) - .attr('class', 'note dashed') - - return part - }, -} - -export const point_rotate = { - name: 'examples.point_rotate', - draft: ({ Point, points, Path, paths, part }) => { - points.sun = new Point(40, 40) - points.moon = new Point(70, 40) - let step = 360 / 36 - for (let i = 1; i < 37; i++) { - let angle = step * i - points[`moon${i}`] = points.moon.rotate(angle, points.sun) - paths[`moon${i}`] = new Path().move(points.sun).line(points[`moon${i}`]) - } - - return part - }, -} - -export const point_setcircle = { - name: 'examples.point_setcircle', - draft: ({ Point, points, part }) => { - 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.c = new Point(70, 10).setCircle(3, 'interfacing').setCircle(7, 'mark lashed') - return box(part, 100, 20) - }, -} - -export const point_settext = { - name: 'examples.point_settext', - draft: ({ Point, points, part }) => { - points.anchor = new Point(100, 25) - .setText('supportFreesewingBecomeAPatron', 'center') - .setText('please?') - - return box(part, 200, 50) - }, -} - -export const point_shift = { - name: 'examples.point_shift', - draft: ({ Point, points, macro, part }) => { - points.A = new Point(90, 40).attr('data-text', 'Point A').attr('data-text-class', 'right') - points.B = points.A.shift(155, 70) - .attr('data-text', 'Point B is point A shifted 7cm\nat a 155 degree angle') - .attr('data-text-lineheight', 6) - - macro('ld', { - from: points.B, - to: points.A, - d: -10, - }) - - return box(part, 100, 45) - }, -} - -export const point_shiftfractiontowards = { - name: 'examples.point_shiftfractiontowards', - draft: ({ Point, points, Path, paths, macro, part }) => { - points.A = new Point(90, 70).attr('data-text', 'Point A') - points.B = new Point(10, 10).attr('data-text', 'Point B') - points.C = points.A.shiftFractionTowards(points.B, 0.5) - .attr('data-text', 'Point C is point A shifted 50%\nin the direction of point B') - .attr('data-text-class', 'center') - .attr('data-text-lineheight', 6) - - paths.direction = new Path().move(points.A).line(points.B).attr('class', 'note dashed') - - macro('ld', { - from: points.C, - to: points.A, - d: -10, - }) - - macro('ld', { - from: points.B, - to: points.A, - d: 20, - }) - - return part - }, -} - -export const point_shiftoutwards = { - name: 'examples.point_shiftoutwards', - draft: ({ Point, points, Path, paths, macro, part }) => { - points.A = new Point(90, 70).attr('data-text', 'Point A') - points.B = new Point(30, 30).attr('data-text', 'Point B') - points.C = points.A.shiftOutwards(points.B, 30) - .attr('data-text', 'Point C is point A shifted 3cm\nbeyond point B') - .attr('data-text-lineheight', 6) - - paths.direction = new Path().move(points.A).line(points.C).attr('class', 'note dashed') - - macro('ld', { - from: points.C, - to: points.B, - d: -10, - }) - - return box(part, 110, 75) - }, -} - -export const point_shifttowards = { - name: 'examples.point_shifttowards', - draft: ({ Point, points, Path, paths, macro, part }) => { - points.A = new Point(90, 70).attr('data-text', 'Point A') - points.B = new Point(10, 10).attr('data-text', 'Point B') - points.C = points.A.shiftTowards(points.B, 35) - .attr('data-text', 'Point C is point A shifted 3.5cm\nin the direction of point B') - .attr('data-text-class', 'center') - .attr('data-text-lineheight', 6) - - paths.direction = new Path().move(points.A).line(points.B).attr('class', 'note dashed') - - macro('ld', { - from: points.C, - to: points.A, - d: -10, - }) - - return box(part, 110, 80) - }, -} - -export const point_sitson = { - name: 'examples.point_sitson', - draft: ({ Point, points, Snippet, snippets, part }) => { - let s - for (let i = 0; i < 10; i++) { - points[`a${i}`] = new Point(i * 10, 40) - points[`b${i}`] = new Point(i * 10, i * 8) - if (points[`a${i}`].sitsOn(points[`b${i}`])) s = 'notch' - else s = 'bnotch' - snippets[`b${i}`] = new Snippet(s, points[`b${i}`]) - snippets[`a${i}`] = new Snippet(s, points[`a${i}`]) - } - - return box(part) - }, -} - -export const point_sitsroughlyon = { - name: 'examples.point_sitsroughlyon', - draft: ({ Point, points, Snippet, snippets, part }) => { - box(part) - - let s - for (let i = 0; i < 10; i++) { - points[`a${i}`] = new Point(i * 10, 40) - points[`b${i}`] = new Point(i * 10, i * 8) - if (points[`a${i}`].sitsRoughlyOn(points[`b${i}`])) s = 'notch' - else s = 'bnotch' - snippets[`b${i}`] = new Snippet(s, points[`b${i}`]) - snippets[`a${i}`] = new Snippet(s, points[`a${i}`]) - } - - return part - }, -} - -export const point_translate = { - name: 'examples.point_translate', - draft: ({ Point, points, macro, part }) => { - points.A = new Point(20, 20).attr('data-text', 'Point A') - points.B = points.A.translate(120, 60) - .attr('data-text', 'Point B is point A with a\ntranslate(120, 60)\ntransform applied') - .attr('data-text-class', 'right') - .attr('data-text-dy', -6) - .attr('data-text-lineheight', 6) - - macro('ld', { - from: points.A, - to: points.B, - text: 'translate(120,60)', - noStartMarker: true, - }) - - return box(part, 150, 85) - }, -} diff --git a/designs/examples/src/settings.mjs b/designs/examples/src/settings.mjs deleted file mode 100644 index a8ffe9ea574..00000000000 --- a/designs/examples/src/settings.mjs +++ /dev/null @@ -1,22 +0,0 @@ -export const settings_sa = { - name: 'examples.settings_sa', - draft: ({ Point, points, Path, paths, 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) - - paths.example = new Path() - .move(points.A) - .line(points.B) - .curve(points.BCp2, points.CCp1, points.C) - .line(points.A) - .close() - .attr('class', 'fabric') - - paths.offset = paths.example.offset(-10).attr('class', 'fabric sa') - - return part - }, -} diff --git a/designs/examples/src/shared.mjs b/designs/examples/src/shared.mjs deleted file mode 100644 index e99bb3fbd3c..00000000000 --- a/designs/examples/src/shared.mjs +++ /dev/null @@ -1,13 +0,0 @@ -/** - * This draws a (diagonal in a) box - * with with w and height h with a non-visible line. - * This is to force our examples parts to a certain size - */ -export function box(part, w = 100, h = 50) { - part.paths.box = new part.Path() - .move(new part.Point(0, 0)) - .line(new part.Point(w, h)) - .setClass('hidden noxray') - - return part -} diff --git a/designs/examples/src/snippet.mjs b/designs/examples/src/snippet.mjs deleted file mode 100644 index 152a6635f07..00000000000 --- a/designs/examples/src/snippet.mjs +++ /dev/null @@ -1,39 +0,0 @@ -import { box } from './shared.mjs' - -export const snippet = { - name: 'examples.snippet', - draft: ({ Point, points, Snippet, snippets, part }) => { - points.anchor1 = new Point(20, 15) - points.anchor2 = new Point(50, 15) - points.anchor3 = new Point(80, 15) - snippets.demo1 = new Snippet('button', points.anchor1) - snippets.demo2 = new Snippet('buttonhole', points.anchor2) - snippets.demo3 = new Snippet('logo', points.anchor3).attr('data-scale', 0.5) - - return box(part) - }, -} - -export const snippet_attr = { - name: 'examples.snippet_attr', - draft: ({ Point, points, Snippet, snippets, part }) => { - points.anchor = new Point(50, 15) - snippets.demo = new Snippet('logo', points.anchor) - .attr('data-scale', 0.8) - .attr('data-rotate', 180) - - return box(part) - }, -} - -export const snippet_clone = { - name: 'examples.snippet_clone', - draft: ({ Point, points, Snippet, snippets, part }) => { - points.anchor = new Point(35, 35) - snippets.demo = new Snippet('logo', points.anchor).attr('style', 'color: #f006') - - snippets.clone = snippets.demo.clone().attr('data-scale', 0.5) - - return box(part) - }, -} diff --git a/designs/examples/src/snippets.mjs b/designs/examples/src/snippets.mjs deleted file mode 100644 index 95c2e3d3ea4..00000000000 --- a/designs/examples/src/snippets.mjs +++ /dev/null @@ -1,91 +0,0 @@ -import { box } from './shared.mjs' - -export const snippet_bnotch = { - name: 'examples.snippet_bnotch', - draft: ({ Point, points, Snippet, snippets, part }) => { - points.anchor = new Point(50, 5) - snippets.demo = new Snippet('bnotch', points.anchor) - - return box(part, 100, 10) - }, -} - -export const snippet_button = { - name: 'examples.snippet_button', - draft: ({ Point, points, Snippet, snippets, part }) => { - points.anchor = new Point(50, 5) - snippets.demo = new Snippet('button', points.anchor) - - return box(part, 100, 10) - }, -} - -export const snippet_buttonholeend = { - name: 'examples.snippet_buttonholeend', - draft: ({ Point, points, Snippet, snippets, part }) => { - points.anchor = new Point(50, 0) - snippets.demo = new Snippet('buttonhole-end', points.anchor) - - return box(part, 100, 10) - }, -} - -export const snippet_buttonholestart = { - name: 'examples.snippet_buttonholestart', - draft: ({ Point, points, Snippet, snippets, part }) => { - points.anchor = new Point(50, 10) - snippets.demo = new Snippet('buttonhole-start', points.anchor) - - return box(part, 100, 10) - }, -} - -export const snippet_buttonhole = { - name: 'examples.snippet_buttonhole', - draft: ({ Point, points, Snippet, snippets, part }) => { - points.anchor = new Point(50, 5) - snippets.demo = new Snippet('buttonhole', points.anchor) - - return box(part, 100, 10) - }, -} - -export const snippet_logo = { - name: 'examples.snippet_logo', - draft: ({ Point, points, Snippet, snippets, part }) => { - points.anchor = new Point(50, 35) - snippets.demo = new Snippet('logo', points.anchor) - - return box(part, 100, 50) - }, -} - -export const snippet_notch = { - name: 'examples.snippet_notch', - draft: ({ Point, points, Snippet, snippets, part }) => { - points.anchor = new Point(50, 5) - snippets.demo = new Snippet('notch', points.anchor) - - return box(part, 100, 10) - }, -} - -export const snippet_snapsocket = { - name: 'examples.snippet_snapsocket', - draft: ({ Point, points, Snippet, snippets, part }) => { - points.anchor = new Point(50, 5) - snippets.demo = new Snippet('snap-socket', points.anchor) - - return box(part, 100, 10) - }, -} - -export const snippet_snapstud = { - name: 'examples.snippet_snapstud', - draft: ({ Point, points, Snippet, snippets, part }) => { - points.anchor = new Point(50, 5) - snippets.demo = new Snippet('snap-stud', points.anchor) - - return box(part, 100, 10) - }, -} diff --git a/designs/examples/src/stacks.mjs b/designs/examples/src/stacks.mjs deleted file mode 100644 index 8b0cd0255f6..00000000000 --- a/designs/examples/src/stacks.mjs +++ /dev/null @@ -1,128 +0,0 @@ -const stack = (settings, partName) => { - if (settings?.options?.stackIt === 'Do stack') return 'example' - else return partName -} - -export const stacks_top = { - name: 'examples.stacks_top', - stack, - measurements: ['head'], - options: { - size: { pct: 50, min: 5, max: 100, menu: 'stack' }, - x: { pct: 0, min: -100, max: 100, menu: 'stack' }, - y: { pct: 0, min: -100, max: 100, menu: 'stack' }, - stackIt: { dflt: 'Do stack', list: ['Do stack', 'Do not stack'], menu: 'stack' }, - }, - draft: ({ store, Point, points, Path, paths, options, measurements, part }) => { - store.set('size', measurements.head * options.size) - store.set('x', measurements.head * options.x) - store.set('y', measurements.head * options.y) - points.from = new Point(store.get('x'), store.get('y')) - points.to = points.from.shift(0, store.get('size')) - paths.line = new Path().move(points.from).line(points.to).attr('class', 'fabric stroke-4xl') - - return part - }, -} - -export const stacks_right = { - name: 'examples.stacks_right', - stack, - after: stacks_top, - draft: ({ store, Point, points, Path, paths, part }) => { - points.from = new Point(store.get('x') + store.get('size'), store.get('y')) - points.to = points.from.shift(-90, store.get('size')) - paths.line = new Path().move(points.from).line(points.to).attr('class', 'fabric stroke-4xl') - - return part - }, -} - -export const stacks_bottom = { - name: 'examples.stacks_bottom', - stack, - after: stacks_top, - draft: ({ store, Point, points, Path, paths, part }) => { - points.from = new Point(store.get('x') + store.get('size'), store.get('y') + store.get('size')) - points.to = points.from.shift(180, store.get('size')) - paths.line = new Path().move(points.from).line(points.to).attr('class', 'fabric stroke-4xl') - - return part - }, -} - -export const stacks_left = { - name: 'examples.stacks_left', - stack, - after: stacks_top, - draft: ({ store, Point, points, Path, paths, part }) => { - points.from = new Point(store.get('x'), store.get('y') + store.get('size')) - points.to = points.from.shift(90, store.get('size')) - paths.line = new Path().move(points.from).line(points.to).attr('class', 'fabric stroke-4xl') - - return part - }, -} - -export const stacks_leftEye = { - name: 'examples.stacks_leftEye', - stack, - after: stacks_top, - draft: ({ store, Point, points, part }) => { - points.leftEye = new Point( - store.get('x') + store.get('size') * 0.35, - store.get('y') + store.get('size') * 0.4 - ) - .attr('data-circle', store.get('size') * 0.1) - .attr('data-circle-class', 'stroke-6xl') - - return part - }, -} - -export const stacks_rightEye = { - name: 'examples.stacks_rightEye', - stack, - after: stacks_top, - draft: ({ store, Point, points, part }) => { - points.rightEye = new Point( - store.get('x') + store.get('size') * 0.65, - store.get('y') + store.get('size') * 0.4 - ) - .attr('data-circle', store.get('size') * 0.08) - .attr('data-circle-class', 'stroke-7xl') - - return part - }, -} - -export const stacks_mouth = { - name: 'examples.stacks_mouth', - stack, - after: stacks_top, - draft: ({ store, Point, points, paths, Path, part }) => { - points.left = new Point( - store.get('x') + store.get('size') * 0.15, - store.get('y') + store.get('size') * 0.5 - ) - points.right = new Point( - store.get('x') + store.get('size') * 0.85, - store.get('y') + store.get('size') * 0.5 - ) - points.leftCp = new Point( - store.get('x') + store.get('size') * 0.35, - store.get('y') + store.get('size') * 0.8 - ) - points.rightCp = new Point( - store.get('x') + store.get('size') * 0.65, - store.get('y') + store.get('size') * 0.8 - ) - - paths.mouth = new Path() - .move(points.left) - .curve(points.leftCp, points.rightCp, points.right) - .attr('class', 'fabric stroke-7xl') - - return part - }, -} diff --git a/designs/examples/src/utils.mjs b/designs/examples/src/utils.mjs deleted file mode 100644 index 201fa7d40f0..00000000000 --- a/designs/examples/src/utils.mjs +++ /dev/null @@ -1,445 +0,0 @@ -import { box } from './shared.mjs' - -export const utils_beamintersectscircle = { - name: 'examples.utils_beamintersectscircle', - draft: ({ Point, points, Path, paths, Snippet, snippets, utils, part }) => { - points.A = new Point(95, 45).attr('data-circle', 35).attr('data-circle-class', 'fabric') - points.B = new Point(55, 50) - points.C = new Point(75, 30) - points.D = new Point(55, 65) - points.E = new Point(115, 5) - points.F = new Point(65, 75) - points.G = new Point(125, 15) - - paths.line1 = new Path().move(points.B).line(points.C) - paths.line2 = new Path().move(points.D).line(points.E) - paths.line3 = new Path().move(points.F).line(points.G) - - let intersections1 = utils.beamIntersectsCircle( - points.A, - points.A.attributes.get('data-circle'), - points.B, - points.C - ) - let intersections2 = utils.beamIntersectsCircle( - points.A, - points.A.attributes.get('data-circle'), - points.D, - points.E, - 'y' - ) - let intersections3 = utils.beamIntersectsCircle( - points.A, - points.A.attributes.get('data-circle'), - points.F, - points.G - ) - - snippets.first1 = new Snippet('bnotch', intersections1[0]) - snippets.second1 = new Snippet('notch', intersections1[1]) - snippets.first2 = new Snippet('bnotch', intersections2[0]) - snippets.second2 = new Snippet('notch', intersections2[1]) - snippets.first3 = new Snippet('bnotch', intersections3[0]) - snippets.second3 = new Snippet('notch', intersections3[1]) - - return box(part, 200, 80) - }, -} - -export const utils_beamintersectsx = { - name: 'examples.utils_beamintersectsx', - draft: ({ Point, points, Path, paths, Snippet, snippets, utils, part }) => { - points.A = new Point(10, 10) - points.B = new Point(90, 30) - - paths.AB = new Path().move(points.A).line(points.B) - - snippets.x = new Snippet('notch', utils.beamIntersectsX(points.A, points.B, 40)) - - paths.help = new Path() - .move(new Point(40, 5)) - .line(new Point(40, 35)) - .attr('class', 'note dashed') - - return part - }, -} - -export const utils_beamintersectsy = { - name: 'examples.utils_beamintersectsy', - draft: ({ Point, points, Path, paths, Snippet, snippets, utils, part }) => { - points.A = new Point(10, 10) - points.B = new Point(50, 40) - - paths.AB = new Path().move(points.A).line(points.B) - - snippets.x = new Snippet('notch', utils.beamIntersectsY(points.A, points.B, 30)) - - paths.help = new Path() - .move(new Point(0, 30)) - .line(new Point(50, 30)) - .attr('class', 'note dashed') - - return part - }, -} - -export const utils_beamsintersect = { - name: 'examples.utils_beamsintersect', - draft: ({ Point, points, Path, paths, Snippet, snippets, utils, part }) => { - points.A = new Point(10, 10) - points.B = new Point(50, 40) - points.C = new Point(45, 20) - points.D = new Point(60, 15) - - paths.AB = new Path().move(points.A).line(points.B) - paths.CD = new Path().move(points.C).line(points.D) - - snippets.x = new Snippet('notch', utils.beamsIntersect(points.A, points.B, points.C, points.D)) - - return part - }, -} - -export const utils_circlesintersect = { - name: 'examples.utils_circlesintersect', - draft: ({ Point, points, Snippet, snippets, utils, part }) => { - points.A = new Point(10, 10).attr('data-circle', 15).attr('data-circle-class', 'fabric') - points.B = new Point(30, 30).attr('data-circle', 35).attr('data-circle-class', 'fabric') - points.C = new Point(90, 10).attr('data-circle', 15).attr('data-circle-class', 'various') - points.D = new Point(110, 30).attr('data-circle', 35).attr('data-circle-class', 'various') - - let intersections1 = utils.circlesIntersect( - points.A, - points.A.attributes.get('data-circle'), - points.B, - points.B.attributes.get('data-circle') - ) - let intersections2 = utils.circlesIntersect( - points.C, - points.C.attributes.get('data-circle'), - points.D, - points.D.attributes.get('data-circle'), - 'y' - ) - - snippets.first1 = new Snippet('bnotch', intersections1[0]) - snippets.second1 = new Snippet('notch', intersections1[1]) - snippets.first2 = new Snippet('bnotch', intersections2[0]) - snippets.second2 = new Snippet('notch', intersections2[1]) - - return part - }, -} - -export const utils_curveintersectsx = { - name: 'examples.utils_curveintersectsx', - draft: ({ Point, points, Path, paths, utils, snippets, Snippet, 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) - - 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]) - .attr('class', '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 - }, -} - -export const utils_curveintersectsy = { - name: 'examples.utils_curveintersectsy', - draft: ({ Point, points, Path, paths, utils, snippets, Snippet, 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) - - 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]) - .attr('class', '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 - }, -} - -export const utils_curvesintersect = { - name: 'examples.utils_curvesintersect', - draft: ({ Point, points, Path, paths, Snippet, snippets, utils, 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.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) - - for (let p of utils.curvesIntersect( - points.A, - points.Acp, - points.Bcp, - points.B, - points.C, - points.Ccp, - points.Dcp, - points.D - )) { - snippets[part.getId()] = new Snippet('notch', p) - } - - return part - }, -} - -export const utils_lineintersectscircle = { - name: 'examples.utils_lineintersectscircle', - draft: ({ Point, points, Path, paths, Snippet, snippets, utils, part }) => { - points.A = new Point(95, 45).attr('data-circle', 35).attr('data-circle-class', 'fabric') - points.B = new Point(55, 50) - points.C = new Point(75, 30) - - points.D = new Point(55, 65) - points.E = new Point(115, 5) - points.F = new Point(65, 75) - points.G = new Point(125, 15) - - paths.line1 = new Path().move(points.B).line(points.C) - paths.line2 = new Path().move(points.D).line(points.E) - paths.line3 = new Path().move(points.F).line(points.G) - - let intersections1 = utils.lineIntersectsCircle( - points.A, - points.A.attributes.get('data-circle'), - points.B, - points.C - ) - let intersections2 = utils.lineIntersectsCircle( - points.A, - points.A.attributes.get('data-circle'), - points.D, - points.E, - 'y' - ) - let intersections3 = utils.lineIntersectsCircle( - points.A, - points.A.attributes.get('data-circle'), - points.F, - points.G - ) - snippets.first1 = new Snippet('bnotch', intersections1[0]) - snippets.first2 = new Snippet('bnotch', intersections2[0]) - snippets.second2 = new Snippet('notch', intersections2[1]) - snippets.first3 = new Snippet('bnotch', intersections3[0]) - snippets.second3 = new Snippet('notch', intersections3[1]) - - return box(part, 200, 80) - }, -} - -export const utils_lineintersectscurve = { - name: 'examples.utils_lineintersectscurve', - draft: ({ Point, points, Path, paths, Snippet, snippets, utils, 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.E = new Point(20, -5) - points.D = new Point(100, 85) - paths.curve = new Path().move(points.A).curve(points.Acp, points.Bcp, points.B) - paths.line = new Path().move(points.E).line(points.D) - - for (let p of utils.lineIntersectsCurve( - points.D, - points.E, - points.A, - points.Acp, - points.Bcp, - points.B - )) { - snippets[part.getId()] = new Snippet('notch', p) - } - - return part - }, -} - -export const utils_linesintersect = { - name: 'examples.utils_linesintersect', - draft: ({ Point, points, Path, paths, Snippet, snippets, utils, part }) => { - points.A = new Point(10, 10) - points.B = new Point(50, 40) - points.C = new Point(15, 30) - points.D = new Point(60, 15) - - paths.AB = new Path().move(points.A).line(points.B) - paths.CD = new Path().move(points.C).line(points.D) - - snippets.X = new Snippet('notch', utils.linesIntersect(points.A, points.B, points.C, points.D)) - - return part - }, -} - -export const utils_pointonbeam = { - name: 'examples.utils_pointonbeam', - draft: ({ Point, points, Path, paths, Snippet, snippets, utils, part }) => { - points.from1 = new Point(10, 10) - points.to1 = new Point(90, 60) - points.from2 = new Point(10, 30) - points.to2 = new Point(90, 80) - points.b1 = new Point(170, 110) - points.b2 = new Point(170, 130) - - let scatter = [] - for (let i = 1; i < 36; i++) { - for (let j = 1; j < 27; j++) { - scatter.push(new Point(i * 10, j * 10)) - } - } - let snippet - for (let point of scatter) { - if (utils.pointOnBeam(points.from1, points.to1, point)) snippet = 'notch' - else snippet = 'bnotch' - snippets[part.getId()] = new Snippet(snippet, point) - if (utils.pointOnBeam(points.from2, points.to2, point, 0.01)) { - snippet = 'notch' - } else snippet = 'bnotch' - snippets[part.getId()] = new Snippet(snippet, point) - } - paths.line1 = new Path().move(points.from1).line(points.to1).attr('class', 'fabric stroke-lg') - paths.lne1 = new Path().move(points.to1).line(points.b1).attr('class', 'fabric dashed') - paths.line2 = new Path().move(points.from2).line(points.to2).attr('class', 'fabric stroke-lg') - paths.lne2 = new Path().move(points.to2).line(points.b2).attr('class', 'fabric dashed') - - return part - }, -} - -export const utils_pointoncurve = { - name: 'examples.utils_pointoncurve', - draft: ({ Point, points, Path, paths, Snippet, snippets, utils, part }) => { - points.start = new Point(10, 10) - points.cp1 = new Point(90, 10) - points.cp2 = new Point(10, 60) - points.end = new Point(90, 60) - - let scatter = [] - for (let i = 1; i < 19; i++) { - for (let j = 1; j < 14; j++) { - scatter.push(new Point(i * 10, j * 10)) - } - } - let snippet - for (let point of scatter) { - if (utils.pointOnCurve(points.start, points.cp1, points.cp2, points.end, point)) { - snippet = 'notch' - } else snippet = 'bnotch' - snippets[part.getId()] = new Snippet(snippet, point) - } - paths.curve = new Path() - .move(points.start) - .curve(points.cp1, points.cp2, points.end) - .attr('class', 'fabric stroke-lg') - - return part - }, -} - -export const utils_pointonline = { - name: 'examples.utils_pointonline', - draft: ({ Point, points, Path, paths, Snippet, snippets, utils, part }) => { - points.from1 = new Point(10, 10) - points.to1 = new Point(90, 60) - points.from2 = new Point(10, 30) - points.to2 = new Point(90, 80) - points.b1 = new Point(170, 110) - points.b2 = new Point(170, 130) - - let scatter = [] - for (let i = 1; i < 36; i++) { - for (let j = 1; j < 27; j++) { - scatter.push(new Point(i * 10, j * 10)) - } - } - let snippet - for (let point of scatter) { - if (utils.pointOnLine(points.from1, points.to1, point)) snippet = 'notch' - else snippet = 'bnotch' - snippets[part.getId()] = new Snippet(snippet, point) - if (utils.pointOnLine(points.from2, points.to2, point, 0.01)) { - snippet = 'notch' - } else snippet = 'bnotch' - snippets[part.getId()] = new Snippet(snippet, point) - } - paths.line1 = new Path().move(points.from1).line(points.to1).attr('class', 'fabric stroke-lg') - paths.lne1 = new Path().move(points.to1).line(points.b1).attr('class', 'fabric dashed') - paths.line2 = new Path().move(points.from2).line(points.to2).attr('class', 'fabric stroke-lg') - paths.lne2 = new Path().move(points.to2).line(points.b2).attr('class', 'fabric dashed') - - return part - }, -} - -export const utils_splitcurve = { - name: 'examples.utils_splitcurve', - draft: ({ Point, points, Path, paths, utils, part }) => { - points.from = new Point(40, 10) - points.to = new Point(40, 80) - paths.line = new Path().move(points.from).line(points.to).attr('class', 'lining dashed') - - 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.i40 = utils.curveIntersectsX(points.start, points.cp1, points.cp2, points.end, 40) - - let parts = utils.splitCurve(points.start, points.cp1, points.cp2, points.end, points.i40) - - let colors = ['lining', 'interfacing'] - for (let p of parts) { - let color = colors.pop() - paths[color] = new Path() - .move(p.start) - .curve(p.cp1, p.cp2, p.end) - .attr('class', 'stroke-xl ' + color) - } - - return part - }, -} diff --git a/designs/examples/tests/shared.test.mjs b/designs/examples/tests/shared.test.mjs deleted file mode 100644 index 88702efb737..00000000000 --- a/designs/examples/tests/shared.test.mjs +++ /dev/null @@ -1,16 +0,0 @@ -// This file is auto-generated | Any changes you make will be overwritten. -import { Examples } from '../src/index.mjs' - -// Shared tests -import { testPatternConfig } from '../../../tests/designs/config.mjs' -import { testPatternDrafting } from '../../../tests/designs/drafting.mjs' -//import { testPatternSampling } from '../../../tests/designs/sampling.mjs' - -// Test config -testPatternConfig(Examples) - -// Test drafting - Change the second parameter to `true` to log errors -testPatternDrafting(Examples, false) - -// Test sampling - Change the second parameter to `true` to log errors -//testPatternSampling(Examples, false) From 81e20e9d281e20373505da028db8061a456a0db9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 28 Sep 2022 15:07:39 +0000 Subject: [PATCH 38/46] chore(deps-dev): bump eslint from 8.23.1 to 8.24.0 Bumps [eslint](https://github.com/eslint/eslint) from 8.23.1 to 8.24.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v8.23.1...v8.24.0) --- updated-dependencies: - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- yarn.lock | 99 ++++++------------------------------------------------- 1 file changed, 10 insertions(+), 89 deletions(-) diff --git a/yarn.lock b/yarn.lock index 2a82625508b..be0cb0cb77c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1271,21 +1271,6 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.15.9.tgz#b658a97babf1f40783354af7039b84c3fdfc3fc3" integrity sha512-O+NfmkfRrb3uSsTa4jE3WApidSe3N5++fyOVGP1SmMZi4A3BZELkhUUvj5hwmMuNdlpzAZ8iAPz2vmcR7DCFQA== -"@eslint/eslintrc@^1.3.0": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.0.tgz#29f92c30bb3e771e4a2048c95fa6855392dfac4f" - integrity sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw== - dependencies: - ajv "^6.12.4" - debug "^4.3.2" - espree "^9.3.2" - globals "^13.15.0" - ignore "^5.2.0" - import-fresh "^3.2.1" - js-yaml "^4.1.0" - minimatch "^3.1.2" - strip-json-comments "^3.1.1" - "@eslint/eslintrc@^1.3.2": version "1.3.2" resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.2.tgz#58b69582f3b7271d8fa67fe5251767a5b38ea356" @@ -1316,19 +1301,10 @@ resolved "https://registry.yarnpkg.com/@heroicons/react/-/react-2.0.10.tgz#191a305aa2dc2271903f027c9f4700ca3dfa9e7b" integrity sha512-Ufr+pgAElNiRCSklnHGOR10bXb02BLlosvbDK7sCRUMOcQ3R/HCXTfXs4BUkYZ4dKpx6l5dUD06VSW1dTpTEDw== -"@humanwhocodes/config-array@^0.10.4": - version "0.10.4" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.10.4.tgz#01e7366e57d2ad104feea63e72248f22015c520c" - integrity sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw== - dependencies: - "@humanwhocodes/object-schema" "^1.2.1" - debug "^4.1.1" - minimatch "^3.0.4" - -"@humanwhocodes/config-array@^0.9.2": - version "0.9.5" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.9.5.tgz#2cbaf9a89460da24b5ca6531b8bbfc23e1df50c7" - integrity sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw== +"@humanwhocodes/config-array@^0.10.5": + version "0.10.5" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.10.5.tgz#bb679745224745fff1e9a41961c1d45a49f81c04" + integrity sha512-XVVDtp+dVvRxMoxSiSfasYaG02VEe1qH5cKgMQJWhol6HwzbcqoCMJi8dAGoYAO57jhUyhI6cWuRiTcRaDaYug== dependencies: "@humanwhocodes/object-schema" "^1.2.1" debug "^4.1.1" @@ -8002,54 +7978,13 @@ eslint-visitor-keys@^3.3.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== -eslint@^8.13.0: - version "8.20.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.20.0.tgz#048ac56aa18529967da8354a478be4ec0a2bc81b" - integrity sha512-d4ixhz5SKCa1D6SCPrivP7yYVi7nyD6A4vs6HIAul9ujBzcEmZVM3/0NN/yu5nKhmO1wjp5xQ46iRfmDGlOviA== - dependencies: - "@eslint/eslintrc" "^1.3.0" - "@humanwhocodes/config-array" "^0.9.2" - ajv "^6.10.0" - chalk "^4.0.0" - cross-spawn "^7.0.2" - debug "^4.3.2" - doctrine "^3.0.0" - escape-string-regexp "^4.0.0" - eslint-scope "^7.1.1" - eslint-utils "^3.0.0" - eslint-visitor-keys "^3.3.0" - espree "^9.3.2" - esquery "^1.4.0" - esutils "^2.0.2" - fast-deep-equal "^3.1.3" - file-entry-cache "^6.0.1" - functional-red-black-tree "^1.0.1" - glob-parent "^6.0.1" - globals "^13.15.0" - ignore "^5.2.0" - import-fresh "^3.0.0" - imurmurhash "^0.1.4" - is-glob "^4.0.0" - js-yaml "^4.1.0" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.4.1" - lodash.merge "^4.6.2" - minimatch "^3.1.2" - natural-compare "^1.4.0" - optionator "^0.9.1" - regexpp "^3.2.0" - strip-ansi "^6.0.1" - strip-json-comments "^3.1.0" - text-table "^0.2.0" - v8-compile-cache "^2.0.3" - -eslint@^8.23.1: - version "8.23.1" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.23.1.tgz#cfd7b3f7fdd07db8d16b4ac0516a29c8d8dca5dc" - integrity sha512-w7C1IXCc6fNqjpuYd0yPlcTKKmHlHHktRkzmBPZ+7cvNBQuiNjx0xaMTjAJGCafJhQkrFJooREv0CtrVzmHwqg== +eslint@^8.13.0, eslint@^8.23.1: + version "8.24.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.24.0.tgz#489516c927a5da11b3979dbfb2679394523383c8" + integrity sha512-dWFaPhGhTAiPcCgm3f6LI2MBWbogMnTJzFBbhXVRQDJPkr9pGZvVjlVfXd+vyDcWPA2Ic9L2AXPIQM0+vk/cSQ== dependencies: "@eslint/eslintrc" "^1.3.2" - "@humanwhocodes/config-array" "^0.10.4" + "@humanwhocodes/config-array" "^0.10.5" "@humanwhocodes/gitignore-to-minimatch" "^1.0.2" "@humanwhocodes/module-importer" "^1.0.1" ajv "^6.10.0" @@ -8093,15 +8028,6 @@ esm@^3.2.25: resolved "https://registry.yarnpkg.com/esm/-/esm-3.2.25.tgz#342c18c29d56157688ba5ce31f8431fbb795cc10" integrity sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA== -espree@^9.3.2: - version "9.3.2" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.3.2.tgz#f58f77bd334731182801ced3380a8cc859091596" - integrity sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA== - dependencies: - acorn "^8.7.1" - acorn-jsx "^5.3.2" - eslint-visitor-keys "^3.3.0" - espree@^9.4.0: version "9.4.0" resolved "https://registry.yarnpkg.com/espree/-/espree-9.4.0.tgz#cd4bc3d6e9336c433265fc0aa016fc1aaf182f8a" @@ -9026,11 +8952,6 @@ function.prototype.name@^1.1.5: es-abstract "^1.19.0" functions-have-names "^1.2.2" -functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g== - functions-have-names@^1.2.2: version "1.2.3" resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" @@ -19493,7 +19414,7 @@ v8-compile-cache-lib@^3.0.1: resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== -v8-compile-cache@2.3.0, v8-compile-cache@^2.0.3: +v8-compile-cache@2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== From d84dab5105ac31d37eaddfcc507447c4a7c304ff Mon Sep 17 00:00:00 2001 From: Joost De Cock Date: Wed, 28 Sep 2022 17:25:18 +0200 Subject: [PATCH 39/46] chore(lab): Fix log layout --- sites/lab/components/layouts/lab.js | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/sites/lab/components/layouts/lab.js b/sites/lab/components/layouts/lab.js index e269676042c..61efdb474ff 100644 --- a/sites/lab/components/layouts/lab.js +++ b/sites/lab/components/layouts/lab.js @@ -7,17 +7,15 @@ export const BeforeNav = ({ app }) => ( - -+ > ) -const LabLayout = ({ app, AltMenu, children=[] }) => ( +const LabLayout = ({ app, AltMenu, children = [] }) => (-+ From 5a9a7b2b91ab68bc9b3c4ad97501ac67d3d3619a Mon Sep 17 00:00:00 2001 From: Joost De Cock- {children} --Date: Wed, 28 Sep 2022 18:07:32 +0200 Subject: [PATCH 40/46] fix(core): Allow run-time hiding of parts --- packages/core/src/pattern.mjs | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/packages/core/src/pattern.mjs b/packages/core/src/pattern.mjs index ed423bb8fdf..575607cf679 100644 --- a/packages/core/src/pattern.mjs +++ b/packages/core/src/pattern.mjs @@ -181,6 +181,7 @@ Pattern.prototype.getConfig = function () { * @return {object} this - The Pattern instance */ Pattern.prototype.getRenderProps = function () { + this.store.log.info('Gathering render props') // Run pre-render hook let svg = new Svg(this) svg.hooks = this.hooks @@ -194,15 +195,6 @@ Pattern.prototype.getRenderProps = function () { props.height = this.height props.autoLayout = this.autoLayout props.settings = this.settings - props.logs = { - pattern: this.store.logs, - sets: this.setStores.map((store) => ({ - debug: store.logs.debug, - info: store.logs.info, - error: store.logs.error, - warning: store.logs.warning, - })), - } props.parts = [] for (const set of this.parts) { const setParts = {} @@ -212,6 +204,10 @@ Pattern.prototype.getRenderProps = function () { ...set[p].asProps(), store: this.setStores[set[p].set], } + } else if (this.setStores[set?.set]) { + this.setStores[set.set].log.info( + `Part${p} is hidden in set ${set.set}. Not adding to render props` + ) } } props.parts.push(setParts) @@ -220,7 +216,16 @@ Pattern.prototype.getRenderProps = function () { for (let s in this.stacks) { if (!this.__isStackHidden(s)) { props.stacks[s] = this.stacks[s].asProps() - } + } else this.store.log.info(`Stack ${s} is hidden. Skipping in render props.`) + } + props.logs = { + pattern: this.store.logs, + sets: this.setStores.map((store) => ({ + debug: store.logs.debug, + info: store.logs.info, + error: store.logs.error, + warning: store.logs.warning, + })), } return props @@ -706,6 +711,7 @@ Pattern.prototype.__isPartHidden = function (partName) { if (this.__designParts?.[partName]?.hideAll) return true if (this.__mutated.partHide?.[partName]) return true if (this.__mutated.partHideAll?.[partName]) return true + if (this.parts?.[this.activeSet]?.[partName]?.hidden) return true return false } @@ -731,6 +737,7 @@ Pattern.prototype.__isStackHidden = function (stackName) { if (this.__designParts?.[partName]?.hideAll) return true if (this.__mutated.partHide?.[partName]) return true if (this.__mutated.partHideAll?.[partName]) return true + if (this.parts?.[this.activeSet]?.[partName]?.hidden) return true } return false @@ -1239,7 +1246,7 @@ Pattern.prototype.__resolveParts = function (count = 0, distance = 0) { if (part.hideAll) this.__mutated.partHide[part.name] = true // Inject (from) if (part.from) { - if (part.hideDependencies || part.hideAll) { + if (part.hideDependencies) { // Don't mutate the part, keep this info in the pattern object this.__mutated.partHide[part.from.name] = true this.__mutated.partHideAll[part.from.name] = true @@ -1258,9 +1265,6 @@ Pattern.prototype.__resolveParts = function (count = 0, distance = 0) { this.__addDependency(name, part, dep) } } else { - if (part.hideDependencies) { - this.__mutated.partHide[part.after.name] = true - } this.__mutated.partDistance[part.after.name] = distance this.__designParts[part.after.name] = part.after this.__addDependency(name, part, part.after) From 22ed2f62bd965e95535f59cf068f1319ddb91821 Mon Sep 17 00:00:00 2001 From: Joost De Cock Date: Wed, 28 Sep 2022 18:33:01 +0200 Subject: [PATCH 41/46] fix(core): Hide grandchild dependencies --- packages/core/src/pattern.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/pattern.mjs b/packages/core/src/pattern.mjs index 575607cf679..ddfd9344078 100644 --- a/packages/core/src/pattern.mjs +++ b/packages/core/src/pattern.mjs @@ -1246,7 +1246,7 @@ Pattern.prototype.__resolveParts = function (count = 0, distance = 0) { if (part.hideAll) this.__mutated.partHide[part.name] = true // Inject (from) if (part.from) { - if (part.hideDependencies) { + if (part.hideDependencies || this.__mutated.partHideAll[name]) { // Don't mutate the part, keep this info in the pattern object this.__mutated.partHide[part.from.name] = true this.__mutated.partHideAll[part.from.name] = true From d09948c8262f1bdc238cbaa884675ca81157f3a1 Mon Sep 17 00:00:00 2001 From: Joost De Cock Date: Wed, 28 Sep 2022 18:36:03 +0200 Subject: [PATCH 42/46] fix(teagan): Don't hide the back part seamline --- designs/teagan/src/back.mjs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/designs/teagan/src/back.mjs b/designs/teagan/src/back.mjs index 4b2afa3fe2c..f87587160f0 100644 --- a/designs/teagan/src/back.mjs +++ b/designs/teagan/src/back.mjs @@ -39,8 +39,7 @@ function teaganBack({ .join(paths.saBase) .line(points.cfHem) .close() - .hide() - .attr('class', 'fabric') + .setClass('fabric') // Set store values required to draft sleevecap store.set('sleevecapEase', 0) From 9f6c20717718b91f722bb07de74af6f4d4023b7e Mon Sep 17 00:00:00 2001 From: Joost De Cock Date: Wed, 28 Sep 2022 18:36:45 +0200 Subject: [PATCH 43/46] fix(shared): Also show logs from gathering render props --- sites/shared/components/workbench/logs.js | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/sites/shared/components/workbench/logs.js b/sites/shared/components/workbench/logs.js index c06eb4598db..fba55cbd8bb 100644 --- a/sites/shared/components/workbench/logs.js +++ b/sites/shared/components/workbench/logs.js @@ -96,12 +96,16 @@ const StoreLogs = ({ logs, units }) => ( ) -const Logs = (props) => ( - `Set ${i}`)].join(',')}> - {[props.draft.store, ...props.draft.setStores].map((store, i) => ( - -) +const Logs = (props) => { + const renderProps = props.draft.getRenderProps() + + return ( +- ))} - `Set ${i}`)].join(',')}> + {[props.draft.store, ...props.draft.setStores].map((store, i) => ( + + ) +} export default Logs From 27c12f77f5932a9abf83d5245a2f3880a1eeda14 Mon Sep 17 00:00:00 2001 From: Joost De Cock+ ))} + Date: Wed, 28 Sep 2022 18:47:34 +0200 Subject: [PATCH 44/46] fix(hugo): Fixed invalid dependency config --- designs/hugo/src/front.mjs | 4 +--- designs/hugo/src/pocket.mjs | 2 +- designs/hugo/src/pocketfacing.mjs | 1 - 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/designs/hugo/src/front.mjs b/designs/hugo/src/front.mjs index 3fcef579843..7ab6591ea44 100644 --- a/designs/hugo/src/front.mjs +++ b/designs/hugo/src/front.mjs @@ -89,9 +89,7 @@ function hugoFront({ .line(points.raglanTipFront) .join(neckOpeningParts[0].reverse()) paths.saBase.hide() - paths.seam = paths.saBase.clone().close().attr('class', 'fabric') - // FIXME: This pocket path is not getting set on the paths object - // It's something to do with the paths proxy which -- I assume -- is proxying the wrong object? + paths.seam = paths.saBase.clone().unhide().close().attr('class', 'fabric') paths.pocket = new Path() .move(points.pocketHem) .line(points.pocketTip) diff --git a/designs/hugo/src/pocket.mjs b/designs/hugo/src/pocket.mjs index 8ef02ff8dc5..1aae397d7e6 100644 --- a/designs/hugo/src/pocket.mjs +++ b/designs/hugo/src/pocket.mjs @@ -101,6 +101,6 @@ function hugoPocket({ export const pocket = { name: 'hugo.pocket', from: front, - hideDependencies: true, + // hideDependencies: true, draft: hugoPocket, } diff --git a/designs/hugo/src/pocketfacing.mjs b/designs/hugo/src/pocketfacing.mjs index e8f5388e608..c2ab9853e5a 100644 --- a/designs/hugo/src/pocketfacing.mjs +++ b/designs/hugo/src/pocketfacing.mjs @@ -47,6 +47,5 @@ function hugoPocketFacing({ sa, points, Path, paths, complete, paperless, macro, export const pocketFacing = { name: 'hugo.pocketFacing', from: pocket, - hideDependencies: true, draft: hugoPocketFacing, } From 9cc97ab164eb0c182df05cbceeef8de8c81237fc Mon Sep 17 00:00:00 2001 From: Joost De Cock Date: Wed, 28 Sep 2022 18:50:12 +0200 Subject: [PATCH 45/46] feat(workbench): Added logging of render props --- .../components/workbench/menu/xray/log.js | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/sites/shared/components/workbench/menu/xray/log.js b/sites/shared/components/workbench/menu/xray/log.js index 8d5ef81e6da..308804dd5c0 100644 --- a/sites/shared/components/workbench/menu/xray/log.js +++ b/sites/shared/components/workbench/menu/xray/log.js @@ -1,7 +1,7 @@ import { Chevron } from 'shared/components/navigation/primary.js' import { Ul, Li, Details, Summary, SumButton, SumDiv, Deg } from 'shared/components/workbench/menu' -const ConsoleLog = props => ( +const ConsoleLog = (props) => ( @@ -12,13 +12,16 @@ const ConsoleLog = props => (
- {['designConfig', 'patternConfig', 'gist', 'draft'].map(it => ( + {['designConfig', 'patternConfig', 'gist', 'draft', 'renderProps'].map((it) => (
- -
{ - if (it === 'designConfig') return console.log(props.design.designConfig) - if (it === 'patternConfig') return console.log(props.design.patternConfig) - return console.log(props[it]) - }}> + { + if (it === 'designConfig') return console.log(props.design.designConfig) + if (it === 'patternConfig') return console.log(props.design.patternConfig) + if (it === 'renderProps') return console.log(props.draft.getRenderProps()) + return console.log(props[it]) + }} + > {it} From 47c6997d3a2efff33adb194195182ede89bfaba0 Mon Sep 17 00:00:00 2001 From: Joost De Cock Date: Wed, 28 Sep 2022 18:53:13 +0200 Subject: [PATCH 46/46] fix(workbench): Wrapping for log lines --- sites/shared/components/workbench/logs.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sites/shared/components/workbench/logs.js b/sites/shared/components/workbench/logs.js index fba55cbd8bb..9d021086271 100644 --- a/sites/shared/components/workbench/logs.js +++ b/sites/shared/components/workbench/logs.js @@ -57,7 +57,7 @@ export const LogGroup = ({ type = 'info', logs = [], units = 'metric' }) => {logs.map((log, i) => ( {i} -+