better-color-tools
Advanced tools
Comparing version 0.0.0 to 0.0.1
@@ -21,6 +21,4 @@ import NP from 'number-precision'; | ||
.map((v, n) => { | ||
// r, g, b | ||
if (n < 3) | ||
return v.toString(16); | ||
// alpha | ||
return leftPad(v.toString(16), 2); | ||
return v < 1 ? NP.round(255 * v, 0).toString(16) : ''; | ||
@@ -31,4 +29,8 @@ }) | ||
get hexVal() { | ||
const [r, g, b, a] = color; | ||
return parseInt(`0x${leftPad(r.toString(16))}${leftPad(g.toString(16))}${leftPad(b.toString(16))}${a < 1 ? leftPad((256 * a).toString(16)) : ''}`, 16); | ||
const hex = color.map((v, n) => { | ||
if (n < 3) | ||
return leftPad(v.toString(16), 2); | ||
return v < 1 ? leftPad((256 * v).toString(16), 2) : ''; | ||
}); | ||
return parseInt(`0x${hex.join('')}`, 16); | ||
}, | ||
@@ -219,6 +221,5 @@ get rgb() { | ||
let [H, S, L, A] = hsl; | ||
H = H % 360; // allow greater-than-360 values | ||
const H1 = H / 60; | ||
H = Math.abs(H % 360); // allow < 0 and > 360 | ||
const C = (1 - Math.abs(2 * L - 1)) * S; | ||
const X = C * (1 - Math.abs((H1 % 2) - 1)); | ||
const X = C * (1 - Math.abs(((H / 60) % 2) - 1)); | ||
let R = 0; | ||
@@ -284,2 +285,5 @@ let G = 0; | ||
} | ||
while (H < 0) { | ||
H += 360; | ||
} | ||
} | ||
@@ -286,0 +290,0 @@ // Saturation |
{ | ||
"name": "better-color-tools", | ||
"description": "Better color manipulation for Sass and JavaScript / TypeScript.", | ||
"version": "0.0.0", | ||
"version": "0.0.1", | ||
"author": { | ||
@@ -30,2 +30,3 @@ "name": "Drew Powers", | ||
"build": "rm -rf dist && tsc", | ||
"changeset": "changeset", | ||
"dev": "tsc -w", | ||
@@ -39,2 +40,3 @@ "lint": "eslint \"**/*.{js,ts}\"", | ||
"devDependencies": { | ||
"@changesets/cli": "^2.18.1", | ||
"@types/node": "^16.11.11", | ||
@@ -41,0 +43,0 @@ "@typescript-eslint/eslint-plugin": "^5.5.0", |
@@ -65,2 +65,5 @@ # better-color-tools | ||
⚠️ Still in development. It’s important to note that Sass’ new [`color.scale()`][sass-color-scale] tool is pretty advanced, and is actually good way to lighten / darken colors (previous methods have been lacking). Right now Sass’ `color.scale()` produces | ||
better results than this library, and I’m not happy with that 🙂. | ||
```scss | ||
@@ -80,2 +83,4 @@ @use 'better-color-tools' as color; | ||
[View comparison](#mix) (Sass’ mix function is a generic implementation of mixing you’ll find with other libraries in JavaScript) | ||
```ts | ||
@@ -90,2 +95,4 @@ import color from 'better-color-tools'; | ||
⚠️ In development ([see note](#lighten--darken)) | ||
```ts | ||
@@ -105,6 +112,24 @@ import color from 'better-color-tools'; | ||
Regarding HSL, any translation to/from HSL is “lossy” and imperfect, so any library—including this one—is subject to rounding errors. But this library does a little extra work to generate better accuracy than other libraries through things like avoiding | ||
JavaScript floats as much as possible. This library also uses [number-precision] to keep HSL values clean without losing accuracy (e.g. ✅ `hsl(90.3, 100%, 100%)` rather than ❌ `hsl(90.30000000000000004, 100%, 100%)`). | ||
It’s in HSL handling where approaches differ. Because HSL is a smaller color space than RGB, in order to use it, it **requires some use of decimals.** So any library that rounds out-of-the-box will yield different results. | ||
Compare this library to [color-convert], converting from RGB -> HSL -> RGB | ||
```ts | ||
const original = [167, 214, 65]; | ||
color.from(color.from(original).hsl).rgb; // ✅ [167, 214, 65] | ||
convert.hsl.rgb(convert.rgb.hsl(...original)); // ❌ [168, 215, 66] | ||
``` | ||
2 things are the cause of the difference: | ||
1. **JavaScript’s rounding errors.** Many implementations are borrowed from other languages that don’t have JavaScript’s “[bad math][number-precision].” This implementation was written with JavaScript in mind and minimizes decimal calculations through | ||
tricks like normalizing to `255` rather than `1.` | ||
2. **No rounding by default.** As stated before, **HSL requires decimal places** to produce the full RGB color space. When a library rounds by default it will always make HSL conversions inaccurate. This is a known limitation, so libraries like | ||
color-convert will allow you to use decimals. But that generates numbers like `hsl(78.9261744966443, 64.50216450216452%, 54.70588235294118%)`. Compare that to better-color-tools: `hsl(78.926, 64.5%, 54.7%)`. Why do you have to choose between accuracy | ||
and utility? | ||
#### Usage | ||
```ts | ||
import color from 'better-color-tools'; | ||
@@ -136,5 +161,6 @@ | ||
[color]: https://www.npmjs.com/package/color | ||
[color-convert]: https://github.com/Qix-/color-convert | ||
[computer-color]: https://www.youtube.com/watch?v=LKnqECcg6Gw&vl=en | ||
[number-precision]: https://github.com/nefe/number-precision | ||
[sass-color]: https://sass-lang.com/documentation/modules/color | ||
[number-precision]: https://www.npmjs.com/package/number-precision | ||
[sass-color-scale]: https://sass-lang.com/documentation/modules/color#scale |
@@ -30,5 +30,3 @@ import NP from 'number-precision'; | ||
.map((v, n) => { | ||
// r, g, b | ||
if (n < 3) return v.toString(16); | ||
// alpha | ||
if (n < 3) return leftPad(v.toString(16), 2); | ||
return v < 1 ? NP.round(255 * v, 0).toString(16) : ''; | ||
@@ -39,4 +37,7 @@ }) | ||
get hexVal(): number { | ||
const [r, g, b, a] = color; | ||
return parseInt(`0x${leftPad(r.toString(16))}${leftPad(g.toString(16))}${leftPad(b.toString(16))}${a < 1 ? leftPad((256 * a).toString(16)) : ''}`, 16); | ||
const hex = color.map((v, n) => { | ||
if (n < 3) return leftPad(v.toString(16), 2); | ||
return v < 1 ? leftPad((256 * v).toString(16), 2) : ''; | ||
}); | ||
return parseInt(`0x${hex.join('')}`, 16); | ||
}, | ||
@@ -221,7 +222,6 @@ get rgb(): string { | ||
let [H, S, L, A] = hsl; | ||
H = H % 360; // allow greater-than-360 values | ||
H = Math.abs(H % 360); // allow < 0 and > 360 | ||
const H1 = H / 60; | ||
const C = (1 - Math.abs(2 * L - 1)) * S; | ||
const X = C * (1 - Math.abs((H1 % 2) - 1)); | ||
const X = C * (1 - Math.abs(((H / 60) % 2) - 1)); | ||
@@ -290,2 +290,5 @@ let R = 0; | ||
} | ||
while (H < 0) { | ||
H += 360; | ||
} | ||
} | ||
@@ -292,0 +295,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
135821
16
162
12
1165