color-bits 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +9 -0
- package/README.md +30 -14
- package/benchmarks/compare-oklab.ts +44 -0
- package/benchmarks/compare-srgb.ts +59 -0
- package/benchmarks/compare.ts +46 -0
- package/benchmarks/parse.ts +41 -0
- package/build/conversion/channels.d.ts +61 -0
- package/build/conversion/channels.js +353 -0
- package/build/conversion/channels.js.map +1 -0
- package/build/{convert.d.ts → conversion/color-spaces.d.ts} +25 -23
- package/build/conversion/color-spaces.js +263 -0
- package/build/conversion/color-spaces.js.map +1 -0
- package/build/core/bits.d.ts +28 -0
- package/build/{core.js → core/bits.js} +25 -26
- package/build/core/bits.js.map +1 -0
- package/build/core/bytes.d.ts +5 -0
- package/build/core/bytes.js +12 -0
- package/build/core/bytes.js.map +1 -0
- package/build/css.d.ts +1 -0
- package/build/css.js +18 -0
- package/build/css.js.map +1 -0
- package/build/formatting/index.d.ts +27 -0
- package/build/{format.js → formatting/index.js} +13 -67
- package/build/formatting/index.js.map +1 -0
- package/build/index.d.ts +6 -4
- package/build/index.js +6 -4
- package/build/index.js.map +1 -1
- package/build/namedColors.d.ts +1 -0
- package/build/namedColors.js +18 -0
- package/build/namedColors.js.map +1 -0
- package/build/operations/adjust.d.ts +19 -0
- package/build/operations/adjust.js +40 -0
- package/build/operations/adjust.js.map +1 -0
- package/build/operations/blend.d.ts +9 -0
- package/build/operations/blend.js +19 -0
- package/build/operations/blend.js.map +1 -0
- package/build/operations/color-mix.d.ts +20 -0
- package/build/operations/color-mix.js +144 -0
- package/build/operations/color-mix.js.map +1 -0
- package/build/operations/luminance.d.ts +7 -0
- package/build/operations/luminance.js +20 -0
- package/build/operations/luminance.js.map +1 -0
- package/build/parsing/calc.d.ts +8 -0
- package/build/parsing/calc.js +205 -0
- package/build/parsing/calc.js.map +1 -0
- package/build/parsing/color-mix.d.ts +8 -0
- package/build/parsing/color-mix.js +70 -0
- package/build/parsing/color-mix.js.map +1 -0
- package/build/parsing/css.d.ts +23 -0
- package/build/parsing/css.js +115 -0
- package/build/parsing/css.js.map +1 -0
- package/build/parsing/fast.d.ts +19 -0
- package/build/parsing/fast.js +184 -0
- package/build/parsing/fast.js.map +1 -0
- package/build/parsing/named-colors.d.ts +12 -0
- package/build/parsing/named-colors.js +68 -0
- package/build/parsing/named-colors.js.map +1 -0
- package/build/parsing/relative.d.ts +9 -0
- package/build/parsing/relative.js +158 -0
- package/build/parsing/relative.js.map +1 -0
- package/build/parsing/tokenizer.d.ts +16 -0
- package/build/parsing/tokenizer.js +78 -0
- package/build/parsing/tokenizer.js.map +1 -0
- package/build/parsing/values.d.ts +41 -0
- package/build/parsing/values.js +139 -0
- package/build/parsing/values.js.map +1 -0
- package/package.json +30 -12
- package/benchmarks/index.ts +0 -35
- package/build/bit.d.ts +0 -3
- package/build/bit.js +0 -29
- package/build/bit.js.map +0 -1
- package/build/convert.js +0 -347
- package/build/convert.js.map +0 -1
- package/build/core.d.ts +0 -27
- package/build/core.js.map +0 -1
- package/build/format.d.ts +0 -27
- package/build/format.js.map +0 -1
- package/build/functions.d.ts +0 -33
- package/build/functions.js +0 -95
- package/build/functions.js.map +0 -1
- package/build/parse.d.ts +0 -17
- package/build/parse.js +0 -392
- package/build/parse.js.map +0 -1
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Nesting-aware scanner for CSS color functions. Unlike the fast-path regex in
|
|
3
|
+
// the fast parser, it correctly handles nested parentheses — needed for relative colors
|
|
4
|
+
// whose origin can be another function (`rgb(from hsl(0 100% 50%) r g b)`) and
|
|
5
|
+
// for `calc(...)` channel expressions — and it keeps `/` (the alpha separator)
|
|
6
|
+
// as its own token.
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.tokenize = tokenize;
|
|
9
|
+
const SPACE = 32; // ' '
|
|
10
|
+
const TAB = 9; // '\t'
|
|
11
|
+
const NEWLINE = 10; // '\n'
|
|
12
|
+
const RETURN = 13; // '\r'
|
|
13
|
+
const COMMA = 44; // ','
|
|
14
|
+
const SLASH = 47; // '/'
|
|
15
|
+
const OPEN = 40; // '('
|
|
16
|
+
const CLOSE = 41; // ')'
|
|
17
|
+
function isSeparator(c) {
|
|
18
|
+
return c === SPACE || c === TAB || c === NEWLINE || c === RETURN;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Tokenize a CSS color function string, e.g. "oklch(from green l c h / .5)".
|
|
22
|
+
* @returns the function name and its top-level tokens, or null if the input is
|
|
23
|
+
* not a function call (no parentheses).
|
|
24
|
+
*/
|
|
25
|
+
function tokenize(input) {
|
|
26
|
+
const open = input.indexOf('(');
|
|
27
|
+
if (open === -1) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
const name = input.slice(0, open).trim().toLowerCase();
|
|
31
|
+
// Inner content is everything between the first '(' and the matching last ')'.
|
|
32
|
+
let end = input.length;
|
|
33
|
+
while (end > open && input.charCodeAt(end - 1) !== CLOSE) {
|
|
34
|
+
end--;
|
|
35
|
+
}
|
|
36
|
+
if (end <= open) {
|
|
37
|
+
return null; // unterminated
|
|
38
|
+
}
|
|
39
|
+
const tokens = [];
|
|
40
|
+
let depth = 0;
|
|
41
|
+
let start = -1; // start index of the current token, or -1 when between tokens
|
|
42
|
+
for (let i = open + 1; i < end - 1; i++) {
|
|
43
|
+
const c = input.charCodeAt(i);
|
|
44
|
+
if (depth === 0 && (isSeparator(c) || c === SLASH || c === COMMA)) {
|
|
45
|
+
if (start !== -1) {
|
|
46
|
+
tokens.push(input.slice(start, i));
|
|
47
|
+
start = -1;
|
|
48
|
+
}
|
|
49
|
+
if (c === SLASH) {
|
|
50
|
+
tokens.push('/');
|
|
51
|
+
}
|
|
52
|
+
else if (c === COMMA) {
|
|
53
|
+
tokens.push(',');
|
|
54
|
+
}
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
if (c === OPEN) {
|
|
58
|
+
depth++;
|
|
59
|
+
}
|
|
60
|
+
else if (c === CLOSE) {
|
|
61
|
+
depth--;
|
|
62
|
+
if (depth < 0) {
|
|
63
|
+
return null; // unbalanced
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if (start === -1) {
|
|
67
|
+
start = i;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (depth !== 0) {
|
|
71
|
+
return null; // unbalanced
|
|
72
|
+
}
|
|
73
|
+
if (start !== -1) {
|
|
74
|
+
tokens.push(input.slice(start, end - 1));
|
|
75
|
+
}
|
|
76
|
+
return { name, tokens };
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=tokenizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenizer.js","sourceRoot":"","sources":["../../src/parsing/tokenizer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/** ASCII case-insensitive check for the `from` keyword of relative colors. */
|
|
2
|
+
export declare function isFromKeyword(token: string): boolean;
|
|
3
|
+
/**
|
|
4
|
+
* Accepts: "50%", "128", "none"
|
|
5
|
+
* https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/rgb#values
|
|
6
|
+
* @returns a value clamped to the 0 to 255 range
|
|
7
|
+
*/
|
|
8
|
+
export declare function parseColorChannel(channel: string): number;
|
|
9
|
+
/**
|
|
10
|
+
* Accepts: "50%", ".5", "0.5", "none"
|
|
11
|
+
* https://developer.mozilla.org/en-US/docs/Web/CSS/alpha-value
|
|
12
|
+
* @returns a value clamped to the [0, 255] range
|
|
13
|
+
*/
|
|
14
|
+
export declare function parseAlphaChannel(channel: string): number;
|
|
15
|
+
/**
|
|
16
|
+
* Accepts: "50%", ".5", "0.5", "none"
|
|
17
|
+
* https://developer.mozilla.org/en-US/docs/Web/CSS/alpha-value
|
|
18
|
+
* @returns a value in the [0, 1] range
|
|
19
|
+
*/
|
|
20
|
+
export declare function parseAlphaValue(channel: string): number;
|
|
21
|
+
/**
|
|
22
|
+
* Accepts: "360", "360deg", "400grad", "6.28rad", "1turn", "none"
|
|
23
|
+
* https://developer.mozilla.org/en-US/docs/Web/CSS/angle
|
|
24
|
+
* @returns a value in degrees
|
|
25
|
+
*/
|
|
26
|
+
export declare function parseAngle(angle: string): number;
|
|
27
|
+
/**
|
|
28
|
+
* Accepts: "100%", "50", "none"
|
|
29
|
+
* @returns the numeric value, with percentages resolved against 100 (so "50%" -> 50)
|
|
30
|
+
*/
|
|
31
|
+
export declare function parsePercent(value: string): number;
|
|
32
|
+
/**
|
|
33
|
+
* Accepts: "1.0", "100%", "none"
|
|
34
|
+
* @returns a value in the 0.0 to 1.0 range
|
|
35
|
+
*/
|
|
36
|
+
export declare function parsePercentageOrValue(value: string): number;
|
|
37
|
+
/**
|
|
38
|
+
* Accepts: "100", "100%", "none"
|
|
39
|
+
* @returns a raw number, with percentages resolved against @range (so "50%" -> 0.5 * range)
|
|
40
|
+
*/
|
|
41
|
+
export declare function parseNumberOrPercentage(value: string, range: number): number;
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Primitive CSS value parsers shared by the fast and relative parsers. Kept in
|
|
3
|
+
// their own module so both paths use the exact same unit conventions and neither
|
|
4
|
+
// can drift from the other.
|
|
5
|
+
//
|
|
6
|
+
// Keyword and unit matching is ASCII case-insensitive, as CSS is: comparisons
|
|
7
|
+
// use `charCode | 0x20`, which lowercases A-Z and leaves digits, '.', '-', '+'
|
|
8
|
+
// and '%' unchanged.
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.isFromKeyword = isFromKeyword;
|
|
11
|
+
exports.parseColorChannel = parseColorChannel;
|
|
12
|
+
exports.parseAlphaChannel = parseAlphaChannel;
|
|
13
|
+
exports.parseAlphaValue = parseAlphaValue;
|
|
14
|
+
exports.parseAngle = parseAngle;
|
|
15
|
+
exports.parsePercent = parsePercent;
|
|
16
|
+
exports.parsePercentageOrValue = parsePercentageOrValue;
|
|
17
|
+
exports.parseNumberOrPercentage = parseNumberOrPercentage;
|
|
18
|
+
const bytes_1 = require("../core/bytes");
|
|
19
|
+
const PERCENT = 37; // '%'
|
|
20
|
+
const G = 103; // 'g'
|
|
21
|
+
const N = 110; // 'n'
|
|
22
|
+
const D = 100; // 'd'
|
|
23
|
+
const E = 101; // 'e'
|
|
24
|
+
/** ASCII case-insensitive check for the `from` keyword of relative colors. */
|
|
25
|
+
function isFromKeyword(token) {
|
|
26
|
+
return token.length === 4
|
|
27
|
+
&& (token.charCodeAt(0) | 0x20) === 102 // 'f'
|
|
28
|
+
&& (token.charCodeAt(1) | 0x20) === 114 // 'r'
|
|
29
|
+
&& (token.charCodeAt(2) | 0x20) === 111 // 'o'
|
|
30
|
+
&& (token.charCodeAt(3) | 0x20) === 109; // 'm'
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Accepts: "50%", "128", "none"
|
|
34
|
+
* https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/rgb#values
|
|
35
|
+
* @returns a value clamped to the 0 to 255 range
|
|
36
|
+
*/
|
|
37
|
+
function parseColorChannel(channel) {
|
|
38
|
+
// No explicit 'none' check: parseFloat('none') is NaN, which clampByte
|
|
39
|
+
// passes through and newColor packs as 0 — exactly CSS none = 0.
|
|
40
|
+
if (channel.charCodeAt(channel.length - 1) === PERCENT) {
|
|
41
|
+
return (0, bytes_1.clampByte)((parseFloat(channel) / 100) * 255);
|
|
42
|
+
}
|
|
43
|
+
return (0, bytes_1.clampByte)(parseFloat(channel));
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Accepts: "50%", ".5", "0.5", "none"
|
|
47
|
+
* https://developer.mozilla.org/en-US/docs/Web/CSS/alpha-value
|
|
48
|
+
* @returns a value clamped to the [0, 255] range
|
|
49
|
+
*/
|
|
50
|
+
function parseAlphaChannel(channel) {
|
|
51
|
+
return (0, bytes_1.clampByte)(parseAlphaValue(channel) * 255);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Accepts: "50%", ".5", "0.5", "none"
|
|
55
|
+
* https://developer.mozilla.org/en-US/docs/Web/CSS/alpha-value
|
|
56
|
+
* @returns a value in the [0, 1] range
|
|
57
|
+
*/
|
|
58
|
+
function parseAlphaValue(channel) {
|
|
59
|
+
if ((channel.charCodeAt(0) | 0x20) === N) {
|
|
60
|
+
return 0;
|
|
61
|
+
}
|
|
62
|
+
if (channel.charCodeAt(channel.length - 1) === PERCENT) {
|
|
63
|
+
return parseFloat(channel) / 100;
|
|
64
|
+
}
|
|
65
|
+
return parseFloat(channel);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Accepts: "360", "360deg", "400grad", "6.28rad", "1turn", "none"
|
|
69
|
+
* https://developer.mozilla.org/en-US/docs/Web/CSS/angle
|
|
70
|
+
* @returns a value in degrees
|
|
71
|
+
*/
|
|
72
|
+
function parseAngle(angle) {
|
|
73
|
+
let factor = 1;
|
|
74
|
+
switch (angle.charCodeAt(angle.length - 1) | 0x20) {
|
|
75
|
+
case E: {
|
|
76
|
+
// 'none'
|
|
77
|
+
return 0;
|
|
78
|
+
}
|
|
79
|
+
case D: {
|
|
80
|
+
// 'rad', 'grad'
|
|
81
|
+
if ((angle.charCodeAt(Math.max(0, angle.length - 4)) | 0x20) === G) {
|
|
82
|
+
// 'grad': 400grad = 360deg
|
|
83
|
+
factor = 360 / 400;
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
// 'rad': 2π rad = 360deg
|
|
87
|
+
factor = 360 / (2 * Math.PI); // 360 / TAU
|
|
88
|
+
}
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
case N: {
|
|
92
|
+
// 'turn': 1turn = 360deg
|
|
93
|
+
factor = 360;
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
// case G: // 'deg', but no need to check as it's also the default
|
|
97
|
+
default: {
|
|
98
|
+
return parseFloat(angle); // degrees
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return parseFloat(angle) * factor;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Accepts: "100%", "50", "none"
|
|
105
|
+
* @returns the numeric value, with percentages resolved against 100 (so "50%" -> 50)
|
|
106
|
+
*/
|
|
107
|
+
function parsePercent(value) {
|
|
108
|
+
if ((value.charCodeAt(0) | 0x20) === N) {
|
|
109
|
+
return 0;
|
|
110
|
+
}
|
|
111
|
+
return parseFloat(value);
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Accepts: "1.0", "100%", "none"
|
|
115
|
+
* @returns a value in the 0.0 to 1.0 range
|
|
116
|
+
*/
|
|
117
|
+
function parsePercentageOrValue(value) {
|
|
118
|
+
if ((value.charCodeAt(0) | 0x20) === N) {
|
|
119
|
+
return 0;
|
|
120
|
+
}
|
|
121
|
+
if (value.charCodeAt(value.length - 1) === PERCENT) {
|
|
122
|
+
return parseFloat(value) / 100;
|
|
123
|
+
}
|
|
124
|
+
return parseFloat(value);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Accepts: "100", "100%", "none"
|
|
128
|
+
* @returns a raw number, with percentages resolved against @range (so "50%" -> 0.5 * range)
|
|
129
|
+
*/
|
|
130
|
+
function parseNumberOrPercentage(value, range) {
|
|
131
|
+
if ((value.charCodeAt(0) | 0x20) === N) {
|
|
132
|
+
return 0;
|
|
133
|
+
}
|
|
134
|
+
if (value.charCodeAt(value.length - 1) === PERCENT) {
|
|
135
|
+
return (parseFloat(value) / 100) * range;
|
|
136
|
+
}
|
|
137
|
+
return parseFloat(value);
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=values.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"values.js","sourceRoot":"","sources":["../../src/parsing/values.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,12 +1,37 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "color-bits",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"main": "./build/index.js",
|
|
5
5
|
"sideEffects": false,
|
|
6
|
+
"homepage": "https://github.com/romgrk/color-bits",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/romgrk/color-bits.git"
|
|
10
|
+
},
|
|
11
|
+
"scripts": {
|
|
12
|
+
"prepack": "pnpm run build && npmignore --auto",
|
|
13
|
+
"build": "tsc",
|
|
14
|
+
"start": "tsc --watch",
|
|
15
|
+
"docs": "pnpm run docs:core && pnpm run docs:string",
|
|
16
|
+
"docs:core": "typedoc --readme none --plugin typedoc-plugin-markdown --out ./docs ./src/index.ts",
|
|
17
|
+
"docs:string": "typedoc --readme none --plugin typedoc-plugin-markdown --out ./docs/string ./src/string.ts",
|
|
18
|
+
"benchmark": "pnpm run benchmark:srgb",
|
|
19
|
+
"benchmark:srgb": "tsx ./benchmarks/compare-srgb.ts",
|
|
20
|
+
"benchmark:oklab": "tsx ./benchmarks/compare-oklab.ts",
|
|
21
|
+
"test": "NODE_OPTIONS=\"$NODE_OPTIONS --experimental-vm-modules\" jest --watch"
|
|
22
|
+
},
|
|
6
23
|
"exports": {
|
|
7
24
|
".": "./build/index.js",
|
|
8
25
|
"./*": "./build/*",
|
|
9
|
-
"./string": "./build/string.js"
|
|
26
|
+
"./string": "./build/string.js",
|
|
27
|
+
"./css": {
|
|
28
|
+
"types": "./build/css.d.ts",
|
|
29
|
+
"default": "./build/css.js"
|
|
30
|
+
},
|
|
31
|
+
"./named": {
|
|
32
|
+
"types": "./build/namedColors.d.ts",
|
|
33
|
+
"default": "./build/namedColors.js"
|
|
34
|
+
}
|
|
10
35
|
},
|
|
11
36
|
"types": "./build/index.d.ts",
|
|
12
37
|
"keywords": [
|
|
@@ -28,6 +53,7 @@
|
|
|
28
53
|
"@babel/preset-env": "^7.25.4",
|
|
29
54
|
"@babel/preset-typescript": "^7.24.7",
|
|
30
55
|
"@jest/globals": "^29.7.0",
|
|
56
|
+
"@texel/color": "^1.1.11",
|
|
31
57
|
"@types/chai": "^4.3.19",
|
|
32
58
|
"@types/jest": "^29.5.12",
|
|
33
59
|
"benny": "^3.7.1",
|
|
@@ -35,6 +61,7 @@
|
|
|
35
61
|
"chroma-js": "^3.0.0",
|
|
36
62
|
"color": "^4.2.3",
|
|
37
63
|
"colord": "^2.9.3",
|
|
64
|
+
"culori": "^4.0.2",
|
|
38
65
|
"jest": "^29.7.0",
|
|
39
66
|
"npmignore": "^0.3.1",
|
|
40
67
|
"tinycolor2": "^1.6.0",
|
|
@@ -44,14 +71,5 @@
|
|
|
44
71
|
"typedoc": "^0.26.6",
|
|
45
72
|
"typedoc-plugin-markdown": "^4.2.6",
|
|
46
73
|
"typescript": "^5.5.4"
|
|
47
|
-
},
|
|
48
|
-
"scripts": {
|
|
49
|
-
"build": "tsc",
|
|
50
|
-
"start": "tsc --watch",
|
|
51
|
-
"docs": "pnpm run docs:core && pnpm run docs:string",
|
|
52
|
-
"docs:core": "typedoc --readme none --plugin typedoc-plugin-markdown --out ./docs ./src/index.ts",
|
|
53
|
-
"docs:string": "typedoc --readme none --plugin typedoc-plugin-markdown --out ./docs/string ./src/string.ts",
|
|
54
|
-
"benchmark": "tsx ./benchmarks/index.ts",
|
|
55
|
-
"test": "NODE_OPTIONS=\"$NODE_OPTIONS --experimental-vm-modules\" jest --watch"
|
|
56
74
|
}
|
|
57
|
-
}
|
|
75
|
+
}
|
package/benchmarks/index.ts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import b from 'benny'
|
|
2
|
-
import { alpha as colorBitsAlpha } from '../src/string'
|
|
3
|
-
import { colord } from 'colord'
|
|
4
|
-
import tinycolor2 from 'tinycolor2'
|
|
5
|
-
import color from 'color'
|
|
6
|
-
import chroma from 'chroma-js'
|
|
7
|
-
|
|
8
|
-
const input = '#808080'
|
|
9
|
-
|
|
10
|
-
b.suite(
|
|
11
|
-
`Parse color, set to 0.5 opacity, and convert back to hexadecimal`,
|
|
12
|
-
|
|
13
|
-
b.add('color-bits', () => {
|
|
14
|
-
colorBitsAlpha(input, 0.5)
|
|
15
|
-
}),
|
|
16
|
-
|
|
17
|
-
b.add('colord', () => {
|
|
18
|
-
colord(input).alpha(0.5).toHex()
|
|
19
|
-
}),
|
|
20
|
-
|
|
21
|
-
b.add('color', () => {
|
|
22
|
-
color(input).alpha(0.5).hex()
|
|
23
|
-
}),
|
|
24
|
-
|
|
25
|
-
b.add('tinycolor2', () => {
|
|
26
|
-
tinycolor2(input).setAlpha(0.5).toHexString()
|
|
27
|
-
}),
|
|
28
|
-
|
|
29
|
-
b.add('chroma-js', () => {
|
|
30
|
-
chroma(input).alpha(0.5).hex()
|
|
31
|
-
}),
|
|
32
|
-
|
|
33
|
-
b.cycle(),
|
|
34
|
-
b.complete()
|
|
35
|
-
)
|
package/build/bit.d.ts
DELETED
package/build/bit.js
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
// Bitwise functions
|
|
3
|
-
//
|
|
4
|
-
// The color representation would ideally be 32-bits unsigned, but JS bitwise
|
|
5
|
-
// operators only work as 32-bits signed. The range of Smi values on V8 is also
|
|
6
|
-
// 32-bits signed. Those two factors make it that it's much more efficient to just
|
|
7
|
-
// use signed integers to represent the data.
|
|
8
|
-
//
|
|
9
|
-
// Colors with a R channel >= 0x80 will be a negative number, but that's not really
|
|
10
|
-
// an issue at any point because the bits for signed and unsigned integers are always
|
|
11
|
-
// the same, only their interpretation changes.
|
|
12
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
-
exports.cast = cast;
|
|
14
|
-
exports.get = get;
|
|
15
|
-
exports.set = set;
|
|
16
|
-
const INT32_TO_UINT32_OFFSET = 2 ** 32;
|
|
17
|
-
function cast(n) {
|
|
18
|
-
if (n < 0) {
|
|
19
|
-
return n + INT32_TO_UINT32_OFFSET;
|
|
20
|
-
}
|
|
21
|
-
return n;
|
|
22
|
-
}
|
|
23
|
-
function get(n, offset) {
|
|
24
|
-
return (n >> offset) & 0xff;
|
|
25
|
-
}
|
|
26
|
-
function set(n, offset, byte) {
|
|
27
|
-
return n ^ ((n ^ (byte << offset)) & (0xff << offset));
|
|
28
|
-
}
|
|
29
|
-
//# sourceMappingURL=bit.js.map
|
package/build/bit.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"bit.js","sourceRoot":"","sources":["../src/bit.ts"],"names":[],"mappings":";AAAA,oBAAoB;AACpB,EAAE;AACF,6EAA6E;AAC7E,+EAA+E;AAC/E,kFAAkF;AAClF,6CAA6C;AAC7C,EAAE;AACF,mFAAmF;AACnF,qFAAqF;AACrF,+CAA+C;;AAI/C,oBAKC;AAED,kBAEC;AAED,kBAEC;AAfD,MAAM,sBAAsB,GAAG,CAAC,IAAI,EAAE,CAAC;AAEvC,SAAgB,IAAI,CAAC,CAAS;IAC5B,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACV,OAAO,CAAC,GAAG,sBAAsB,CAAC;IACpC,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAgB,GAAG,CAAC,CAAS,EAAE,MAAc;IAC3C,OAAO,CAAC,CAAC,IAAI,MAAM,CAAC,GAAG,IAAI,CAAC;AAC9B,CAAC;AAED,SAAgB,GAAG,CAAC,CAAS,EAAE,MAAc,EAAE,IAAY;IACzD,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC;AACzD,CAAC"}
|