pax_global_header 0000666 0000000 0000000 00000000064 14223624663 0014522 g ustar 00root root 0000000 0000000 52 comment=f998e9b67936dbe4d35e43cc0772717bd9ce8ea2
fabiospampinato-khroma-f998e9b/ 0000775 0000000 0000000 00000000000 14223624663 0016616 5 ustar 00root root 0000000 0000000 fabiospampinato-khroma-f998e9b/.editorconfig 0000664 0000000 0000000 00000000224 14223624663 0021271 0 ustar 00root root 0000000 0000000
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
fabiospampinato-khroma-f998e9b/.gitignore 0000664 0000000 0000000 00000000642 14223624663 0020610 0 ustar 00root root 0000000 0000000
# Numerous always-ignore extensions
*.diff
*.err
*.log
*.orig
*.rej
*.swo
*.swp
*.vi
*.zip
*~
*.sass-cache
*.ruby-version
*.rbenv-version
# OS or Editor folders
._*
.cache
.DS_Store
.idea
.project
.settings
.tmproj
*.esproj
*.sublime-project
*.sublime-workspace
nbproject
Thumbs.db
.fseventsd
.DocumentRevisions*
.TemporaryItems
.Trashes
# Other paths to ignore
bower_components
node_modules
package-lock.json
dist
fabiospampinato-khroma-f998e9b/LICENSE 0000664 0000000 0000000 00000002121 14223624663 0017617 0 ustar 00root root 0000000 0000000 The MIT License (MIT)
Copyright (c) 2019-present Fabio Spampinato, Andrew Maney
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
fabiospampinato-khroma-f998e9b/README.md 0000664 0000000 0000000 00000026453 14223624663 0020107 0 ustar 00root root 0000000 0000000 # [Khrôma](https://en.wiktionary.org/wiki/%CF%87%CF%81%E1%BF%B6%CE%BC%CE%B1#Noun)
A collection of functions for manipulating CSS colors, inspired by SASS.
## Features
- **Small**: the entire library weighs ~5kb (min + gzip) and has no dependencies.
- **Fast**: in our benchmark suite functions are executed at ~0.0025ms per call on a mid-2014 MBP.
- **Flexible**: All valid CSS colors are supported.
- **SASS-like**: if you're familiar with SASS you should feel right at home.
## Install
```sh
npm install --save khroma
```
## Usage
```ts
import {red, isDark, darken, change} from 'khroma';
red ( '#ffffff' ); // => 255
isDark ( 'white' ); // => false
darken ( 'hsl(0, 5%, 100%)', 50 ); // => 'hsl(0, 5%, 50%)'
change ( 'rgb(255, 255, 255)', { a: 0.5 } ); // => 'rgba(255, 255, 255, 0.5)'
```
## Functions
These are all the provided functions, for each of them below you can find a short description, its interface and examples.
| Create | Convert | Get channel | Get more | Edit channel | Edit more |
| ------------- | ----------------------- | ------------------------- | ----------------------- | --------------------------------- | -------------------- |
| [hex](#hex) | [toKeyword](#tokeyword) | [channel](#channel) | [contrast](#contrast) | [saturate](#saturate) | [adjust](#adjust) |
| [rgb](#rgb) | [toHex](#tohex) | [red](#red) | [luminance](#luminance) | [desaturate](#desaturate) | [change](#change) |
| [rgba](#rgba) | [toRgba](#torgba) | [green](#green) | [isDark](#isdark) | [lighten](#lighten) | [invert](#invert) |
| [hsl](#hsl) | [toHsla](#tohsla) | [blue](#blue) | [isLight](#islight) | [darken](#darken) | [mix](#mix) |
| [hsla](#hsla) | | [hue](#hue) | [isValid](#isvalid) | [opacify](#opacify) | [scale](#scale) |
| | | [saturation](#saturation) | | [fadeIn](#fadein) | |
| | | [lightness](#lightness) | | [transparentize](#transparentize) | |
| | | [alpha](#alpha) | | [fadeOut](#fadeout) | |
| | | [opacity](#opacity) | | [rgba](#rgba-alt) (alt) | |
| | | | | [complement](#complement) | |
| | | | | [grayscale](#grayscale) | |
### Create
These functions create a new color given the provided channels.
#### `hex`
Alias for [`rgba`](#rgba).
#### `rgb`
Alias for [`rgba`](#rgba).
#### `rgba`
Creates a new color given its rgba channels, the alpha channel is optional.
```ts
function rgba ( r: string, g: number, b: number, a: number = 1 ): string;
```
```ts
rgba ( 255, 204, 0 ); // => '#ffcc00'
rgba ( 255, 204, 0, 0.5 ); // => 'rgba(255, 204, 0, 0.5)'
```
#### `hsl`
Alias for [`hsla`](#hsla).
#### `hsla`
Creates a new color given its hsla channels, the alpha channel is optional.
```ts
function hsla ( h: number, s: number, l: number, a: number = 1 ): string;
```
```ts
hsla ( 0, 50, 100 ); // => 'hsl(0, 50%, 100%)'
hsla ( 10, 50, 100, 0.5 ); // => 'hsla(10, 50%, 100%, 0.5)'
```
### Convert
These functions convert supported colors to a specific format.
#### `toKeyword`
Convert a color to the keyword format, when possible.
```ts
function toKeyword ( color: string ): string | undefined;
```
```ts
toKeyword ( '#ff0000' ); // => 'red'
toKeyword ( '#ffcc00' ); // => undefined
```
#### `toHex`
Convert a color to the HEX format.
```ts
function toHex ( color: string ): string;
```
```ts
toHex ( 'red' ); // => '#ff0000'
toHex ( '#ff0000' ); // => '#ff0000'
```
#### `toRgba`
Convert a color to the RGBA format.
```ts
function toRgba ( color: string ): string;
```
```ts
toRgba ( 'red' ); // => 'rgb(255, 0, 0)'
toRgba ( '#ff0000' ); // => 'rgb(255, 0, 0)'
toRgba ( '#00000088' ); // => 'rgba(0, 0, 0, 0.5333333333)'
```
#### `toHsla`
Convert a color to the HSLA format.
```ts
function toHsla ( color: string ): string;
```
```ts
toHsla ( 'red' ); // => 'hsl(0, 100%, 50%)'
toHsla ( '#ff0000' ); // => 'hsl(0, 100%, 50%)'
toHsla ( 'rgb(255, 0, 0)' ); // => 'hsl(0, 100%, 50%)'
```
### Get channel
These functions get a single channel from the provided color.
#### `channel`
Gets any single channel of the color.
```ts
function channel ( color: string, channel: 'r' | 'g' | 'b' | 'h' | 's' | 'l' | 'a' ): number;
```
```ts
channel ( '#ffcc00', 'r' ); // => 255
channel ( '#ffcc00', 'h' ); // => 48
channel ( '#ffcc00', 'a' ); // => 1
```
#### `red`
Gets the red channel of the color.
```ts
function red ( color: string ): number;
```
```ts
red ( '#ffcc00' ); // => 255
```
#### `green`
Gets the green channel of the color.
```ts
function green ( color: string ): number;
```
```ts
green ( '#ffcc00' ); // => 204
```
#### `blue`
Gets the blue channel of the color.
```ts
function blue ( color: string ): number;
```
```ts
blue ( '#ffcc00' ); // => 0
```
#### `hue`
Gets the hue channel of the color.
```ts
function hue ( color: string ): number;
```
```ts
hue ( 'hsl(0, 50%, 100%)' ); // => 0
```
#### `saturation`
Gets the saturation channel of the color.
```ts
function saturation ( color: string ): number;
```
```ts
saturation ( 'hsl(0, 50%, 100%)' ); // => 50
```
#### `lightness`
Gets the lightness channel of the color.
```ts
function lightness ( color: string ): number;
```
```ts
lightness ( 'hsl(0, 50%, 100%)' ); // => 100
```
#### `alpha`
Gets the alpha channel of the color.
```ts
function alpha ( color: string ): number;
```
```ts
alpha ( '#ffcc00' ); // => 1
alpha ( 'rgba(255, 205, 0, 0.5)' ); // => 0.5
```
#### `opacity`
Alias for [`alpha`](#alpha).
### Get more
These functions get some other information from the provided color.
#### `contrast`
Gets the contrast in luminance between two colors.
Contrast values go between 1 and 10. 1 means same color, >= 4 means decent contrast, >= 7 means great contrast, 10 means great contrast.
```ts
function contrast ( color1: string, color2: string ): number;
```
```ts
contrast ( '#000000', '#000000' ); // => 1
contrast ( '#000000', '#ffffff' ); // => 10
contrast ( '#888888', '#ffffff' ); // => 4.0617165366
```
#### `luminance`
Gets the [relative luminance](https://en.wikipedia.org/wiki/Relative_luminance) of the color.
```ts
function luminance ( color: string ): number;
```
```ts
luminance ( 'black' ); // => 0
luminance ( 'white' ); // => 1
luminance ( '#ffcc00' ); // => 0.6444573127
```
#### `isDark`
Checks if the provided color is a dark color.
```ts
function isDark ( color: string ): number;
```
```ts
isDark ( 'black' ); // => true
isDark ( 'white' ); // => false
isDark ( '#ffcc00' ); // => false
```
#### `isLight`
Checks if the provided color is a light color.
```ts
function isLight ( color: string ): number;
```
```ts
isLight ( 'black' ); // => false
isLight ( 'white' ); // => true
isLight ( '#ffcc00' ); // => true
```
#### `isValid`
Checks if the provided color is a valid color.
```ts
function isLight ( color: string ): boolean;
```
```ts
isValid ( 'black' ); // => true
isValid ( '#ffcc00' ); // => true
isValid ( '#wtf' ); // => false
```
### Edit channel
These functions change a single channel of the provided color.
#### `saturate`
Increases the saturation channel of the color.
```ts
function saturate ( color: string, amount: number ): string;
```
```ts
saturate ( 'hsl(0, 50%, 50%)', 25 ); // => 'hsl(0, 75%, 50%)'
```
#### `desaturate`
Decreases the saturation channel of the color.
```ts
function desaturate ( color: string, amount: number ): string;
```
```ts
desaturate ( 'hsl(0, 50%, 50%)', 25 ); // => 'hsl(0, 25%, 50%)'
```
#### `lighten`
Increases the lightness channel of the color.
```ts
function lighten ( color: string, amount: number ): string;
```
```ts
lighten ( 'hsl(0, 50%, 50%)', 25 ); // => 'hsl(0, 50%, 75%)'
```
#### `darken`
Decreases the lightness channel of the color.
```ts
function darken ( color: string, amount: number ): string;
```
```ts
darken ( 'hsl(0, 50%, 50%)', 25 ); // => 'hsl(0, 50%, 25%)'
```
#### `opacify`
Increases the opacity channel of the color.
```ts
function opacify ( color: string, amount: number ): string;
```
```ts
opacify ( 'rgba(255, 204, 0, 0.5)', 0.25 ); // => 'rgba(255, 204, 0, 0.75)'
```
#### `fadeIn`
Alias for [`opacify`](#opacify).
#### `transparentize`
Decreases the opacity channel of the color.
```ts
function transparentize ( color: string, amount: number ): string;
```
```ts
transparentize ( 'rgba(255, 204, 0, 0.5)', 0.25 ); // => 'rgba(255, 204, 0, 0.25)'
```
#### `fadeOut`
Alias for [`transparentize`](#transparentize).
#### `rgba` (alt)
Sets a new value for the opacity channel.
```ts
function rgba ( color: string, amount: number ): string;
```
```ts
rgba ( 'rgba(255, 204, 0, 0.5)', 0.1 ); // => 'rgba(255, 204, 0, 0.1)'
```
#### `complement`
Gets the complement of the color, rotating its hue channel by 180 degrees.
```ts
function complement ( color: string ): string;
```
```ts
complement ( '#ffcc00' ); // => 'hsl(228, 100%, 50%)'
```
#### `grayscale`
Gets the grayscale version of the color, setting its saturation to 0.
```ts
function grayscale ( color: string ): string;
```
```ts
grayscale ( '#ffcc00' ); // => 'hsl(48, 0%, 50%)'
```
### Edit more
These functions can/will change more than a single channel at once of the provided color.
#### `adjust`
Increases or decreases the value of any channel of the color.
```ts
function adjust ( color: string, channels: Record<'r' | 'g' | 'b' | 'h' | 's' | 'l' | 'a', number> ): string;
```
```ts
adjust ( '#ffcc00', { r: -10, g: 200 } ); // => '#f5ff00'
adjust ( '#ffcc00', { a: -0.5 } ); // => 'rgba(255, 204, 0, 0.5)'
adjust ( '#ffcc00', { h: 50, l: -30 } ); // => 'hsl(98, 100%, 20%)'
```
#### `change`
Sets a new value for any channel of the color.
```ts
function change ( color: string, channels: Record<'r' | 'g' | 'b' | 'h' | 's' | 'l' | 'a', number> ): string;
```
```ts
change ( '#ffcc00', { r: 10, g: 200 } ); // => '#0ac800'
change ( '#ffcc00', { a: 0.5 } ); // => 'rgba(255, 204, 0, 0.5)'
change ( '#ffcc00', { h: 50, l: 30 } ); // => 'hsl(50, 100%, 30%)'
```
#### `invert`
Gets the inverse of the color.
```ts
function invert ( color: string, weight: number = 100 ): string;
```
```ts
invert ( '#ffcc00' ); // => '#0033ff'
invert ( '#ffcc00', 50 ); // => '#808080'
```
#### `mix`
Mixes two colors together.
```ts
function mix ( color1: string, color2: string, weight: number = 50 ): string;
```
```ts
mix ( 'red', 'blue' ); // => '#800080'
mix ( 'red', 'blue', 15 ); // => '#2600d9'
```
#### `scale`
Scales any channel of the color.
```ts
function scale ( color: string, channels: Record<'r' | 'g' | 'b' | 'h' | 's' | 'l' | 'a', number> ): string;
```
```ts
scale ( '#ffcc00', { r: -50, b: 10 } ); // => '#80cc1a'
```
## License
MIT © Fabio Spampinato, Andrew Maney
fabiospampinato-khroma-f998e9b/package.json 0000775 0000000 0000000 00000001627 14223624663 0021115 0 ustar 00root root 0000000 0000000 {
"name": "khroma",
"repository": "github:fabiospampinato/khroma",
"description": "A collection of functions for manipulating CSS colors, inspired by SASS.",
"version": "2.0.0",
"type": "module",
"sideEffects": false,
"main": "dist/index.js",
"exports": "./dist/index.js",
"types": "./dist/index.d.ts",
"scripts": {
"benchmark": "tsex benchmark",
"benchmark:watch": "tsex benchmark --watch",
"clean": "tsex clean",
"compile": "tsex compile",
"compile:watch": "tsex compile --watch",
"test": "tsex test",
"test:watch": "tsex test --watch",
"prepublishOnly": "npm run clean && npm run compile && npm run test"
},
"keywords": [
"sass",
"color",
"manipulation",
"manipulate",
"css",
"hex",
"rgb",
"hsl"
],
"devDependencies": {
"benchloop": "^1.3.2",
"fava": "^0.0.6",
"tsex": "^1.1.0",
"typescript": "^4.6.3"
}
}
fabiospampinato-khroma-f998e9b/src/ 0000775 0000000 0000000 00000000000 14223624663 0017405 5 ustar 00root root 0000000 0000000 fabiospampinato-khroma-f998e9b/src/channels/ 0000775 0000000 0000000 00000000000 14223624663 0021200 5 ustar 00root root 0000000 0000000 fabiospampinato-khroma-f998e9b/src/channels/index.ts 0000664 0000000 0000000 00000006666 14223624663 0022675 0 ustar 00root root 0000000 0000000
/* IMPORT */
import _ from '~/utils';
import Type from '~/channels/type';
import {TYPE} from '~/constants';
import type {RGBA, HSLA, CHANNELS} from '~/types';
/* MAIN */
class Channels {
/* VARIABLES */
color?: string;
changed: boolean;
data: CHANNELS; //TSC: It should really be "Partial", but TS gets excessively noisy
type: Type;
/* CONSTRUCTOR */
constructor ( data: RGBA | HSLA | CHANNELS, color?: string ) {
this.color = color;
this.changed = false;
this.data = data as CHANNELS; //TSC
this.type = new Type ();
}
/* API */
set ( data: RGBA | HSLA | CHANNELS, color?: string ): this {
this.color = color;
this.changed = false;
this.data = data as CHANNELS; //TSC
this.type.type = TYPE.ALL;
return this;
}
/* HELPERS */
_ensureHSL (): void {
const data = this.data;
const {h, s, l} = data;
if ( h === undefined ) data.h = _.channel.rgb2hsl ( data, 'h' );
if ( s === undefined ) data.s = _.channel.rgb2hsl ( data, 's' );
if ( l === undefined ) data.l = _.channel.rgb2hsl ( data, 'l' );
}
_ensureRGB (): void {
const data = this.data;
const {r, g, b} = data;
if ( r === undefined ) data.r = _.channel.hsl2rgb ( data, 'r' );
if ( g === undefined ) data.g = _.channel.hsl2rgb ( data, 'g' );
if ( b === undefined ) data.b = _.channel.hsl2rgb ( data, 'b' );
}
/* GETTERS */
get r (): number {
const data = this.data;
const r = data.r;
if ( !this.type.is ( TYPE.HSL ) && r !== undefined ) return r;
this._ensureHSL ();
return _.channel.hsl2rgb ( data, 'r' );
}
get g (): number {
const data = this.data;
const g = data.g;
if ( !this.type.is ( TYPE.HSL ) && g !== undefined ) return g;
this._ensureHSL ();
return _.channel.hsl2rgb ( data, 'g' );
}
get b (): number {
const data = this.data;
const b = data.b;
if ( !this.type.is ( TYPE.HSL ) && b !== undefined ) return b;
this._ensureHSL ();
return _.channel.hsl2rgb ( data, 'b' );
}
get h (): number {
const data = this.data;
const h = data.h;
if ( !this.type.is ( TYPE.RGB ) && h !== undefined ) return h;
this._ensureRGB ();
return _.channel.rgb2hsl ( data, 'h' );
}
get s (): number {
const data = this.data;
const s = data.s;
if ( !this.type.is ( TYPE.RGB ) && s !== undefined ) return s;
this._ensureRGB ();
return _.channel.rgb2hsl ( data, 's' );
}
get l (): number {
const data = this.data;
const l = data.l;
if ( !this.type.is ( TYPE.RGB ) && l !== undefined ) return l;
this._ensureRGB ();
return _.channel.rgb2hsl ( data, 'l' );
}
get a (): number {
return this.data.a;
}
/* SETTERS */
set r ( r: number ) {
this.type.set ( TYPE.RGB );
this.changed = true;
this.data.r = r;
}
set g ( g: number ) {
this.type.set ( TYPE.RGB );
this.changed = true;
this.data.g = g;
}
set b ( b: number ) {
this.type.set ( TYPE.RGB );
this.changed = true;
this.data.b = b;
}
set h ( h: number ) {
this.type.set ( TYPE.HSL );
this.changed = true;
this.data.h = h;
}
set s ( s: number ) {
this.type.set ( TYPE.HSL );
this.changed = true;
this.data.s = s;
}
set l ( l: number ) {
this.type.set ( TYPE.HSL );
this.changed = true;
this.data.l = l;
}
set a ( a: number ) {
this.changed = true;
this.data.a = a;
}
}
/* EXPORT */
export default Channels;
fabiospampinato-khroma-f998e9b/src/channels/reusable.ts 0000664 0000000 0000000 00000000264 14223624663 0023354 0 ustar 00root root 0000000 0000000
/* IMPORT */
import Channels from '~/channels';
/* MAIN */
const channels = new Channels ( { r: 0, g: 0, b: 0, a: 0 }, 'transparent' );
/* EXPORT */
export default channels;
fabiospampinato-khroma-f998e9b/src/channels/type.ts 0000664 0000000 0000000 00000001021 14223624663 0022523 0 ustar 00root root 0000000 0000000
/* IMPORT */
import {TYPE} from '~/constants';
/* MAIN */
class Type {
/* VARIABLES */
type: number = TYPE.ALL;
/* API */
get (): number {
return this.type;
}
set ( type: number ): void {
if ( this.type && this.type !== type ) throw new Error ( 'Cannot change both RGB and HSL channels at the same time' );
this.type = type;
}
reset (): void {
this.type = TYPE.ALL;
}
is ( type: number ): boolean {
return this.type === type;
}
}
/* EXPORT */
export default Type;
fabiospampinato-khroma-f998e9b/src/color/ 0000775 0000000 0000000 00000000000 14223624663 0020523 5 ustar 00root root 0000000 0000000 fabiospampinato-khroma-f998e9b/src/color/hex.ts 0000664 0000000 0000000 00000003042 14223624663 0021656 0 ustar 00root root 0000000 0000000
/* IMPORT */
import _ from '~/utils';
import ChannelsReusable from '~/channels/reusable';
import {DEC2HEX} from '~/constants';
import type {Channels} from '~/types';
/* MAIN */
const Hex = {
/* VARIABLES */
re: /^#((?:[a-f0-9]{2}){2,4}|[a-f0-9]{3})$/i,
/* API */
parse: ( color: string ): Channels | void => {
if ( color.charCodeAt ( 0 ) !== 35 ) return; // '#'
const match = color.match ( Hex.re );
if ( !match ) return;
const hex = match[1];
const dec = parseInt ( hex, 16 );
const length = hex.length;
const hasAlpha = length % 4 === 0;
const isFullLength = length > 4;
const multiplier = isFullLength ? 1 : 17;
const bits = isFullLength ? 8 : 4;
const bitsOffset = hasAlpha ? 0 : -1;
const mask = isFullLength ? 255 : 15;
return ChannelsReusable.set ({
r: ( ( dec >> ( bits * ( bitsOffset + 3 ) ) ) & mask ) * multiplier,
g: ( ( dec >> ( bits * ( bitsOffset + 2 ) ) ) & mask ) * multiplier,
b: ( ( dec >> ( bits * ( bitsOffset + 1 ) ) ) & mask ) * multiplier,
a: hasAlpha ? ( dec & mask ) * multiplier / 255 : 1
}, color );
},
stringify: ( channels: Channels ): string => {
const {r, g, b, a} = channels;
if ( a < 1 ) { // #RRGGBBAA
return `#${DEC2HEX[Math.round ( r )]}${DEC2HEX[Math.round ( g )]}${DEC2HEX[Math.round ( b )]}${DEC2HEX[Math.round ( a * 255 )]}`;
} else { // #RRGGBB
return `#${DEC2HEX[Math.round ( r )]}${DEC2HEX[Math.round ( g )]}${DEC2HEX[Math.round ( b )]}`;
}
}
};
/* EXPORT */
export default Hex;
fabiospampinato-khroma-f998e9b/src/color/hsl.ts 0000664 0000000 0000000 00000003662 14223624663 0021670 0 ustar 00root root 0000000 0000000
/* IMPORT */
import _ from '~/utils';
import ChannelsReusable from '~/channels/reusable';
import type {Channels} from '~/types';
/* MAIN */
const HSL = {
/* VARIABLES */
re: /^hsla?\(\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?(?:deg|grad|rad|turn)?)\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?%)\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?%)(?:\s*?(?:,|\/)\s*?\+?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?(%)?))?\s*?\)$/i,
hueRe: /^(.+?)(deg|grad|rad|turn)$/i,
/* HELPERS */
_hue2deg: ( hue: string ): number => {
const match = hue.match ( HSL.hueRe );
if ( match ) {
const [, number, unit] = match;
switch ( unit ) {
case 'grad': return _.channel.clamp.h ( parseFloat ( number ) * .9 );
case 'rad': return _.channel.clamp.h ( parseFloat ( number ) * 180 / Math.PI );
case 'turn': return _.channel.clamp.h ( parseFloat ( number ) * 360 );
}
}
return _.channel.clamp.h ( parseFloat ( hue ) );
},
/* API */
parse: ( color: string ): Channels | void => {
const charCode = color.charCodeAt ( 0 );
if ( charCode !== 104 && charCode !== 72 ) return; // 'h'/'H'
const match = color.match ( HSL.re );
if ( !match ) return;
const [, h, s, l, a, isAlphaPercentage] = match;
return ChannelsReusable.set ({
h: HSL._hue2deg ( h ),
s: _.channel.clamp.s ( parseFloat ( s ) ),
l: _.channel.clamp.l ( parseFloat ( l ) ),
a: a ? _.channel.clamp.a ( isAlphaPercentage ? parseFloat ( a ) / 100 : parseFloat ( a ) ) : 1
}, color );
},
stringify: ( channels: Channels ): string => {
const {h, s, l, a} = channels;
if ( a < 1 ) { // HSLA
return `hsla(${_.lang.round ( h )}, ${_.lang.round ( s )}%, ${_.lang.round ( l )}%, ${a})`;
} else { // HSL
return `hsl(${_.lang.round ( h )}, ${_.lang.round ( s )}%, ${_.lang.round ( l )}%)`;
}
}
};
/* EXPORT */
export default HSL;
fabiospampinato-khroma-f998e9b/src/color/index.ts 0000664 0000000 0000000 00000002653 14223624663 0022210 0 ustar 00root root 0000000 0000000
/* IMPORT */
import _ from '~/utils';
import Hex from '~/color/hex';
import HSL from '~/color/hsl';
import Keyword from '~/color/keyword';
import RGB from '~/color/rgb';
import {TYPE} from '~/constants';
import type {Channels} from '~/types';
/* MAIN */
const Color = {
/* VARIABLES */
format: {
keyword: Keyword,
hex: Hex,
rgb: RGB,
rgba: RGB,
hsl: HSL,
hsla: HSL
},
/* API */
parse: ( color: string | Channels ): Channels => {
if ( typeof color !== 'string' ) return color;
const channels = Hex.parse ( color ) || RGB.parse ( color ) || HSL.parse ( color ) || Keyword.parse ( color ); // Color providers ordered with performance in mind
if ( channels ) return channels;
throw new Error ( `Unsupported color format: "${color}"` );
},
stringify: ( channels: Channels ): string => {
// SASS returns a keyword if possible, but we avoid doing that as it's slower and doesn't really add any value
if ( !channels.changed && channels.color ) return channels.color;
if ( channels.type.is ( TYPE.HSL ) || channels.data.r === undefined ) {
return HSL.stringify ( channels );
} else if ( channels.a < 1 || !Number.isInteger ( channels.r ) || !Number.isInteger ( channels.g ) || !Number.isInteger ( channels.b ) ) {
return RGB.stringify ( channels );
} else {
return Hex.stringify ( channels );
}
}
};
/* EXPORT */
export default Color;
fabiospampinato-khroma-f998e9b/src/color/keyword.ts 0000664 0000000 0000000 00000010542 14223624663 0022561 0 ustar 00root root 0000000 0000000
/* IMPORT */
import Hex from '~/color/hex';
import type {Channels} from '~/types';
/* MAIN */
const Keyword = {
/* VARIABLES */
colors: {
aliceblue: '#f0f8ff',
antiquewhite: '#faebd7',
aqua: '#00ffff',
aquamarine: '#7fffd4',
azure: '#f0ffff',
beige: '#f5f5dc',
bisque: '#ffe4c4',
black: '#000000',
blanchedalmond: '#ffebcd',
blue: '#0000ff',
blueviolet: '#8a2be2',
brown: '#a52a2a',
burlywood: '#deb887',
cadetblue: '#5f9ea0',
chartreuse: '#7fff00',
chocolate: '#d2691e',
coral: '#ff7f50',
cornflowerblue: '#6495ed',
cornsilk: '#fff8dc',
crimson: '#dc143c',
cyanaqua: '#00ffff',
darkblue: '#00008b',
darkcyan: '#008b8b',
darkgoldenrod: '#b8860b',
darkgray: '#a9a9a9',
darkgreen: '#006400',
darkgrey: '#a9a9a9',
darkkhaki: '#bdb76b',
darkmagenta: '#8b008b',
darkolivegreen: '#556b2f',
darkorange: '#ff8c00',
darkorchid: '#9932cc',
darkred: '#8b0000',
darksalmon: '#e9967a',
darkseagreen: '#8fbc8f',
darkslateblue: '#483d8b',
darkslategray: '#2f4f4f',
darkslategrey: '#2f4f4f',
darkturquoise: '#00ced1',
darkviolet: '#9400d3',
deeppink: '#ff1493',
deepskyblue: '#00bfff',
dimgray: '#696969',
dimgrey: '#696969',
dodgerblue: '#1e90ff',
firebrick: '#b22222',
floralwhite: '#fffaf0',
forestgreen: '#228b22',
fuchsia: '#ff00ff',
gainsboro: '#dcdcdc',
ghostwhite: '#f8f8ff',
gold: '#ffd700',
goldenrod: '#daa520',
gray: '#808080',
green: '#008000',
greenyellow: '#adff2f',
grey: '#808080',
honeydew: '#f0fff0',
hotpink: '#ff69b4',
indianred: '#cd5c5c',
indigo: '#4b0082',
ivory: '#fffff0',
khaki: '#f0e68c',
lavender: '#e6e6fa',
lavenderblush: '#fff0f5',
lawngreen: '#7cfc00',
lemonchiffon: '#fffacd',
lightblue: '#add8e6',
lightcoral: '#f08080',
lightcyan: '#e0ffff',
lightgoldenrodyellow: '#fafad2',
lightgray: '#d3d3d3',
lightgreen: '#90ee90',
lightgrey: '#d3d3d3',
lightpink: '#ffb6c1',
lightsalmon: '#ffa07a',
lightseagreen: '#20b2aa',
lightskyblue: '#87cefa',
lightslategray: '#778899',
lightslategrey: '#778899',
lightsteelblue: '#b0c4de',
lightyellow: '#ffffe0',
lime: '#00ff00',
limegreen: '#32cd32',
linen: '#faf0e6',
magenta: '#ff00ff',
maroon: '#800000',
mediumaquamarine: '#66cdaa',
mediumblue: '#0000cd',
mediumorchid: '#ba55d3',
mediumpurple: '#9370db',
mediumseagreen: '#3cb371',
mediumslateblue: '#7b68ee',
mediumspringgreen: '#00fa9a',
mediumturquoise: '#48d1cc',
mediumvioletred: '#c71585',
midnightblue: '#191970',
mintcream: '#f5fffa',
mistyrose: '#ffe4e1',
moccasin: '#ffe4b5',
navajowhite: '#ffdead',
navy: '#000080',
oldlace: '#fdf5e6',
olive: '#808000',
olivedrab: '#6b8e23',
orange: '#ffa500',
orangered: '#ff4500',
orchid: '#da70d6',
palegoldenrod: '#eee8aa',
palegreen: '#98fb98',
paleturquoise: '#afeeee',
palevioletred: '#db7093',
papayawhip: '#ffefd5',
peachpuff: '#ffdab9',
peru: '#cd853f',
pink: '#ffc0cb',
plum: '#dda0dd',
powderblue: '#b0e0e6',
purple: '#800080',
rebeccapurple: '#663399',
red: '#ff0000',
rosybrown: '#bc8f8f',
royalblue: '#4169e1',
saddlebrown: '#8b4513',
salmon: '#fa8072',
sandybrown: '#f4a460',
seagreen: '#2e8b57',
seashell: '#fff5ee',
sienna: '#a0522d',
silver: '#c0c0c0',
skyblue: '#87ceeb',
slateblue: '#6a5acd',
slategray: '#708090',
slategrey: '#708090',
snow: '#fffafa',
springgreen: '#00ff7f',
tan: '#d2b48c',
teal: '#008080',
thistle: '#d8bfd8',
transparent: '#00000000',
turquoise: '#40e0d0',
violet: '#ee82ee',
wheat: '#f5deb3',
white: '#ffffff',
whitesmoke: '#f5f5f5',
yellow: '#ffff00',
yellowgreen: '#9acd32'
},
/* API */
parse: ( color: string ): Channels | void => {
color = color.toLowerCase ();
const hex = Keyword.colors[color];
if ( !hex ) return;
return Hex.parse ( hex );
},
stringify: ( channels: Channels ): string | undefined => {
const hex = Hex.stringify ( channels );
for ( const name in Keyword.colors ) {
if ( Keyword.colors[name] === hex ) return name;
}
return;
}
};
/* EXPORT */
export default Keyword;
fabiospampinato-khroma-f998e9b/src/color/rgb.ts 0000664 0000000 0000000 00000003131 14223624663 0021643 0 ustar 00root root 0000000 0000000
/* IMPORT */
import _ from '~/utils';
import ChannelsReusable from '~/channels/reusable';
import type {Channels} from '~/types';
/* MAIN */
const RGB = {
/* VARIABLES */
re: /^rgba?\(\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))(?:\s*?(?:,|\/)\s*?\+?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?)))?\s*?\)$/i,
/* API */
parse: ( color: string ): Channels | void => {
const charCode = color.charCodeAt ( 0 );
if ( charCode !== 114 && charCode !== 82 ) return; // 'r'/'R'
const match = color.match ( RGB.re );
if ( !match ) return;
const [, r, isRedPercentage, g, isGreenPercentage, b, isBluePercentage, a, isAlphaPercentage] = match;
return ChannelsReusable.set ({
r: _.channel.clamp.r ( isRedPercentage ? parseFloat ( r ) * 2.55 : parseFloat ( r ) ),
g: _.channel.clamp.g ( isGreenPercentage ? parseFloat ( g ) * 2.55 : parseFloat ( g ) ),
b: _.channel.clamp.b ( isBluePercentage ? parseFloat ( b ) * 2.55 : parseFloat ( b ) ),
a: a ? _.channel.clamp.a ( isAlphaPercentage ? parseFloat ( a ) / 100 : parseFloat ( a ) ) : 1
}, color );
},
stringify: ( channels: Channels ): string => {
const {r, g, b, a} = channels;
if ( a < 1 ) { // RGBA
return `rgba(${_.lang.round ( r )}, ${_.lang.round ( g )}, ${_.lang.round ( b )}, ${_.lang.round ( a )})`;
} else { // RGB
return `rgb(${_.lang.round ( r )}, ${_.lang.round ( g )}, ${_.lang.round ( b )})`;
}
}
};
/* EXPORT */
export default RGB;
fabiospampinato-khroma-f998e9b/src/constants.ts 0000664 0000000 0000000 00000000525 14223624663 0021773 0 ustar 00root root 0000000 0000000
/* IMPORT */
import _ from '~/utils';
/* MAIN */
const DEC2HEX: Record = {};
for ( let i = 0; i <= 255; i++ ) DEC2HEX[i] = _.unit.dec2hex ( i ); // Populating dynamically, striking a balance between code size and performance
const TYPE = {
ALL: 0,
RGB: 1,
HSL: 2
};
/* EXPORT */
export {DEC2HEX, TYPE};
fabiospampinato-khroma-f998e9b/src/index.ts 0000775 0000000 0000000 00000000052 14223624663 0021064 0 ustar 00root root 0000000 0000000
/* EXPORT */
export * from '~/methods';
fabiospampinato-khroma-f998e9b/src/methods/ 0000775 0000000 0000000 00000000000 14223624663 0021050 5 ustar 00root root 0000000 0000000 fabiospampinato-khroma-f998e9b/src/methods/adjust.ts 0000664 0000000 0000000 00000000764 14223624663 0022721 0 ustar 00root root 0000000 0000000
/* IMPORT */
import Color from '~/color';
import change from '~/methods/change';
import type {CHANNELS, Channels} from '~/types';
/* MAIN */
const adjust = ( color: string | Channels, channels: Partial ): string => {
const ch = Color.parse ( color );
const changes: Partial = {};
for ( const c in channels ) {
if ( !channels[c] ) continue;
changes[c] = ch[c] + channels[c];
}
return change ( color, changes );
};
/* EXPORT */
export default adjust;
fabiospampinato-khroma-f998e9b/src/methods/adjust_channel.ts 0000664 0000000 0000000 00000001043 14223624663 0024400 0 ustar 00root root 0000000 0000000
/* IMPORT */
import _ from '~/utils';
import Color from '~/color';
import type {CHANNEL, Channels} from '~/types';
/* MAIN */
const adjustChannel = ( color: string | Channels, channel: CHANNEL, amount: number ): string => {
const channels = Color.parse ( color );
const amountCurrent = channels[channel];
const amountNext = _.channel.clamp[channel]( amountCurrent + amount );
if ( amountCurrent !== amountNext ) channels[channel] = amountNext;
return Color.stringify ( channels );
};
/* EXPORT */
export default adjustChannel;
fabiospampinato-khroma-f998e9b/src/methods/alpha.ts 0000664 0000000 0000000 00000000357 14223624663 0022512 0 ustar 00root root 0000000 0000000
/* IMPORT */
import channel from '~/methods/channel';
import type {Channels} from '~/types';
/* MAIN */
const alpha = ( color: string | Channels ): number => {
return channel ( color, 'a' );
};
/* EXPORT */
export default alpha;
fabiospampinato-khroma-f998e9b/src/methods/blue.ts 0000664 0000000 0000000 00000000355 14223624663 0022352 0 ustar 00root root 0000000 0000000
/* IMPORT */
import channel from '~/methods/channel';
import type {Channels} from '~/types';
/* MAIN */
const blue = ( color: string | Channels ): number => {
return channel ( color, 'b' );
};
/* EXPORT */
export default blue;
fabiospampinato-khroma-f998e9b/src/methods/change.ts 0000664 0000000 0000000 00000000640 14223624663 0022645 0 ustar 00root root 0000000 0000000
/* IMPORT */
import _ from '~/utils';
import Color from '~/color';
import type {CHANNELS, Channels} from '~/types';
/* MAIN */
const change = ( color: string | Channels, channels: Partial ): string => {
const ch = Color.parse ( color );
for ( const c in channels ) {
ch[c] = _.channel.clamp[c]( channels[c] );
}
return Color.stringify ( ch );
};
/* EXPORT */
export default change;
fabiospampinato-khroma-f998e9b/src/methods/channel.ts 0000664 0000000 0000000 00000000464 14223624663 0023034 0 ustar 00root root 0000000 0000000
/* IMPORT */
import _ from '~/utils';
import Color from '~/color';
import type {CHANNEL, Channels} from '~/types';
/* MAIN */
const channel = ( color: string | Channels, channel: CHANNEL ): number => {
return _.lang.round ( Color.parse ( color )[channel] );
};
/* EXPORT */
export default channel;
fabiospampinato-khroma-f998e9b/src/methods/complement.ts 0000664 0000000 0000000 00000000421 14223624663 0023560 0 ustar 00root root 0000000 0000000
/* IMPORT */
import adjustChannel from '~/methods/adjust_channel';
import type {Channels} from '~/types';
/* MAIN */
const complement = ( color: string | Channels ): string => {
return adjustChannel ( color, 'h', 180 );
};
/* EXPORT */
export default complement;
fabiospampinato-khroma-f998e9b/src/methods/contrast.ts 0000664 0000000 0000000 00000001013 14223624663 0023250 0 ustar 00root root 0000000 0000000
/* IMPORT */
import _ from '~/utils';
import luminance from '~/methods/luminance';
/* MAIN */
const contrast = ( color1: string, color2: string ): number => {
const luminance1 = luminance ( color1 );
const luminance2 = luminance ( color2 );
const max = Math.max ( luminance1, luminance2 );
const min = Math.min ( luminance1, luminance2 );
const ratio = ( max + Number.EPSILON ) / ( min + Number.EPSILON );
return _.lang.round ( _.lang.clamp ( ratio, 1, 10 ) );
};
/* EXPORT */
export default contrast;
fabiospampinato-khroma-f998e9b/src/methods/darken.ts 0000664 0000000 0000000 00000000435 14223624663 0022666 0 ustar 00root root 0000000 0000000
/* IMPORT */
import adjustChannel from '~/methods/adjust_channel';
import type {Channels} from '~/types';
/* MAIN */
const darken = ( color: string | Channels, amount: number ): string => {
return adjustChannel ( color, 'l', -amount );
};
/* EXPORT */
export default darken;
fabiospampinato-khroma-f998e9b/src/methods/desaturate.ts 0000664 0000000 0000000 00000000445 14223624663 0023564 0 ustar 00root root 0000000 0000000
/* IMPORT */
import adjustChannel from '~/methods/adjust_channel';
import type {Channels} from '~/types';
/* MAIN */
const desaturate = ( color: string | Channels, amount: number ): string => {
return adjustChannel ( color, 's', -amount );
};
/* EXPORT */
export default desaturate;
fabiospampinato-khroma-f998e9b/src/methods/grayscale.ts 0000664 0000000 0000000 00000000371 14223624663 0023373 0 ustar 00root root 0000000 0000000
/* IMPORT */
import change from '~/methods/change';
import type {Channels} from '~/types';
/* MAIN */
const grayscale = ( color: string | Channels ): string => {
return change ( color, { s: 0 } );
};
/* EXPORT */
export default grayscale;
fabiospampinato-khroma-f998e9b/src/methods/green.ts 0000664 0000000 0000000 00000000357 14223624663 0022525 0 ustar 00root root 0000000 0000000
/* IMPORT */
import channel from '~/methods/channel';
import type {Channels} from '~/types';
/* MAIN */
const green = ( color: string | Channels ): number => {
return channel ( color, 'g' );
};
/* EXPORT */
export default green;
fabiospampinato-khroma-f998e9b/src/methods/hsla.ts 0000664 0000000 0000000 00000000724 14223624663 0022352 0 ustar 00root root 0000000 0000000
/* IMPORT */
import _ from '~/utils';
import ChannelsReusable from '~/channels/reusable';
import Color from '~/color';
/* MAIN */
const hsla = ( h: number, s: number, l: number, a: number = 1 ): string => {
const channels = ChannelsReusable.set ({
h: _.channel.clamp.h ( h ),
s: _.channel.clamp.s ( s ),
l: _.channel.clamp.l ( l ),
a: _.channel.clamp.a ( a )
});
return Color.stringify ( channels );
};
/* EXPORT */
export default hsla;
fabiospampinato-khroma-f998e9b/src/methods/hue.ts 0000664 0000000 0000000 00000000353 14223624663 0022202 0 ustar 00root root 0000000 0000000
/* IMPORT */
import channel from '~/methods/channel';
import type {Channels} from '~/types';
/* MAIN */
const hue = ( color: string | Channels ): number => {
return channel ( color, 'h' );
};
/* EXPORT */
export default hue;
fabiospampinato-khroma-f998e9b/src/methods/index.ts 0000664 0000000 0000000 00000004125 14223624663 0022531 0 ustar 00root root 0000000 0000000
/* IMPORT */
import hex from '~/methods/rgba'; // Alias
import rgb from '~/methods/rgba'; // Alias
import rgba from '~/methods/rgba';
import hsl from '~/methods/hsla'; // Alias
import hsla from '~/methods/hsla';
import toKeyword from '~/methods/to_keyword';
import toHex from '~/methods/to_hex';
import toRgba from '~/methods/to_rgba';
import toHsla from '~/methods/to_hsla';
import channel from '~/methods/channel';
import red from '~/methods/red';
import green from '~/methods/green';
import blue from '~/methods/blue';
import hue from '~/methods/hue';
import saturation from '~/methods/saturation';
import lightness from '~/methods/lightness';
import alpha from '~/methods/alpha';
import opacity from '~/methods/alpha'; // Alias
import contrast from '~/methods/contrast';
import luminance from '~/methods/luminance';
import isDark from '~/methods/is_dark';
import isLight from '~/methods/is_light';
import isValid from '~/methods/is_valid';
import saturate from '~/methods/saturate';
import desaturate from '~/methods/desaturate';
import lighten from '~/methods/lighten';
import darken from '~/methods/darken';
import opacify from '~/methods/opacify';
import fadeIn from '~/methods/opacify'; // Alias
import transparentize from '~/methods/transparentize';
import fadeOut from '~/methods/transparentize'; // Alias
import complement from '~/methods/complement';
import grayscale from '~/methods/grayscale';
import adjust from '~/methods/adjust';
import change from '~/methods/change';
import invert from '~/methods/invert';
import mix from '~/methods/mix';
import scale from '~/methods/scale';
/* EXPORT */
export {
/* CREATE */
hex,
rgb,
rgba,
hsl,
hsla,
/* CONVERT */
toKeyword,
toHex,
toRgba,
toHsla,
/* GET - CHANNEL */
channel,
red,
green,
blue,
hue,
saturation,
lightness,
alpha,
opacity,
/* GET - MORE */
contrast,
luminance,
isDark,
isLight,
isValid,
/* EDIT - CHANNEL */
saturate,
desaturate,
lighten,
darken,
opacify,
fadeIn,
transparentize,
fadeOut,
complement,
grayscale,
/* EDIT - MORE */
adjust,
change,
invert,
mix,
scale
};
fabiospampinato-khroma-f998e9b/src/methods/invert.ts 0000664 0000000 0000000 00000000654 14223624663 0022734 0 ustar 00root root 0000000 0000000
/* IMPORT */
import Color from '~/color';
import mix from '~/methods/mix';
import type {Channels} from '~/types';
/* MAIN */
const invert = ( color: string | Channels, weight: number = 100 ): string => {
const inverse = Color.parse ( color );
inverse.r = 255 - inverse.r;
inverse.g = 255 - inverse.g;
inverse.b = 255 - inverse.b;
return mix ( inverse, color, weight );
};
/* EXPORT */
export default invert;
fabiospampinato-khroma-f998e9b/src/methods/is_dark.ts 0000664 0000000 0000000 00000000357 14223624663 0023041 0 ustar 00root root 0000000 0000000
/* IMPORT */
import isLight from '~/methods/is_light';
import type {Channels} from '~/types';
/* MAIN */
const isDark = ( color: string | Channels ): boolean => {
return !isLight ( color );
};
/* EXPORT */
export default isDark;
fabiospampinato-khroma-f998e9b/src/methods/is_light.ts 0000664 0000000 0000000 00000000373 14223624663 0023225 0 ustar 00root root 0000000 0000000
/* IMPORT */
import luminance from '~/methods/luminance';
import type {Channels} from '~/types';
/* MAIN */
const isLight = ( color: string | Channels ): boolean => {
return luminance ( color ) >= .5;
};
/* EXPORT */
export default isLight;
fabiospampinato-khroma-f998e9b/src/methods/is_valid.ts 0000664 0000000 0000000 00000000360 14223624663 0023211 0 ustar 00root root 0000000 0000000
/* IMPORT */
import Color from '~/color';
/* MAIN */
const isValid = ( color: string ): boolean => {
try {
Color.parse ( color );
return true;
} catch {
return false;
}
};
/* EXPORT */
export default isValid;
fabiospampinato-khroma-f998e9b/src/methods/lighten.ts 0000664 0000000 0000000 00000000436 14223624663 0023055 0 ustar 00root root 0000000 0000000
/* IMPORT */
import adjustChannel from '~/methods/adjust_channel';
import type {Channels} from '~/types';
/* MAIN */
const lighten = ( color: string | Channels, amount: number ): string => {
return adjustChannel ( color, 'l', amount );
};
/* EXPORT */
export default lighten;
fabiospampinato-khroma-f998e9b/src/methods/lightness.ts 0000664 0000000 0000000 00000000367 14223624663 0023426 0 ustar 00root root 0000000 0000000
/* IMPORT */
import channel from '~/methods/channel';
import type {Channels} from '~/types';
/* MAIN */
const lightness = ( color: string | Channels ): number => {
return channel ( color, 'l' );
};
/* EXPORT */
export default lightness;
fabiospampinato-khroma-f998e9b/src/methods/luminance.ts 0000664 0000000 0000000 00000000727 14223624663 0023401 0 ustar 00root root 0000000 0000000
/* IMPORT */
import _ from '~/utils';
import Color from '~/color';
import type {Channels} from '~/types';
/* MAIN */
//SOURCE: https://planetcalc.com/7779
const luminance = ( color: string | Channels ): number => {
const {r, g, b} = Color.parse ( color );
const luminance = .2126 * _.channel.toLinear ( r ) + .7152 * _.channel.toLinear ( g ) + .0722 * _.channel.toLinear ( b );
return _.lang.round ( luminance );
};
/* EXPORT */
export default luminance;
fabiospampinato-khroma-f998e9b/src/methods/mix.ts 0000664 0000000 0000000 00000002160 14223624663 0022214 0 ustar 00root root 0000000 0000000
/* IMPORT */
import Color from '~/color';
import rgba from '~/methods/rgba';
import type {Channels} from '~/types';
/* MAIN */
//SOURCE: https://github.com/sass/dart-sass/blob/7457d2e9e7e623d9844ffd037a070cf32d39c348/lib/src/functions/color.dart#L718-L756
const mix = ( color1: string | Channels, color2: string | Channels, weight: number = 50 ): string => {
const {r: r1, g: g1, b: b1, a: a1} = Color.parse ( color1 );
const {r: r2, g: g2, b: b2, a: a2} = Color.parse ( color2 );
const weightScale = weight / 100;
const weightNormalized = ( weightScale * 2 ) - 1;
const alphaDelta = a1 - a2;
const weight1combined = ( ( weightNormalized * alphaDelta ) === -1 ) ? weightNormalized : ( weightNormalized + alphaDelta ) / ( 1 + weightNormalized * alphaDelta );
const weight1 = ( weight1combined + 1 ) / 2;
const weight2 = 1 - weight1;
const r = ( r1 * weight1 ) + ( r2 * weight2 );
const g = ( g1 * weight1 ) + ( g2 * weight2 );
const b = ( b1 * weight1 ) + ( b2 * weight2 );
const a = ( a1 * weightScale ) + ( a2 * ( 1 - weightScale ) );
return rgba ( r, g, b, a );
};
/* EXPORT */
export default mix;
fabiospampinato-khroma-f998e9b/src/methods/opacify.ts 0000664 0000000 0000000 00000000436 14223624663 0023055 0 ustar 00root root 0000000 0000000
/* IMPORT */
import adjustChannel from '~/methods/adjust_channel';
import type {Channels} from '~/types';
/* MAIN */
const opacify = ( color: string | Channels, amount: number ): string => {
return adjustChannel ( color, 'a', amount );
};
/* EXPORT */
export default opacify;
fabiospampinato-khroma-f998e9b/src/methods/red.ts 0000664 0000000 0000000 00000000353 14223624663 0022173 0 ustar 00root root 0000000 0000000
/* IMPORT */
import channel from '~/methods/channel';
import type {Channels} from '~/types';
/* MAIN */
const red = ( color: string | Channels ): number => {
return channel ( color, 'r' );
};
/* EXPORT */
export default red;
fabiospampinato-khroma-f998e9b/src/methods/rgba.ts 0000664 0000000 0000000 00000001475 14223624663 0022342 0 ustar 00root root 0000000 0000000
/* IMPORT */
import _ from '~/utils';
import ChannelsReusable from '~/channels/reusable';
import Color from '~/color';
import change from '~/methods/change';
import type {Channels} from '~/types';
/* TYPES */
type IRgba = {
( color: string | Channels, opacity: number ): string,
( r: number, g: number, b: number, a?: number ): string
};
/* MAIN */
const rgba: IRgba = ( r: string | Channels | number, g: number, b: number = 0, a: number = 1 ): string => { //TSC: `b` shouldn't have a default value
if ( typeof r !== 'number' ) return change ( r, { a: g } );
const channels = ChannelsReusable.set ({
r: _.channel.clamp.r ( r ),
g: _.channel.clamp.g ( g ),
b: _.channel.clamp.b ( b ),
a: _.channel.clamp.a ( a )
});
return Color.stringify ( channels );
};
/* EXPORT */
export default rgba;
fabiospampinato-khroma-f998e9b/src/methods/saturate.ts 0000664 0000000 0000000 00000000440 14223624663 0023246 0 ustar 00root root 0000000 0000000
/* IMPORT */
import adjustChannel from '~/methods/adjust_channel';
import type {Channels} from '~/types';
/* MAIN */
const saturate = ( color: string | Channels, amount: number ): string => {
return adjustChannel ( color, 's', amount );
};
/* EXPORT */
export default saturate;
fabiospampinato-khroma-f998e9b/src/methods/saturation.ts 0000664 0000000 0000000 00000000371 14223624663 0023612 0 ustar 00root root 0000000 0000000
/* IMPORT */
import channel from '~/methods/channel';
import type {Channels} from '~/types';
/* MAIN */
const saturation = ( color: string | Channels ): number => {
return channel ( color, 's' );
};
/* EXPORT */
export default saturation;
fabiospampinato-khroma-f998e9b/src/methods/scale.ts 0000664 0000000 0000000 00000001230 14223624663 0022503 0 ustar 00root root 0000000 0000000
/* IMPORT */
import _ from '~/utils';
import Color from '~/color';
import adjust from '~/methods/adjust';
import type {CHANNELS, Channels} from '~/types';
/* MAIN */
const scale = ( color: string | Channels, channels: Partial ): string => {
const ch = Color.parse ( color );
const adjustments: Partial = {};
const delta = ( amount: number, weight: number, max: number ) => weight > 0 ? ( max - amount ) * weight / 100 : amount * weight / 100;
for ( const c in channels ) {
adjustments[c] = delta ( ch[c], channels[c], _.channel.max[c] );
}
return adjust ( color, adjustments );
};
/* EXPORT */
export default scale;
fabiospampinato-khroma-f998e9b/src/methods/to_hex.ts 0000664 0000000 0000000 00000000317 14223624663 0022707 0 ustar 00root root 0000000 0000000
/* IMPORT */
import Color from '~/color';
/* MAIN */
const toHex = ( color: string ): string => {
return Color.format.hex.stringify ( Color.parse ( color ) );
};
/* EXPORT */
export default toHex;
fabiospampinato-khroma-f998e9b/src/methods/to_hsla.ts 0000664 0000000 0000000 00000000322 14223624663 0023046 0 ustar 00root root 0000000 0000000
/* IMPORT */
import Color from '~/color';
/* MAIN */
const toHsla = ( color: string ): string => {
return Color.format.hsla.stringify ( Color.parse ( color ) );
};
/* EXPORT */
export default toHsla;
fabiospampinato-khroma-f998e9b/src/methods/to_keyword.ts 0000664 0000000 0000000 00000000347 14223624663 0023612 0 ustar 00root root 0000000 0000000
/* IMPORT */
import Color from '~/color';
/* MAIN */
const toKeyword = ( color: string ): string | undefined => {
return Color.format.keyword.stringify ( Color.parse ( color ) );
};
/* EXPORT */
export default toKeyword;
fabiospampinato-khroma-f998e9b/src/methods/to_rgba.ts 0000664 0000000 0000000 00000000322 14223624663 0023032 0 ustar 00root root 0000000 0000000
/* IMPORT */
import Color from '~/color';
/* MAIN */
const toRgba = ( color: string ): string => {
return Color.format.rgba.stringify ( Color.parse ( color ) );
};
/* EXPORT */
export default toRgba;
fabiospampinato-khroma-f998e9b/src/methods/transparentize.ts 0000664 0000000 0000000 00000000455 14223624663 0024475 0 ustar 00root root 0000000 0000000
/* IMPORT */
import adjustChannel from '~/methods/adjust_channel';
import type {Channels} from '~/types';
/* MAIN */
const transparentize = ( color: string | Channels, amount: number ): string => {
return adjustChannel ( color, 'a', -amount );
};
/* EXPORT */
export default transparentize;
fabiospampinato-khroma-f998e9b/src/types.ts 0000664 0000000 0000000 00000001105 14223624663 0021116 0 ustar 00root root 0000000 0000000
/* IMPORT */
import type Channels from './channels';
/* MAIN */
type ALPHA = {
a: number // Alpha (0~1)
};
type RGB = {
r: number, // Red (0~255)
g: number, // Green (0~255)
b: number // Blue (0~255)
};
type RGBA = RGB & ALPHA;
type HSL = {
h: number, // Hue (0~360)
s: number, // Saturation (0~100)
l: number // Lightness (0~100)
};
type HSLA = HSL & ALPHA;
type CHANNEL = 'r' | 'g' | 'b' | 'h' | 's' | 'l' | 'a';
type CHANNELS = Record;
/* EXPORT */
export type {Channels};
export type {ALPHA, RGB, RGBA, HSL, HSLA, CHANNEL, CHANNELS};
fabiospampinato-khroma-f998e9b/src/utils/ 0000775 0000000 0000000 00000000000 14223624663 0020545 5 ustar 00root root 0000000 0000000 fabiospampinato-khroma-f998e9b/src/utils/channel.ts 0000664 0000000 0000000 00000004672 14223624663 0022536 0 ustar 00root root 0000000 0000000
/* IMPORT */
import type {RGB, HSL} from '~/types';
/* MAIN */
const Channel = {
/* CLAMP */
min: {
r: 0,
g: 0,
b: 0,
s: 0,
l: 0,
a: 0
},
max: {
r: 255,
g: 255,
b: 255,
h: 360,
s: 100,
l: 100,
a: 1
},
clamp: {
r: ( r: number ) => r >= 255 ? 255 : ( r < 0 ? 0 : r ),
g: ( g: number ) => g >= 255 ? 255 : ( g < 0 ? 0 : g ),
b: ( b: number ) => b >= 255 ? 255 : ( b < 0 ? 0 : b ),
h: ( h: number ) => h % 360,
s: ( s: number ) => s >= 100 ? 100 : ( s < 0 ? 0 : s ),
l: ( l: number ) => l >= 100 ? 100 : ( l < 0 ? 0 : l ),
a: ( a: number ) => a >= 1 ? 1 : ( a < 0 ? 0 : a )
},
/* CONVERSION */
//SOURCE: https://planetcalc.com/7779
toLinear: ( c: number ): number => {
const n = c / 255;
return c > .03928 ? Math.pow ( ( ( n + .055 ) / 1.055 ), 2.4 ) : n / 12.92;
},
//SOURCE: https://gist.github.com/mjackson/5311256
hue2rgb: ( p: number, q: number, t: number ): number => {
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;
},
hsl2rgb: ( { h, s, l }: HSL, channel: keyof RGB ): number => {
if ( !s ) return l * 2.55; // Achromatic
h /= 360;
s /= 100;
l /= 100;
const q = ( l < .5 ) ? l * ( 1 + s ) : ( l + s ) - ( l * s );
const p = 2 * l - q;
switch ( channel ) {
case 'r': return Channel.hue2rgb ( p, q, h + 1/3 ) * 255;
case 'g': return Channel.hue2rgb ( p, q, h ) * 255;
case 'b': return Channel.hue2rgb ( p, q, h - 1/3 ) * 255;
}
},
rgb2hsl: ( { r, g, b }: RGB, channel: keyof HSL ): number => {
r /= 255;
g /= 255;
b /= 255;
const max = Math.max ( r, g, b );
const min = Math.min ( r, g, b );
const l = ( max + min ) / 2;
if ( channel === 'l' ) return l * 100;
if ( max === min ) return 0; // Achromatic
const d = max - min;
const s = ( l > .5 ) ? d / ( 2 - max - min ) : d / ( max + min );
if ( channel === 's' ) return s * 100;
switch ( max ) {
case r: return ( ( g - b ) / d + ( g < b ? 6 : 0 ) ) * 60;
case g: return ( ( b - r ) / d + 2 ) * 60;
case b: return ( ( r - g ) / d + 4 ) * 60;
default: return -1; //TSC: TypeScript is stupid and complains if there isn't this useless default statement
}
}
};
/* EXPORT */
export default Channel;
fabiospampinato-khroma-f998e9b/src/utils/index.ts 0000664 0000000 0000000 00000000327 14223624663 0022226 0 ustar 00root root 0000000 0000000
/* IMPORT */
import channel from '~/utils/channel';
import lang from '~/utils/lang';
import unit from '~/utils/unit';
/* MAIN */
const Utils = {
channel,
lang,
unit
};
/* EXPORT */
export default Utils;
fabiospampinato-khroma-f998e9b/src/utils/lang.ts 0000664 0000000 0000000 00000000660 14223624663 0022040 0 ustar 00root root 0000000 0000000
/* MAIN */
const Lang = {
/* API */
clamp: ( number: number, lower: number, upper: number ): number => {
if ( lower > upper ) return Math.min ( lower, Math.max ( upper, number ) );
return Math.min ( upper, Math.max ( lower, number ) );
},
round: ( number: number ): number => { // 10 digits rounding
return Math.round ( number * 10000000000 ) / 10000000000;
}
};
/* EXPORT */
export default Lang;
fabiospampinato-khroma-f998e9b/src/utils/unit.ts 0000664 0000000 0000000 00000000342 14223624663 0022073 0 ustar 00root root 0000000 0000000
/* MAIN */
const Unit = {
/* API */
dec2hex: ( dec: number ): string => {
const hex = Math.round ( dec ).toString ( 16 );
return hex.length > 1 ? hex : `0${hex}`;
}
};
/* EXPORT */
export default Unit;
fabiospampinato-khroma-f998e9b/tasks/ 0000775 0000000 0000000 00000000000 14223624663 0017743 5 ustar 00root root 0000000 0000000 fabiospampinato-khroma-f998e9b/tasks/benchmark.js 0000664 0000000 0000000 00000014305 14223624663 0022236 0 ustar 00root root 0000000 0000000
/* IMPORT */
import benchmark from 'benchloop';
import Color from '../dist/color/index.js';
import {hex, rgb, rgba, hsl, hsla, channel, red, green, blue, alpha, hue, saturation, lightness, darken, lighten, opacify, transparentize, saturate, desaturate, grayscale, invert, complement, scale, adjust, change, mix, contrast, luminance, isDark, isLight, toKeyword, toHex, toRgba, toHsla} from '../dist/index.js';
/* MAIN */
benchmark.defaultOptions = Object.assign ( benchmark.defaultOptions, {
log: 'compact',
iterations: 2500
});
benchmark.group ( 'parse', () => {
benchmark ({
name: 'keyword',
fn: () => {
Color.parse ( 'blue' );
}
});
benchmark.group ( 'hex', () => {
benchmark ({
name: 'rgb',
fn: () => {
Color.parse ( '#fc0' );
}
});
benchmark ({
name: 'rgba',
fn: () => {
Color.parse ( '#fc08' );
}
});
benchmark ({
name: 'rrggbb',
fn: () => {
Color.parse ( '#ffcc00' );
}
});
benchmark ({
name: 'rrggbbaa',
fn: () => {
Color.parse ( '#ffcc0088' );
}
});
});
benchmark.group ( 'rgb', () => {
benchmark ({
name: 'rgb',
fn: () => {
Color.parse ( 'rgb(255, 204, 0)' );
}
});
benchmark ({
name: 'rgba',
fn: () => {
Color.parse ( 'rgb(255, 204, 0, .5)' );
}
});
benchmark ({
name: 'rgba:percentage',
fn: () => {
Color.parse ( 'rgb(100%, 80%, 0%, .5)' );
}
});
benchmark ({
name: 'rgba:scientific',
fn: () => {
Color.parse ( 'rgba(1e2, .5e1, .5e0, +.25e2%)' );
}
});
});
benchmark.group ( 'hsl', () => {
benchmark ({
name: 'hsl',
fn: () => {
Color.parse ( 'hsl(150, 50%, 50%)' );
}
});
benchmark ({
name: 'hsla',
fn: () => {
Color.parse ( 'hsla(150, 50%, 50%, .5)' );
}
});
benchmark ({
name: 'hsla:deg',
fn: () => {
Color.parse ( 'hsla(0deg, 50%, 50%, .5)' );
}
});
benchmark ({
name: 'hsla:scientific',
fn: () => {
Color.parse ( 'hsla(1e2, 2e1%, .5e2%, +.25e2%)' );
}
});
benchmark ({
name: 'hsla:grad',
fn: () => {
Color.parse ( 'hsla(0grad, 50%, 50%, .5)' );
}
});
benchmark ({
name: 'hsla:rad',
fn: () => {
Color.parse ( 'hsla(3.14rad, 50%, 50%, .5)' );
}
});
benchmark ({
name: 'hsla:turn',
fn: () => {
Color.parse ( 'hsla(1turn, 50%, 50%, .5)' );
}
});
});
});
benchmark.group ( 'stringify', () => {
const channels = Color.parse ( '#ff00ff' );
benchmark ({
name: 'keyword',
fn: () => {
toKeyword ( channels );
}
});
benchmark ({
name: 'hex',
fn: () => {
toHex ( channels );
}
});
benchmark ({
name: 'rgba',
fn: () => {
toRgba ( channels );
}
});
benchmark ({
name: 'hsla',
fn: () => {
toHsla ( channels );
}
});
});
benchmark.group ( 'create', () => {
benchmark ({
name: 'hex',
fn: () => {
hex ( 255, 204, 0 );
}
});
benchmark ({
name: 'rgb',
fn: () => {
rgb ( 255, 204, 0 );
}
});
benchmark ({
name: 'rgba',
fn: () => {
rgba ( 255, 204, 0, 136 );
}
});
benchmark ({
name: 'hsl',
fn: () => {
hsl ( 150, 50, 50 );
}
});
benchmark ({
name: 'hsla',
fn: () => {
hsla ( 150, 50, 50, .5 );
}
});
});
benchmark.group ( 'get.channel', () => {
benchmark ({
name: 'channel',
fn: () => {
channel ( '#ffcc00', 'r' );
}
});
benchmark ({
name: 'red',
fn: () => {
red ( '#ffcc00' );
}
});
benchmark ({
name: 'green',
fn: () => {
green ( '#ffcc00' );
}
});
benchmark ({
name: 'blue',
fn: () => {
blue ( '#ffcc00' );
}
});
benchmark ({
name: 'hue',
fn: () => {
hue ( '#ffcc00' );
}
});
benchmark ({
name: 'saturation',
fn: () => {
saturation ( '#ffcc00' );
}
});
benchmark ({
name: 'lightness',
fn: () => {
lightness ( '#ffcc00' );
}
});
benchmark ({
name: 'alpha',
fn: () => {
alpha ( '#ffcc00' );
}
});
});
benchmark.group ( 'get.more', () => {
benchmark ({
name: 'contrast',
fn: () => {
contrast ( '#000000', '#ffffff' );
}
});
benchmark ({
name: 'luminance',
fn: () => {
luminance ( '#ffcc00' );
}
});
benchmark ({
name: 'isDark',
fn: () => {
isDark ( '#ffcc00' );
}
});
benchmark ({
name: 'isLight',
fn: () => {
isLight ( '#ffcc00' );
}
});
});
benchmark.group ( 'edit.channel', () => {
benchmark ({
name: 'saturate',
fn: () => {
saturate ( '#ffcc00', 50 );
}
});
benchmark ({
name: 'desaturate',
fn: () => {
desaturate ( '#ffcc00', 50 );
}
});
benchmark ({
name: 'lighten',
fn: () => {
lighten ( '#ffcc00', 50 );
}
});
benchmark ({
name: 'darken',
fn: () => {
darken ( '#ffcc00', 50 );
}
});
benchmark ({
name: 'opacify',
fn: () => {
opacify ( '#ffcc00', .5 );
}
});
benchmark ({
name: 'transparentize',
fn: () => {
transparentize ( '#ffcc00', .5 );
}
});
benchmark ({
name: 'rgba',
fn: () => {
rgba ( '#ffcc00', .5 );
}
});
benchmark ({
name: 'complement',
fn: () => {
complement ( '#ffcc00' );
}
});
benchmark ({
name: 'grayscale',
fn: () => {
grayscale ( '#ffcc00' );
}
});
});
benchmark.group ( 'edit.more', () => {
benchmark ({
name: 'adjust',
fn: () => {
adjust ( '#ffcc00', { a: -.5 } );
}
});
benchmark ({
name: 'change',
fn: () => {
change ( '#ffcc00', { a: .5 } );
}
});
benchmark ({
name: 'invert',
fn: () => {
invert ( '#ffcc00', 50 );
}
});
benchmark ({
name: 'mix',
fn: () => {
mix ( '#ffcc00', '#000000', 50 );
}
});
benchmark ({
name: 'scale',
fn: () => {
scale ( '#ffcc00', { r: 50, g: 50, b: 50 } );
}
});
});
benchmark.summary ();
fabiospampinato-khroma-f998e9b/test/ 0000775 0000000 0000000 00000000000 14223624663 0017575 5 ustar 00root root 0000000 0000000 fabiospampinato-khroma-f998e9b/test/color/ 0000775 0000000 0000000 00000000000 14223624663 0020713 5 ustar 00root root 0000000 0000000 fabiospampinato-khroma-f998e9b/test/color/hex.js 0000664 0000000 0000000 00000002422 14223624663 0022035 0 ustar 00root root 0000000 0000000
/* IMPORT */
import {describe} from 'fava';
import Color from '../../dist/color/index.js';
/* MAIN */
describe ( 'Hex', it => {
it ( 'parses hex colors', t => {
const tests = [
/* RGB */
['#000', '#000000'],
['#fff', '#ffffff'],
['#a2b', '#aa22bb'],
['#a2B', '#aa22bb'],
/* RGBA */
['#0000', '#00000000'],
['#fffF', '#ffffff'],
['#fff8', '#ffffff88'],
['#a2bf', '#aa22bb'],
['#a2Bf', '#aa22bb'],
/* RRGGBB */
['#000000', '#000000'],
['#FFFFFF', '#ffffff'],
['#ffffff', '#ffffff'],
['#ae12b4', '#ae12b4'],
['#Ae12B4', '#ae12b4'],
/* RRGGBBAA */
['#000000ff', '#000000'],
['#00000000', '#00000000'],
['#ffffffa8', '#ffffffa8'],
['#ffffffA8', '#ffffffa8']
];
tests.forEach ( ([ input, output ]) => {
t.is ( Color.format.hex.stringify ( Color.parse ( input ) ), output );
});
});
it ( 'throws with unsupported colors', t => {
const colors = [
'#',
'#0',
'#00',
'#ggg',
'#zzz',
'fff',
'#0 0 0',
'# 000',
'#aabbc',
'#aabbccd',
'#aabbccdde'
];
colors.forEach ( color => {
t.throws ( () => Color.parse ( color ), /unsupported/i );
});
});
});
fabiospampinato-khroma-f998e9b/test/color/hsl.js 0000664 0000000 0000000 00000006377 14223624663 0022054 0 ustar 00root root 0000000 0000000
/* IMPORT */
import {describe} from 'fava';
import Color from '../../dist/color/index.js';
/* MAIN */
describe ( 'HSL', it => {
it ( 'parses HSL colors', t => {
const tests = [
/* NO UNIT HUE */
['hsl(0, 0%, 0%)', 'hsl(0, 0%, 0%)'],
['hsl(0, 100%, 0%)', 'hsl(0, 100%, 0%)'],
['hsl(0, 0%, 100%)', 'hsl(0, 0%, 100%)'],
['hsl(0, 100%, 100%)', 'hsl(0, 100%, 100%)'],
['hsl(180, 50%, 50%)', 'hsl(180, 50%, 50%)'],
['hsl(180, 40.4%, 70.4%)', 'hsl(180, 40.4%, 70.4%)'],
/* S & L CLAMPING - H WRAPPING */
['hsl(-180, 40.4%, 70.4%)', 'hsl(-180, 40.4%, 70.4%)'],
['hsl(180, -40.4%, -70.4%)', 'hsl(180, 0%, 0%)'],
['hsl(180, 400.4%, 700.4%)', 'hsl(180, 100%, 100%)'],
['hsl(540, 100%, 50%)', 'hsl(180, 100%, 50%)'],
/* DEGREES */
['hsl(-180deg, 50%, 50%)', 'hsl(-180, 50%, 50%)'],
['hsl(0deg, 50%, 50%)', 'hsl(0, 50%, 50%)'],
['hsl(180deg, 50%, 50%)', 'hsl(180, 50%, 50%)'],
['hsl(360deg, 50%, 50%)', 'hsl(0, 50%, 50%)'],
['hsl(540deg, 50%, 50%)', 'hsl(180, 50%, 50%)'],
/* GRADIANS */
['hsl(0grad, 50%, 50%)', 'hsl(0, 50%, 50%)'],
['hsl(200grad, 50%, 50%)', 'hsl(180, 50%, 50%)'],
['hsl(400grad, 50%, 50%)', 'hsl(0, 50%, 50%)'],
/* RADIANS */
['hsl(0rad, 50%, 50%)', 'hsl(0, 50%, 50%)'],
['hsl(3.14159265359rad, 50%, 50%)', 'hsl(180, 50%, 50%)'],
/* TURNS */
['hsl(0turn, 50%, 50%)', 'hsl(0, 50%, 50%)'],
['hsl(0.5turn, 50%, 50%)', 'hsl(180, 50%, 50%)'],
['hsl(1turn, 50%, 50%)', 'hsl(0, 50%, 50%)'],
/* SCIENTIFIC NOTATION */
['hsl(1.8e2, 4.04e1%, .704e2%)', 'hsl(180, 40.4%, 70.4%)'],
['hsl(1.8e2deg, 4.04e1%, .704e2%)', 'hsl(180, 40.4%, 70.4%)'],
['hsl(1800e-1deg, 404e-1%, 7040e-2%)', 'hsl(180, 40.4%, 70.4%)'],
/* WITH COMMAS AND WEIRD SPACES */
['hsl( 0 , 0% , 0% )', 'hsl(0, 0%, 0%)'],
['hsl(0,0%,0%)', 'hsl(0, 0%, 0%)'],
/* WITHOUT COMMAS */
['hsl(0 0% 0%)', 'hsl(0, 0%, 0%)'],
['hsl( 0 0% 0% )', 'hsl(0, 0%, 0%)'],
['hsl(180deg 50% 50%)', 'hsl(180, 50%, 50%)'],
['hsl(180 40.4% 70.4%)', 'hsl(180, 40.4%, 70.4%)'],
/* WEIRD CASING */
['HSL(0 0% 0%)', 'hsl(0, 0%, 0%)'],
['hSl(0 0% 0%)', 'hsl(0, 0%, 0%)']
];
tests.forEach ( ([ input, output ]) => {
t.is ( Color.format.hsl.stringify ( Color.parse ( input ) ), output );
});
});
it ( 'throws with unsupported colors', t => {
const colors = [
'hsl',
'hsl()',
'hsl(0, 0)',
'hsl(0, 1, dog)',
'hsl(0de, 0, 0)',
'hsl(0gra, 0, 0)',
'hsl(1, 2, 3, 4, 5)',
'hsl(1/2/3)',
'hsl(1,, 20, 255)',
'hsl(1%,, 20%, 255%)',
'hsl(1%, 255%)',
'hsl(1%, 10%%, 255%)',
'hsl(1%, %10%, 255%)',
'hsl(1)',
'hsl(1, 20, 255',
'hsl 1, 20, 255',
'hsl 1, 20, 255)',
'hsl(1, a, 255)',
'hsl (1, 2, 255)',
'hsl(1,2,3..5)',
'hsl(1, 2, 3.4.5)',
'hslQ(1, 2, 255)',
'h s l(1, 2, 255)',
'hsl(0, 0, 0)',
'hsl(0, 100, 0)',
'hsl(0, 0, 100)',
'hsl(0, 100, 100)',
'hsl(180, 50, 50)',
'hsl(180, 40.4, 70.4)'
];
colors.forEach ( color => {
t.throws ( () => Color.parse ( color ), /unsupported/i );
});
});
});
fabiospampinato-khroma-f998e9b/test/color/hsla.js 0000664 0000000 0000000 00000005574 14223624663 0022213 0 ustar 00root root 0000000 0000000
/* IMPORT */
import {describe} from 'fava';
import Color from '../../dist/color/index.js';
/* MAIN */
describe ( 'HSLA', it => {
it ( 'parses HSLA colors', t => {
const tests = [
/* NO UNIT HUE */
['hsla(0, 0%, 0%, 0)', 'hsla(0, 0%, 0%, 0)'],
['hsla(0, 0%, 0%)', 'hsl(0, 0%, 0%)'],
['hsla(0, 0%, 0%, 10)', 'hsl(0, 0%, 0%)'],
['hsla(0, 0%, 0%, -10)', 'hsla(0, 0%, 0%, 0)'],
['hsla(0, 0%, 0%, 0.5)', 'hsla(0, 0%, 0%, 0.5)'],
['hsla(0, 0%, 0%, .5)', 'hsla(0, 0%, 0%, 0.5)'],
['hsla(0, 0%, 0%, 0.5 )', 'hsla(0, 0%, 0%, 0.5)'],
/* PERCENTAGE 0~100 */
['hsla(0, 0%, 0%, 0%)', 'hsla(0, 0%, 0%, 0)'],
['hsla(0, 0%, 0%, 100%)', 'hsl(0, 0%, 0%)'],
['hsla(0, 0%, 0%, 110%)', 'hsl(0, 0%, 0%)'],
['hsla(0, 0%, 0%, -110%)', 'hsla(0, 0%, 0%, 0)'],
['hsla(0, 0%, 0%, 50%)', 'hsla(0, 0%, 0%, 0.5)'],
['hsla(0, 0%, 0%, 50.5%)', 'hsla(0, 0%, 0%, 0.505)'],
/* WITH COMMAS AND WEIRD SPACES */
['hsla( 1 , 20% , 50%, 0.5 )', 'hsla(1, 20%, 50%, 0.5)'],
['hsla(1,20%,50%,50%)', 'hsla(1, 20%, 50%, 0.5)'],
['hsla( 1,20%,50%,0.5 )', 'hsla(1, 20%, 50%, 0.5)'],
/* WITH SLASH */
['hsla(0 0% 0% / 0.4)', 'hsla(0, 0%, 0%, 0.4)'],
['hsla(0 0% 0%/0.4)', 'hsla(0, 0%, 0%, 0.4)'],
['hsla(0 0% 0% / 40%)', 'hsla(0, 0%, 0%, 0.4)'],
['hsla(0, 0%, 0% / 40%)', 'hsla(0, 0%, 0%, 0.4)'],
['hsla(0,0%,0%/40%)', 'hsla(0, 0%, 0%, 0.4)'],
/* SCIENTIFIC NOTATION */
['hsla(1e2, 2e1%, .5e2%, +.25e2%)', 'hsla(100, 20%, 50%, 0.25)'],
['hsla(1e2, 2e1%, .5e2%, +.25e1%)', 'hsla(100, 20%, 50%, 0.025)'],
['hsla(1e2, 2e1%, .5e2%, +.25e0%)', 'hsla(100, 20%, 50%, 0.0025)'],
['hsla(1e2, 2e1%, .5e2%, .25e0)', 'hsla(100, 20%, 50%, 0.25)'],
['hsla(1e2, 2e1%, .5e2%, .25e1)', 'hsl(100, 20%, 50%)'],
['hsla(1e2, 2e1%, .5e2%, 25e-2)', 'hsla(100, 20%, 50%, 0.25)'],
/* MIXED UNITS */
['hsla(1, 20%, .5e2%, +.25e2%)', 'hsla(1, 20%, 50%, 0.25)'],
/* WEIRD CASING */
['HSLA(1, 20%, 50%, 0.5)', 'hsla(1, 20%, 50%, 0.5)'],
['hSlA(1, 20%, 50%, 0.5)', 'hsla(1, 20%, 50%, 0.5)']
];
tests.forEach ( ([ input, output ]) => {
t.is ( Color.format.hsla.stringify ( Color.parse ( input ) ), output );
});
});
it ( 'throws with unsupported colors', t => {
const colors = [
'hsla()',
'hsla(51 170 51 0.4)',
'hsla(1, 2, 3, 4, 5)',
'hsla(0, 0, 0, 0..5)',
'hsla(0, 0, 0, 0.5.)',
'hsla(0, 0, 0, 0%%)',
'hsla(51 170 51 // 0.4)',
'hsla(1ee2, .5e1, .5e0, +.25e2%)',
'hsla(1f2, .5e1, .5e0, +.25e2%)',
'hsla(0, 0, 0, 0)',
'hsla(0, 100, 0, 0)',
'hsla(0, 0, 100, 0)',
'hsla(0, 100, 100, 0)',
'hsla(180, 50, 50, 0)',
'hsla(180, 40.4, 70.4, 0)'
];
colors.forEach ( color => {
t.throws ( () => Color.parse ( color ), /unsupported/i );
});
});
});
fabiospampinato-khroma-f998e9b/test/color/keyword.js 0000664 0000000 0000000 00000001216 14223624663 0022735 0 ustar 00root root 0000000 0000000
/* IMPORT */
import {describe} from 'fava';
import Color from '../../dist/color/index.js';
/* MAIN */
describe ( 'Keyword', it => {
it ( 'parses keywords colors', t => {
const tests = [
['black', '#000000'],
['BLACK', '#000000'],
['tranSpaRent', '#00000000']
];
tests.forEach ( ([ input, output ]) => {
t.is ( Color.format.hex.stringify ( Color.parse ( input ) ), output );
});
});
it ( 'throws with unsupported colors', t => {
const colors = [
'foo',
'bar'
];
colors.forEach ( color => {
t.throws ( () => Color.parse ( color ), /unsupported/i );
});
});
});
fabiospampinato-khroma-f998e9b/test/color/rgb.js 0000664 0000000 0000000 00000003626 14223624663 0022032 0 ustar 00root root 0000000 0000000
/* IMPORT */
import {describe} from 'fava';
import Color from '../../dist/color/index.js';
/* MAIN */
describe ( 'RGB', it => {
it ( 'parses RGB colors', t => {
const tests = [
/* DECIAML 0~255 */
['rgb(1, 20, 255)', 'rgb(1, 20, 255)'],
['rgb(1.99, 20.5, 255)', 'rgb(1.99, 20.5, 255)'],
['rgb(300, 255, -100)', 'rgb(255, 255, 0)'],
/* PERCENTAGE 0~100 */
['rgb(10%, 20%, 30%)', 'rgb(25.5, 51, 76.5)'],
['rgb(10.5%, 20.7%, 30%)', 'rgb(26.775, 52.785, 76.5)'],
['rgb(100% 200% -30%)', 'rgb(255, 255, 0)'],
/* WITH COMMAS AND WEIRD SPACES */
['rgb( 1 , 20 , 255 )', 'rgb(1, 20, 255)'],
['rgb(1,20,255)', 'rgb(1, 20, 255)'],
['rgb( 1,20,255 )', 'rgb(1, 20, 255)'],
/* WITHOUT COMMAS */
['rgb(10% 20% 30%)', 'rgb(25.5, 51, 76.5)'],
['rgb(1 20 255)', 'rgb(1, 20, 255)'],
['rgb( 1 20 255 )', 'rgb(1, 20, 255)'],
/* MIXED UNITS */
['rgb(10% 20 30%)', 'rgb(25.5, 20, 76.5)'],
['rgb(1 25.5 25.5)', 'rgb(1, 25.5, 25.5)'],
/* WEIRD CASING */
['RGB(1, 20, 255)', 'rgb(1, 20, 255)'],
['rGb(1, 20, 255)', 'rgb(1, 20, 255)']
];
tests.forEach ( ([ input, output ]) => {
t.is ( Color.format.rgb.stringify ( Color.parse ( input ) ), output );
});
});
it ( 'throws with unsupported colors', t => {
const colors = [
'rgb()',
'rgb(1, 2, 3, 4, 5)',
'rgb(1/2/3)',
'rgb(1,, 20, 255)',
'rgb(1%,, 20%, 255%)',
'rgb(1%, 255%)',
'rgb(1%, 10%%, 255%)',
'rgb(1%, %10%, 255%)',
'rgb(1)',
'rgb(1, 20, 255',
'rgb 1, 20, 255',
'rgb 1, 20, 255)',
'rgb(1, a, 255)',
'rgb (1, 2, 255)',
'rgb(1,2,3..5)',
'rgb(1, 2, 3.4.5)',
'rgbQ(1, 2, 255)',
'r g b(1, 2, 255)'
];
colors.forEach ( color => {
t.throws ( () => Color.parse ( color ), /unsupported/i );
});
});
});
fabiospampinato-khroma-f998e9b/test/color/rgba.js 0000664 0000000 0000000 00000005116 14223624663 0022167 0 ustar 00root root 0000000 0000000
/* IMPORT */
import {describe} from 'fava';
import Color from '../../dist/color/index.js';
/* MAIN */
describe ( 'RGBA', it => {
it ( 'parses RGBA colors', t => {
const tests = [
/* FRACTION 0~1 */
['rgba(0, 0, 0, 0)', 'rgba(0, 0, 0, 0)'],
['rgba(0, 0, 0)', 'rgb(0, 0, 0)'],
['rgba(0, 0, 0, 10)', 'rgb(0, 0, 0)'],
['rgba(0, 0, 0, -10)', 'rgba(0, 0, 0, 0)'],
['rgba(0, 0, 0, 0.5)', 'rgba(0, 0, 0, 0.5)'],
['rgba(0, 0, 0, .5)', 'rgba(0, 0, 0, 0.5)'],
['rgba(0, 0, 0, 0.5 )', 'rgba(0, 0, 0, 0.5)'],
/* PERCENTAGE 0~100 */
['rgba(0, 0, 0, 0%)', 'rgba(0, 0, 0, 0)'],
['rgba(0, 0, 0, 100%)', 'rgb(0, 0, 0)'],
['rgba(0, 0, 0, 110%)', 'rgb(0, 0, 0)'],
['rgba(0, 0, 0, -110%)', 'rgba(0, 0, 0, 0)'],
['rgba(0, 0, 0, 50%)', 'rgba(0, 0, 0, 0.5)'],
['rgba(0, 0, 0, 50.5%)', 'rgba(0, 0, 0, 0.505)'],
/* WITH COMMAS AND WEIRD SPACES */
['rgba( 1 , 20 , 255, 0.5 )', 'rgba(1, 20, 255, 0.5)'],
['rgba(1,20,255,50%)', 'rgba(1, 20, 255, 0.5)'],
['rgba( 1,20,255,0.5 )', 'rgba(1, 20, 255, 0.5)'],
/* WITH SLASH */
['rgba(51 170 51 / 0.4)', 'rgba(51, 170, 51, 0.4)'],
['rgba(51 170 51/0.4)', 'rgba(51, 170, 51, 0.4)'],
['rgba(51 170 51 / 40%)', 'rgba(51, 170, 51, 0.4)'],
['rgba(51, 170, 51 / 40%)', 'rgba(51, 170, 51, 0.4)'],
['rgba(51,170,51/40%)', 'rgba(51, 170, 51, 0.4)'],
/* SCIENTIFIC NOTATION */
['rgba(1e2, .5e1, .5e0, +.25e2%)', 'rgba(100, 5, 0.5, 0.25)'],
['rgba(1e2, .5e1, .5e0, +.25e1%)', 'rgba(100, 5, 0.5, 0.025)'],
['rgba(1e2, .5e1, .5e0, +.25e0%)', 'rgba(100, 5, 0.5, 0.0025)'],
['rgba(1e2, .5e1, .5e0, .25e0)', 'rgba(100, 5, 0.5, 0.25)'],
['rgba(1e2, .5e1, .5e0, .25e1)', 'rgb(100, 5, 0.5)'],
/* MIXED UNITS */
['rgba(1, 10%, .5e0, +.25e2%)', 'rgba(1, 25.5, 0.5, 0.25)'],
/* WEIRD CASING */
['RGBA(1, 20, 255, 0.5)', 'rgba(1, 20, 255, 0.5)'],
['rgbA(1, 20, 255, 0.5)', 'rgba(1, 20, 255, 0.5)']
];
tests.forEach ( ([ input, output ]) => {
t.is ( Color.format.rgba.stringify ( Color.parse ( input ) ), output );
});
});
it ( 'throws with unsupported colors', t => {
const colors = [
'rgba()',
'rgba(51 170 51 0.4)',
'rgba(1, 2, 3, 4, 5)',
'rgba(0, 0, 0, 0..5)',
'rgba(0, 0, 0, 0.5.)',
'rgba(0, 0, 0, 0%%)',
'rgba(51 170 51 // 0.4)',
'rgba(1ee2, .5e1, .5e0, +.25e2%)',
'rgba(1f2, .5e1, .5e0, +.25e2%)'
];
colors.forEach ( color => {
t.throws ( () => Color.parse ( color ), /unsupported/i );
});
});
});
fabiospampinato-khroma-f998e9b/test/methods/ 0000775 0000000 0000000 00000000000 14223624663 0021240 5 ustar 00root root 0000000 0000000 fabiospampinato-khroma-f998e9b/test/methods/adjust.js 0000664 0000000 0000000 00000006110 14223624663 0023066 0 ustar 00root root 0000000 0000000
/* IMPORT */
import {describe} from 'fava';
import {adjust} from '../../dist/index.js';
import Color from '../../dist/color/index.js';
/* MAIN */
describe ( 'adjust', it => {
it ( 'increases or decreases the value of any RGB channel of the color', t => {
const tests = [
[['rgb(0, 0, 0)', { r: 100 }], 'rgb(100, 0, 0)'],
[['rgb(0, 0, 0)', { g: 100 }], 'rgb(0, 100, 0)'],
[['rgb(0, 0, 0)', { b: 100 }], 'rgb(0, 0, 100)'],
[['rgb(0, 0, 0)', { r: 100, g: 100 }], 'rgb(100, 100, 0)'],
[['rgb(0, 0, 0)', { r: 100, g: 100, b: 100 }], 'rgb(100, 100, 100)'],
[['rgb(255, 255, 255)', { r: -100 }], 'rgb(155, 255, 255)'],
[['rgb(255, 255, 255)', { g: -100 }], 'rgb(255, 155, 255)'],
[['rgb(255, 255, 255)', { b: -100 }], 'rgb(255, 255, 155)'],
[['rgb(200, 0, 0)', { r: 100 }], 'rgb(255, 0, 0)'],
[['rgb(100, 0, 0)', { r: -200 }], 'rgb(0, 0, 0)']
];
tests.forEach ( ([ args, output ]) => {
t.is ( Color.format.rgb.stringify ( Color.parse ( adjust ( ...args ) ) ), output );
});
});
it ( 'increases or decreases the value of any HSL channel of the color', t => {
const tests = [
[['hsl(0, 50%, 50%)', { h: 100 }], 'hsl(100, 50%, 50%)'],
[['hsl(0, 50%, 50%)', { s: 25 }], 'hsl(0, 75%, 50%)'],
[['hsl(0, 50%, 50%)', { l: 25 }], 'hsl(0, 50%, 75%)'],
[['hsl(0, 50%, 50%)', { h: 100, s: 25 }], 'hsl(100, 75%, 50%)'],
[['hsl(0, 50%, 50%)', { h: 100, s: 25, l: 25 }], 'hsl(100, 75%, 75%)'],
[['hsl(100, 50%, 50%)', { h: -100 }], 'hsl(0, 50%, 50%)'],
[['hsl(0, 50%, 50%)', { s: -25 }], 'hsl(0, 25%, 50%)'],
[['hsl(0, 50%, 50%)', { l: -25 }], 'hsl(0, 50%, 25%)'],
[['hsl(300, 50%, 50%)', { h: 100 }], 'hsl(40, 50%, 50%)'],
[['hsl(0, 50%, 50%)', { h: -100 }], 'hsl(-100, 50%, 50%)'],
[['hsl(0, 100%, 50%)', { s: 25 }], 'hsl(0, 100%, 50%)'],
[['hsl(0, 0%, 50%)', { s: -25 }], 'hsl(0, 0%, 50%)'],
[['hsla(0, 0%, 50%, .5)', { s: -25 }], 'hsla(0, 0%, 50%, 0.5)']
];
tests.forEach ( ([ args, output ]) => {
t.is ( Color.format.hsl.stringify ( Color.parse ( adjust ( ...args ) ) ), output );
});
});
it ( 'increases or decreases the value of the alpha channel of the color', t => {
const tests = [
[['rgba(0, 0, 0, 0)', { a: 0.5 }], 'rgba(0, 0, 0, 0.5)'],
[['hsla(0, 0%, 0%, 0)', { a: 0.5 }], 'hsla(0, 0%, 0%, 0.5)'],
[['rgba(0, 0, 0, 0)', { a: 1 }], '#000000'],
[['rgba(0, 0, 0, 1)', { a: -0.5 }], 'rgba(0, 0, 0, 0.5)'],
[['rgba(0, 0, 0, 1)', { a: -1 }], 'rgba(0, 0, 0, 0)'],
[['rgba(0, 0, 0, 0.5)', { a: 1 }], '#000000'],
[['rgba(0, 0, 0, 0.5)', { a: -1 }], 'rgba(0, 0, 0, 0)']
];
tests.forEach ( ([ args, output ]) => {
t.is ( adjust ( ...args ), output );
});
});
it ( 'throws when setting RGB and HSL channels at the same time', t => {
const tests = [
['#000', { r: 10, h: 10 }],
['#000', { g: 10, l: 10 }],
['#000', { b: 10, s: 10 }]
];
tests.forEach ( args => {
t.throws ( () => adjust ( ...args ), /cannot.*at the same time/i );
});
});
});
fabiospampinato-khroma-f998e9b/test/methods/alpha.js 0000664 0000000 0000000 00000000715 14223624663 0022666 0 ustar 00root root 0000000 0000000
/* IMPORT */
import {describe} from 'fava';
import {alpha} from '../../dist/index.js';
/* MAIN */
describe ( 'alpha', it => {
it ( 'gets the alpha channel of the color', t => {
const tests = [
['rgba(10, 20, 30)', 1],
['rgba(10, 20, 30, 0.1)', 0.1],
['#10203040', 0.2509803922],
['hsla(10, 20%, 30%, 0.5)', 0.5]
];
tests.forEach ( ([ color, output ]) => {
t.is ( alpha ( color ), output );
});
});
});
fabiospampinato-khroma-f998e9b/test/methods/blue.js 0000664 0000000 0000000 00000000622 14223624663 0022525 0 ustar 00root root 0000000 0000000
/* IMPORT */
import {describe} from 'fava';
import {blue} from '../../dist/index.js';
/* MAIN */
describe ( 'blue', it => {
it ( 'gets the blue channel of the color', t => {
const tests = [
['rgb(10, 20, 30)', 30],
['#102030', 48],
['hsl(10, 20%, 30%)', 61.2]
];
tests.forEach ( ([ color, output ]) => {
t.is ( blue ( color ), output );
});
});
});
fabiospampinato-khroma-f998e9b/test/methods/change.js 0000664 0000000 0000000 00000005420 14223624663 0023024 0 ustar 00root root 0000000 0000000
/* IMPORT */
import {describe} from 'fava';
import {change} from '../../dist/index.js';
import Color from '../../dist/color/index.js';
/* MAIN */
describe ( 'change', it => {
it ( 'sets a new value for any RGBA channel of the color', t => {
const tests = [
[['rgb(100, 100, 100)', { r: 0 }], 'rgb(0, 100, 100)'],
[['rgb(100, 100, 100)', { r: 255 }], 'rgb(255, 100, 100)'],
[['rgb(100, 100, 100)', { r: 100 }], 'rgb(100, 100, 100)'],
[['rgb(100, 100, 100)', { g: 0 }], 'rgb(100, 0, 100)'],
[['rgb(100, 100, 100)', { b: 0 }], 'rgb(100, 100, 0)'],
[['rgb(100, 100, 100)', { r: 50, g: 150 }], 'rgb(50, 150, 100)'],
[['rgb(100, 100, 100)', { r: 50, g: 150, b: 200 }], 'rgb(50, 150, 200)'],
[['rgb(100, 100, 100)', { r: 50, g: 150, b: 200, a: 0.5 }], 'rgba(50, 150, 200, 0.5)'],
[['rgb(100, 100, 100)', { r: 0, g: 0, b: 0, a: 0 }], 'rgba(0, 0, 0, 0)'],
[['rgba(100, 100, 100, .5)', { g: 0 }], 'rgba(100, 0, 100, 0.5)']
];
tests.forEach ( ([ args, output ]) => {
t.is ( Color.format.rgb.stringify ( Color.parse ( change ( ...args ) ) ), output );
});
});
it ( 'sets a new value for any HSLA channel of the color', t => {
const tests = [
[['hsl(50, 50%, 50%)', { h: 100 }], 'hsl(100, 50%, 50%)'],
[['hsl(50, 50%, 50%)', { h: 400 }], 'hsl(40, 50%, 50%)'],
[['hsl(50, 50%, 50%)', { h: 0 }], 'hsl(0, 50%, 50%)'],
[['hsl(50, 50%, 50%)', { s: 25 }], 'hsl(50, 25%, 50%)'],
[['hsl(50, 50%, 50%)', { l: 25 }], 'hsl(50, 50%, 25%)'],
[['hsl(50, 50%, 50%)', { h: 100, s: 75 }], 'hsl(100, 75%, 50%)'],
[['hsl(50, 50%, 50%)', { h: 100, s: 75, l: 25 }], 'hsl(100, 75%, 25%)'],
[['hsl(50, 50%, 50%)', { h: 100, s: 75, l: 25, a: 0.5 }], 'hsla(100, 75%, 25%, 0.5)'],
[['hsl(50, 50%, 50%)', { h: 0, s: 0, l: 0, a: 0 }], 'hsla(0, 0%, 0%, 0)'],
[['hsla(50, 50%, 50%, 0.5)', { h: 360, s: 100, l: 100, a: 1 }], 'hsl(0, 100%, 100%)']
];
tests.forEach ( ([ args, output ]) => {
t.is ( Color.format.hsl.stringify ( Color.parse ( change ( ...args ) ) ), output );
});
});
it ( 'sets a new value for the alpha channel of the color', t => {
const tests = [
[['rgba(0, 0, 0, 0)', { a: 0.5 }], 'rgba(0, 0, 0, 0.5)'],
[['hsla(0, 0%, 0%, 0.25)', { a: 0.5 }], 'hsla(0, 0%, 0%, 0.5)'],
[['rgba(0, 0, 0, 1)', { a: 1 }], '#000000']
];
tests.forEach ( ([ args, output ]) => {
t.is ( change ( ...args ), output );
});
});
it ( 'throws when setting RGB and HSL channels at the same time', t => {
const tests = [
['#000', { r: 0, h: 0 }],
['#000', { g: 0, l: 0 }],
['#000', { b: 0, s: 0 }]
];
tests.forEach ( args => {
t.throws ( () => change ( ...args ), /cannot.*at the same time/i );
});
});
});
fabiospampinato-khroma-f998e9b/test/methods/complement.js 0000664 0000000 0000000 00000000737 14223624663 0023750 0 ustar 00root root 0000000 0000000
/* IMPORT */
import {describe} from 'fava';
import {complement} from '../../dist/index.js';
/* MAIN */
describe ( 'complement', it => {
it ( 'gets the complement of the color', t => {
const tests = [
['#6b717f', 'hsl(42, 8.547008547%, 45.8823529412%)'],
['#d2e1dd', 'hsl(344, 20%, 85.2941176471%)'],
['#036', 'hsl(30, 100%, 20%)']
];
tests.forEach ( ([ color, output ]) => {
t.is ( complement ( color ), output );
});
});
});
fabiospampinato-khroma-f998e9b/test/methods/contrast.js 0000664 0000000 0000000 00000001075 14223624663 0023436 0 ustar 00root root 0000000 0000000
/* IMPORT */
import {describe} from 'fava';
import {contrast} from '../../dist/index.js';
/* MAIN */
describe ( 'contrast', it => {
it ( 'gets the contrast ratio between two colors', t => {
const tests = [
['#000000', '#000000', 1],
['#ffffff', '#ffffff', 1],
['#000000', '#ffffff', 10],
['#ffffff', '#000000', 10],
['#888888', '#ffffff', 4.0617165366],
['#ffffff', '#888888', 4.0617165366]
];
tests.forEach ( ([ color1, color2, output ]) => {
t.is ( contrast ( color1, color2 ), output );
});
});
});
fabiospampinato-khroma-f998e9b/test/methods/darken.js 0000664 0000000 0000000 00000001122 14223624663 0023036 0 ustar 00root root 0000000 0000000
/* IMPORT */
import {describe} from 'fava';
import {darken} from '../../dist/index.js';
/* MAIN */
describe ( 'darken', it => {
it ( 'decreases the lightness channel of the color', t => {
const tests = [
[['hsl(0, 0%, 100%)', 0], 'hsl(0, 0%, 100%)'],
[['hsl(0, 0%, 100%)', 50], 'hsl(0, 0%, 50%)'],
[['hsl(0, 0%, 100%)', 75], 'hsl(0, 0%, 25%)'],
[['hsl(0, 0%, 100%)', 100], 'hsl(0, 0%, 0%)'],
[['hsl(0, 0%, 50%)', 100], 'hsl(0, 0%, 0%)']
];
tests.forEach ( ([ args, output ]) => {
t.is ( darken ( ...args ), output );
});
});
});
fabiospampinato-khroma-f998e9b/test/methods/desaturate.js 0000664 0000000 0000000 00000001236 14223624663 0023741 0 ustar 00root root 0000000 0000000
/* IMPORT */
import {describe} from 'fava';
import {desaturate} from '../../dist/index.js';
/* MAIN */
describe ( 'desaturate', it => {
it ( 'decreases the saturation channel of the color', t => {
const tests = [
[['hsl(0, 100%, 50%)', 0], 'hsl(0, 100%, 50%)'],
[['hsl(0, 100%, 50%)', 50], 'hsl(0, 50%, 50%)'],
[['hsl(0, 100%, 50%)', 75], 'hsl(0, 25%, 50%)'],
[['hsl(0, 100%, 50%)', 100], 'hsl(0, 0%, 50%)'],
[['hsl(0, 50%, 50%)', 100], 'hsl(0, 0%, 50%)'],
[['hsl(0, 0%, 50%)', 100], 'hsl(0, 0%, 50%)']
];
tests.forEach ( ([ args, output ]) => {
t.is ( desaturate ( ...args ), output );
});
});
});
fabiospampinato-khroma-f998e9b/test/methods/grayscale.js 0000664 0000000 0000000 00000000730 14223624663 0023550 0 ustar 00root root 0000000 0000000
/* IMPORT */
import {describe} from 'fava';
import {grayscale} from '../../dist/index.js';
/* MAIN */
describe ( 'grayscale', it => {
it ( 'gets the grayscale version of the color', t => {
const tests = [
['#6b717f', 'hsl(222, 0%, 45.8823529412%)'],
['#d2e1dd', 'hsl(164, 0%, 85.2941176471%)'],
['#036', 'hsl(210, 0%, 20%)']
];
tests.forEach ( ([ color, output ]) => {
t.is ( grayscale ( color ), output );
});
});
});
fabiospampinato-khroma-f998e9b/test/methods/green.js 0000664 0000000 0000000 00000000626 14223624663 0022702 0 ustar 00root root 0000000 0000000
/* IMPORT */
import {describe} from 'fava';
import {green} from '../../dist/index.js';
/* MAIN */
describe ( 'green', it => {
it ( 'gets the green channel of the color', t => {
const tests = [
['rgb(10, 20, 30)', 20],
['#102030', 32],
['hsl(10, 20%, 30%)', 66.3]
];
tests.forEach ( ([ color, output ]) => {
t.is ( green ( color ), output );
});
});
});
fabiospampinato-khroma-f998e9b/test/methods/hex.js 0000664 0000000 0000000 00000001474 14223624663 0022370 0 ustar 00root root 0000000 0000000
/* IMPORT */
import {describe} from 'fava';
import {hex} from '../../dist/index.js';
/* MAIN */
describe ( 'hex', it => {
it ( 'creates a new color given its rgba channels', t => {
const tests = [
[[0, 0, 0, 0], 'rgba(0, 0, 0, 0)'],
[[255, 255, 255, 0.5], 'rgba(255, 255, 255, 0.5)'],
[[0, 0, 0, 1], '#000000'],
[[128, 128, 128, 1], '#808080'],
[[-1, -1, -1, -1], 'rgba(0, 0, 0, 0)'],
[[1000, 1000, 1000, 1000], '#ffffff']
];
tests.forEach ( ([ args, output ]) => {
t.is ( hex ( ...args ), output );
});
});
it ( 'allows ommiting the alpha channel', t => {
const tests = [
[[0, 0, 0], '#000000'],
[[255, 255, 255], '#ffffff']
];
tests.forEach ( ([ args, output ]) => {
t.is ( hex ( ...args ), output );
});
});
});
fabiospampinato-khroma-f998e9b/test/methods/hsla.js 0000664 0000000 0000000 00000001551 14223624663 0022527 0 ustar 00root root 0000000 0000000
/* IMPORT */
import {describe} from 'fava';
import {hsla} from '../../dist/index.js';
/* MAIN */
describe ( 'hsla', it => {
it ( 'creates a new color given its hsla channels.', t => {
const tests = [
[[0, 0, 0, 0], 'hsla(0, 0%, 0%, 0)'],
[[0, 0, 0, 0.5], 'hsla(0, 0%, 0%, 0.5)'],
[[0, 0, 0, 1], 'hsl(0, 0%, 0%)'],
[[180, 50, 50, 1], 'hsl(180, 50%, 50%)'],
[[-1, -1, -1, -1], 'hsla(-1, 0%, 0%, 0)'],
[[1000, 1000, 1000, 1000], 'hsl(280, 100%, 100%)']
];
tests.forEach ( ([ args, output ]) => {
t.is ( hsla ( ...args ), output );
});
});
it ( 'allows ommiting the alpha channel', t => {
const tests = [
[[0, 0, 0], 'hsl(0, 0%, 0%)'],
[[180, 50, 50], 'hsl(180, 50%, 50%)']
];
tests.forEach ( ([ args, output ]) => {
t.is ( hsla ( ...args ), output );
});
});
});
fabiospampinato-khroma-f998e9b/test/methods/hue.js 0000664 0000000 0000000 00000000616 14223624663 0022362 0 ustar 00root root 0000000 0000000
/* IMPORT */
import {describe} from 'fava';
import {hue} from '../../dist/index.js';
/* MAIN */
describe ( 'hue', it => {
it ( 'gets the hue channel of the color', t => {
const tests = [
['hsl(10, 20%, 30%)', 10],
['rgb(10, 20, 30)', 210],
['#102030', 210]
];
tests.forEach ( ([ color, output ]) => {
t.is ( hue ( color ), output );
});
});
});
fabiospampinato-khroma-f998e9b/test/methods/invert.js 0000664 0000000 0000000 00000000653 14223624663 0023111 0 ustar 00root root 0000000 0000000
/* IMPORT */
import {describe} from 'fava';
import {invert} from '../../dist/index.js';
/* MAIN */
describe ( 'invert', it => {
it ( 'gets the inverse of the color', t => {
const tests = [
[['#b37399'], '#4c8c66'],
[['black'], '#ffffff'],
[['#550e0c', 20 ], 'rgb(102, 59.4, 58.2)']
];
tests.forEach ( ([ args, output ]) => {
t.is ( invert ( ...args ), output );
});
});
});
fabiospampinato-khroma-f998e9b/test/methods/is_dark.js 0000664 0000000 0000000 00000000742 14223624663 0023215 0 ustar 00root root 0000000 0000000
/* IMPORT */
import {describe} from 'fava';
import {isDark} from '../../dist/index.js';
/* MAIN */
describe ( 'isDark', it => {
it ( 'checks if the provided color is a dark color', t => {
const tests = [
['#000000', true],
['#8a8a8a', true],
['#bbbbbb', true],
['#ffcc00', false],
['#e0e0e0', false],
['#ffffff', false]
];
tests.forEach ( ([ color, output ]) => {
t.is ( isDark ( color ), output );
});
});
});
fabiospampinato-khroma-f998e9b/test/methods/is_light.js 0000664 0000000 0000000 00000000746 14223624663 0023407 0 ustar 00root root 0000000 0000000
/* IMPORT */
import {describe} from 'fava';
import {isLight} from '../../dist/index.js';
/* MAIN */
describe ( 'isLight', it => {
it ( 'checks if the provided color is a light color', t => {
const tests = [
['#000000', false],
['#8a8a8a', false],
['#bbbbbb', false],
['#ffcc00', true],
['#e0e0e0', true],
['#ffffff', true]
];
tests.forEach ( ([ color, output ]) => {
t.is ( isLight ( color ), output );
});
});
});
fabiospampinato-khroma-f998e9b/test/methods/is_valid.js 0000664 0000000 0000000 00000000756 14223624663 0023400 0 ustar 00root root 0000000 0000000
/* IMPORT */
import {describe} from 'fava';
import {isValid} from '../../dist/index.js';
/* MAIN */
describe ( 'isValid', it => {
it ( 'checks if the provided color is a valid color', t => {
const tests = [
['black', true],
['rgb(10, 20, 30)', true],
['#102030', true],
['hsl(10, 20%, 30%)', true],
['#ggg', false],
['foo', false]
];
tests.forEach ( ([ color, output ]) => {
t.is ( isValid ( color ), output );
});
});
});
fabiospampinato-khroma-f998e9b/test/methods/lighten.js 0000664 0000000 0000000 00000001206 14223624663 0023227 0 ustar 00root root 0000000 0000000
/* IMPORT */
import {describe} from 'fava';
import {lighten} from '../../dist/index.js';
/* MAIN */
describe ( 'lighten', it => {
it ( 'increases the lightness channel of the color', t => {
const tests = [
[['hsl(0, 0%, 0%)', 0], 'hsl(0, 0%, 0%)'],
[['hsl(0, 0%, 0%)', 50], 'hsl(0, 0%, 50%)'],
[['hsl(0, 0%, 0%)', 75], 'hsl(0, 0%, 75%)'],
[['hsl(0, 0%, 0%)', 100], 'hsl(0, 0%, 100%)'],
[['hsl(0, 0%, 50%)', 100], 'hsl(0, 0%, 100%)'],
[['hsl(0, 0%, 100%)', 100], 'hsl(0, 0%, 100%)']
];
tests.forEach ( ([ args, output ]) => {
t.is ( lighten ( ...args ), output );
});
});
});
fabiospampinato-khroma-f998e9b/test/methods/lightness.js 0000664 0000000 0000000 00000000724 14223624663 0023601 0 ustar 00root root 0000000 0000000
/* IMPORT */
import {describe} from 'fava';
import {lightness} from '../../dist/index.js';
/* MAIN */
describe ( 'lightness', it => {
it ( 'gets the lightness channel of the color', t => {
const tests = [
['hsl(10, 20%, 30%)', 30],
['rgb(10, 20, 30)', 7.8431372549],
['rgb(0, 0, 0)', 0],
['#102030', 12.5490196078]
];
tests.forEach ( ([ color, output ]) => {
t.is ( lightness ( color ), output );
});
});
});
fabiospampinato-khroma-f998e9b/test/methods/luminance.js 0000664 0000000 0000000 00000000772 14223624663 0023557 0 ustar 00root root 0000000 0000000
/* IMPORT */
import {describe} from 'fava';
import {luminance} from '../../dist/index.js';
/* MAIN */
describe ( 'luminance', it => {
it ( 'gets the relative luminance of the color', t => {
const tests = [
['#000000', 0],
['#8a8a8a', .2541520943],
['#bbbbbb', .4969329951],
['#ffcc00', .6444573127],
['#e0e0e0', .7454042095],
['#ffffff', 1]
];
tests.forEach ( ([ color, output ]) => {
t.is ( luminance ( color ), output );
});
});
});
fabiospampinato-khroma-f998e9b/test/methods/mix.js 0000664 0000000 0000000 00000001066 14223624663 0022376 0 ustar 00root root 0000000 0000000
/* IMPORT */
import {describe} from 'fava';
import {mix} from '../../dist/index.js';
/* MAIN */
describe ( 'mix', it => {
it ( 'mixes two colors together', t => {
const tests = [
[['#036', '#d2e1dd'], 'rgb(105, 138, 161.5)'],
[['#036', '#d2e1dd', 75 ], 'rgb(52.5, 94.5, 131.75)'],
[['#036', '#d2e1dd', 25 ], 'rgb(157.5, 181.5, 191.25)'],
[['rgba(242, 236, 228, 0.5)', '#6b717f'], 'rgba(140.75, 143.75, 152.25, 0.75)']
];
tests.forEach ( ([ args, output ]) => {
t.is ( mix ( ...args ), output );
});
});
});
fabiospampinato-khroma-f998e9b/test/methods/opacify.js 0000664 0000000 0000000 00000000731 14223624663 0023231 0 ustar 00root root 0000000 0000000
/* IMPORT */
import {describe} from 'fava';
import {opacify} from '../../dist/index.js';
/* MAIN */
describe ( 'opacify', it => {
it ( 'increases the opacity channel of the color', t => {
const tests = [
[['#000000', 1], '#000000'],
[['rgba(0, 0, 0, 0.5)', 0.5], '#000000'],
[['rgba(0, 0, 0, 0.5)', 0.1], 'rgba(0, 0, 0, 0.6)']
];
tests.forEach ( ([ args, output ]) => {
t.is ( opacify ( ...args ), output );
});
});
});
fabiospampinato-khroma-f998e9b/test/methods/red.js 0000664 0000000 0000000 00000000616 14223624663 0022353 0 ustar 00root root 0000000 0000000
/* IMPORT */
import {describe} from 'fava';
import {red} from '../../dist/index.js';
/* MAIN */
describe ( 'red', it => {
it ( 'gets the red channel of the color', t => {
const tests = [
['rgb(10, 20, 30)', 10],
['#102030', 16],
['hsl(10, 20%, 30%)', 91.8]
];
tests.forEach ( ([ color, output ]) => {
t.is ( red ( color ), output );
});
});
});
fabiospampinato-khroma-f998e9b/test/methods/rgba.js 0000664 0000000 0000000 00000002427 14223624663 0022516 0 ustar 00root root 0000000 0000000
/* IMPORT */
import {describe} from 'fava';
import {rgba} from '../../dist/index.js';
/* MAIN */
describe ( 'rgba', it => {
it ( 'creates a new color given its rgba channels', t => {
const tests = [
[[0, 0, 0, 0], 'rgba(0, 0, 0, 0)'],
[[255, 255, 255, 0.5], 'rgba(255, 255, 255, 0.5)'],
[[0, 0, 0, 1], '#000000'],
[[128, 128, 128, 1], '#808080'],
[[-1, -1, -1, -1], 'rgba(0, 0, 0, 0)'],
[[1000, 1000, 1000, 1000], '#ffffff']
];
tests.forEach ( ([ args, output ]) => {
t.is ( rgba ( ...args ), output );
});
});
it ( 'sets the opacity', t => {
const tests = [
[['#000000', .5], 'rgba(0, 0, 0, 0.5)'],
[['#00000066', .5], 'rgba(0, 0, 0, 0.5)'],
[['#ffffff', .5], 'rgba(255, 255, 255, 0.5)'],
[['#ffffff66', .5], 'rgba(255, 255, 255, 0.5)'],
[['#ffcc00', .5], 'rgba(255, 204, 0, 0.5)'],
[['#ffcc0066', .5], 'rgba(255, 204, 0, 0.5)']
];
tests.forEach ( ([ args, output ]) => {
t.is ( rgba ( ...args ), output );
});
});
it ( 'allows ommiting the alpha channel', t => {
const tests = [
[[0, 0, 0], '#000000'],
[[255, 255, 255], '#ffffff']
];
tests.forEach ( ([ args, output ]) => {
t.is ( rgba ( ...args ), output );
});
});
});
fabiospampinato-khroma-f998e9b/test/methods/saturate.js 0000664 0000000 0000000 00000001226 14223624663 0023427 0 ustar 00root root 0000000 0000000
/* IMPORT */
import {describe} from 'fava';
import {saturate} from '../../dist/index.js';
/* MAIN */
describe ( 'saturate', it => {
it ( 'increases the saturation channel of the color', t => {
const tests = [
[['hsl(0, 0%, 50%)', 0], 'hsl(0, 0%, 50%)'],
[['hsl(0, 0%, 50%)', 50], 'hsl(0, 50%, 50%)'],
[['hsl(0, 0%, 50%)', 75], 'hsl(0, 75%, 50%)'],
[['hsl(0, 0%, 50%)', 100], 'hsl(0, 100%, 50%)'],
[['hsl(0, 50%, 50%)', 100], 'hsl(0, 100%, 50%)'],
[['hsl(0, 100%, 50%)', 100], 'hsl(0, 100%, 50%)']
];
tests.forEach ( ([ args, output ]) => {
t.is ( saturate ( ...args ), output );
});
});
});
fabiospampinato-khroma-f998e9b/test/methods/saturation.js 0000664 0000000 0000000 00000000733 14223624663 0023772 0 ustar 00root root 0000000 0000000
/* IMPORT */
import {describe} from 'fava';
import {saturation} from '../../dist/index.js';
/* MAIN */
describe ( 'saturation', it => {
it ( 'gets the saturation channel of the color', t => {
const tests = [
['hsl(10, 20%, 30%)', 20],
['rgb(10, 20, 30)', 50],
['rgb(0, 0, 0)', 0],
['#102030', 50],
['#ff0000', 100]
];
tests.forEach ( ([ color, output ]) => {
t.is ( saturation ( color ), output );
});
});
});
fabiospampinato-khroma-f998e9b/test/methods/scale.js 0000664 0000000 0000000 00000006430 14223624663 0022670 0 ustar 00root root 0000000 0000000
/* IMPORT */
import {describe} from 'fava';
import {scale} from '../../dist/index.js';
import Color from '../../dist/color/index.js';
/* MAIN */
describe ( 'scale', it => {
it ( 'scales any RGBA channels of the color', t => {
const tests = [
[['rgb(0, 0, 0)', { r: 100 }], 'rgb(255, 0, 0)'],
[['rgb(0, 0, 0)', { r: 50 }], 'rgb(127.5, 0, 0)'],
[['rgb(0, 0, 0)', { r: 0 }], 'rgb(0, 0, 0)'],
[['rgb(255, 0, 0)', { r: -100 }], 'rgb(0, 0, 0)'],
[['rgb(255, 0, 0)', { r: -50 }], 'rgb(127.5, 0, 0)'],
[['rgb(255, 0, 0)', { r: -0 }], 'rgb(255, 0, 0)'],
[['rgb(0, 0, 0)', { g: 100 }], 'rgb(0, 255, 0)'],
[['rgb(0, 0, 0)', { g: 50 }], 'rgb(0, 127.5, 0)'],
[['rgb(0, 0, 0)', { g: 0 }], 'rgb(0, 0, 0)'],
[['rgb(0, 0, 0)', { b: 100 }], 'rgb(0, 0, 255)'],
[['rgb(0, 0, 0)', { b: 50 }], 'rgb(0, 0, 127.5)'],
[['rgb(0, 0, 0)', { b: 0 }], 'rgb(0, 0, 0)'],
[['rgb(0, 0, 0)', { r: 50, g: 50, b: 50 }], 'rgb(127.5, 127.5, 127.5)'],
[['rgba(0, 0, 0, .5)', { b: 0 }], 'rgba(0, 0, 0, 0.5)']
];
tests.forEach ( ([ args, ouptut ]) => {
t.is ( Color.format.rgb.stringify ( Color.parse ( scale ( ...args ) ) ), ouptut );
});
});
it ( 'scales any HSLA channels of the color', t => {
const tests = [
[['hsl(0, 50%, 50%)', { h: 100 }], 'hsl(0, 50%, 50%)'], // Wraps becuase 360deg = 0deg
[['hsl(0, 50%, 50%)', { h: 50 }], 'hsl(180, 50%, 50%)'],
[['hsl(0, 50%, 50%)', { h: 0 }], 'hsl(0, 50%, 50%)'],
[['hsl(180, 50%, 50%)', { h: -100 }], 'hsl(0, 50%, 50%)'],
[['hsl(180, 50%, 50%)', { h: -50 }], 'hsl(90, 50%, 50%)'],
[['hsl(0, 50%, 50%)', { s: 100 }], 'hsl(0, 100%, 50%)'],
[['hsl(0, 50%, 50%)', { s: 50 }], 'hsl(0, 75%, 50%)'],
[['hsl(0, 50%, 50%)', { s: 0 }], 'hsl(0, 50%, 50%)'],
[['hsl(0, 50%, 50%)', { s: -100 }], 'hsl(0, 0%, 50%)'],
[['hsl(0, 50%, 50%)', { s: -50 }], 'hsl(0, 25%, 50%)'],
[['hsl(0, 50%, 50%)', { l: 100 }], 'hsl(0, 50%, 100%)'],
[['hsl(0, 50%, 50%)', { l: 50 }], 'hsl(0, 50%, 75%)'],
[['hsl(0, 50%, 50%)', { l: 0 }], 'hsl(0, 50%, 50%)'],
[['hsla(0, 50%, 50%, .5)', { l: 0 }], 'hsla(0, 50%, 50%, 0.5)']
];
tests.forEach ( ([ args, output ]) => {
t.is ( Color.format.hsl.stringify ( Color.parse ( scale ( ...args ) ) ), output );
});
});
it ( 'scales the alpha channel', t => {
const tests = [
[['rgba(0, 0, 0, 0)', { a: 0 }], 'rgba(0, 0, 0, 0)'],
[['rgba(0, 0, 0, 0)', { a: 50 }], 'rgba(0, 0, 0, 0.5)'],
[['rgba(0, 0, 0, 0)', { a: 100 }], '#000000'],
[['hsla(0, 0%, 0%, 0)', { a: 50 }], 'hsla(0, 0%, 0%, 0.5)'],
[['rgba(0, 0, 0, 1)', { a: -50 }], 'rgba(0, 0, 0, 0.5)'],
[['rgba(0, 0, 0, 1)', { a: -100 }], 'rgba(0, 0, 0, 0)'],
[['rgba(0, 0, 0, 0.5)', { a: 100 }], '#000000'],
[['rgba(0, 0, 0, 0.5)', { a: -100 }], 'rgba(0, 0, 0, 0)']
];
tests.forEach ( ([ args, output ]) => {
t.is ( scale ( ...args ), output );
});
});
it ( 'throws when setting RGB and HSL channels at the same time', t => {
const tests = [
['#000', { r: 10, h: 10 }],
['#000', { g: 10, l: 10 }],
['#000', { b: 10, s: 10 }]
];
tests.forEach ( args => {
t.throws ( () => scale ( ...args ), /cannot.*at the same time/i );
});
});
});
fabiospampinato-khroma-f998e9b/test/methods/transparentize.js 0000664 0000000 0000000 00000001067 14223624663 0024653 0 ustar 00root root 0000000 0000000
/* IMPORT */
import {describe} from 'fava';
import {transparentize} from '../../dist/index.js';
/* MAIN */
describe ( 'transparentize', it => {
it ( 'decreases the opacity channel of the color', t => {
const tests = [
[['#000000', 1], 'rgba(0, 0, 0, 0)'],
[['rgba(0, 0, 0, 0.5)', 0.5], 'rgba(0, 0, 0, 0)'],
[['rgba(0, 0, 0, 0.5)', 1], 'rgba(0, 0, 0, 0)'],
[['rgba(0, 0, 0, 0.5)', 0.1], 'rgba(0, 0, 0, 0.4)']
];
tests.forEach ( ([ args, output ]) => {
t.is ( transparentize ( ...args ), output );
});
});
});
fabiospampinato-khroma-f998e9b/tsconfig.json 0000775 0000000 0000000 00000000135 14223624663 0021327 0 ustar 00root root 0000000 0000000 {
"extends": "tsex/tsconfig.json",
"compilerOptions": {
"noImplicitAny": false
}
}