-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
✨ Added Support for Client Side Usage
1 parent
8136a2a
commit c929f82
Showing
29 changed files
with
759 additions
and
727 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,5 @@ | ||
{ | ||
"env": { | ||
"development": { | ||
"presets": [ | ||
"presets": [ | ||
"env" | ||
], | ||
"plugins": [ | ||
"add-module-exports" | ||
] | ||
}, | ||
"production": { | ||
"presets": [ | ||
[ | ||
"env", | ||
"minify" | ||
] | ||
], | ||
"plugins": [ | ||
"add-module-exports" | ||
] | ||
} | ||
} | ||
] | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,44 +1,11 @@ | ||
# Logs | ||
logs | ||
*.log | ||
npm-debug.log* | ||
|
||
# Runtime data | ||
pids | ||
*.pid | ||
*.seed | ||
|
||
# Directory for instrumented libs generated by jscoverage/JSCover | ||
lib-cov | ||
|
||
# Coverage directory used by tools like istanbul | ||
coverage | ||
|
||
# nyc test coverage | ||
.nyc_output | ||
|
||
# Compiled binary addons (http://nodejs.org/api/addons.html) | ||
build/Release | ||
|
||
# Dependency directories | ||
node_modules | ||
jspm_packages | ||
|
||
# Optional npm cache directory | ||
.npm | ||
|
||
# Optional REPL history | ||
.node_repl_history | ||
|
||
# Editors | ||
.idea | ||
|
||
# Lib | ||
lib | ||
.DS_Store | ||
|
||
# npm package lock | ||
package-lock.json | ||
yarn.lock | ||
|
||
others | ||
.DS_Store | ||
yarn.lock |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"reporter": [ | ||
"json-summary", | ||
"html", | ||
"text" | ||
], | ||
"lines" : 100 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,61 +1,60 @@ | ||
{ | ||
"name": "matercolors", | ||
"version": "1.1.1", | ||
"version": "1.2.0", | ||
"description": "A tiny, zero-dependency libary for building harmonious material palettes for any color.", | ||
"main": "./src/index.js", | ||
"type": "module", | ||
"main": "dist/index.js", | ||
"umd:main": "dist/index.umd.js", | ||
"module": "dist/index.mjs", | ||
"esmodule": "dist/index.modern.js", | ||
"source": "src/index.js", | ||
"scripts": { | ||
"clean": "rimraf lib", | ||
"test": "npm run lint && npm run cover", | ||
"test:prod": "cross-env BABEL_ENV=production npm run test", | ||
"test:only": "mocha --require babel-core/register --require babel-polyfill --recursive", | ||
"test:watch": "npm test -- --watch", | ||
"test:examples": "node examples/index.js", | ||
"cover": "nyc --check-coverage npm run test:only", | ||
"lint": "eslint src test", | ||
"lint:fix": "eslint src test --fix", | ||
"build": "cross-env BABEL_ENV=production babel src --out-dir lib", | ||
"prepublish": "npm run clean && npm run lint && npm run test" | ||
"dev": "microbundle watch", | ||
"build": "microbundle --name Matercolor --compress --raw true", | ||
"lint": "standard --fix", | ||
"test": "ava", | ||
"coverage": "nyc npm run test" | ||
}, | ||
"ava": { | ||
"require": [ | ||
"esm" | ||
], | ||
"files": [ | ||
"test/**/*" | ||
], | ||
"concurrency": 5, | ||
"failFast": true, | ||
"failWithoutAssertions": false, | ||
"verbose": true | ||
}, | ||
"files": [ | ||
"lib", | ||
"src" | ||
"dist/*" | ||
], | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/arvindcheenu/Matercolors.git" | ||
}, | ||
"keywords": [ | ||
"npm", | ||
"material", | ||
"color", | ||
"palette", | ||
"design", | ||
"node", | ||
"javascript" | ||
"javascript", | ||
"browser", | ||
"generator" | ||
], | ||
"author": "Arvind Srinivasan <arvind@cheenu.net>", | ||
"license": "MIT", | ||
"license": "Apache-2.0", | ||
"bugs": { | ||
"url": "https://github.com/arvindcheenu/Matercolors/issues" | ||
}, | ||
"homepage": "https://github.com/arvindcheenu/Matercolors#readme", | ||
"devDependencies": { | ||
"babel-cli": "^6.26.0", | ||
"babel-eslint": "^10.0.1", | ||
"babel-plugin-add-module-exports": "^1.0.0", | ||
"babel-polyfill": "^6.26.0", | ||
"babel-preset-env": "^1.6.1", | ||
"babel-preset-minify": "^0.5.0", | ||
"chai": "^4.1.2", | ||
"cross-env": "^5.1.3", | ||
"eslint": "^5.16.0", | ||
"eslint-config-airbnb": "^17.1.0", | ||
"eslint-plugin-import": "^2.22.0", | ||
"eslint-plugin-jsx-a11y": "^6.0.2", | ||
"eslint-plugin-react": "^7.20.3", | ||
"mocha": "^6.1.3", | ||
"ava": "^3.13.0", | ||
"babel-preset-env": "^1.7.0", | ||
"esm": "^3.2.25", | ||
"microbundle": "^0.12.4", | ||
"nyc": "^15.1.0", | ||
"rimraf": "^2.6.2" | ||
}, | ||
"dependencies": {} | ||
"standard": "^14.3.4" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,134 +1,134 @@ | ||
/* eslint-disable no-bitwise */ | ||
export function RGBToHSL(rgb) { | ||
const r = rgb.r / 255; | ||
const g = rgb.g / 255; | ||
const b = rgb.b / 255; | ||
const cmin = Math.min(r, g, b); | ||
const cmax = Math.max(r, g, b); | ||
const delta = cmax - cmin; | ||
let h = 0; | ||
let s = 0; | ||
let l = 0; | ||
if (delta === 0) h = 0; | ||
else if (cmax === r) h = ((g - b) / delta) % 6; | ||
else if (cmax === g) h = (b - r) / delta + 2; | ||
else h = (r - g) / delta + 4; | ||
h = Math.round(h * 60); | ||
if (h < 0) h += 360; | ||
l = (cmax + cmin) / 2; | ||
s = delta === 0 ? 0 : delta / (1 - Math.abs(2 * l - 1)); | ||
s = +(s * 100).toFixed(1); | ||
l = +(l * 100).toFixed(1); | ||
export function RGBToHSL (rgb) { | ||
const r = rgb.r / 255 | ||
const g = rgb.g / 255 | ||
const b = rgb.b / 255 | ||
const cmin = Math.min(r, g, b) | ||
const cmax = Math.max(r, g, b) | ||
const delta = cmax - cmin | ||
let h = 0 | ||
let s = 0 | ||
let l = 0 | ||
if (delta === 0) h = 0 | ||
else if (cmax === r) h = ((g - b) / delta) % 6 | ||
else if (cmax === g) h = (b - r) / delta + 2 | ||
else h = (r - g) / delta + 4 | ||
h = Math.round(h * 60) | ||
if (h < 0) h += 360 | ||
l = (cmax + cmin) / 2 | ||
s = delta === 0 ? 0 : delta / (1 - Math.abs(2 * l - 1)) | ||
s = +(s * 100).toFixed(1) | ||
l = +(l * 100).toFixed(1) | ||
return { | ||
h, | ||
s, | ||
l, | ||
string: `hsl(${h},${s}%,${l}%)`, | ||
}; | ||
string: `hsl(${h},${s}%,${l}%)` | ||
} | ||
} | ||
export function RGBToCYMK(rgb) { | ||
const r = rgb.r / 255; | ||
const g = rgb.g / 255; | ||
const b = rgb.b / 255; | ||
let k = Math.min(1 - r, 1 - g, 1 - b); | ||
const c = parseFloat((((1 - r - k) / (1 - k) || 0) * 100).toFixed(4)); | ||
const m = parseFloat((((1 - g - k) / (1 - k) || 0) * 100).toFixed(4)); | ||
const y = parseFloat((((1 - b - k) / (1 - k) || 0) * 100).toFixed(4)); | ||
k *= 100; | ||
k = parseFloat(k.toFixed(4)); | ||
export function RGBToCYMK (rgb) { | ||
const r = rgb.r / 255 | ||
const g = rgb.g / 255 | ||
const b = rgb.b / 255 | ||
let k = Math.min(1 - r, 1 - g, 1 - b) | ||
const c = parseFloat((((1 - r - k) / (1 - k) || 0) * 100).toFixed(4)) | ||
const m = parseFloat((((1 - g - k) / (1 - k) || 0) * 100).toFixed(4)) | ||
const y = parseFloat((((1 - b - k) / (1 - k) || 0) * 100).toFixed(4)) | ||
k *= 100 | ||
k = parseFloat(k.toFixed(4)) | ||
return { | ||
c, | ||
y, | ||
m, | ||
k, | ||
string: `cymk(${c}%,${y}%,${m}%,${k}%)`, | ||
}; | ||
string: `cymk(${c}%,${y}%,${m}%,${k}%)` | ||
} | ||
} | ||
export function hexToRgba(hex) { | ||
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); | ||
export function hexToRgba (hex) { | ||
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex) | ||
return result | ||
? { | ||
r: parseInt(result[1], 16), | ||
g: parseInt(result[2], 16), | ||
b: parseInt(result[3], 16), | ||
b: parseInt(result[3], 16) | ||
} | ||
: {}; | ||
: {} | ||
} | ||
export function normalizeRGB(rgbObj) { | ||
export function normalizeRGB (rgbObj) { | ||
return { | ||
red: rgbObj.r / 255, | ||
green: rgbObj.g / 255, | ||
blue: rgbObj.b / 255, | ||
alpha: 1, | ||
}; | ||
alpha: 1 | ||
} | ||
} | ||
export function componentToHex(c) { | ||
const hex = c.toString(16); | ||
return hex.length === 1 ? `0${hex}` : hex; | ||
export function componentToHex (c) { | ||
const hex = c.toString(16) | ||
return hex.length === 1 ? `0${hex}` : hex | ||
} | ||
export function rgbToHex(r, g, b) { | ||
return `#${componentToHex(r)}${componentToHex(g)}${componentToHex(b)}`; | ||
export function rgbToHex (r, g, b) { | ||
return `#${componentToHex(r)}${componentToHex(g)}${componentToHex(b)}` | ||
} | ||
export function getContrastText({ r, g, b }, threshold) { | ||
const contrast = (Math.round(r * 299) + Math.round(g * 587) + Math.round(b * 114)) / 1000; | ||
return contrast >= threshold ? 'black' : 'white'; | ||
export function getContrastText ({ r, g, b }, threshold) { | ||
const contrast = (Math.round(r * 299) + Math.round(g * 587) + Math.round(b * 114)) / 1000 | ||
return contrast >= threshold ? 'black' : 'white' | ||
} | ||
|
||
export function getComplementary(hex) { | ||
const rgb = hexToRgba(hex); | ||
let r = rgb.r / 255.0; | ||
let g = rgb.g / 255.0; | ||
let b = rgb.b / 255.0; | ||
const max = Math.max(r, g, b); | ||
const min = Math.min(r, g, b); | ||
let h; | ||
let s; | ||
const l = (max + min) / 2.0; | ||
export function getComplementary (hex) { | ||
const rgb = hexToRgba(hex) | ||
let r = rgb.r / 255.0 | ||
let g = rgb.g / 255.0 | ||
let b = rgb.b / 255.0 | ||
const max = Math.max(r, g, b) | ||
const min = Math.min(r, g, b) | ||
let h | ||
let s | ||
const l = (max + min) / 2.0 | ||
if (max === min) { | ||
h = 0; s = 0; // achromatic | ||
h = 0; s = 0 // achromatic | ||
} else { | ||
const d = max - min; | ||
s = l > 0.5 ? d / (2.0 - max - min) : d / (max + min); | ||
const d = max - min | ||
s = l > 0.5 ? d / (2.0 - max - min) : d / (max + min) | ||
if (max === r && g >= b) { | ||
h = 1.0472 * (g - b) / d; | ||
h = 1.0472 * (g - b) / d | ||
} else if (max === r && g < b) { | ||
h = 1.0472 * (g - b) / d + 6.2832; | ||
h = 1.0472 * (g - b) / d + 6.2832 | ||
} else if (max === g) { | ||
h = 1.0472 * (b - r) / d + 2.0944; | ||
h = 1.0472 * (b - r) / d + 2.0944 | ||
} else if (max === b) { | ||
h = 1.0472 * (r - g) / d + 4.1888; | ||
h = 1.0472 * (r - g) / d + 4.1888 | ||
} | ||
} | ||
h = h / 6.2832 * 360.0 + 0; | ||
h = h / 6.2832 * 360.0 + 0 | ||
// Shift hue to opposite side of wheel and convert to [0-1] value | ||
h += 180; | ||
h += 180 | ||
if (h > 360) { | ||
h -= 360; | ||
h -= 360 | ||
} | ||
h /= 360; | ||
h /= 360 | ||
if (s === 0) { | ||
r = l; g = l; b = l; // achromatic | ||
r = l; g = l; b = l // achromatic | ||
} else { | ||
const hue2rgb = function hue2rgb(p, q, T) { | ||
let t = T; | ||
if (t < 0) t += 1; | ||
if (t > 1) t -= 1; | ||
if (t < 1 / 6) return p + (q - p) * 6 * t; | ||
if (t < 1 / 2) return q; | ||
if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; | ||
return p; | ||
}; | ||
const q = l < 0.5 ? l * (1 + s) : l + s - l * s; | ||
const p = 2 * l - q; | ||
const hue2rgb = function hue2rgb (p, q, T) { | ||
let t = T | ||
if (t < 0) t += 1 | ||
if (t > 1) t -= 1 | ||
if (t < 1 / 6) return p + (q - p) * 6 * t | ||
if (t < 1 / 2) return q | ||
if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6 | ||
return p | ||
} | ||
const q = l < 0.5 ? l * (1 + s) : l + s - l * s | ||
const p = 2 * l - q | ||
|
||
r = hue2rgb(p, q, h + 1 / 3); | ||
g = hue2rgb(p, q, h); | ||
b = hue2rgb(p, q, h - 1 / 3); | ||
r = hue2rgb(p, q, h + 1 / 3) | ||
g = hue2rgb(p, q, h) | ||
b = hue2rgb(p, q, h - 1 / 3) | ||
} | ||
r = Math.round(r * 255); | ||
g = Math.round(g * 255); | ||
b = Math.round(b * 255); | ||
r = Math.round(r * 255) | ||
g = Math.round(g * 255) | ||
b = Math.round(b * 255) | ||
// Convert r b and g values to hex | ||
const final = b | (g << 8) | (r << 16); | ||
return `#${(0x1000000 | final).toString(16).substring(1)}`; | ||
const final = b | (g << 8) | (r << 16) | ||
return `#${(0x1000000 | final).toString(16).substring(1)}` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,99 +1,97 @@ | ||
/* eslint-disable no-nested-ternary */ | ||
import { T } from './global.constants.js'; | ||
// Local Functions | ||
function S(a, b, c) { | ||
if (Number.isNaN(a) || a < 0 || a > b) throw new RangeError(`${a} for ${c} is not between 0 and ${b}`); | ||
function isWithinRange (num, max, term) { | ||
if (Number.isNaN(num) || num < 0 || num > max) throw new RangeError(`${num} for ${term} is not between 0 and ${max}`) | ||
} | ||
function W(a) { | ||
return a <= 0.04045 ? a / 12.92 : (((a + 0.055) / 1.055) ** 2.4); | ||
function sRGB2linear (a) { | ||
/* Send this function a decimal sRGB gamma encoded color value * | ||
* between 0.0 and 1.0, and it returns a linearized value. */ | ||
return a <= 0.04045 ? a / 12.92 : (((a + 0.055) / 1.055) ** 2.4) | ||
} | ||
function Dd(a) { | ||
const b = 6 / 29; const | ||
c = 1 / (3 * (b ** 2)); | ||
return a > (b ** 3) ? (a ** (1 / 3)) : c * a + 4 / 29; | ||
function forwardTransformer (a) { | ||
/* Computes f(t) for Forward Transformation where t is of the form A/normalized_A and the * | ||
* denominator term correspond to CIEXYZ tristimulus values of the reference white points */ | ||
const b = 6 / 29 | ||
const c = 1 / (3 * (b ** 2)) | ||
return a > (b ** 3) ? (a ** (1 / 3)) : c * a + 4 / 29 | ||
} | ||
// Exported Functions | ||
export function L(a, b, c) { | ||
return Math.min(Math.max(a, b), c); | ||
export function minOfMax (a, b, c) { | ||
return Math.min(Math.max(a, b), c) | ||
} | ||
export function Hd(a) { | ||
return a <= 0.0031308 ? 12.92 * a : 1.055 * (a ** (1 / 2.4)) - 0.055; | ||
export function linear2sRGB (a) { | ||
// Converts linear channels to their sRGB counterparts. | ||
return a <= 0.0031308 ? 12.92 * a : 1.055 * (a ** (1 / 2.4)) - 0.055 | ||
} | ||
export function Id(a) { | ||
const b = 6 / 29; const | ||
c = 3 * (b ** 2); | ||
return a > b ? (a ** 3) : c * (a - 4 / 29); | ||
export function reverseTransformer (a) { | ||
// The function for reversing transformation. | ||
const b = 6 / 29 | ||
const c = 3 * (b ** 2) | ||
return a > b ? (a ** 3) : c * (a - 4 / 29) | ||
} | ||
export function Jd(a, b) { | ||
if (Math.abs(a) < 1e-4 && Math.abs(b) < 1e-4) return 0; | ||
const A = 180 * Math.atan2(a, b) / Math.PI; | ||
return A >= 0 ? A : A + 360; | ||
export function getHueDegrees (a, b) { | ||
// This function returns Hue Degrees for given coordinates in LAB Color Space. | ||
if (Math.abs(a) < 1e-4 && Math.abs(b) < 1e-4) return 0 | ||
const A = 180 * Math.atan2(a, b) / Math.PI | ||
return A >= 0 ? A : A + 360 | ||
} | ||
export class U { | ||
constructor(a, b, c, D) { | ||
const d = D === undefined ? 1 : D; | ||
this.red = a; | ||
this.green = b; | ||
this.blue = c; | ||
this.alpha = d; | ||
S(a, 1, 'red'); | ||
S(b, 1, 'green'); | ||
S(c, 1, 'blue'); | ||
S(d, 1, 'alpha'); | ||
export class ConstrainRGBA { | ||
constructor (a, b, c, D) { | ||
const d = D === undefined ? 1 : D | ||
this.red = a | ||
this.green = b | ||
this.blue = c | ||
this.alpha = d | ||
isWithinRange(a, 1, 'red') | ||
isWithinRange(b, 1, 'green') | ||
isWithinRange(c, 1, 'blue') | ||
isWithinRange(d, 1, 'alpha') | ||
} | ||
} | ||
export class Fd { | ||
constructor(a, b, c, D) { | ||
const d = D === undefined ? 1 : D; | ||
this.g = a; | ||
this.T = b; | ||
this.hue = c; | ||
this.alpha = d; | ||
S(a, Number.MAX_VALUE, 'lightness'); | ||
S(b, Number.MAX_VALUE, 'chroma'); | ||
S(c, 360, 'hue'); | ||
S(d, 1, 'alpha'); | ||
export class ConstrainHCLA { | ||
constructor (a, b, c, D) { | ||
const d = D === undefined ? 1 : D | ||
this.g = a | ||
this.T = b | ||
this.hue = c | ||
this.alpha = d | ||
isWithinRange(a, Number.MAX_VALUE, 'lightness') | ||
isWithinRange(b, Number.MAX_VALUE, 'chroma') | ||
isWithinRange(c, 360, 'hue') | ||
isWithinRange(d, 1, 'alpha') | ||
} | ||
} | ||
export function Gd(a) { | ||
return new Fd( | ||
export function computeLABterms (a) { | ||
// Compute the Polar Parameters for Chroma (C*) and Hue (h_ab) in the CIELAB Space | ||
return new ConstrainHCLA( | ||
a.g, | ||
Math.sqrt((a.A ** 2) + (a.B ** 2)), | ||
(180 * Math.atan2(a.B, a.A) / Math.PI + 360) % 360, | ||
Math.sqrt((a.A ** 2) + (a.B ** 2)), // Chroma | ||
(180 * Math.atan2(a.B, a.A) / Math.PI + 360) % 360, // Hue | ||
a.alpha | ||
); | ||
) | ||
} | ||
export class Y { | ||
constructor(a, b, c, D) { | ||
const d = D === undefined ? 1 : D; | ||
this.g = a; | ||
this.A = b; | ||
this.B = c; | ||
this.alpha = d; | ||
S(a, Number.MAX_VALUE, 'lightness'); | ||
S(d, 1, 'alpha'); | ||
} | ||
|
||
La(a) { | ||
return ( | ||
Math.abs(this.g - a.g) < 1e-4 | ||
&& Math.abs(this.A - a.A) < 1e-4 | ||
&& Math.abs(this.B - a.B) < 1e-4 | ||
&& Math.abs(this.alpha - a.alpha) < T | ||
); | ||
export class ValidateBounds { | ||
constructor (a, b, c, D) { | ||
const d = D === undefined ? 1 : D | ||
this.g = a | ||
this.A = b | ||
this.B = c | ||
this.alpha = d | ||
isWithinRange(a, Number.MAX_VALUE, 'lightness') | ||
isWithinRange(d, 1, 'alpha') | ||
} | ||
} | ||
export function Ed(a) { | ||
const b = W(a.red); | ||
const c = W(a.green); | ||
const d = W(a.blue); | ||
const e = 0.2126729 * b + 0.7151522 * c + 0.072175 * d; | ||
return new Y( | ||
116 * Dd(e) - 16, | ||
500 | ||
* (Dd((0.4124564 * b + 0.3575761 * c + 0.1804375 * d) / 0.95047) - Dd(e)), | ||
200 | ||
* (Dd(e) - Dd((0.0193339 * b + 0.119192 * c + 0.9503041 * d) / 1.08883)), | ||
a.alpha | ||
); | ||
export function ConvertToLAB (rgb) { | ||
const red = sRGB2linear(rgb.red) | ||
const green = sRGB2linear(rgb.green) | ||
const blue = sRGB2linear(rgb.blue) | ||
const D65 = 0.2126729 * red + 0.7151522 * green + 0.072175 * blue // Reference | ||
return new ValidateBounds( | ||
116 * forwardTransformer(D65) - 16, | ||
500 * | ||
(forwardTransformer((0.4124564 * red + 0.3575761 * green + 0.1804375 * blue) / 0.95047) - forwardTransformer(D65)), | ||
200 * | ||
(forwardTransformer(D65) - forwardTransformer((0.0193339 * red + 0.119192 * green + 0.9503041 * blue) / 1.08883)), | ||
rgb.alpha | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,99 +1,98 @@ | ||
import { keys, defaultOptions } from './global.constants.js'; | ||
import { keys, defaultOptions } from './global.constants.js' | ||
import { | ||
normalizeRGB, rgbToHex, hexToRgba, RGBToCYMK, RGBToHSL, getContrastText, getComplementary | ||
} from './color.utils.js'; | ||
import { createPallete } from './goldenPalettes.js'; | ||
|
||
} from './color.utils.js' | ||
import { createPallete } from './goldenPalettes.js' | ||
export default class Matercolor { | ||
constructor(color, options) { | ||
this.color = color; | ||
const complementary = getComplementary(color); | ||
this.complementary = () => complementary; | ||
constructor (color, options) { | ||
this.color = color | ||
const complementary = getComplementary(color) | ||
this.complementary = () => complementary | ||
this.options = options | ||
? Object.assign(defaultOptions, options) | ||
: defaultOptions; | ||
const paletteObject = {}; | ||
this.palette = () => paletteObject; | ||
this.getPalette(); | ||
: defaultOptions | ||
const paletteObject = {} | ||
this.palette = () => paletteObject | ||
this.getPalette() | ||
} | ||
|
||
shades(paletteType) { | ||
shades (paletteType) { | ||
return { | ||
light: this.palette()[paletteType][this.options.light], | ||
main: this.palette()[paletteType][this.options.main], | ||
dark: this.palette()[paletteType][this.options.dark], | ||
}; | ||
dark: this.palette()[paletteType][this.options.dark] | ||
} | ||
} | ||
|
||
accents(paletteType) { | ||
accents (paletteType) { | ||
return { | ||
A100: this.palette()[paletteType].A100, | ||
A200: this.palette()[paletteType].A200, | ||
A400: this.palette()[paletteType].A400, | ||
A700: this.palette()[paletteType].A700, | ||
}; | ||
A700: this.palette()[paletteType].A700 | ||
} | ||
} | ||
|
||
getPalette() { | ||
this.palette().primary = {}; | ||
this.palette().secondary = {}; | ||
getPalette () { | ||
this.palette().primary = {} | ||
this.palette().secondary = {} | ||
const primaryPalette = createPallete( | ||
normalizeRGB(hexToRgba(this.color)) | ||
).map(u => rgbToHex( | ||
Math.round(u.red * 255), | ||
Math.round(u.green * 255), | ||
Math.round(u.blue * 255) | ||
)); | ||
)) | ||
const primaryAccents = createPallete( | ||
normalizeRGB(hexToRgba(this.color)), | ||
true | ||
).map(u => rgbToHex( | ||
Math.round(u.red * 255), | ||
Math.round(u.green * 255), | ||
Math.round(u.blue * 255) | ||
)); | ||
)) | ||
const secondaryPalette = createPallete( | ||
normalizeRGB(hexToRgba(this.complementary())) | ||
).map(u => rgbToHex( | ||
Math.round(u.red * 255), | ||
Math.round(u.green * 255), | ||
Math.round(u.blue * 255) | ||
)); | ||
)) | ||
const secondaryAccents = createPallete( | ||
normalizeRGB(hexToRgba(this.complementary())), | ||
true | ||
).map(u => rgbToHex( | ||
Math.round(u.red * 255), | ||
Math.round(u.green * 255), | ||
Math.round(u.blue * 255) | ||
)); | ||
primaryPalette.push(...primaryAccents); | ||
)) | ||
primaryPalette.push(...primaryAccents) | ||
for (let i = 0; i < keys.length; i += 1) { | ||
const colorObject = {}; | ||
colorObject.hex = primaryPalette[i]; | ||
colorObject.rgb = hexToRgba(primaryPalette[i]); | ||
colorObject.rgb.string = `rgb(${colorObject.rgb.r},${colorObject.rgb.g},${colorObject.rgb.b})`; | ||
colorObject.hsl = RGBToHSL(colorObject.rgb); | ||
colorObject.cymk = RGBToCYMK(colorObject.rgb); | ||
const colorObject = {} | ||
colorObject.hex = primaryPalette[i] | ||
colorObject.rgb = hexToRgba(primaryPalette[i]) | ||
colorObject.rgb.string = `rgb(${colorObject.rgb.r},${colorObject.rgb.g},${colorObject.rgb.b})` | ||
colorObject.hsl = RGBToHSL(colorObject.rgb) | ||
colorObject.cymk = RGBToCYMK(colorObject.rgb) | ||
colorObject.contrastText = getContrastText( | ||
colorObject.rgb, | ||
this.options.threshold | ||
); | ||
this.palette().primary[keys[i]] = colorObject; | ||
) | ||
this.palette().primary[keys[i]] = colorObject | ||
} | ||
secondaryPalette.push(...secondaryAccents); | ||
secondaryPalette.push(...secondaryAccents) | ||
for (let i = 0; i < keys.length; i += 1) { | ||
const colorObject = {}; | ||
colorObject.hex = secondaryPalette[i]; | ||
colorObject.rgb = hexToRgba(secondaryPalette[i]); | ||
colorObject.rgb.string = `rgb(${colorObject.rgb.r},${colorObject.rgb.g},${colorObject.rgb.b})`; | ||
colorObject.hsl = RGBToHSL(colorObject.rgb); | ||
colorObject.cymk = RGBToCYMK(colorObject.rgb); | ||
const colorObject = {} | ||
colorObject.hex = secondaryPalette[i] | ||
colorObject.rgb = hexToRgba(secondaryPalette[i]) | ||
colorObject.rgb.string = `rgb(${colorObject.rgb.r},${colorObject.rgb.g},${colorObject.rgb.b})` | ||
colorObject.hsl = RGBToHSL(colorObject.rgb) | ||
colorObject.cymk = RGBToCYMK(colorObject.rgb) | ||
colorObject.contrastText = getContrastText( | ||
colorObject.rgb, | ||
this.options.threshold | ||
); | ||
this.palette().secondary[keys[i]] = colorObject; | ||
) | ||
this.palette().secondary[keys[i]] = colorObject | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import test from "ava" | ||
import { RGBToHSL } from "../../src/color.utils" | ||
test('computes valid HSL if r is greatest', t => { | ||
t.deepEqual(RGBToHSL({r: 30, g: 20, b: 10}), {h: 30, s: 50, l: 7.8, string: 'hsl(30,50%,7.8%)'}) | ||
}) | ||
test('computes valid HSL if g is greatest', t => { | ||
t.deepEqual(RGBToHSL({r: 10, g: 30, b: 20}), {h: 150, s: 50, l: 7.8, string: 'hsl(150,50%,7.8%)'}) | ||
}) | ||
test('computes valid HSL if b is greatest', t => { | ||
t.deepEqual(RGBToHSL({r: 10, g: 20, b: 30}), {h: 210, s: 50, l: 7.8, string: 'hsl(210,50%,7.8%)'}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import test from "ava" | ||
import { componentToHex } from "../../src/color.utils" | ||
test('left pads zero if single digit hex', t => { | ||
t.is(componentToHex("f"), "0f") | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import test from "ava" | ||
import { getComplementary } from "../../src/color.utils" | ||
test('computes valid hue if r > g > b', t => { | ||
t.is(getComplementary("#f58742"), "#42b0f5") | ||
}) | ||
test('computes valid hue if r > b > g', t => { | ||
t.is(getComplementary("#f54287"), "#42f5b0") | ||
}) | ||
test('computes valid hue if g is greatest', t => { | ||
t.is(getComplementary("#87f542"), "#b042f5") | ||
}) | ||
test('computes valid hue if b is greatest', t => { | ||
t.is(getComplementary("#4287f5"), "#f5b042") | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import test from 'ava' | ||
const mockIsWithinRange = (num, max, term) => { | ||
if (Number.isNaN(num) || num < 0 || num > max) throw new RangeError(`${num} for ${term} is not between 0 and ${max}`) | ||
} | ||
test('10 lies within (0,12)', t => { | ||
t.is(mockIsWithinRange(10, 12, 'x'), undefined) | ||
}) | ||
test('16 does not lie within (0,12)', t => { | ||
t.throws(() => mockIsWithinRange(16, 12, 'x'), { | ||
instanceOf: RangeError, | ||
message: '16 for x is not between 0 and 12' | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import test from "ava" | ||
const mockKd = [[0,0,0],[155,23,0],[40,134,50]] | ||
const mockKdA = [[1,1,1],[255,13,1],[80,245,100]] | ||
function mockPaletteGenerator (_, B, accent) { | ||
const refPalletes = accent ? mockKdA : mockKd | ||
const b = B === undefined ? refPalletes : B | ||
return b; | ||
} | ||
test('sets input as refPallete if defined', t => { | ||
t.deepEqual(mockPaletteGenerator(10, [[1,1,1]], false), [[1,1,1]]) | ||
}) | ||
test('sets Kd as refPallete if undefined and not accent', t => { | ||
t.is(mockPaletteGenerator(10, undefined, false), mockKd) | ||
}) | ||
test('sets KdA as refPallete if undefined and accent', t => { | ||
t.is(mockPaletteGenerator(10, undefined, true), mockKdA) | ||
}) |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import test from 'ava' | ||
import Matercolor from '../../src/index' | ||
test('fails on empty constructor', t => { | ||
const err = t.throws(() => new Matercolor(), { instanceOf: RangeError }) | ||
t.true(err.message.includes('NaN for lightness is not between')) | ||
}) | ||
test('valid constructor has four keys', t => { | ||
const color = new Matercolor('#FFFFFF') | ||
t.is(Object.keys(color).length, 4) | ||
}) | ||
test('fails on invalid hex', t => { | ||
const err = t.throws(() => new Matercolor('#GGEEFF'), { instanceOf: RangeError }) | ||
t.true(err.message.includes('NaN for lightness is not between')) | ||
}) | ||
test.todo('supports triple hex codes') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import test from 'ava' | ||
import Matercolor from '../../src/index' | ||
test('has four valid accent keys', t => { | ||
const color = new Matercolor('#FFFFFF').accents('primary') | ||
t.deepEqual(Object.keys(color), ["A100","A200","A400","A700"]) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import test from 'ava' | ||
import Matercolor from '../../src/index' | ||
test('has four valid accent keys', t => { | ||
const color = new Matercolor('#FFFFFF').shades('primary') | ||
t.deepEqual(Object.keys(color), ["light","main","dark"]) | ||
}) |