diff --git a/.husky/pre-commit b/.husky/pre-commit index 559759f6..151b2508 100644 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,5 +1,5 @@ #!/usr/bin/env sh . "$(dirname -- "$0")/_/husky.sh" -npm run lint + diff --git a/.husky/pre-push b/.husky/pre-push index 94a0de27..728a507d 100644 --- a/.husky/pre-push +++ b/.husky/pre-push @@ -2,4 +2,4 @@ . "$(dirname -- "$0")/_/husky.sh" # We cant push code that doesn't build. - npm run format + npm run lint && npm run format diff --git a/.vscode/launch.json b/.vscode/launch.json index 43a7d50d..cf315ca2 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,22 +1,14 @@ { "version": "0.2.0", "configurations": [ - { - "name": "ts-node", - "type": "node", - "request": "launch", - "runtimeExecutable": "node", - "runtimeArgs": [ - "--nolazy", - "-r", - "ts-node/register/transpile-only" - ], - "cwd": "${workspaceRoot}", - "internalConsoleOptions": "openOnSessionStart", - "skipFiles": [ - "/**", - "node_modules/**" - ] - } + { + "name": "Launch Program", + "program": "${workspaceFolder}/app.js", + "request": "launch", + "skipFiles": [ + "/**" + ], + "type": "node" + } ] } \ No newline at end of file diff --git a/README.md b/README.md index f9609f8d..436c5508 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,11 @@ -![](./huetiful-logo.png) - - #### JavaScript library for general purpose color manipulations. +![Logo](./huetiful-logo.png) +#### JavaScript library for general purpose color manipulations The aim of this project is to help designers and developers alike work with color more programatically using utilities based on color theory. Though not necessarily a requirement, a basic background of color spaces, properties of color and any other color theory related information will make the library's use cases appear more simpler. -This project is inspired by projects such a [chroma-js](),[colorBrewer.org](),[TailwindCSS]() and borrows some of the reasoning behind them to build functionality. In fact this library uses [Culori]() as its core dependency because it provides a rich API of low level functions written in JavaScript to perform color conversions and other general purpose color manipulations. +This project is inspired by projects such a [chroma-js](https://gka.github.io/chroma.js),[colorbrewer](https://colorbrewer2.org),[TailwindCSS](https://tailwindcss.com) and borrows some of the reasoning behind them to build functionality. In fact this library uses [Culori](https://culorijs.org) as its core dependency because it provides a rich API of low level functions written in JavaScript to perform color conversions and other general purpose color manipulations. ## Getting started @@ -19,11 +18,14 @@ Use [npm](https://www.npmjs.com/package/huetiful-js) to install the package. npm i huetiful-js ``` -For use in the browser use [CDN]() to load the package (UMD) +For use in the browser, you can use a CDN [you can use jsdelivr]() to load the library. ```html +https://cdn.jsdelivr.net/npm/huetiful-js/dist/huetiful.min.js + +# With script tag -Code sample + ``` ## Overview @@ -76,17 +78,15 @@ console.log(toHex(arrColorWithAlpha)) Note that toHex takes any color format and returns the hex string represantation of it: - We can even mix different color formats with no problem at all: - -For more information on the color spaces supported by the library and the expected ranges, checkout the [Color Spaces page on the Culori docs]() . Or checkout the library's [Color conversions]() page. +For more information on the color spaces supported by the library and the expected ranges, checkout the [Color Spaces page on the Culori docs](https://culorijs.org/color-spaces) . Or checkout the library's [Color conversions](https://huetiful-docs.vercel.app/blog/color-spaces-and-converters) page. > All the functions are internally guarded by `toHex()` so you don't have to worry about converting colors back and fourth. #### Tailwind colors -As a starting point the library comes along with the default [TailwindCSS]() palette included.. This helps you get started easier when you're using [palette functions]() such as `hueShift()` and `earthtone()` +As a starting point the library comes along with the default TailwindCSS palette included.. This helps you get started easier when you're using [palette functions](https://huetiful-docs.vercel.app/blog/palette-utilities) such as `hueShift()` and `earthtone()` The Tailwind colors are in the form of two wrapper functions that both take the same parameters but with a few differences: one is curried by default and the other is a tweaked variant of the same functionality but with a few improvements. Below are some examples showing the differences between the two functions: @@ -154,7 +154,7 @@ The library has functions for sorting and filtering colors using their property #### Sorting colors -Below is an example of sorting colors by the relative luminance as defined by [WCAG 2.0](). +Below is an example of sorting colors by the relative luminance as defined by WCAG 2.0. > Note that you can specify the order as either ascending (`asc`) or descending (`desc`). The default is ascending. : ```js @@ -202,7 +202,7 @@ console.log(sortedDescending) #### Filtering colors -Below is an example of filtering colors by their hue angle. The function uses LCH internally because its more perceptually uniform than HSL. [George Francis explains this phenomena in detail here.]() +Below is an example of filtering colors by their hue angle. The function uses LCH internally because its more perceptually uniform than HSL. [George Francis explains this phenomena in detail here.](https://tympanus.net/codrops/2021/12/07/coloring-with-code-a-programmatic-approach-to-design/) ```js let sample = [ @@ -235,13 +235,11 @@ console.log(filterByHue(sample, '<=100') // [ '#ffff00', '#310000', '#3e0000', '#4e0000', '#600000', '#720000' ] ``` -[See more about the parameter types and other sorting/filtering functions]() - +[See more about the parameter types and other filtering functions](https://huetiful-docs.vercel.app/blog/sorting-color) ### Palette functions -A small collection of simple palette functions are included in the library. One of my favourites is the `hueShift()` (as a color becomes lighter, its hue shifts up and darker when its hue shifts down. ) , function which was inspired by (special thanks) [George Francis's implementation in this post]() - +A small collection of simple palette functions are included in the library. One of my favourites is the `hueShift()` (as a color becomes lighter, its hue shifts up and darker when its hue shifts down. ) . ```js import { hueShift } from "huetiful-js"; @@ -264,7 +262,6 @@ console.log(hueShiftedPalette); There's more where that came from. [See the palettes page]() - ### Predicates Is this color cool or warm, is it achromatic (grayscale) or chromatic? Though its easy to tell colors apart visually when they're displayed on the screen it can be a bit confusing to tell colors apart using code. Below is an example of demonstrating how to determine if a color is gray or not: @@ -391,28 +388,28 @@ console.log(getFarthestHue('lime', sample, 'lch')) ``` - - ## What's next -The list of functions goes on beyond this. And since the library is pure JavaScript, you can hook it up with your creative coding library of choice like [p5js]() or [runejs](). The possibilities are limited by the imagination of the user. +The list of functions goes on beyond this. And since the library is pure JavaScript, you can hook it up with your creative coding library of choice like p5js or runejs. The possibilities are limited by the imagination of the user. -For an introduction to terminology used in color checkout this guide on my blog. - -[See the full docs here]() +[See the full docs here](https:huetiful-docs.vercel.app) ## Need help ? -See some unexpected results? [Checkout our issue tracker]() to open an issue or search for the problem to see if your issue already exists +See some unexpected results? [Check the issue tracker](https://github.com/prjctimg/huetiful/issues) to open an issue or search for the problem to see if your issue already exists or has been resolved. -Would like to join the chat and share ideas and suggestions ? [See our discussions]() for the open topics. +Would like to join the chat and share ideas and suggestions ? [See the discussions and just say hi, or share a coding meme(whatever breaks the ice)](https://github.com/prjctimg/huetiful/discussions) ## Contributing First of all, thank you for using huetiful-js! Its people like you that make open source software better for the community! Contributions are welcome! Help make this project better and easier to use for other developers by sharing your ideas and stomping out bugs and feature suggestions. Please see the [CONTRIBUTING](./CONTRIBUTING.md) file for more information on how to get started. +## References + +[Coloring with code: A programmatic approach by George Francis](https://tympanus.net/codrops/2021/12/07/coloring-with-code-a-programmatic-approach-to-design/) + > ## License > > Copyright (c) 2023 diff --git a/build.cjs b/build.cjs index a71e29fe..7fdd2be4 100644 --- a/build.cjs +++ b/build.cjs @@ -4,7 +4,7 @@ // eslint-disable-next-line no-undef var { build } = require('esbuild'); - +var { dependencies } = require('./package.json') const sharedConfig = { @@ -31,7 +31,7 @@ build({ format: 'esm', outfile: 'dist/filterBy/index.esm.mjs', - platform: 'neutral' + }); // sortBy/ import @@ -49,16 +49,8 @@ build({ format: 'esm', entryPoints: ['.//src/colors/index.ts'], outfile: 'dist/colors/index.esm.mjs', - }); -// fp/ import -build({ - ...sharedConfig, - format: 'esm', - entryPoints: ['.//src/fp/index.ts'], - outfile: 'dist/fp/index.esm.mjs' -}); // core-utils/ import build({ @@ -69,19 +61,15 @@ build({ }); -//Bundled CJS minified -build({ - ...sharedConfig, - outfile: 'dist/huetiful.min.cjs', - minify: true, -}); //Bundled ESM build({ ...sharedConfig, + external: Object.keys(dependencies), format: 'esm', - outfile: 'dist/huetiful.esm.mjs' + outfile: 'dist/huetiful.esm.mjs', minifySyntax: true, + }); //Bundled ESM minified @@ -94,19 +82,13 @@ build({ }); //Bundled IIFE -build({ - ...sharedConfig, - format: 'iife', - outfile: 'dist/huetiful.js', - globalName: 'huetiful', - minify: false -}); - -//Bundled IIFE minified build({ ...sharedConfig, format: 'iife', outfile: 'dist/huetiful.min.js', globalName: 'huetiful', minify: true + }); + + diff --git a/changelog.md b/changelog.md index 5da001f8..a74edcb1 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,7 @@ +# Changelog +Some of the major notable changes in the past releases.Please note that the list of changes is not final and is still a work in progress. More information will be updated from the Git commit history. + + ### v0.0.5 First publish, lots of broken code. Basically nothing worked well in this release. Deprecated @@ -30,18 +34,21 @@ Changed docs to docsify ### 1.8.0 (stable) -Fully treeshakable -Added the `load()` to create read-manipulate-output chains like the one presented by the `chroma()` in chroma-js -Added the `toHex` utility which parses all known color tokens similar to chroma-js -Eliminated dependancy on lodash. -Used treeshaken Culori modules to reduce bundle size. Only 20KB when minified! -Created the `fp` directory with helpe functions used in the library grouped by input type -More modular codebase -Simplified code to make it more readable and easier to understand for other developers who may want to contribute +- Fully treeshakable +- Core-utils directory was split to submodules. +- Added the `load()` to create read-manipulate-output chains like the one presented by the `chroma()` constructor in chroma-js +- Added the `toHex` utility which parses all known color tokens similar to chroma-js +- Eliminated dependancy on lodash. +- Used treeshaken Culori modules to reduce bundle size. Only 20KB when minified! +- Created the `fp` directory with helper functions used in the library grouped by input type. +- More modular codebase +- Simplified code to make it more readable and easier to understand for other developers who may want to contribute Over 50 utilities in the API now! -All palette functions have easings for internal computations +- All palette functions have easings for internal computations Updated the docs! -Added introduction guides to help users understand the project -Rewrote the README and CONTRIBUTING. Added missing licenses for borrowed code. -Special thanks to [contributors] +- Improved the accuracy of temperature based utilities. +- All palette functions now take an optional overrides object to fine tune parameters like easing methods, fixups etc. +- Added introduction guides to help users understand the project +- Rewrote the README and CONTRIBUTING. Added missing licenses for borrowed code. +Special thanks to our [contributors!]() diff --git a/guides/palettes.md b/guides/palettes.md index 3142065a..6013b1c4 100644 --- a/guides/palettes.md +++ b/guides/palettes.md @@ -1,6 +1,6 @@ # Palettes -A small collection of functions to help you kickstart your designs using mostly just a single base color and a few adjustable built-n parameters. All palette functions use `easingSmootherstep()` easing under the hood to ease certain values on channels being worked with. +A small collection of functions to help you kickstart your designs using mostly just a single base color and a few adjustable built-in parameters. All palette functions use `easingSmoothstep()` easing under the hood to ease certain values on channels being worked with. Because certain end results are easier to achieve in different color spaces, colors are converted to a mode that is suited for the desired and result. For example pastel colors have a high `value` and low `saturation` there are easier to compute in the HSV color space. But for the most part colors are converted to LCH and then returned as optional hex strings or plain color objects. diff --git a/package-lock.json b/package-lock.json index 81ef9e12..67a261d4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "huetiful-js", - "version": "1.7.5", + "version": "1.7.6", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "huetiful-js", - "version": "1.7.5", + "version": "1.7.6", "license": "Apache 2.0", "dependencies": { "culori": "^3.0.1" diff --git a/package.json b/package.json index f0c95811..783ae809 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,13 @@ { "name": "huetiful-js", - "version": "1.7.5", + "version": "1.7.6", "type": "module", - "main": "./dist/huetiful.cjs", "module": "./dist/huetiful.esm.mjs", "browser": "./dist/huetiful.min.js", "exports": { "./fp": "./dist/fp/index.esm.mjs", - "./core-utils": "./dist/core-utils/index.esm.mjs", + "./getters_and_setters/index.esm.mjs": "./dist/getters_and_setters/index.esm.mjs", + "./converters": "./dist/converters/index.esm.mjs", "./palettes": "./dist/palettes/index.esm.mjs", "./filterBy": "./dist/filterBy/index.esm.mjs", "./sortBy": "./dist/sortBy/index.esm.mjs", @@ -50,15 +50,24 @@ "dist", "src" ], - "repository": "github:prjctimg/huetiful", + "repository": { + "type": "git", + "url": "git+https://github.com/prjctimg/huetiful.git" + }, "keywords": [ "lch", - "palette", + "palettes", "color schemes", "color", "culori", "gradients", - "tailwind" + "tailwind", + "cielab", + "rgb", + "hsl", + "hsv", + "colorbrewer", + "tailwindcss" ], "author": "Dean Tarisai", "email": "arcaneqoder@gmail.com", diff --git a/src/colors/chroma.ts b/src/colors/chroma.ts index b9bb54e8..314650d3 100644 --- a/src/colors/chroma.ts +++ b/src/colors/chroma.ts @@ -1,10 +1,10 @@ // @ts-nocheck // This module contains minChroma,maxChroma,getFarthestChroma,getNearestChroma -import { Color, HueColorSpaces, factor } from '../paramTypes'; +import { Color, HueColorSpaces, Factor } from '../paramTypes'; import { getChannel } from '../getters_and_setters/get.ts'; -import { matchChromaChannel } from '../fp/string.ts'; -import { sortedArr } from '../fp/array.ts'; +import { matchChromaChannel } from '../fp/string/matchChromaChannel.ts'; +import { sortedArr } from '../fp/array/sortedArr.ts'; // I must test if the passed in mode has a chroma/saturation channel. Should I use RegExp ? @@ -53,7 +53,7 @@ const getNearestChroma = ( ): number => { // The factor being investigated. - const factor: factor = 'saturation'; + const factor: Factor = 'saturation'; const cb = chromaDiff(color, colorSpace || 'lch'); const sortedObjArr = sortedArr( factor, @@ -90,7 +90,7 @@ const getFarthestChroma = ( ): number => { // The factor being investigated. - const factor: factor = 'saturation'; + const factor: Factor = 'saturation'; const cb = chromaDiff(color, colorSpace || 'lch'); const sortedObjArr = sortedArr( factor, @@ -125,7 +125,7 @@ const minChroma = ( ): number | { factor: number; color: Color } => { // The factor being investigated. - const factor: factor = 'saturation'; + const factor: Factor = 'saturation'; const result: Array<{ factor: number; name: Color }> = sortedArr( factor, predicate(colorSpace || 'lch'), @@ -169,7 +169,7 @@ const maxChroma = ( ): number | { factor: number; color: Color } => { // The factor being investigated. - const factor: factor = 'saturation'; + const factor: Factor = 'saturation'; const result: Array<{ factor: number; name: Color }> = sortedArr( factor, predicate(colorSpace || 'lch'), diff --git a/src/colors/colorBrewer.ts b/src/colors/colorBrewer.ts index dbd43457..a8ec8189 100644 --- a/src/colors/colorBrewer.ts +++ b/src/colors/colorBrewer.ts @@ -1,8 +1,8 @@ //@ts-nocheck import type { - sequentialScheme, - divergingScheme, - qualitativeScheme, + SequentialScheme, + DivergingScheme, + QualitativeScheme, Color } from '../paramTypes'; @@ -47,7 +47,7 @@ console.log(sequential("OrRd")) */ -const sequential = (scheme: sequentialScheme): Color[] => { +const sequential = (scheme: SequentialScheme): Color[] => { const schemes = { OrRd: [ '#fff7ec', @@ -283,7 +283,7 @@ console.log(diverging("Spectral")) ] */ -const diverging = (scheme: divergingScheme): Color[] => { +const diverging = (scheme: DivergingScheme): Color[] => { const schemes = { Spectral: [ '#9e0142', @@ -427,7 +427,7 @@ console.log(qualitative("Accent")) */ -const qualitative = (scheme: qualitativeScheme): Color[] => { +const qualitative = (scheme: QualitativeScheme): Color[] => { const schemes = { Set2: [ '#66c2a5', diff --git a/src/colors/hue.ts b/src/colors/hue.ts index e35482e3..37915613 100644 --- a/src/colors/hue.ts +++ b/src/colors/hue.ts @@ -2,14 +2,14 @@ // @ts-nocheck import { getChannel } from '../getters_and_setters/get.ts'; -import { sortedArr } from '../fp/array.ts'; -import type { Color, HueColorSpaces, factor } from '../paramTypes'; +import { sortedArr } from '../fp/array/sortedArr.ts'; +import type { Color, HueColorSpaces, Factor } from '../paramTypes'; // Globals const { abs } = Math; -const factor: factor = 'hue'; +const factor: Factor = 'hue'; const mode = (colorSpace: HueColorSpaces): string => `${colorSpace || 'lch'}.h`; // The hue value of our color which we are using for comparison const targetHue = (color: Color, colorSpace: HueColorSpaces): number => diff --git a/src/colors/lightness.ts b/src/colors/lightness.ts index 1dc2a69a..578aa2e8 100644 --- a/src/colors/lightness.ts +++ b/src/colors/lightness.ts @@ -1,8 +1,8 @@ // @ts-nocheck import { getChannel } from '../getters_and_setters/get.ts'; -import { sortedArr } from '../fp/array.ts'; -import type { Color, factor } from '../paramTypes'; +import { sortedArr } from '../fp/array/sortedArr.ts'; +import type { Color, Factor } from '../paramTypes'; const lightness = 'lab.l'; @@ -38,7 +38,7 @@ console.log(getNearestLightness("green", sample)) const getNearestLightness = (color: Color, colors: Color[]): number => { // The factor being investigated. - const factor: factor = 'lightness'; + const factor: Factor = 'lightness'; const cb = lightnessDiff(color); const sortedObjArr = sortedArr(factor, cb, 'asc', true)(colors); return sortedObjArr[0][factor]; @@ -66,7 +66,7 @@ console.log(getFarthestLightness("green", sample)) const getFarthestLightness = (color: Color, colors: Color[]): number => { // The factor being investigated. - const factor: factor = 'lightness'; + const factor: Factor = 'lightness'; const cb = lightnessDiff(color); const sortedObjArr = sortedArr(factor, cb, 'desc', true)(colors); return sortedObjArr[0][factor]; @@ -95,7 +95,7 @@ const minLightness = ( ): number | { factor: number; color: Color } => { // The factor being investigated. - const factor: factor = 'lightness'; + const factor: Factor = 'lightness'; const cb = getChannel(lightness); const result: Array<{ factor: number; name: Color }> = sortedArr( factor, @@ -138,7 +138,7 @@ const maxLightness = ( ): number | { factor: number; color: Color } => { // The factor being investigated. - const factor: factor = 'lightness'; + const factor: Factor = 'lightness'; const cb = getChannel(lightness); const result: Array<{ factor: number; name: Color }> = sortedArr( factor, diff --git a/src/colors/overtone.ts b/src/colors/overtone.ts index 1fad3512..f1dcd2c6 100644 --- a/src/colors/overtone.ts +++ b/src/colors/overtone.ts @@ -2,40 +2,8 @@ import { getChannel } from '../getters_and_setters/get.ts'; import hueTempMap from '../color-maps/samples/hueTemperature'; import { isAchromatic } from './achromatic.ts'; +import { customFindKey } from '../fp/object/customFindKey.ts'; import type { Color } from '../paramTypes.ts'; -import { inRange } from '../fp/number.ts'; -import { max, min } from '../fp/array.ts'; -import { customConcat } from '../fp/object.ts'; - -/** - - * - * @private - * @param {Array|Object} collection The collection to inspect. - * @param {Function} predicate The function invoked per iteration. - * @param {number} factor The value to compare against - * @returns {*} Returns the found element or its key, else `undefined`. - */ -const customFindKey = (collection: object, factor: number) => { - // If the color is achromatic return the string gray - - const propKeys = Object.keys(collection); - - const result: string = propKeys - .filter((key) => { - const hueVals = customConcat(collection[key]); - // @ts-ignore - const minVal = min(...hueVals); - // @ts-ignore - const maxVal = max(...hueVals); - // Capture the min and max values and see if the passed in color is within that range - - return inRange(factor, minVal, maxVal); - }) - .toString(); - - return result; -}; /** * @function diff --git a/src/colors/temperature.ts b/src/colors/temperature.ts index 1215195a..68386c1a 100644 --- a/src/colors/temperature.ts +++ b/src/colors/temperature.ts @@ -3,31 +3,13 @@ import { getChannel } from '../getters_and_setters/get.ts'; import hueTempMap from '../color-maps/samples/hueTemperature'; import { getTemp } from '../converters/getTemp.ts'; -import { floorCeil, inRange } from '../fp/number.ts'; -import { min, max } from '../fp/array.ts'; -import { customConcat } from '../fp/object.ts'; +import { floorCeil } from '../fp/number/floorCeil.ts'; +import { inRange } from '../fp/number/inRange.ts'; +import { min, max } from '../fp/array/min_max.ts'; +import { customConcat } from '../fp/object/customConcat.ts'; +import { customFindKey } from '../fp/object/customFindKey.ts'; import type { Color } from '../paramTypes.ts'; -const customFindKey = (collection: object, factor: number) => { - // If the color is achromatic return the string gray - - const propKeys = Object.keys(collection); - - const result: string = propKeys - .filter((key) => { - const hueVals = customConcat(collection[key]); - // @ts-ignore - const minVal = min(...hueVals); - // @ts-ignore - const maxVal = max(...hueVals); - // Capture the min and max values and see if the passed in color is within that range - - return inRange(factor, minVal, maxVal); - }) - .toString(); - - return result; -}; const predicate = (factor: number, temp: 'warm' | 'cool'): boolean => { const hueKeys = Object.keys(hueTempMap); if ( diff --git a/src/filterBy/filterByContrast.ts b/src/filterBy/filterByContrast.ts index 1fb95776..66e756ac 100644 --- a/src/filterBy/filterByContrast.ts +++ b/src/filterBy/filterByContrast.ts @@ -1,8 +1,8 @@ // @ts-nocheck -import { filteredArr } from '../fp/array.ts'; +import { filteredArr } from '../fp/array/filteredArr.ts'; import { wcagContrast } from 'culori/fn'; -import type { Color, factor } from '../paramTypes.ts'; +import type { Color, Factor } from '../paramTypes.ts'; import { toHex } from '../converters/toHex.ts'; /** @@ -43,7 +43,7 @@ const filterByContrast = ( ): Color[] => { // Formatting color tokens to parseable type // Create an object that has the contrast and name of color as properties. - const factor: factor = 'contrast'; + const factor: Factor = 'contrast'; const cb = (against: Color) => (color: Color) => wcagContrast(...[color, against].map(toHex)); diff --git a/src/filterBy/filterByDistance.ts b/src/filterBy/filterByDistance.ts index 775b2efb..d325621f 100644 --- a/src/filterBy/filterByDistance.ts +++ b/src/filterBy/filterByDistance.ts @@ -1,8 +1,8 @@ // @ts-nocheck -import { filteredArr } from '../fp/array.ts'; +import { filteredArr } from '../fp/array/filteredArr.ts'; import { differenceEuclidean } from 'culori/fn'; -import type { Color, factor, ColorSpaces } from '../paramTypes.ts'; +import type { Color, Factor, ColorSpaces } from '../paramTypes.ts'; import { toHex } from '../converters/toHex.ts'; /** * @function @@ -43,7 +43,7 @@ const filterByDistance = ( // How do I get the distance // Create an object that has the distance and name of color as properties. - const factor: factor = 'distance'; + const factor: Factor = 'distance'; const cb = (against: Color, mode: ColorSpaces) => (color: Color) => differenceEuclidean( mode || 'lch', diff --git a/src/filterBy/filterByHue.ts b/src/filterBy/filterByHue.ts index 2c403be2..de76bc7a 100644 --- a/src/filterBy/filterByHue.ts +++ b/src/filterBy/filterByHue.ts @@ -1,6 +1,6 @@ -import { filteredArr } from '../fp/array.ts'; +import { filteredArr } from '../fp/array/filteredArr.ts'; import { getChannel } from '../getters_and_setters/get.ts'; -import type { Color, factor } from '../paramTypes.ts'; +import type { Color, Factor } from '../paramTypes.ts'; //filterByHue takes an array of colors and /** @@ -31,7 +31,7 @@ filterByHue(sample, 20, 80) */ const filterByHue = (colors: Color[], startHue = 0, endHue = 360): Color[] => { - const factor: factor = 'hue'; + const factor: Factor = 'hue'; const cb = getChannel('lch.h'); return filteredArr(factor, cb)(colors, startHue, endHue); diff --git a/src/filterBy/filterByLightness.ts b/src/filterBy/filterByLightness.ts index cc6ea504..3c558c9d 100644 --- a/src/filterBy/filterByLightness.ts +++ b/src/filterBy/filterByLightness.ts @@ -1,6 +1,6 @@ -import { filteredArr } from '../fp/array.ts'; +import { filteredArr } from '../fp/array/filteredArr.ts'; import { getChannel } from '../getters_and_setters/get.ts'; -import { Color, factor } from '../paramTypes.ts'; +import { Color, Factor } from '../paramTypes.ts'; /** * @function * @description Returns an array of colors in the specified lightness range. The range is between 0 and 100. @@ -37,7 +37,7 @@ const filterByLightness = ( ): Color[] => { // Formatting color tokens to parseable type // Create an object that has the lightness and name of color as properties. - const factor: factor = 'lightness'; + const factor: Factor = 'lightness'; const cb = getChannel('lch.l'); return filteredArr(factor, cb)(colors, startLightness, endLightness); diff --git a/src/filterBy/filterByLuminance.ts b/src/filterBy/filterByLuminance.ts index 1bd0d218..02d687f2 100644 --- a/src/filterBy/filterByLuminance.ts +++ b/src/filterBy/filterByLuminance.ts @@ -1,7 +1,7 @@ -import { filteredArr } from '../fp/array.ts'; +import { filteredArr } from '../fp/array/filteredArr.ts'; import { Color } from '../paramTypes.ts'; import { getLuminance } from '../getters_and_setters/luminance.ts'; -import type { factor } from '../paramTypes'; +import type { Factor } from '../paramTypes'; /** * @function * @description Returns an array of colors in the specified luminance range. The range is normalised to [0,1]. @@ -38,7 +38,7 @@ const filterByLuminance = ( ): Color[] => { // Formatting color tokens to parseable type // Create an object that has the luminance and name of color as properties. - const factor: factor = 'luminance'; + const factor: Factor = 'luminance'; const cb = getLuminance; return filteredArr(factor, cb)(colors, startLuminance, endLuminance); diff --git a/src/filterBy/filterBySaturation.ts b/src/filterBy/filterBySaturation.ts index 514523c2..70b00396 100644 --- a/src/filterBy/filterBySaturation.ts +++ b/src/filterBy/filterBySaturation.ts @@ -1,7 +1,7 @@ // @ts-nocheck import { getChannel } from '../getters_and_setters/get.ts'; -import { filteredArr } from '../fp/array.ts'; -import type { Color, factor } from '../paramTypes'; +import { filteredArr } from '../fp/array/filteredArr.ts'; +import type { Color, Factor } from '../paramTypes'; /** * @function @@ -36,7 +36,7 @@ const filterBySaturation = ( startSaturation = 0.05, endSaturation = 1 ): Color[] => { - const factor: factor = 'saturation'; + const factor: Factor = 'saturation'; const cb = getChannel('lch.c'); // Normalize saturation ranges later diff --git a/src/filterBy/filterByTemp.ts b/src/filterBy/filterByTemp.ts index df612be5..143f62ff 100644 --- a/src/filterBy/filterByTemp.ts +++ b/src/filterBy/filterByTemp.ts @@ -1,6 +1,6 @@ import { getTemp } from '../converters/getTemp.ts'; -import { filteredArr } from '../fp/array.ts'; -import type { Color, factor } from '../paramTypes.ts'; +import { filteredArr } from '../fp/array/filteredArr.ts'; +import type { Color, Factor } from '../paramTypes.ts'; /** * @function @@ -45,7 +45,7 @@ const filterByTemp = ( endTemp = 6000 ): Color[] => { // This variable stores the array that matches the filtering criteria defined by the start and end hues - const factor: factor = 'temp'; + const factor: Factor = 'temp'; const cb = getTemp; return filteredArr(factor, cb)(colors, startTemp, endTemp); diff --git a/src/fp/array.ts b/src/fp/array.ts deleted file mode 100644 index 652b1c0c..00000000 --- a/src/fp/array.ts +++ /dev/null @@ -1,169 +0,0 @@ -// This module has array methods -// @ts-nocheck -import { colorObj } from './object'; -import { factor, Color, callback, order } from '../paramTypes'; -import { gt, gte, lt, lte, inRange } from './number'; -/* - * @function - * @private - * Creates a custom object with a factor to pass to the predicate function. - * @param factor The quality being queried. - * @param cb The callback function for computing the factor's start. - * @param colors The array of colors to iterate over. - * @returns An array of objects. - */ -const colorObjArr = - (factor: factor, callback) => - (colors: Color[]): Array<{ factor: factor; name: Color }> => { - const cb = colorObj(factor, callback); - return colors.map((color) => cb(color)); - }; - -/** - * @description Filters an array according to the value of a color's queried factor - * @param factor The property to query and use as filtering criteria - * @param cb The function to use for comparison - * @returns The filtered array - */ -const filteredArr = - (factor: factor, cb?: callback) => - (colors: Color[], start: number | string, end: number): Color[] => { - let result: Color[]; - - if (typeof start == 'number') { - result = colorObjArr(factor, cb)(colors); - result = result - .filter((color) => inRange(color[factor], start, end)) - .map((color) => color['name']); - - return result; - - // If string split the the string to an array of signature [sign,value] with sign being the type of predicate returned to mapFilter. - } else if (typeof start == 'string') { - //The pattern to match - const operator = /^(>=|<=|<|>)/; - - const value = /[0-9]*\.?[0-9]+/; - - // Array - const val = value.exec(start), - op = operator.exec(start); - - const mapFilter = (test: (x: number, y: number) => boolean): Color[] => { - return colorObjArr( - factor, - cb - )(colors) - .filter((el) => test(el[factor], parseFloat(val['0']))) - .map((el) => el['name']); - }; - switch (op['0']) { - case '<': - result = mapFilter(lt); - - break; - case '>': - result = mapFilter(gt); - break; - case '<=': - result = mapFilter(lte); - break; - case '>=': - result = mapFilter(gte); - break; - } - } - return result; - }; - -/** - * @description Helper function for native sorting method for arrays. - * @param factor The property to query. - * @param order Either ascending or descending. - * @returns A sorted array. - */ -const customSort = (order: order, factor?: factor) => { - // Special thanks to deechris27 on youtube - // a-b gives asc order & b-a gives desc order - factor = factor || 'factor'; - return (a, b) => { - if (order === 'asc') { - return a[factor] - b[factor]; - } else if (order === 'desc') { - return b[factor] - a[factor]; - } - }; -}; - -/** - * Filters an array of color objects with a "factor" property whose value is determined by a predicate or getter via the cb param. - * @param factor The property to query - * @param callback The function to use for comparison. - * @returns An array of colors or color objects. - */ - -const sortedArr = - (factor: factor, callback: callback, order: order, colorObj = false) => - (colors: Color[]) => { - const results: Color[] | Array<{ factor: number; name: Color }> = - colorObjArr(factor, callback)(colors); - // (colorObj && color) || color['name']; - - // Assign the value of colorObj to results variable - - // Sort the array using our customSort helper function - results.sort(customSort(order, factor)); - - // colorObj parameter is true return the array of color objects - // else just return the color's name value. - if (colorObj) { - return results; - } else { - return results.map((color) => color['name']); - } - }; - -// from the lodash implementation of _.min and _.max -const identity = (value) => { - return value; -}; -const baseExtremum = (array: number[], iteratee, comparator) => { - var index = -1, - length = array.length; - - while (++index < length) { - var value = array[index], - current = iteratee(value); - - if ( - current != null && - (computed === undefined - ? current === current - : comparator(current, computed)) - ) { - var computed = current, - result = value; - } - } - return result; -}; - -/** - * @description Gets the smallest value in an array - * @param array The array to retrieve minimum value - * @returns The smallest number in the array - */ -const min = (array: number[]): number => { - return array && array.length ? baseExtremum(array, identity, lt) : undefined; -}; -/** - * @description Gets the largest value in an array - * @param array The array to retrieve maximum value - * @returns The largest number in the array - */ - -const max = (array: number[]): number => { - return array && array.length ? baseExtremum(array, identity, gt) : undefined; -}; - -export { colorObjArr, filteredArr, sortedArr, customSort, max, min }; diff --git a/src/fp/array/colorObjArr.ts b/src/fp/array/colorObjArr.ts new file mode 100644 index 00000000..71e6c246 --- /dev/null +++ b/src/fp/array/colorObjArr.ts @@ -0,0 +1,20 @@ +// @ts-nocheck + +import { colorObj } from '../object/colorObj'; +import { Factor, Color } from '../../paramTypes'; + +/* + * @function + * @private + * Creates a custom object with a factor to pass to the predicate function. + * @param factor The quality being queried. + * @param cb The callback function for computing the factor's start. + * @param colors The array of colors to iterate over. + * @returns An array of objects. + */ +export const colorObjArr = + (factor: Factor, callback) => + (colors: Color[]): Array<{ factor: Factor; name: Color }> => { + const cb = colorObj(factor, callback); + return colors.map((color) => cb(color)); + }; diff --git a/src/fp/array/customSort.ts b/src/fp/array/customSort.ts new file mode 100644 index 00000000..d14a5483 --- /dev/null +++ b/src/fp/array/customSort.ts @@ -0,0 +1,21 @@ +//@ts-nocheck +import { Factor, Order } from '../../paramTypes'; + +/** + * @description Helper function for native sorting method for arrays. + * @param factor The property to query. + * @param order Either ascending or descending. + * @returns A sorted array. + */ +export const customSort = (order: Order, factor?: Factor) => { + // Special thanks to deechris27 on youtube + // a-b gives asc order & b-a gives desc order + factor = factor || 'factor'; + return (a, b) => { + if (order === 'asc') { + return a[factor] - b[factor]; + } else if (order === 'desc') { + return b[factor] - a[factor]; + } + }; +}; diff --git a/src/fp/array/filteredArr.ts b/src/fp/array/filteredArr.ts new file mode 100644 index 00000000..1b0f111e --- /dev/null +++ b/src/fp/array/filteredArr.ts @@ -0,0 +1,66 @@ +// @ts-nocheck +import { Factor, Color, callback } from '../../paramTypes'; +import { gt, gte, lt, lte } from '../number/comparison'; +import { inRange } from '../number/inRange'; +import { colorObjArr } from './colorObjArr'; + +/** + * @description Filters an array according to the value of a color's queried factor + * @param factor The property to query and use as filtering criteria + * @param cb The function to use for comparison + * @returns The filtered array + */ +const filteredArr = + (factor: Factor, cb?: callback) => + (colors: Color[], start: number | string, end: number): Color[] => { + let result: Color[]; + + if (typeof start === 'number') { + result = colorObjArr( + factor, + cb + )(colors) + .filter((color) => inRange(color[factor], start, end)) + .map((color) => color['name']); + + return result; + + // If string split the the string to an array of signature [sign,value] with sign being the type of predicate returned to mapFilter. + } else if (typeof start === 'string') { + //The pattern to match + const reOperator = /^(>=|<=|<|>)/; + + const value = /[0-9]*\.?[0-9]+/; + + // Array + const val = value.exec(start), + op = reOperator.exec(start); + + const mapFilter = (test: (x: number, y: number) => boolean): Color[] => { + return colorObjArr( + factor, + cb + )(colors) + .filter((el) => test(el[factor], parseFloat(val['0']))) + .map((el) => el['name']); + }; + switch (op['0']) { + case '<': + result = mapFilter(lt); + + break; + case '>': + result = mapFilter(gt); + break; + case '<=': + result = mapFilter(lte); + break; + case '>=': + result = mapFilter(gte); + break; + } + } + return result; + }; + +export { filteredArr }; diff --git a/src/fp/array/index.ts b/src/fp/array/index.ts new file mode 100644 index 00000000..42a2e514 --- /dev/null +++ b/src/fp/array/index.ts @@ -0,0 +1,7 @@ +// This module has array methods +// @ts-nocheck +export { min, max } from './min_max'; +export { colorObjArr } from './colorObjArr'; +export { customSort } from './customSort'; +export { filteredArr } from './filteredArr'; +export { sortedArr } from './sortedArr'; diff --git a/src/fp/array/min_max.ts b/src/fp/array/min_max.ts new file mode 100644 index 00000000..b1ea4c0b --- /dev/null +++ b/src/fp/array/min_max.ts @@ -0,0 +1,46 @@ +// @ts-nocheck + +import { gt, lt } from '../number/comparison'; + +// from the lodash implementation of _.min and _.max +const identity = (value) => { + return value; +}; +const baseExtremum = (array: number[], iteratee, comparator) => { + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index], + current = iteratee(value); + + if ( + current != null && + (computed === undefined + ? current === current + : comparator(current, computed)) + ) { + var computed = current, + result = value; + } + } + return result; +}; +/** + * @description Gets the smallest value in an array + * @param array The array to retrieve minimum value + * @returns The smallest number in the array + */ +const min = (array: number[]): number => { + return array && array.length ? baseExtremum(array, identity, lt) : undefined; +}; +/** + * @description Gets the largest value in an array + * @param array The array to retrieve maximum value + * @returns The largest number in the array + */ +const max = (array: number[]): number => { + return array && array.length ? baseExtremum(array, identity, gt) : undefined; +}; + +export { min, max }; diff --git a/src/fp/array/sortedArr.ts b/src/fp/array/sortedArr.ts new file mode 100644 index 00000000..0ae00f57 --- /dev/null +++ b/src/fp/array/sortedArr.ts @@ -0,0 +1,30 @@ +import { Factor, Color, callback, Order } from '../../paramTypes'; +import { colorObjArr } from './colorObjArr'; +import { customSort } from './customSort'; + +/** + * Filters an array of color objects with a "factor" property whose value is determined by a predicate or getter via the cb param. + * @param factor The property to query + * @param callback The function to use for comparison. + * @returns An array of colors or color objects. + */ +const sortedArr = + (factor: Factor, callback: callback, order: Order, colorObj = false) => + (colors: Color[]) => { + const results: Color[] | Array<{ factor: number; name: Color }> = + colorObjArr(factor, callback)(colors); + // (colorObj && color) || color['name']; + // Assign the value of colorObj to results variable + // Sort the array using our customSort helper function + results.sort(customSort(order, factor)); + + // colorObj parameter is true return the array of color objects + // else just return the color's name value. + if (colorObj) { + return results; + } else { + return results.map((color) => color['name']); + } + }; + +export { sortedArr }; diff --git a/src/fp/index.ts b/src/fp/index.ts index b3e8dc36..2f921de2 100644 --- a/src/fp/index.ts +++ b/src/fp/index.ts @@ -1,15 +1,4 @@ -export { - lt, - gt, - gte, - lte, - inRange, - floorCeil, - isInt, - normalize, - adjustHue, - random -} from './number'; -export { colorObjArr, filteredArr, sortedArr, max, min } from './array'; -export { colorObj } from './object'; -export { matchChromaChannel, expressionParser } from './string'; +export * from './number'; +export * from './array'; +export * from './object'; +export * from './string'; diff --git a/src/fp/number.ts b/src/fp/number.ts deleted file mode 100644 index 27754144..00000000 --- a/src/fp/number.ts +++ /dev/null @@ -1,93 +0,0 @@ -// This module has number methods -// @ts-nocheck - -const { ceil, floor } = Math; - -/** - * @description Normalizes passed in values to 0 and 1 - * @param start - * @param end - */ -const normalize = (num: number, start: number, end: number): number => { - return num * (end - start); -}; - -const random = (min: number, max: number): number => { - if (min > max) { - const mn = min; - const mx = max; - max = mn; - min = mx; - } else { - return Math.random() * (max - min) + min; - } -}; - -const adjustHue = (value = 0) => { - if (value > 0) { - return (value += ceil(-value / 360) * 360); - } else { - return value % 360; - } -}; - -const inRange = (number: number, start: number, end?: number): boolean => { - /* Built-in method references for those with the same name as other `lodash` methods. */ - var nativeMax = Math.max, - nativeMin = Math.min; - return number >= nativeMin(start, end) && number < nativeMax(start, end); -}; - -/** - * Checks if a number is a float. - * @param num The number to query - * @returns True if the number is an integer else false - */ -const isInt = (num: number) => { - const reInt = /^-?[0-9]+$/; - return reInt.test(num.toString()); -}; - -/** - * @function - * Rounds up or down a number based on the float value. - * @param num The number to round up or down. - * @returns An integer - */ -const floorCeil = (num: number): number => { - if (isInt(num)) { - return num; - } else { - const strArr = num.toString().split('.'); - const float = strArr[1]; - - //If the decimal value is .4 and below it will be rounded down else it will be rounded up. - const reFloorCeil = (float: string) => /^[0-4]$/.test(float.charAt(0)); - - if (reFloorCeil(float)) { - num = floor(num); - } else { - num = ceil(num); - } - } - return num; -}; - -// Comparison operators -const gt = (x: number, y: number): boolean => x > y; -const lt = (x: number, y: number): boolean => x < y; -const gte = (x: number, y: number): boolean => x >= y; -const lte = (x: number, y: number): boolean => x <= y; - -export { - lt, - gt, - gte, - lte, - inRange, - floorCeil, - isInt, - normalize, - adjustHue, - random -}; diff --git a/src/fp/number/adjustHue.ts b/src/fp/number/adjustHue.ts new file mode 100644 index 00000000..38ef9e56 --- /dev/null +++ b/src/fp/number/adjustHue.ts @@ -0,0 +1,11 @@ +// @ts-nocheck + +const adjustHue = (value = 0) => { + if (value > 0) { + return (value += Math.ceil(-value / 360) * 360); + } else { + return value % 360; + } +}; + +export { adjustHue }; diff --git a/src/fp/number/comparison.ts b/src/fp/number/comparison.ts new file mode 100644 index 00000000..743598dd --- /dev/null +++ b/src/fp/number/comparison.ts @@ -0,0 +1,9 @@ +// @ts-nocheck + +// Comparison operators +const gt = (x: number, y: number): boolean => x > y; +const lt = (x: number, y: number): boolean => x < y; +const gte = (x: number, y: number): boolean => x >= y; +const lte = (x: number, y: number): boolean => x <= y; + +export { lt, gt, gte, lte }; diff --git a/src/fp/number/floorCeil.ts b/src/fp/number/floorCeil.ts new file mode 100644 index 00000000..32580ff6 --- /dev/null +++ b/src/fp/number/floorCeil.ts @@ -0,0 +1,29 @@ +import { isInt } from './isInt'; + +const { ceil, floor } = Math; +/** + * @function + * Rounds up or down a number based on the float value. + * @param num The number to round up or down. + * @returns An integer + */ +const floorCeil = (num: number): number => { + if (isInt(num)) { + return num; + } else { + const strArr = num.toString().split('.'); + const float = strArr[1]; + + //If the decimal value is .4 and below it will be rounded down else it will be rounded up. + const reFloorCeil = (float: string) => /^[0-4]$/.test(float.charAt(0)); + + if (reFloorCeil(float)) { + num = floor(num); + } else { + num = ceil(num); + } + } + return num; +}; + +export { floorCeil }; diff --git a/src/fp/number/inRange.ts b/src/fp/number/inRange.ts new file mode 100644 index 00000000..e98bfca1 --- /dev/null +++ b/src/fp/number/inRange.ts @@ -0,0 +1,10 @@ +// @ts-nocheck + +const inRange = (number: number, start: number, end?: number): boolean => { + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeMax = Math.max, + nativeMin = Math.min; + return number >= nativeMin(start, end) && number < nativeMax(start, end); +}; + +export { inRange }; diff --git a/src/fp/number/index.ts b/src/fp/number/index.ts new file mode 100644 index 00000000..9895d298 --- /dev/null +++ b/src/fp/number/index.ts @@ -0,0 +1,10 @@ +// This module has number methods +// @ts-nocheck + +export { lt, gt, gte, lte } from './comparison'; +export { random } from './random'; +export { isInt } from './isInt'; +export { normalize } from './normalize'; +export { floorCeil } from './floorCeil'; +export { adjustHue } from './adjustHue'; +export { inRange } from './inRange'; diff --git a/src/fp/number/isInt.ts b/src/fp/number/isInt.ts new file mode 100644 index 00000000..2377046e --- /dev/null +++ b/src/fp/number/isInt.ts @@ -0,0 +1,11 @@ +/** + * Checks if a number is a float. + * @param num The number to query + * @returns True if the number is an integer else false + */ +const isInt = (num: number) => { + const reInt = /^-?[0-9]+$/; + return reInt.test(num.toString()); +}; + +export { isInt }; diff --git a/src/fp/number/normalize.ts b/src/fp/number/normalize.ts new file mode 100644 index 00000000..743639a9 --- /dev/null +++ b/src/fp/number/normalize.ts @@ -0,0 +1,10 @@ +/** + * @description Normalizes passed in values to 0 and 1 + * @param start + * @param end + */ +const normalize = (num: number, start: number, end: number): number => { + return num * (end - start); +}; + +export { normalize }; diff --git a/src/fp/number/random.ts b/src/fp/number/random.ts new file mode 100644 index 00000000..d29ea33a --- /dev/null +++ b/src/fp/number/random.ts @@ -0,0 +1,12 @@ +const random = (min: number, max: number): number => { + if (min > max) { + const mn = min; + const mx = max; + max = mn; + min = mx; + } else { + return Math.random() * (max - min) + min; + } +}; + +export { random }; diff --git a/src/fp/object.ts b/src/fp/object.ts deleted file mode 100644 index 4647b6dc..00000000 --- a/src/fp/object.ts +++ /dev/null @@ -1,21 +0,0 @@ -// This module has object methods - -import type { callback, factor, Color } from '../paramTypes'; - -// @ts-nocheck -const colorObj = (factor: factor, callback: callback) => (color: Color) => { - return { [factor]: callback(color), name: color }; -}; - -const customConcat = (hue: object) => { - const res: number[] = []; - const { keys } = Object; - if (typeof hue == 'object') { - const hueKeys = keys(hue); - - //@ts-ignore - res.push(...hueKeys.map((key) => hue[key])); - } - return res; -}; -export { colorObj, customConcat }; diff --git a/src/fp/object/colorObj.ts b/src/fp/object/colorObj.ts new file mode 100644 index 00000000..240fbed1 --- /dev/null +++ b/src/fp/object/colorObj.ts @@ -0,0 +1,8 @@ +import type { callback, Factor, Color } from '../../paramTypes'; + +// @ts-nocheck +const colorObj = (factor: Factor, callback: callback) => (color: Color) => { + return { [factor]: callback(color), name: color }; +}; + +export { colorObj }; diff --git a/src/fp/object/customConcat.ts b/src/fp/object/customConcat.ts new file mode 100644 index 00000000..922c7496 --- /dev/null +++ b/src/fp/object/customConcat.ts @@ -0,0 +1,15 @@ +// @ts-nocheck + +const customConcat = (hue: object) => { + const res: number[] = []; + const { keys } = Object; + if (typeof hue == 'object') { + const hueKeys = keys(hue); + + //@ts-ignore + res.push(...hueKeys.map((key) => hue[key])); + } + return res; +}; + +export { customConcat }; diff --git a/src/fp/object/customFindKey.ts b/src/fp/object/customFindKey.ts new file mode 100644 index 00000000..2e8f58b6 --- /dev/null +++ b/src/fp/object/customFindKey.ts @@ -0,0 +1,31 @@ +import { inRange } from '../number/inRange.js'; +import { max, min } from '../array/min_max.js'; +import { customConcat } from '../object/customConcat.js'; + +/** + + * + * @private + * @param {Array|Object} collection The collection to inspect. + * @param {Function} predicate The function invoked per iteration. + * @param {number} factor The value to compare against + * @returns {*} Returns the found element or its key, else `undefined`. + */ +export const customFindKey = (collection: object, factor: number) => { + // If the color is achromatic return the string gray + const propKeys = Object.keys(collection); + + const result: string = propKeys + .filter((key) => { + const hueVals = customConcat(collection[key]); + // @ts-ignore + const minVal = min(...hueVals); + // @ts-ignore + const maxVal = max(...hueVals); + // Capture the min and max values and see if the passed in color is within that range + return inRange(factor, minVal, maxVal); + }) + .toString(); + + return result; +}; diff --git a/src/fp/object/index.ts b/src/fp/object/index.ts new file mode 100644 index 00000000..bea29240 --- /dev/null +++ b/src/fp/object/index.ts @@ -0,0 +1,5 @@ +// This module has object methods + +export { colorObj } from './colorObj'; +export { customConcat } from './customConcat'; +export { customFindKey } from './customFindKey'; diff --git a/src/fp/string.ts b/src/fp/string/expressionParser.ts similarity index 59% rename from src/fp/string.ts rename to src/fp/string/expressionParser.ts index 172c8384..f87b85d9 100644 --- a/src/fp/string.ts +++ b/src/fp/string/expressionParser.ts @@ -1,4 +1,5 @@ // @ts-nocheck +import { Color } from '../../paramTypes'; /** * Performs arithmetic operations on colors by passing the arithmetic operator from the value if it is a string. It requires the src variable to be declared in the global scope of the invoking func. @@ -6,12 +7,7 @@ * @param channel The channel to set. * @param value The value to apply. */ - -const expressionParser = ( - src: Color, - channel: string, - value: string -): number => { +function expressionParser(src: Color, channel: string, value: string): number { // regExp to match arithmetic operator and the value const reOperator = /^(\*|\+|\-|\/)/; const reValue = /[0-9]*\.?[0-9]+/; @@ -40,26 +36,5 @@ const expressionParser = ( src[channel] = +cb(amt['0']); } return src; -}; - -/** - * @function - * Matches the chroma/saturation channel of any compliant color space - * @param colorSpace The color space to match saturation/chroma channel. - * @returns The mode channel string passed to getChannel() - */ -const matchChromaChannel = (colorSpace: HueColorSpaces | string): string => { - // Matches any string with c or s - const reChroma = /(s|c)/; - const ch = reChroma.exec(colorSpace); - - if (reChroma.test(colorSpace)) { - return `${colorSpace}.${ch[0]}`; - } else { - throw Error( - `The color space ${colorSpace} has no chroma/saturation channel.` - ); - } -}; - -export { matchChromaChannel, expressionParser }; +} +export { expressionParser }; diff --git a/src/fp/string/index.ts b/src/fp/string/index.ts new file mode 100644 index 00000000..a45c8a6d --- /dev/null +++ b/src/fp/string/index.ts @@ -0,0 +1,2 @@ +export { matchChromaChannel } from './matchChromaChannel'; +export { expressionParser } from './expressionParser'; diff --git a/src/fp/string/matchChromaChannel.ts b/src/fp/string/matchChromaChannel.ts new file mode 100644 index 00000000..8d37c40d --- /dev/null +++ b/src/fp/string/matchChromaChannel.ts @@ -0,0 +1,23 @@ +import { HueColorSpaces } from '../../paramTypes'; + +/** + * @function + * Matches the chroma/saturation channel of any compliant color space + * @param colorSpace The color space to match saturation/chroma channel. + * @returns The mode channel string passed to getChannel() + */ +const matchChromaChannel = (colorSpace: HueColorSpaces | string): string => { + // Matches any string with c or s + const reChroma = /(s|c)/; + const ch = reChroma.exec(colorSpace); + + if (reChroma.test(colorSpace)) { + return `${colorSpace}.${ch[0]}`; + } else { + throw Error( + `The color space ${colorSpace} has no chroma/saturation channel.` + ); + } +}; + +export { matchChromaChannel }; diff --git a/src/getters_and_setters/alpha.ts b/src/getters_and_setters/alpha.ts index b11bf1ff..49b4d3ac 100644 --- a/src/getters_and_setters/alpha.ts +++ b/src/getters_and_setters/alpha.ts @@ -1,7 +1,7 @@ //@ts-nocheck import { useMode, modeLch } from 'culori/fn'; -import { inRange } from '../fp/number.js'; -import { expressionParser } from '../fp/string.js'; +import { inRange } from '../fp/number/inRange.js'; +import { expressionParser } from '../fp/string/expressionParser.js'; import { toHex } from '../converters/toHex.js'; import type { Color } from '../paramTypes.js'; diff --git a/src/getters_and_setters/darken.ts b/src/getters_and_setters/darken.ts index b0b1bfb6..96c3169a 100644 --- a/src/getters_and_setters/darken.ts +++ b/src/getters_and_setters/darken.ts @@ -1,7 +1,7 @@ //@ts-nocheck import { easingSmootherstep, modeLab, useMode } from 'culori/fn'; import { toHex } from '../converters/toHex'; -import { expressionParser } from '../fp/string'; +import { expressionParser } from '../fp/string/expressionParser'; import type { Color } from '../paramTypes'; // ported froma chroma-js brighten const toLab = useMode(modeLab); diff --git a/src/getters_and_setters/set.ts b/src/getters_and_setters/set.ts index 344573d6..98196f47 100644 --- a/src/getters_and_setters/set.ts +++ b/src/getters_and_setters/set.ts @@ -5,7 +5,7 @@ import { converter } from 'culori/fn'; import 'culori/css'; import { toHex } from '../converters/toHex.js'; -import { expressionParser } from '../fp/string.js'; +import { expressionParser } from '../fp/string/expressionParser.js'; import type { Color } from '../paramTypes.js'; /** * @function diff --git a/src/palettes/adaptive.ts b/src/palettes/adaptive.ts new file mode 100644 index 00000000..2b510e9c --- /dev/null +++ b/src/palettes/adaptive.ts @@ -0,0 +1,3 @@ +// @ts-nocheck + +// This module will make use of contrast ratio to create adaptive palettes diff --git a/src/palettes/base.ts b/src/palettes/base.ts index 1878f64d..8a974a7e 100644 --- a/src/palettes/base.ts +++ b/src/palettes/base.ts @@ -2,7 +2,8 @@ import { useMode, modeLch, easingSmoothstep, samples } from 'culori/fn'; import type { Color } from '../paramTypes.ts'; -import { adjustHue, random } from '../fp/number.ts'; +import { adjustHue } from '../fp/number/adjustHue.ts'; +import { random } from '../fp/number/random.ts'; import { toHex } from '../converters/toHex.ts'; // Globals const cb = (iterations: number, distance: number, color: Color) => @@ -15,6 +16,7 @@ const cb = (iterations: number, distance: number, color: Color) => * @description Generates a randomised classic color scheme from a single base color. * @param scheme Any classic color scheme either "analogous"|"triadic"|"tetradic"|"complementary"|"splitComplementary". * @param hex Optional boolen to return lch color objects or hex codes in the result array. Default is false which returns LCH color objects. + * @param easingFunc Optional parameter to pass in a custom easing function. The default is smoothstep * @returns An array of 8 character hex codes. Elements in the array depend on the number of sample colors in the targeted scheme. * @example * @@ -26,7 +28,9 @@ console.log(base("triadic")("#a1bd2f", true)) const base = (scheme: 'analogous' | 'triadic' | 'tetradic' | 'complementary') => - (color: Color, hex = false): Color[] => { + (color: Color, hex = false, easingFunc: (t: number) => number): Color[] => { + scheme = scheme.toLowerCase(); + easingFunc = easingFunc || easingSmoothstep; // Converting the color to lch const lch = useMode(modeLch); color = lch(color); @@ -50,10 +54,10 @@ const base = } // The map for steps to obtain the targeted palettes - const colors = targetHueSteps[scheme.toLowerCase()].map((step: number) => ({ + const colors = targetHueSteps[scheme].map((step: number) => ({ l: color['l'], c: color['c'], - h: step, + h: step * easingFunc(1 / targetHueSteps[scheme].length), mode: 'lch' })); diff --git a/src/palettes/discoverPalettes.ts b/src/palettes/discoverPalettes.ts index ec153a74..6208f8e2 100644 --- a/src/palettes/discoverPalettes.ts +++ b/src/palettes/discoverPalettes.ts @@ -1,7 +1,8 @@ // @ts-nocheck -import { nearest, differenceEuclidean, converter, formatHex8 } from 'culori'; +import { nearest, differenceEuclidean, useMode, modeLch } from 'culori/fn'; import { Color } from '../paramTypes'; import { base } from './base.ts'; +import { toHex } from '../converters/toHex.ts'; const { keys } = Object; const isColorEqual = (c1: Color, c2: Color): boolean => { @@ -39,7 +40,8 @@ const discoverPalettes = ( colors: Color[], scheme: 'analogous' | 'triadic' | 'tetradic' | 'complementary' ): Color[] | object => { - colors = colors.map((c) => converter('lch')(c)); + const toLch = useMode(modeLch); + colors = colors.map((color) => toLch('lch')(toHex(color))); const palettes = {}; const schemes = ['analogous', 'triadic', 'tetradic', 'complementary']; const targetPalettes = {}; @@ -72,12 +74,14 @@ const discoverPalettes = ( } } - if (typeof scheme == 'string') { + if (typeof scheme === 'string') { return palettes[scheme.toLowerCase()]; - } else if (typeof scheme == 'undefined') { + } else if (typeof scheme === 'undefined') { return palettes; } else { - throw Error(`${scheme} is not a valid palette scheme.`); + throw Error( + `${scheme} is not a valid scheme. The schemes are triadic | tetradic | analogous | complementary` + ); } }; diff --git a/src/palettes/earthtone.ts b/src/palettes/earthtone.ts index 35fdd867..1ab83612 100644 --- a/src/palettes/earthtone.ts +++ b/src/palettes/earthtone.ts @@ -6,19 +6,23 @@ import { samples, easingSmootherstep, interpolatorSplineNatural, - fixupHueShorter + fixupHueShorter, + interpolatorSplineMonotone, + interpolatorSplineBasisClosed } from 'culori/fn'; -import type { Color, earthtones } from '../paramTypes.ts'; +import type { Color, Earthtones, EarthtoneOptions } from '../paramTypes.ts'; import { toHex } from '../converters/toHex.ts'; +//Add an overrides object with interpolation function and + /** * @function * @description Creates a scale of a spline based interpolation between an earthtone and a color. * @param color The color to interpolate an earth tone with. * @param earthtone The earthtone to interpolate with. - * @param num The number of iterations to produce from the color and earthtone. + * @param iterations The number of iterations to produce from the color and earthtone. + * @param options Optional overrides for customising interpolation and easing functions. * @returns The array of colors resulting from the earthtone interpolation as hex codes. - * * @example * * import { earthtone } from 'huetiful-js' @@ -29,8 +33,20 @@ console.log(earthtone("pink", "clay", 5)) */ -//Add an overrides object with interpolation function and -const earthtone = (color: Color, earthtone: earthtones, num = 1): Color[] => { +const earthtone = ( + color: Color, + earthtone?: Earthtones, + iterations?: number, + options?: EarthtoneOptions +): Color[] => { + options = { + easingFunc: easingSmootherstep, + hueInterpolator: interpolatorSplineBasisClosed, + chromaInterpolator: interpolatorSplineNatural, + hueFixup: fixupHueShorter, + lightnessInterpolator: interpolatorSplineMonotone + }; + iterations = iterations < 1 ? 1 : iterations; earthtone = earthtone.toLowerCase(); const tones = { 'light-gray': '#e5e5e5', @@ -46,14 +62,24 @@ const earthtone = (color: Color, earthtone: earthtones, num = 1): Color[] => { }; const base: Color = tones[earthtone || 'dark']; - const f = interpolate([base, toHex(color), easingSmootherstep], 'lch', { + const f = interpolate([base, toHex(color), options['easingFunc']], 'lch', { h: { - use: interpolatorSplineNatural, - fixup: fixupHueShorter + fixup: options['hueFixup'], + use: options['hueInterpolator'] + }, + c: { + use: options['chromaInterpolator'] + }, + l: { + use: options['lightnessInterpolator'] } }); - return samples(num).map((t) => toHex(f(t))); + if (iterations === 1) { + return toHex(f(0.5)); + } else { + return samples(iterations).map((t) => toHex(f(t))); + } }; export { earthtone }; diff --git a/src/palettes/getComplimentaryHue.ts b/src/palettes/getComplimentaryHue.ts index e6b6a1af..4deff96e 100644 --- a/src/palettes/getComplimentaryHue.ts +++ b/src/palettes/getComplimentaryHue.ts @@ -1,9 +1,10 @@ // @ts-nocheck import hueTempMap from '../color-maps/samples/hueTemperature'; import { getChannel } from '../getters_and_setters/get.ts'; -import { min, max } from '../fp/array.ts'; -import { customConcat } from '../fp/object.ts'; -import { adjustHue, inRange } from '../fp/number.ts'; +import { min, max } from '../fp/array/min_max.ts'; +import { customConcat } from '../fp/object/customConcat.ts'; +import { inRange } from '../fp/number/inRange.ts'; +import { adjustHue } from '../fp/number/adjustHue.ts'; import { setChannel } from '../getters_and_setters/set.ts'; import type { Color } from '../paramTypes'; import { toHex } from '../converters/toHex.ts'; diff --git a/src/palettes/getHue.ts b/src/palettes/getHue.ts index 40679164..69dba642 100644 --- a/src/palettes/getHue.ts +++ b/src/palettes/getHue.ts @@ -3,11 +3,11 @@ // @ts-nocheck import hueTempMap from '../color-maps/samples/hueTemperature'; import { useMode, modeLch } from 'culori/fn'; -import { inRange } from '../fp/number.ts'; -import { min, max } from '../fp/array.ts'; -import { customConcat } from '../fp/object.ts'; +import { inRange } from '../fp/number/inRange.ts'; +import { min, max } from '../fp/array/min_max.ts'; +import { customConcat } from '../fp/object/customConcat.ts'; import { toHex } from '../converters/toHex.ts'; -import type { Color, hue } from '../paramTypes'; +import type { Color, Hue } from '../paramTypes'; /** *@function @@ -22,7 +22,7 @@ import type { Color, hue } from '../paramTypes'; console.log(getHue("#310000")) // red */ -const getHue = (color: Color): hue => { +const getHue = (color: Color): Hue => { // First convert the color to LCH const lch = useMode(modeLch); color = lch(toHex(color)); diff --git a/src/palettes/hueShift.ts b/src/palettes/hueShift.ts index d3706a4b..def39c49 100644 --- a/src/palettes/hueShift.ts +++ b/src/palettes/hueShift.ts @@ -4,7 +4,7 @@ import { easingSmootherstep, modeLch, samples, useMode } from 'culori/fn'; import type { Color } from '../paramTypes.ts'; -import { adjustHue } from '../fp/number.ts'; +import { adjustHue } from '../fp/number/adjustHue.ts'; import { toHex } from '../converters/toHex.ts'; const lightnessMapper = @@ -22,12 +22,12 @@ const lightnessMapper = * @param iterations The number of iterations to perform on the color. The length of the resultant array is the number of iterations multiplied by 2 plus the base color passed or (iterations*2)+1. * @param hueStep Controls how much the hue will shift at each iteration. * @param hex Optional boolen to return lch color objects or hex codes in the result array. Default is false which returns LCH color objects. - * @returns An array of colors. + * @returns An array of colors in either hex or as LCH color objects. * @example * * import { hueShift } from "huetiful-js"; -let hueShiftedPalette = hueShift("#3e0000", {}, true); +let hueShiftedPalette = hueShift("#3e0000",true); console.log(hueShiftedPalette); @@ -43,63 +43,74 @@ console.log(hueShiftedPalette); const hueShift = ( color: Color, + hex = false, { minLightness, maxLightness, hueStep, - iterations + iterations, + easingFn }: { minLightness?: number; maxLightness?: number; hueStep?: number; iterations?: number; - }, - hex = false + easingFn: (t: number) => number; + } ): Color[] => { - const lch = useMode(modeLch); - - color = lch(toHex(color)); - - // Pass in default values if any of the opts is undefined minLightness = minLightness || 10; maxLightness = maxLightness || 90; hueStep = hueStep || 5; iterations = iterations || 6; + easingFn = easingSmootherstep || easingFn; + const toLch = useMode(modeLch); + + color = toLch(toHex(color)); + + // Pass in default values if any of the opts is undefined const palette: Color[] = [color]; + // Maximum number of iterations possible. + const MAX_SAFE_ITERATIONS = 360 / hueStep; //Each iteration add a darker shade to the start of the array and a lighter tint to the end. - samples(iterations).map((t) => { - //adjustHue checks hue values are clamped. - const hueDark = adjustHue(color['h'] - hueStep * t); - const hueLight = adjustHue(color['h'] + hueStep * t); - - // Here we use lightnessMapper to calculate our lightness values which takes a number that exists in range [0,1]. - const lightnessDark = lightnessMapper(easingSmootherstep(t))( - 0.1, - iterations - )(color['l'], minLightness); - - const lightnessLight = lightnessMapper(easingSmootherstep(t))( - 0.05, - iterations - )(color['l'], maxLightness); - - palette.push({ - l: lightnessDark, - c: color['c'], - h: hueDark, - mode: 'lch' - }); - - palette.unshift({ - l: lightnessLight, - c: color['c'], - h: hueLight, - mode: 'lch' + if (iterations <= MAX_SAFE_ITERATIONS) { + samples(iterations).map((t) => { + //adjustHue checks hue values are clamped. + const hueDark = adjustHue(color['h'] - hueStep * t); + const hueLight = adjustHue(color['h'] + hueStep * t); + + // Here we use lightnessMapper to calculate our lightness values which takes a number that exists in range [0,1]. + const lightnessDark = lightnessMapper(easingFn(t))(0.1, iterations)( + color['l'], + minLightness + ); + + const lightnessLight = lightnessMapper(easingFn(t))(0.05, iterations)( + color['l'], + maxLightness + ); + + palette.push({ + l: lightnessDark, + c: color['c'], + h: hueDark, + mode: 'lch' + }); + + palette.unshift({ + l: lightnessLight, + c: color['c'], + h: hueLight, + mode: 'lch' + }); }); - }); + } else { + throw Error( + `The number of iterations exceeds the maximum number of iterations. The maximum iterations are determined by the size of the hueStep. To find the maximum iterations possible, use this formula: 360/hueStep` + ); + } if (hex) { return palette.map(toHex); diff --git a/src/palettes/paired.ts b/src/palettes/paired.ts index 4b37021e..d3f69a0d 100644 --- a/src/palettes/paired.ts +++ b/src/palettes/paired.ts @@ -3,16 +3,15 @@ import { toHex } from '../converters/toHex.ts'; import { setChannel } from '../getters_and_setters/set.ts'; -import { Color, tone } from '../paramTypes.ts'; +import { Color, EarthtoneOptions, Tone } from '../paramTypes.ts'; import { + interpolate, + samples, easingSmootherstep, + interpolatorSplineNatural, fixupHueShorter, - interpolate, - interpolatorSplineBasis, + interpolatorSplineMonotone, interpolatorSplineBasisClosed, - interpolatorSplineNatural, - fixupAlpha, - samples, useMode, modeLch } from 'culori/fn'; @@ -23,7 +22,7 @@ import { * @param color The color to return a paired color scheme from. * @param via The tone to interpolate through (either white or black). Default is white. * @param hueStep The value to increment the base color's hue channel with. - * @param num The number of color samples to generate. + * @param iterations The number of color samples to generate. * @param overrides The optional overrides object to customize per channel options like interpolation methods and channel fixups. * @returns An array containing the paired scheme. * @example @@ -36,9 +35,18 @@ console.log(pairedScheme("green", 6, 5, "dark")) const pairedScheme = ( color: Color, hueStep: number, - num: number, - via: tone + iterations: number, + via: Tone, + options: EarthtoneOptions ): Color[] => { + // eslint-disable-next-line prefer-const + options = { + easingFunc: defaultArg(easingSmootherstep), + hueInterpolator: defaultArg(interpolatorSplineBasisClosed), + chromaInterpolator: defaultArg(interpolatorSplineNatural), + hueFixup: defaultArg(fixupHueShorter), + lightnessInterpolator: defaultArg(interpolatorSplineMonotone) + }; const toLch = useMode(modeLch); color = toLch(toHex(color)); @@ -48,17 +56,20 @@ const pairedScheme = ( // Set the tones to color objects with hardcoded hue values and lightness channels clamped at extremes const tones = { dark: '#263238', - light: { l: 100, c: 0.1, h: 0, mode: 'lch' } + light: { l: 100, c: 0, h: 0, mode: 'lch' } }; const scale = interpolate([color, tones[via || 'dark'], derivedHue], 'lch', { h: { - use: interpolatorSplineBasis, - fixup: fixupHueShorter + fixup: options['hueFixup'], + use: options['hueInterpolator'] + }, + c: { + use: options['chromaInterpolator'] }, - c: interpolatorSplineNatural, - l: interpolatorSplineBasisClosed, - alpha: { fixup: fixupAlpha } + l: { + use: options['lightnessInterpolator'] + } }); const { abs, round } = Math; @@ -66,7 +77,7 @@ const pairedScheme = ( // Declare the num of iterations in samples() which will be used as the t value // Since the interpolation returns half duplicate values we double the sample value // Guard the num param against negative values and floats - const smp = samples((round(abs(num)) || 4) * 2); + const smp = samples((round(abs(iterations)) || 4) * 2); //The array to capture the different iterations const results: Color[] = smp.map((t) => diff --git a/src/palettes/pastel.ts b/src/palettes/pastel.ts index eeed59a0..344396a4 100644 --- a/src/palettes/pastel.ts +++ b/src/palettes/pastel.ts @@ -2,8 +2,8 @@ // Pastels.mjs. - This module creates pastel versions of a color. It will take an arr or single value , tweak it and then return the result. Optional overrides for min max values when iterating over an arr. import type { Color } from '../paramTypes.ts'; import { averageNumber, modeHsv, useMode } from 'culori/fn'; -import { min, max } from '../fp/array.ts'; -import { random } from '../fp/number.ts'; +import { min, max } from '../fp/array/min_max.ts'; +import { random } from '../fp/number/random.ts'; import { toHex } from '../converters/toHex.js'; const samplePastelObj = [ diff --git a/src/paramTypes.d.ts b/src/paramTypes.d.ts index 0242ca6d..e6226f52 100644 --- a/src/paramTypes.d.ts +++ b/src/paramTypes.d.ts @@ -1,5 +1,13 @@ -export type tone = 'light' | 'dark'; -export type hue = +export type EarthtoneOptions = { + easingFunc?: (t: number) => number; + hueInterpolator?: Interpolator; + chromaInterpolator?: Interpolator; + hueFixup?: (arr: number[]) => number[]; + lightnessInterpolator?: Interpolator; +}; +export type Interpolator = (arr: number[]) => (t: number) => number; +export type Tone = 'light' | 'dark'; +export type Hue = | 'red-purple' | 'red' | 'yellow-red' @@ -11,7 +19,7 @@ export type hue = | 'purple-blue' | 'purple'; -export type earthtones = +export type Earthtones = | 'light gray' | 'silver' | 'sand' @@ -22,7 +30,7 @@ export type earthtones = | 'cocoa' | 'dark brown' | 'dark'; -export type divergingScheme = +export type DivergingScheme = | 'Spectral' | 'RdYlGn' | 'RdBu' @@ -32,7 +40,7 @@ export type divergingScheme = | 'BrBG' | 'RdGy' | 'PuOr'; -export type qualitativeScheme = +export type QualitativeScheme = | 'Set2' | 'Accent' | 'Set1' @@ -42,7 +50,7 @@ export type qualitativeScheme = | 'Pastel2' | 'Pastel1'; -export type sequentialScheme = +export type SequentialScheme = | 'OrRd' | 'PuBu' | 'BuPu' @@ -78,7 +86,7 @@ export type Color = * @type * The property being queried. Used in utilities that perform operations on collections. */ -export type factor = +export type Factor = | 'luminance' | 'temp' | 'saturation' @@ -87,14 +95,14 @@ export type factor = | 'lightness' | 'hue'; -type order = 'asc' | 'desc'; +type Order = 'asc' | 'desc'; type callback = (arg: Color, colorSpace?: HueColorSpaces) => number; -type factorMapper = ( - factor: factor, +type FactorMapper = ( + factor: Factor, callback: callback, - order?: order, + order?: Order, colorObj = false ) => (colors: Color[]) => Color[]; diff --git a/src/sortBy/sortByContrast.ts b/src/sortBy/sortByContrast.ts index d72ad9cf..9e9b0939 100644 --- a/src/sortBy/sortByContrast.ts +++ b/src/sortBy/sortByContrast.ts @@ -1,6 +1,6 @@ // @ts-nocheck -import type { factor, Color } from '../paramTypes.ts'; -import { sortedArr } from '../fp/array.ts'; +import type { Factor, Color } from '../paramTypes.ts'; +import { sortedArr } from '../fp/array/sortedArr.ts'; import { wcagContrast } from 'culori/fn'; /** @@ -27,7 +27,7 @@ const sortByContrast = ( against: Color, order: 'asc' | 'desc' ): Color[] => { - const factor: factor = 'contrast'; + const factor: Factor = 'contrast'; const cb = (against: Color) => (color: Color) => wcagContrast(color, against); //Sorting the color array of object by the 'temp' property in the specified order. diff --git a/src/sortBy/sortByDistance.ts b/src/sortBy/sortByDistance.ts index bd1cb6f4..414caffd 100644 --- a/src/sortBy/sortByDistance.ts +++ b/src/sortBy/sortByDistance.ts @@ -1,6 +1,6 @@ // @ts-nocheck -import type { factor, Color, ColorSpaces } from '../paramTypes.ts'; -import { sortedArr } from '../fp/array.ts'; +import type { Factor, Color, ColorSpaces } from '../paramTypes.ts'; +import { sortedArr } from '../fp/array/sortedArr.ts'; import { differenceEuclidean } from 'culori/fn'; /** @@ -41,7 +41,7 @@ const sortByDistance = ( mode?: ColorSpaces, weights?: [number, number, number, number] ): Color[] => { - const factor: factor = 'distance'; + const factor: Factor = 'distance'; const cb = (against: Color, mode: ColorSpaces) => (color: Color) => differenceEuclidean(mode || 'lch', weights || [1, 1, 1, 0])(against, color); //Sorting the color array of object by the 'distance' property in the specified order. diff --git a/src/sortBy/sortByHue.ts b/src/sortBy/sortByHue.ts index 57804fb9..ffee0b41 100644 --- a/src/sortBy/sortByHue.ts +++ b/src/sortBy/sortByHue.ts @@ -1,8 +1,8 @@ // @ts-nocheck import { getChannel } from '../getters_and_setters/get.ts'; -import { sortedArr } from '../fp/array.ts'; +import { sortedArr } from '../fp/array/sortedArr.ts'; -import type { factor, Color } from '../paramTypes.ts'; +import type { Factor, Color } from '../paramTypes.ts'; /** * @function @@ -53,7 +53,7 @@ console.log(sortedDescending) // Todo: Add the mode param so that users can select mode to work with. The default is const sortByHue = (colors: Color[], order: 'asc' | 'desc'): Color[] => { - const factor: factor = 'hue'; + const factor: Factor = 'hue'; const cb = getChannel('lch.h'); //Sorting the color array of object by the 'temp' property in the specified order. diff --git a/src/sortBy/sortByLightness.ts b/src/sortBy/sortByLightness.ts index 14f11a74..5d009d37 100644 --- a/src/sortBy/sortByLightness.ts +++ b/src/sortBy/sortByLightness.ts @@ -1,7 +1,7 @@ // @ts-nocheck -import type { factor, Color } from '../paramTypes.ts'; +import type { Factor, Color } from '../paramTypes.ts'; import { getChannel } from '../getters_and_setters/get.ts'; -import { sortedArr } from '../fp/array.ts'; +import { sortedArr } from '../fp/array/sortedArr.ts'; /** * @function @@ -52,7 +52,7 @@ sortByLightness(sample,'desc') */ const sortByLightness = (colors: Color[], order: 'asc' | 'desc'): Color[] => { - const factor: factor = 'lightness'; + const factor: Factor = 'lightness'; const cb = getChannel('lch.l'); //Sorting the color array of object by the 'temp' property in the specified order. diff --git a/src/sortBy/sortByLuminance.ts b/src/sortBy/sortByLuminance.ts index e6d781b9..1cfb4984 100644 --- a/src/sortBy/sortByLuminance.ts +++ b/src/sortBy/sortByLuminance.ts @@ -1,6 +1,6 @@ // @ts-nocheck -import type { factor, Color } from '../paramTypes.ts'; -import { sortedArr } from '../fp/array.ts'; +import type { Factor, Color } from '../paramTypes.ts'; +import { sortedArr } from '../fp/array/sortedArr.ts'; import { getLuminance } from '../getters_and_setters/luminance.ts'; /** @@ -53,7 +53,7 @@ console.log(sortedDescending) */ const sortByLuminance = (colors: Color[], order: 'asc' | 'desc'): Color[] => { - const factor: factor = 'luminance'; + const factor: Factor = 'luminance'; const cb = getLuminance; //Sorting the color array of object by the 'temp' property in the specified order. diff --git a/src/sortBy/sortBySaturation.ts b/src/sortBy/sortBySaturation.ts index 459ce8ba..03d07847 100644 --- a/src/sortBy/sortBySaturation.ts +++ b/src/sortBy/sortBySaturation.ts @@ -1,7 +1,7 @@ // @ts-nocheck -import type { factor, Color } from '../paramTypes.ts'; +import type { Factor, Color } from '../paramTypes.ts'; import { getChannel } from '../getters_and_setters/get.ts'; -import { sortedArr } from '../fp/array.ts'; +import { sortedArr } from '../fp/array/sortedArr.ts'; /** * @function @@ -51,7 +51,7 @@ console.log(sortedDescending) */ const sortBySaturation = (colors: Color[], order: 'asc' | 'desc'): Color[] => { - const factor: factor = 'saturation'; + const factor: Factor = 'saturation'; const cb = getChannel('lch.c'); //Sorting the color array of object by the 'temp' property in the specified order. diff --git a/src/sortBy/sortByTemp.ts b/src/sortBy/sortByTemp.ts index 9bc87927..61cd7597 100644 --- a/src/sortBy/sortByTemp.ts +++ b/src/sortBy/sortByTemp.ts @@ -1,7 +1,7 @@ //@ts-nocheck import { getTemp } from '../converters/getTemp.ts'; -import type { Color, factor } from '../paramTypes.ts'; -import { sortedArr } from '../fp/array.ts'; +import type { Color, Factor } from '../paramTypes.ts'; +import { sortedArr } from '../fp/array/sortedArr.ts'; /** * @function @@ -35,7 +35,7 @@ console.log(sortedDescending) const sortByTemp = (colors: Color[], order: 'asc' | 'desc'): Color[] => { // Purifying the data.All colors are converted to the specified mode to ensure unbiased results. - const factor: factor = 'temp'; + const factor: Factor = 'temp'; const cb = getTemp; //Sorting the color array of object by the 'temp' property in the specified order.