1
0
Fork 0

Added @freesewing/utils

This commit is contained in:
Joost De Cock 2019-04-27 12:21:14 +02:00
parent d8cc1f76f3
commit e7b7c5a7dd
18 changed files with 393 additions and 0 deletions

98
packages/utils/README.md Normal file
View file

@ -0,0 +1,98 @@
> **Note**: This is part of version 2 of FreeSewing.
> It is a work in progress, and not ready for prime-time yet
>
> For all questions, please come say hello in [our chatroom on Gitter](https://gitter.im/).
<p align="center"><a title="Go to freesewing.org" href="https://freesewing.org/"><img src="https://freesewing.org/img/logo/black.svg" align="center" width="150px" alt="Freesewing logo"/></a></p>
<p align="center">FreeSewing is a free and open source library for made-to-measure sewing patterns</p>
<p align='center'><a
href="https://www.npmjs.com/package/@freesewing/utils"
title="@freesewing/utils on NPM"
><img src="https://img.shields.io/npm/v/freesewing.svg"
alt="@freesewing/utils on NPM"/>
</a><a
href="https://opensource.org/licenses/MIT"
title="License: MIT"
><img src="https://img.shields.io/npm/l/freesewing.svg?label=License"
alt="License: MIT"/>
</a><a
href="https://github.com/freesewing/freesewing/issues?q=is%3Aissue+is%3Aopen+label%3Apkg%3Autils"
title="Open issues tagged pkg:utils"
><img src="https://img.shields.io/github/issues/freesewing/freesewing/pkg:utils.svg?label=Issues"
alt="Open issues tagged pkg:utils"/>
</a></p><p align='center'><a
href="https://twitter.com/freesewing_org"
title="Follow @freesewing_org on Twitter"
><img src="https://img.shields.io/badge/%F3%A0%80%A0-Follow%20us-blue.svg?logo=twitter&logoColor=white&logoWidth=15"
alt="Follow @freesewing_org on Twitter"/>
</a><a
href="https://gitter.im/freesewing/freesewing"
title="Chat with us on Gitter"
><img src="https://img.shields.io/badge/%F3%A0%80%A0-Chat%20with%20us-CA0547.svg?logo=gitter&logoColor=white&logoWidth=15"
alt="Chat with us on Gitter"/>
</a><a
href="https://freesewing.org/patrons/join"
title="Become a FreeSewing Patron"
><img src="https://img.shields.io/badge/%F3%A0%80%A0-Support%20us-blueviolet.svg?logo=cash-app&logoColor=white&logoWidth=15"
alt="Become a FreeSewing Patron"/>
</a><a
href="https://instagram.com/freesewing_org"
title="Follow @freesewing_org on Twitter"
><img src="https://img.shields.io/badge/%F3%A0%80%A0-Follow%20us-E4405F.svg?logo=instagram&logoColor=white&logoWidth=15"
alt="Follow @freesewing_org on Twitter"/>
</a></p>
# @freesewing/utils
A collection of utilities shared across freesewing frontend projects
## 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).

View file

@ -0,0 +1,46 @@
{
"name": "@freesewing/utils",
"version": "0.33.0",
"description": "A collection of utilities shared across freesewing frontend projects",
"author": "Joost De Cock <joost@decock.org> (https://github.com/joostdecock)",
"homepage": "https://freesewing.org/",
"repository": "github:freesewing/freesewing",
"license": "MIT",
"bugs": {
"url": "https://github.com/freesewing/freesewing/issues"
},
"keywords": [
"freesewing",
"design",
"diy",
"fashion",
"made to measure",
"parametric design",
"sewing"
],
"main": "dist/index.js",
"module": "dist/index.mjs",
"scripts": {
"clean": "rimraf ../../dist/utils",
"nodebuild": "BABEL_ENV=production rollup -c -o ../../dist/utils/index.js -f cjs",
"modulebuild": "BABEL_ENV=production rollup -c -o ../../dist/utils/index.mjs -f es",
"build": "npm run clean && npm run nodebuild && npm run modulebuild",
"test": "echo \"utils: No tests configured. Perhaps you'd like to do this?\" && exit 0",
"pubtest": "npm publish --registry http://localhost:6662"
},
"peerDependencies": {},
"dependencies": {},
"devDependencies": {},
"files": [
"../../dist/packages/utils/*",
"README.md",
"package.json"
],
"publishConfig": {
"access": "public"
},
"engines": {
"node": ">=8.0.0",
"npm": ">=5"
}
}

View file

@ -0,0 +1,29 @@
import babel from "rollup-plugin-babel";
import resolve from "rollup-plugin-node-resolve";
import json from "rollup-plugin-json";
import minify from "rollup-plugin-babel-minify";
import yaml from "rollup-plugin-yaml";
import peerDepsExternal from "rollup-plugin-peer-deps-external";
import { name, version, description, author, license } from "./package.json";
export default {
input: "src/index.js",
output: {
sourcemap: true
},
plugins: [
peerDepsExternal(),
resolve({ modulesOnly: true }),
json(),
yaml(),
babel({
exclude: "node_modules/**",
plugins: ["@babel/plugin-proposal-object-rest-spread"]
}),
minify({
comments: false,
sourceMap: true,
banner: `/**\n * ${name} | v${version}\n * ${description}\n * (c) ${new Date().getFullYear()} ${author}\n * @license ${license}\n */`
})
]
};

View file

@ -0,0 +1,3 @@
const cloneObject = src => Object.assign({}, src);
export default cloneObject;

View file

@ -0,0 +1,15 @@
const defaultGist = {
settings: {
embed: true,
sa: 0,
complete: true,
paperless: false,
locale: "en",
units: "metric",
margin: 2,
measurements: {},
options: {}
}
};
export default defaultGist;

View file

@ -0,0 +1,6 @@
const defaultSa = {
imperial: 15.875,
metric: 10
};
export default defaultSa;

View file

@ -0,0 +1,17 @@
const formatImperial = (
neg,
inch,
numo = false,
deno = false,
format = "html"
) => {
if (format === "html") {
if (numo) return `<span>${neg}${inch}<sup>${numo}</sup>/<sub>${deno}</sub></span>`;
else return `<span>{neg}{inch}</span>`;
} else {
if (numo) return `${neg}${inch}`;
else return `${neg}${inch} ${numo}/${deno}`;
}
};
export default formatImperial;

View file

@ -0,0 +1,43 @@
import roundMm from "./roundMm";
import formatImperial from "./formatImperial";
const formatMm = (val, units, format = "html") => {
val = roundMm(val);
let H = format === "html" ? true : false;
if (units === "imperial") {
if (val == 0) return formatImperial("", 0, false, false, format);
let negative = "";
let inches = "";
let rest = "";
let fraction = val / 25.4;
if (fraction < 0) {
fraction = fraction * -1;
negative = "-";
}
if (Math.abs(fraction) < 1) rest = fraction;
else {
inches = Math.floor(fraction);
rest = fraction - inches;
}
let fraction128 = Math.round(rest * 128);
if (fraction128 == 0) return formatImperial(negative, inches);
if (fraction128 % 64 == 0)
return formatImperial(negative, inches, fraction128 / 64, 2);
if (fraction128 % 32 == 0)
return formatImperial(negative, inches, fraction128 / 32, 4);
if (fraction128 % 16 == 0)
return formatImperial(negative, inches, fraction128 / 16, 8);
if (fraction128 % 8 == 0)
return formatImperial(negative, inches, fraction128 / 8, 16);
if (fraction128 % 4 == 0)
return formatImperial(negative, inches, fraction128 / 4, 32);
if (fraction128 % 2 == 0)
return formatImperial(negative, inches, fraction128 / 2, 64);
return negative + fraction;
} else {
if (format === "html") return roundMm(val / 10) + "cm";
else return roundMm(val / 10);
}
};
export default formatMm;

View file

@ -0,0 +1,29 @@
import defaultGist from "./defaultGist";
import optionDefault from "./optionDefault";
const gistDefaults = (config, gist = false) => {
if (!gist) gist = defaultGist;
let options = {};
for (let option of Object.keys(config.options)) {
if (
typeof gist.options !== "undefined" &&
typeof gist.options[option] !== undefined
)
options[option] = gist.options[option];
else options[option] = optionDefault(config.options[option]);
}
delete gist.options;
let settings = JSON.parse(JSON.stringify(defaultGist.settings));
delete settings.locale;
delete settings.units;
for (let setting of Object.keys(settings)) {
if (typeof gist.settings[setting] !== "undefined") {
settings[setting] = gist.settings[setting];
}
}
settings.options = options;
return settings;
};
export default gistDefaults;

View file

@ -0,0 +1,14 @@
export { default as smallestImperialStep } from "./smallestImperialStep";
export { default as roundMm } from "./roundMm";
export { default as roundMmDown } from "./roundMmDown";
export { default as roundMmUp } from "./roundMmUp";
export { default as formatImperial } from "./formatImperial";
export { default as formatMm } from "./formatMm";
export { default as defaultSa } from "./defaultSa";
export { default as sliderStep } from "./sliderStep";
export { default as optionType } from "./optionType";
export { default as defaultGist } from "./defaultGist";
export { default as gistDefaults } from "./gistDefaults";
export { default as optionDefault } from "./optionDefault";
export { default as storage } from "./storage";
export { default as cloneObject } from "./cloneObject";

View file

@ -0,0 +1,17 @@
import optionType from "./optionType";
const optionDefault = option => {
let type = optionType(option);
switch (optionType(option)) {
case "constant":
return option;
break;
case "list":
return option.dflt;
break;
default:
return option[type];
}
};
export default optionDefault;

View file

@ -0,0 +1,15 @@
const optionType = option => {
if (typeof option === "object") {
if (typeof option.pct !== "undefined") return "pct";
if (typeof option.mm !== "undefined") return "mm";
if (typeof option.deg !== "undefined") return "deg";
if (typeof option.count !== "undefined") return "count";
if (typeof option.bool !== "undefined") return "bool";
if (typeof option.list !== "undefined") return "list";
return "unknown";
}
return "constant";
};
export default optionType;

View file

@ -0,0 +1,8 @@
const roundMm = (val, units) => {
if (units === "imperial")
return Math.round(val * 1000000) / 1000000;
else
return Math.round(val * 10) / 10;
};
export default roundMm;

View file

@ -0,0 +1,10 @@
import smallestImperialStep from "./smallestImperialStep";
const roundMmDown = (val, units) => {
if (units === "imperial")
return val - (val % smallestImperialStep);
else
return Math.floor(val * 10) / 10;
};
export default roundMmDown;

View file

@ -0,0 +1,10 @@
import smallestImperialStep from "./smallestImperialStep";
const roundMmUp = (val, units) => {
if (units === "imperial")
return val - (val % smallestImperialStep);
else
return Math.ceil(val * 10) / 10;
};
export default roundMmUp;

View file

@ -0,0 +1,6 @@
const sliderStep = {
metric: 0.1,
imperial: 0.396875
};
export default sliderStep;

View file

@ -0,0 +1,3 @@
const smallestImperialStep = 0.396875;
export default smallestImperialStep;

View file

@ -0,0 +1,24 @@
const storage = {
set: (key, value, raw) => {
if (typeof localStorage === "undefined")
throw(new Error("No localStorage support. And we need it. Bailing out."));
const _key = "fs_" + key;
if (typeof value === "undefined" || value === null)
localStorage.removeItem(_key);
else localStorage.setItem(_key, raw ? value : JSON.stringify(value));
return value;
},
get: (key, raw) => {
if (typeof localStorage === "undefined")
throw(new Error("No localStorage support. And we need it. Bailing out."));
const value = localStorage.getItem("fs_"+key);
return raw ? value : JSON.parse(value);
}
}
export default storage;