@tokens-studio/tokenscript-schemas 0.1.1 → 0.1.3
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/README.md +31 -7
- package/dist/cli/index.cjs +21 -35
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +21 -35
- package/dist/cli/index.js.map +1 -1
- package/dist/index.cjs +19 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +19 -19
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/bundler/{bundle-schema.ts → build-schema.ts} +2 -2
- package/src/bundler/index.ts +25 -25
- package/src/bundler/schema-dependency-resolver.ts +3 -3
- package/src/bundler/selective-bundler.ts +3 -3
- package/src/cli/commands/bundle.test.ts +95 -1
- package/src/cli/commands/bundle.ts +11 -1
- package/src/cli/index.ts +1 -0
- package/src/cli/version-info.ts +16 -18
- package/bundled/functions/adjust_chroma.json +0 -60
- package/bundled/functions/adjust_hue.json +0 -60
- package/bundled/functions/adjust_lightness.json +0 -60
- package/bundled/functions/adjust_to_contrast.json +0 -67
- package/bundled/functions/alpha_blend.json +0 -31
- package/bundled/functions/alpha_scale.json +0 -27
- package/bundled/functions/analogous.json +0 -32
- package/bundled/functions/apca_contrast.json +0 -27
- package/bundled/functions/are_similar.json +0 -73
- package/bundled/functions/auto_text_color.json +0 -66
- package/bundled/functions/best_contrast.json +0 -28
- package/bundled/functions/chroma.json +0 -54
- package/bundled/functions/clamp_chroma.json +0 -66
- package/bundled/functions/clamp_lightness.json +0 -66
- package/bundled/functions/clamp_to_gamut.json +0 -23
- package/bundled/functions/complement.json +0 -24
- package/bundled/functions/contrast_ratio.json +0 -27
- package/bundled/functions/cooler.json +0 -52
- package/bundled/functions/darken.json +0 -28
- package/bundled/functions/delta_e_2000.json +0 -40
- package/bundled/functions/delta_e_76.json +0 -27
- package/bundled/functions/delta_e_ok.json +0 -27
- package/bundled/functions/desaturate.json +0 -28
- package/bundled/functions/distributed.json +0 -36
- package/bundled/functions/diverging.json +0 -36
- package/bundled/functions/grayscale.json +0 -24
- package/bundled/functions/harmonize.json +0 -65
- package/bundled/functions/hue.json +0 -54
- package/bundled/functions/hue_difference.json +0 -27
- package/bundled/functions/in_gamut.json +0 -27
- package/bundled/functions/interpolate.json +0 -66
- package/bundled/functions/invert.json +0 -23
- package/bundled/functions/is_cool.json +0 -23
- package/bundled/functions/is_dark.json +0 -27
- package/bundled/functions/is_light.json +0 -27
- package/bundled/functions/is_neutral.json +0 -65
- package/bundled/functions/is_warm.json +0 -23
- package/bundled/functions/lighten.json +0 -28
- package/bundled/functions/lightness.json +0 -61
- package/bundled/functions/luminance.json +0 -23
- package/bundled/functions/meets_contrast.json +0 -31
- package/bundled/functions/mix.json +0 -32
- package/bundled/functions/monochromatic.json +0 -28
- package/bundled/functions/muted.json +0 -59
- package/bundled/functions/neutral_variant.json +0 -59
- package/bundled/functions/relative_luminance.json +0 -61
- package/bundled/functions/rotate_hue.json +0 -28
- package/bundled/functions/saturate.json +0 -28
- package/bundled/functions/scale_chroma.json +0 -60
- package/bundled/functions/scale_lightness.json +0 -60
- package/bundled/functions/sepia.json +0 -59
- package/bundled/functions/set_chroma.json +0 -28
- package/bundled/functions/set_hue.json +0 -28
- package/bundled/functions/set_lightness.json +0 -28
- package/bundled/functions/shade_scale.json +0 -28
- package/bundled/functions/split_complement.json +0 -28
- package/bundled/functions/steps.json +0 -32
- package/bundled/functions/tetradic.json +0 -24
- package/bundled/functions/tint_scale.json +0 -36
- package/bundled/functions/to_gamut.json +0 -59
- package/bundled/functions/triadic.json +0 -24
- package/bundled/functions/vibrant.json +0 -59
- package/bundled/functions/warmer.json +0 -52
- package/bundled/functions/wcag_level.json +0 -60
- package/bundled/functions.json +0 -2624
- package/bundled/registry.json +0 -3833
- package/bundled/types/css-color.json +0 -151
- package/bundled/types/hex-color.json +0 -25
- package/bundled/types/hsl-color.json +0 -66
- package/bundled/types/hsv-color.json +0 -57
- package/bundled/types/hwb-color.json +0 -66
- package/bundled/types/lab-color.json +0 -57
- package/bundled/types/lch-color.json +0 -57
- package/bundled/types/okhsl-color.json +0 -57
- package/bundled/types/okhsv-color.json +0 -57
- package/bundled/types/oklab-color.json +0 -87
- package/bundled/types/oklch-color.json +0 -57
- package/bundled/types/p3-color.json +0 -57
- package/bundled/types/p3-linear-color.json +0 -57
- package/bundled/types/rgb-color.json +0 -73
- package/bundled/types/srgb-color.json +0 -77
- package/bundled/types/srgb-linear-color.json +0 -67
- package/bundled/types/xyz-d50-color.json +0 -57
- package/bundled/types/xyz-d65-color.json +0 -77
- package/bundled/types.json +0 -1207
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "are_similar",
|
|
3
|
-
"type": "function",
|
|
4
|
-
"description": "Determines if two colors are perceptually similar using Delta E OK (Euclidean distance in OKLab space). Returns true if the colors are within the specified threshold. Default threshold of 0.02 corresponds to a 'just noticeable difference' (JND). Based on Björn Ottosson's OKLab color space which provides excellent perceptual uniformity.",
|
|
5
|
-
"keyword": "are_similar",
|
|
6
|
-
"requirements": [
|
|
7
|
-
"https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/srgb-color/0/",
|
|
8
|
-
"https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/oklab-color/0/"
|
|
9
|
-
],
|
|
10
|
-
"schema": {
|
|
11
|
-
"type": "object",
|
|
12
|
-
"properties": {
|
|
13
|
-
"input": {
|
|
14
|
-
"type": "array",
|
|
15
|
-
"items": [
|
|
16
|
-
{
|
|
17
|
-
"description": "First color",
|
|
18
|
-
"type": "color"
|
|
19
|
-
},
|
|
20
|
-
{
|
|
21
|
-
"description": "Second color",
|
|
22
|
-
"type": "color"
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
"description": "Delta E threshold (default 0.02 ≈ JND)",
|
|
26
|
-
"type": "number"
|
|
27
|
-
}
|
|
28
|
-
],
|
|
29
|
-
"minItems": 2,
|
|
30
|
-
"maxItems": 3
|
|
31
|
-
}
|
|
32
|
-
},
|
|
33
|
-
"required": [
|
|
34
|
-
"input"
|
|
35
|
-
]
|
|
36
|
-
},
|
|
37
|
-
"returns": {
|
|
38
|
-
"type": "boolean",
|
|
39
|
-
"description": "True if colors are perceptually similar (within threshold)"
|
|
40
|
-
},
|
|
41
|
-
"script": {
|
|
42
|
-
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
|
|
43
|
-
"script": "// are_similar: Check if two colors are perceptually similar\n// Uses Delta E OK (OKLab Euclidean distance) for perceptual comparison\n// Default threshold 0.02 approximates \"just noticeable difference\"\n\nvariable input: List = {input};\nvariable color1: Color.OKLab = input.get(0).to.oklab();\nvariable color2: Color.OKLab = input.get(1).to.oklab();\n\n// Default threshold for JND (just noticeable difference)\nvariable threshold: Number = 0.02;\nif (input.length() > 2) [\n threshold = input.get(2);\n];\n\n// Calculate Delta E OK (Euclidean distance in OKLab)\nvariable delta_l: Number = color1.l - color2.l;\nvariable delta_a: Number = color1.a - color2.a;\nvariable delta_b: Number = color1.b - color2.b;\n\nvariable delta_e: Number = sqrt(delta_l * delta_l + delta_a * delta_a + delta_b * delta_b);\n\n// Return true if within threshold\nreturn delta_e <= threshold;"
|
|
44
|
-
},
|
|
45
|
-
"examples": [
|
|
46
|
-
{
|
|
47
|
-
"description": "Nearly identical colors",
|
|
48
|
-
"input": [
|
|
49
|
-
"#ff0000",
|
|
50
|
-
"#ff0001"
|
|
51
|
-
],
|
|
52
|
-
"output": true
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
"description": "Obviously different colors",
|
|
56
|
-
"input": [
|
|
57
|
-
"#ff0000",
|
|
58
|
-
"#00ff00"
|
|
59
|
-
],
|
|
60
|
-
"output": false
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
"description": "Custom threshold for stricter comparison",
|
|
64
|
-
"input": [
|
|
65
|
-
"#808080",
|
|
66
|
-
"#818181",
|
|
67
|
-
0.01
|
|
68
|
-
],
|
|
69
|
-
"output": true
|
|
70
|
-
}
|
|
71
|
-
],
|
|
72
|
-
"slug": "are_similar"
|
|
73
|
-
}
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "auto_text_color",
|
|
3
|
-
"type": "function",
|
|
4
|
-
"description": "Returns black or white text color for optimal contrast against a background. Uses WCAG relative luminance to determine if the background is light or dark, then returns the opposite for maximum readability. Essential for generating accessible text colors in design systems.",
|
|
5
|
-
"keyword": "auto_text_color",
|
|
6
|
-
"requirements": [
|
|
7
|
-
"https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/srgb-color/0/",
|
|
8
|
-
"https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/xyz-d65-color/0/"
|
|
9
|
-
],
|
|
10
|
-
"schema": {
|
|
11
|
-
"type": "object",
|
|
12
|
-
"properties": {
|
|
13
|
-
"input": {
|
|
14
|
-
"type": "array",
|
|
15
|
-
"items": [
|
|
16
|
-
{
|
|
17
|
-
"description": "Background color to test",
|
|
18
|
-
"type": "color"
|
|
19
|
-
},
|
|
20
|
-
{
|
|
21
|
-
"description": "Optional threshold (0-1, default 0.179 per WCAG). Higher values bias toward white text.",
|
|
22
|
-
"type": "number"
|
|
23
|
-
}
|
|
24
|
-
],
|
|
25
|
-
"minItems": 1,
|
|
26
|
-
"maxItems": 2
|
|
27
|
-
}
|
|
28
|
-
},
|
|
29
|
-
"required": [
|
|
30
|
-
"input"
|
|
31
|
-
]
|
|
32
|
-
},
|
|
33
|
-
"returns": {
|
|
34
|
-
"type": "color",
|
|
35
|
-
"description": "Either black (#000000) or white (#ffffff) for optimal contrast"
|
|
36
|
-
},
|
|
37
|
-
"script": {
|
|
38
|
-
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
|
|
39
|
-
"script": "// auto_text_color: Select black or white text for optimal contrast\n// Reference: WCAG 2.1 Relative Luminance\n// Reference: https://www.w3.org/TR/WCAG21/#dfn-relative-luminance\n//\n// Returns black (#000) or white (#fff) depending on which provides\n// better contrast against the input background color.\n//\n// Default threshold: 0.179 (geometric mean of WCAG luminance range)\n// - sqrt(1.05 * 0.05) - 0.05 ≈ 0.179\n// - Above threshold: light background → black text\n// - Below threshold: dark background → white text\n\nvariable input: List = {input};\n\n// Default threshold based on WCAG luminance midpoint\nvariable threshold: Number = 0.179;\nif (input.length() > 1) [\n threshold = input.get(1);\n];\n\n// Convert to XYZ-D65 to get relative luminance (Y component)\nvariable xyz: Color.XYZD65 = input.get(0).to.xyzd65();\nvariable luminance: Number = xyz.y;\n\n// If luminance is above threshold, background is \"light\" -> use black text\n// If luminance is below threshold, background is \"dark\" -> use white text\nvariable result: Color.SRGB;\n\nif (luminance > threshold) [\n // Light background: return black\n result.r = 0;\n result.g = 0;\n result.b = 0;\n] else [\n // Dark background: return white\n result.r = 1;\n result.g = 1;\n result.b = 1;\n];\n\nreturn result;"
|
|
40
|
-
},
|
|
41
|
-
"examples": [
|
|
42
|
-
{
|
|
43
|
-
"description": "Dark background returns white text",
|
|
44
|
-
"input": [
|
|
45
|
-
"#1a1a1a"
|
|
46
|
-
],
|
|
47
|
-
"output": "#ffffff"
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
"description": "Light background returns black text",
|
|
51
|
-
"input": [
|
|
52
|
-
"#f0f0f0"
|
|
53
|
-
],
|
|
54
|
-
"output": "#000000"
|
|
55
|
-
},
|
|
56
|
-
{
|
|
57
|
-
"description": "Mid-tone with custom threshold",
|
|
58
|
-
"input": [
|
|
59
|
-
"#808080",
|
|
60
|
-
0.5
|
|
61
|
-
],
|
|
62
|
-
"output": "#ffffff"
|
|
63
|
-
}
|
|
64
|
-
],
|
|
65
|
-
"slug": "auto_text_color"
|
|
66
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "Best Contrast",
|
|
3
|
-
"type": "function",
|
|
4
|
-
"description": "Selects the color with highest contrast against a background from a list of candidates. Uses WCAG 2.1 contrast ratio. Perfect for choosing readable text colors.",
|
|
5
|
-
"keyword": "best_contrast",
|
|
6
|
-
"input": {
|
|
7
|
-
"type": "object",
|
|
8
|
-
"properties": {
|
|
9
|
-
"background": {
|
|
10
|
-
"type": "color",
|
|
11
|
-
"description": "The background color to contrast against"
|
|
12
|
-
},
|
|
13
|
-
"candidates": {
|
|
14
|
-
"type": "list",
|
|
15
|
-
"description": "List of candidate colors to choose from. Default is [black, white]"
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
},
|
|
19
|
-
"script": {
|
|
20
|
-
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
|
|
21
|
-
"script": "// Select the most contrasting color from a list of candidates\n// Uses WCAG 2.1 contrast ratio based on relative luminance\n//\n// Algorithm:\n// 1. Calculate relative luminance: L = 0.2126*R + 0.7152*G + 0.0722*B (linear RGB)\n// 2. Contrast ratio: (L_lighter + 0.05) / (L_darker + 0.05)\n// 3. Return candidate with highest contrast ratio\n//\n// Default candidates: black (#000) and white (#fff)\n\nvariable input: List = {input};\nvariable bg: Color.LinearSRGB = input.get(0).to.linearsrgb();\n\n// Calculate background luminance\nvariable bg_lum: Number = 0.2126 * bg.r + 0.7152 * bg.g + 0.0722 * bg.b;\n\n// Get candidates list, default to black and white\nvariable candidates: List;\nif (input.length() > 1) [\n candidates = input.get(1);\n] else [\n // Default: black and white\n variable black: Color.SRGB;\n black.r = 0; black.g = 0; black.b = 0;\n variable white: Color.SRGB;\n white.r = 1; white.g = 1; white.b = 1;\n candidates = black, white;\n];\n\n// Find candidate with highest contrast\nvariable best_color: Color.SRGB = candidates.get(0).to.srgb();\nvariable best_contrast: Number = 0;\nvariable candidate: Color.LinearSRGB;\nvariable cand_lum: Number = 0;\nvariable lighter: Number = 0;\nvariable darker: Number = 0;\nvariable contrast: Number = 0;\n\nvariable i: Number = 0;\nwhile (i < candidates.length()) [\n candidate = candidates.get(i).to.linearsrgb();\n \n // Calculate candidate luminance\n cand_lum = 0.2126 * candidate.r + 0.7152 * candidate.g + 0.0722 * candidate.b;\n \n // Calculate contrast ratio (lighter / darker)\n lighter = bg_lum;\n darker = cand_lum;\n if (cand_lum > bg_lum) [\n lighter = cand_lum;\n darker = bg_lum;\n ];\n \n contrast = (lighter + 0.05) / (darker + 0.05);\n \n // Track best\n if (contrast > best_contrast) [\n best_contrast = contrast;\n best_color = candidates.get(i).to.srgb();\n ];\n \n i = i + 1;\n];\n\nreturn best_color;"
|
|
22
|
-
},
|
|
23
|
-
"requirements": [
|
|
24
|
-
"https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/srgb-linear-color/0/",
|
|
25
|
-
"https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/srgb-color/0/"
|
|
26
|
-
],
|
|
27
|
-
"slug": "best_contrast"
|
|
28
|
-
}
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "chroma",
|
|
3
|
-
"type": "function",
|
|
4
|
-
"description": "Extracts the chroma (colorfulness/saturation) value from any color using OKLCH. Returns a value from 0 (gray) to approximately 0.4 (most saturated colors). Chroma in OKLCH represents the colorfulness independent of lightness - higher values mean more vivid colors. Essential for creating consistent color scales and checking color vibrancy.",
|
|
5
|
-
"keyword": "chroma",
|
|
6
|
-
"requirements": [
|
|
7
|
-
"https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/srgb-color/0/",
|
|
8
|
-
"https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/oklch-color/0/"
|
|
9
|
-
],
|
|
10
|
-
"schema": {
|
|
11
|
-
"type": "object",
|
|
12
|
-
"properties": {
|
|
13
|
-
"input": {
|
|
14
|
-
"type": "array",
|
|
15
|
-
"items": [
|
|
16
|
-
{
|
|
17
|
-
"description": "Color to extract chroma from",
|
|
18
|
-
"type": "color"
|
|
19
|
-
}
|
|
20
|
-
],
|
|
21
|
-
"minItems": 1,
|
|
22
|
-
"maxItems": 1
|
|
23
|
-
}
|
|
24
|
-
},
|
|
25
|
-
"required": [
|
|
26
|
-
"input"
|
|
27
|
-
]
|
|
28
|
-
},
|
|
29
|
-
"returns": {
|
|
30
|
-
"type": "number",
|
|
31
|
-
"description": "Chroma value (0 to ~0.4)"
|
|
32
|
-
},
|
|
33
|
-
"script": {
|
|
34
|
-
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
|
|
35
|
-
"script": "// chroma: Extract chroma (colorfulness) from a color\n// Reference: OKLCH Color Space (Björn Ottosson)\n// Reference: https://bottosson.github.io/posts/oklab/\n//\n// Returns the C component from OKLCH, which represents\n// colorfulness/saturation. Range: 0 (gray) to ~0.4 (most vivid).\n\nvariable input: List = {input};\nvariable color: Color.OKLCH = input.get(0).to.oklch();\n\nreturn color.c;"
|
|
36
|
-
},
|
|
37
|
-
"examples": [
|
|
38
|
-
{
|
|
39
|
-
"description": "Gray has chroma 0",
|
|
40
|
-
"input": [
|
|
41
|
-
"#808080"
|
|
42
|
-
],
|
|
43
|
-
"output": 0
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
"description": "Saturated red has high chroma",
|
|
47
|
-
"input": [
|
|
48
|
-
"#ff0000"
|
|
49
|
-
],
|
|
50
|
-
"output": 0.26
|
|
51
|
-
}
|
|
52
|
-
],
|
|
53
|
-
"slug": "chroma"
|
|
54
|
-
}
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "clamp_chroma",
|
|
3
|
-
"type": "function",
|
|
4
|
-
"description": "Constrains a color's chroma (saturation) to a specified range while preserving hue and lightness. Useful for ensuring colors stay within brand guidelines or design constraints. Uses OKLCH for perceptually uniform clamping.",
|
|
5
|
-
"keyword": "clamp_chroma",
|
|
6
|
-
"requirements": [
|
|
7
|
-
"https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/srgb-color/0/",
|
|
8
|
-
"https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/oklch-color/0/"
|
|
9
|
-
],
|
|
10
|
-
"schema": {
|
|
11
|
-
"type": "object",
|
|
12
|
-
"properties": {
|
|
13
|
-
"input": {
|
|
14
|
-
"type": "array",
|
|
15
|
-
"items": [
|
|
16
|
-
{
|
|
17
|
-
"description": "Color to clamp",
|
|
18
|
-
"type": "color"
|
|
19
|
-
},
|
|
20
|
-
{
|
|
21
|
-
"description": "Minimum chroma (0+)",
|
|
22
|
-
"type": "number"
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
"description": "Maximum chroma (typically 0-0.4)",
|
|
26
|
-
"type": "number"
|
|
27
|
-
}
|
|
28
|
-
],
|
|
29
|
-
"minItems": 3,
|
|
30
|
-
"maxItems": 3
|
|
31
|
-
}
|
|
32
|
-
},
|
|
33
|
-
"required": [
|
|
34
|
-
"input"
|
|
35
|
-
]
|
|
36
|
-
},
|
|
37
|
-
"returns": {
|
|
38
|
-
"type": "color",
|
|
39
|
-
"description": "Color with clamped chroma"
|
|
40
|
-
},
|
|
41
|
-
"script": {
|
|
42
|
-
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
|
|
43
|
-
"script": "// clamp_chroma: Constrain chroma to a range\n// Preserves hue and lightness\n\nvariable input: List = {input};\nvariable color: Color.OKLCH = input.get(0).to.oklch();\nvariable min_c: Number = input.get(1);\nvariable max_c: Number = input.get(2);\n\n// Clamp chroma\nvariable new_c: Number = color.c;\nif (new_c < min_c) [ new_c = min_c; ];\nif (new_c > max_c) [ new_c = max_c; ];\n\n// Create result\nvariable result: Color.OKLCH;\nresult.l = color.l;\nresult.c = new_c;\nresult.h = color.h;\n\nreturn result;"
|
|
44
|
-
},
|
|
45
|
-
"examples": [
|
|
46
|
-
{
|
|
47
|
-
"description": "Limit maximum saturation",
|
|
48
|
-
"input": [
|
|
49
|
-
"#ff0000",
|
|
50
|
-
0,
|
|
51
|
-
0.15
|
|
52
|
-
],
|
|
53
|
-
"output": "Muted red with chroma 0.15"
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
"description": "Ensure minimum saturation",
|
|
57
|
-
"input": [
|
|
58
|
-
"#808080",
|
|
59
|
-
0.05,
|
|
60
|
-
0.3
|
|
61
|
-
],
|
|
62
|
-
"output": "Slightly colored gray"
|
|
63
|
-
}
|
|
64
|
-
],
|
|
65
|
-
"slug": "clamp_chroma"
|
|
66
|
-
}
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "clamp_lightness",
|
|
3
|
-
"type": "function",
|
|
4
|
-
"description": "Constrains a color's lightness to a specified range while preserving hue and chroma. Useful for ensuring colors stay within readable/accessible bounds. Uses OKLCH for perceptually uniform clamping.",
|
|
5
|
-
"keyword": "clamp_lightness",
|
|
6
|
-
"requirements": [
|
|
7
|
-
"https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/srgb-color/0/",
|
|
8
|
-
"https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/oklch-color/0/"
|
|
9
|
-
],
|
|
10
|
-
"schema": {
|
|
11
|
-
"type": "object",
|
|
12
|
-
"properties": {
|
|
13
|
-
"input": {
|
|
14
|
-
"type": "array",
|
|
15
|
-
"items": [
|
|
16
|
-
{
|
|
17
|
-
"description": "Color to clamp",
|
|
18
|
-
"type": "color"
|
|
19
|
-
},
|
|
20
|
-
{
|
|
21
|
-
"description": "Minimum lightness (0-1)",
|
|
22
|
-
"type": "number"
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
"description": "Maximum lightness (0-1)",
|
|
26
|
-
"type": "number"
|
|
27
|
-
}
|
|
28
|
-
],
|
|
29
|
-
"minItems": 3,
|
|
30
|
-
"maxItems": 3
|
|
31
|
-
}
|
|
32
|
-
},
|
|
33
|
-
"required": [
|
|
34
|
-
"input"
|
|
35
|
-
]
|
|
36
|
-
},
|
|
37
|
-
"returns": {
|
|
38
|
-
"type": "color",
|
|
39
|
-
"description": "Color with clamped lightness"
|
|
40
|
-
},
|
|
41
|
-
"script": {
|
|
42
|
-
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
|
|
43
|
-
"script": "// clamp_lightness: Constrain lightness to a range\n// Preserves hue and chroma\n\nvariable input: List = {input};\nvariable color: Color.OKLCH = input.get(0).to.oklch();\nvariable min_l: Number = input.get(1);\nvariable max_l: Number = input.get(2);\n\n// Clamp lightness\nvariable new_l: Number = color.l;\nif (new_l < min_l) [ new_l = min_l; ];\nif (new_l > max_l) [ new_l = max_l; ];\n\n// Create result\nvariable result: Color.OKLCH;\nresult.l = new_l;\nresult.c = color.c;\nresult.h = color.h;\n\nreturn result;"
|
|
44
|
-
},
|
|
45
|
-
"examples": [
|
|
46
|
-
{
|
|
47
|
-
"description": "Clamp too-dark color to minimum",
|
|
48
|
-
"input": [
|
|
49
|
-
"#111111",
|
|
50
|
-
0.3,
|
|
51
|
-
0.9
|
|
52
|
-
],
|
|
53
|
-
"output": "Color with lightness 0.3"
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
"description": "Clamp too-light color to maximum",
|
|
57
|
-
"input": [
|
|
58
|
-
"#ffffff",
|
|
59
|
-
0.2,
|
|
60
|
-
0.8
|
|
61
|
-
],
|
|
62
|
-
"output": "Color with lightness 0.8"
|
|
63
|
-
}
|
|
64
|
-
],
|
|
65
|
-
"slug": "clamp_lightness"
|
|
66
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "Clamp to Gamut",
|
|
3
|
-
"type": "function",
|
|
4
|
-
"description": "Clips a color to the sRGB gamut by clamping each RGB channel to [0,1]. This is a simple but lossy approach - for perceptually better results, consider using gamut mapping algorithms that reduce chroma first.",
|
|
5
|
-
"keyword": "clamp_to_gamut",
|
|
6
|
-
"input": {
|
|
7
|
-
"type": "object",
|
|
8
|
-
"properties": {
|
|
9
|
-
"color": {
|
|
10
|
-
"type": "color",
|
|
11
|
-
"description": "Color to clamp"
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
},
|
|
15
|
-
"script": {
|
|
16
|
-
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
|
|
17
|
-
"script": "// Clamp to Gamut (Simple Clipping)\n// Clips out-of-gamut sRGB values to [0, 1] range\n// Reference: Color.js toGamut with method=\"clip\"\n//\n// This is the simplest gamut mapping approach:\n// - Fast and deterministic\n// - Preserves hue when only one channel clips\n// - Can cause hue shifts when multiple channels clip\n// - May lose saturation detail\n//\n// For perceptually better results, use toGamut() which\n// reduces chroma in OKLCH before clipping.\n\nvariable input: List = {input};\nvariable color: Color.SRGB = input.get(0).to.srgb();\n\n// Get RGB values\nvariable r: Number = color.r;\nvariable g: Number = color.g;\nvariable b: Number = color.b;\n\n// Clamp R\nif (r < 0) [ r = 0; ];\nif (r > 1) [ r = 1; ];\n\n// Clamp G\nif (g < 0) [ g = 0; ];\nif (g > 1) [ g = 1; ];\n\n// Clamp B\nif (b < 0) [ b = 0; ];\nif (b > 1) [ b = 1; ];\n\n// Create clamped result\nvariable result: Color.SRGB;\nresult.r = r;\nresult.g = g;\nresult.b = b;\n\nreturn result;"
|
|
18
|
-
},
|
|
19
|
-
"requirements": [
|
|
20
|
-
"https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/srgb-color/0/"
|
|
21
|
-
],
|
|
22
|
-
"slug": "clamp_to_gamut"
|
|
23
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "Complement",
|
|
3
|
-
"type": "function",
|
|
4
|
-
"description": "Returns the complementary color by rotating hue 180° in OKLCH space.",
|
|
5
|
-
"keyword": "complement",
|
|
6
|
-
"input": {
|
|
7
|
-
"type": "object",
|
|
8
|
-
"properties": {
|
|
9
|
-
"color": {
|
|
10
|
-
"type": "color",
|
|
11
|
-
"description": "The color to find the complement of"
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
},
|
|
15
|
-
"script": {
|
|
16
|
-
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
|
|
17
|
-
"script": "// Get the complementary color by rotating hue 180° in OKLCH\n// Preserves lightness and chroma for perceptually balanced results\n\nvariable input: List = {input};\nvariable color: Color.OKLCH = input.get(0).to.oklch();\n\n// Rotate hue by 180°\nvariable new_h: Number = color.h + 180;\nif (new_h >= 360) [ new_h = new_h - 360; ];\n\n// Create complementary color\nvariable result: Color.OKLCH;\nresult.l = color.l;\nresult.c = color.c;\nresult.h = new_h;\n\nreturn result;"
|
|
18
|
-
},
|
|
19
|
-
"requirements": [
|
|
20
|
-
"https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/oklch-color/0/",
|
|
21
|
-
"https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/srgb-color/0/"
|
|
22
|
-
],
|
|
23
|
-
"slug": "complement"
|
|
24
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "Contrast Ratio",
|
|
3
|
-
"type": "function",
|
|
4
|
-
"description": "Calculates the WCAG 2.1 contrast ratio between two colors. Returns a value from 1 (no contrast) to 21 (black/white). WCAG AA requires 4.5:1 for normal text, 3:1 for large text.",
|
|
5
|
-
"keyword": "contrast_ratio",
|
|
6
|
-
"input": {
|
|
7
|
-
"type": "object",
|
|
8
|
-
"properties": {
|
|
9
|
-
"color1": {
|
|
10
|
-
"type": "color",
|
|
11
|
-
"description": "First color (e.g., background)"
|
|
12
|
-
},
|
|
13
|
-
"color2": {
|
|
14
|
-
"type": "color",
|
|
15
|
-
"description": "Second color (e.g., foreground)"
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
},
|
|
19
|
-
"script": {
|
|
20
|
-
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
|
|
21
|
-
"script": "// Calculate WCAG 2.1 contrast ratio between two colors\n//\n// Returns: 1.0 (identical) to 21.0 (black vs white)\n//\n// WCAG Guidelines:\n// - AA Normal text: ≥ 4.5:1\n// - AA Large text: ≥ 3.0:1\n// - AAA Normal text: ≥ 7.0:1\n// - AAA Large text: ≥ 4.5:1\n//\n// Algorithm:\n// 1. Convert to linear RGB\n// 2. Calculate relative luminance: L = 0.2126*R + 0.7152*G + 0.0722*B\n// 3. Contrast ratio: (L_lighter + 0.05) / (L_darker + 0.05)\n\nvariable input: List = {input};\nvariable color1: Color.LinearSRGB = input.get(0).to.linearsrgb();\nvariable color2: Color.LinearSRGB = input.get(1).to.linearsrgb();\n\n// Calculate relative luminance for each color\nvariable lum1: Number = 0.2126 * color1.r + 0.7152 * color1.g + 0.0722 * color1.b;\nvariable lum2: Number = 0.2126 * color2.r + 0.7152 * color2.g + 0.0722 * color2.b;\n\n// Determine lighter and darker\nvariable lighter: Number = lum1;\nvariable darker: Number = lum2;\nif (lum2 > lum1) [\n lighter = lum2;\n darker = lum1;\n];\n\n// Calculate contrast ratio\nvariable ratio: Number = (lighter + 0.05) / (darker + 0.05);\n\nreturn ratio;"
|
|
22
|
-
},
|
|
23
|
-
"requirements": [
|
|
24
|
-
"https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/srgb-linear-color/0/"
|
|
25
|
-
],
|
|
26
|
-
"slug": "contrast_ratio"
|
|
27
|
-
}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "cooler",
|
|
3
|
-
"type": "function",
|
|
4
|
-
"description": "Shifts a color's hue towards cool colors (blue, ~260° in OKLCH). The amount parameter controls how much to shift, from 0 (no change) to 1 (fully cool). Preserves lightness and chroma.",
|
|
5
|
-
"keyword": "cooler",
|
|
6
|
-
"requirements": [
|
|
7
|
-
"https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/srgb-color/0/",
|
|
8
|
-
"https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/oklch-color/0/"
|
|
9
|
-
],
|
|
10
|
-
"schema": {
|
|
11
|
-
"type": "object",
|
|
12
|
-
"properties": {
|
|
13
|
-
"input": {
|
|
14
|
-
"type": "array",
|
|
15
|
-
"items": [
|
|
16
|
-
{
|
|
17
|
-
"description": "Color to cool",
|
|
18
|
-
"type": "color"
|
|
19
|
-
},
|
|
20
|
-
{
|
|
21
|
-
"description": "Amount to shift (0-1), default 0.25",
|
|
22
|
-
"type": "number"
|
|
23
|
-
}
|
|
24
|
-
],
|
|
25
|
-
"minItems": 1,
|
|
26
|
-
"maxItems": 2
|
|
27
|
-
}
|
|
28
|
-
},
|
|
29
|
-
"required": [
|
|
30
|
-
"input"
|
|
31
|
-
]
|
|
32
|
-
},
|
|
33
|
-
"returns": {
|
|
34
|
-
"type": "color",
|
|
35
|
-
"description": "Color shifted towards cool hues"
|
|
36
|
-
},
|
|
37
|
-
"script": {
|
|
38
|
-
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
|
|
39
|
-
"script": "// cooler: Shift hue towards cool colors\n//\n// Cool colors are centered around blue (~260° in OKLCH).\n// The function interpolates the hue towards this target via\n// the shortest angular path on the hue wheel.\n//\n// Parameters:\n// color - Input color\n// amount - Shift amount (0 = no change, 1 = fully cool), default 0.25\n//\n// Preserves lightness and chroma.\n\nvariable input: List = {input};\nvariable color: Color.OKLCH = input.get(0).to.oklch();\nvariable amount: Number = 0.25;\n\nif (input.length() > 1) [\n amount = input.get(1);\n];\n\n// Cool hue target (blue in OKLCH is around 260°)\nvariable cool_hue: Number = 260;\n\n// Calculate shortest path hue difference\nvariable hue_diff: Number = cool_hue - color.h;\n\n// Wrap to shortest path\nif (hue_diff > 180) [ hue_diff = hue_diff - 360; ];\nif (hue_diff < -180) [ hue_diff = hue_diff + 360; ];\n\n// Apply interpolation\nvariable new_hue: Number = color.h + (hue_diff * amount);\n\n// Normalize to 0-360\nif (new_hue < 0) [ new_hue = new_hue + 360; ];\nif (new_hue >= 360) [ new_hue = new_hue - 360; ];\n\n// Create result\nvariable result: Color.OKLCH;\nresult.l = color.l;\nresult.c = color.c;\nresult.h = new_hue;\n\nreturn result;"
|
|
40
|
-
},
|
|
41
|
-
"examples": [
|
|
42
|
-
{
|
|
43
|
-
"description": "Make orange cooler",
|
|
44
|
-
"input": [
|
|
45
|
-
"#ff6600",
|
|
46
|
-
0.5
|
|
47
|
-
],
|
|
48
|
-
"output": "Orange shifted towards neutral"
|
|
49
|
-
}
|
|
50
|
-
],
|
|
51
|
-
"slug": "cooler"
|
|
52
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "Darken",
|
|
3
|
-
"type": "function",
|
|
4
|
-
"description": "Makes a color darker by decreasing its lightness in OKLab space. Amount is 0-1 where 0.25 = 25% darker.",
|
|
5
|
-
"keyword": "darken",
|
|
6
|
-
"input": {
|
|
7
|
-
"type": "object",
|
|
8
|
-
"properties": {
|
|
9
|
-
"color": {
|
|
10
|
-
"type": "color",
|
|
11
|
-
"description": "The color to darken"
|
|
12
|
-
},
|
|
13
|
-
"amount": {
|
|
14
|
-
"type": "number",
|
|
15
|
-
"description": "Amount to darken (0-1). Default is 0.25"
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
},
|
|
19
|
-
"script": {
|
|
20
|
-
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
|
|
21
|
-
"script": "// darken: Decrease lightness proportionally towards black\n// Amount: 0-1 where 0.25 means 25% closer to black\n//\n// Algorithm: L' = L * (1 - amount)\n// This ensures we approach black (L=0) proportionally.\n//\n// Input: Any color space (converted to OKLab internally)\n// Output: OKLCH (working space)\n// To get sRGB: darken(color, 0.25).to.srgb()\n\nvariable input: List = {input};\nvariable color: Color.OKLab = input.get(0).to.oklab();\n\n// Default amount is 0.25 (25%)\nvariable amount: Number = 0.25;\nif (input.length() > 1) [\n amount = input.get(1);\n];\n\n// Calculate new lightness (move toward 0)\nvariable current_l: Number = color.l;\nvariable new_l: Number = current_l * (1 - amount);\n\n// Clamp to valid range\nif (new_l < 0) [ new_l = 0; ];\n\n// Create output in OKLab, return as OKLCH (working space)\nvariable result: Color.OKLab;\nresult.l = new_l;\nresult.a = color.a;\nresult.b = color.b;\n\nreturn result.to.oklch();"
|
|
22
|
-
},
|
|
23
|
-
"requirements": [
|
|
24
|
-
"https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/oklab-color/0/",
|
|
25
|
-
"https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/srgb-color/0/"
|
|
26
|
-
],
|
|
27
|
-
"slug": "darken"
|
|
28
|
-
}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "Delta E 2000",
|
|
3
|
-
"type": "function",
|
|
4
|
-
"description": "Calculates perceptual color difference using CIEDE2000 (ΔE00), the CIE-recommended color difference formula. More accurate than CIE76 for small differences. Industry standard for color quality control. Uses parametric weighting factors kL, kC, kH (all default to 1).",
|
|
5
|
-
"keyword": "delta_e_2000",
|
|
6
|
-
"input": {
|
|
7
|
-
"type": "object",
|
|
8
|
-
"properties": {
|
|
9
|
-
"color1": {
|
|
10
|
-
"type": "color",
|
|
11
|
-
"description": "First color (reference)"
|
|
12
|
-
},
|
|
13
|
-
"color2": {
|
|
14
|
-
"type": "color",
|
|
15
|
-
"description": "Second color (sample)"
|
|
16
|
-
},
|
|
17
|
-
"kL": {
|
|
18
|
-
"type": "number",
|
|
19
|
-
"description": "Lightness weight (default 1)"
|
|
20
|
-
},
|
|
21
|
-
"kC": {
|
|
22
|
-
"type": "number",
|
|
23
|
-
"description": "Chroma weight (default 1)"
|
|
24
|
-
},
|
|
25
|
-
"kH": {
|
|
26
|
-
"type": "number",
|
|
27
|
-
"description": "Hue weight (default 1)"
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
},
|
|
31
|
-
"script": {
|
|
32
|
-
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
|
|
33
|
-
"script": "// CIEDE2000 Color Difference Formula (ΔE00)\n// Reference: CIE 142-2001 (Technical Report)\n// Reference: Color.js deltaE2000 implementation\n// Reference: Sharma, Wu, Dalal \"The CIEDE2000 Color-Difference Formula\" (2005)\n//\n// This is the CIE-recommended color difference formula, providing\n// better correlation with visual perception than CIE76 or CIE94.\n//\n// Parametric factors (kL, kC, kH):\n// - All default to 1.0 for reference conditions\n// - kL can be increased for lightness texture/noise\n// - kC can be increased for chroma noise\n//\n// Interpretation (approximate):\n// 0.0 - Identical colors\n// < 1.0 - Not perceptible by human eye\n// 1.0 - 2.0 - Perceptible through close observation\n// 2.0 - 10.0 - Perceptible at a glance\n// > 10.0 - Colors are obviously different\n\nvariable input: List = {input};\n\n// Convert both colors to CIE Lab\nvariable color1: Color.Lab = input.get(0).to.lab();\nvariable color2: Color.Lab = input.get(1).to.lab();\n\n// Get parametric weighting factors (default to 1)\nvariable k_l: Number = 1;\nvariable k_c: Number = 1;\nvariable k_h: Number = 1;\nif (input.length() > 2) [ k_l = input.get(2); ];\nif (input.length() > 3) [ k_c = input.get(3); ];\nif (input.length() > 4) [ k_h = input.get(4); ];\n\n// Constants\nvariable pi: Number = pi();\nvariable r2d: Number = 180 / pi;\nvariable d2r: Number = pi / 180;\nvariable g_factor: Number = 6103515625; // 25^7\nvariable e: Number = 2.718281828459045; // Euler's number\n\n// Get Lab values\nvariable l1: Number = color1.l;\nvariable a1: Number = color1.a;\nvariable b1: Number = color1.b;\n\nvariable l2: Number = color2.l;\nvariable a2: Number = color2.a;\nvariable b2: Number = color2.b;\n\n// Calculate C* (chroma) for both colors\nvariable c1: Number = sqrt(a1 * a1 + b1 * b1);\nvariable c2: Number = sqrt(a2 * a2 + b2 * b2);\n\n// Ensure non-negative chroma\nif (c1 < 0) [ c1 = 0; ];\nif (c2 < 0) [ c2 = 0; ];\n\n// Mean chroma\nvariable c_bar: Number = (c1 + c2) / 2;\n\n// Calculate G (a-axis asymmetry factor)\nvariable c7: Number = c_bar * c_bar * c_bar * c_bar * c_bar * c_bar * c_bar;\nvariable g: Number = 0.5 * (1 - sqrt(c7 / (c7 + g_factor)));\n\n// Scale a* values by asymmetry factor\nvariable a_prime1: Number = (1 + g) * a1;\nvariable a_prime2: Number = (1 + g) * a2;\n\n// Calculate C' from scaled a' and original b\nvariable c_prime1: Number = sqrt(a_prime1 * a_prime1 + b1 * b1);\nvariable c_prime2: Number = sqrt(a_prime2 * a_prime2 + b2 * b2);\n\n// Calculate h' (hue angles in degrees)\nvariable h1: Number = 0;\nif (a_prime1 != 0) [ h1 = atan2(b1, a_prime1); ];\nif (b1 != 0) [ h1 = atan2(b1, a_prime1); ];\nif (a_prime1 == 0) [\n if (b1 == 0) [ h1 = 0; ] else [ h1 = atan2(b1, a_prime1); ];\n];\nh1 = h1 * r2d;\nif (h1 < 0) [ h1 = h1 + 360; ];\n\nvariable h2: Number = 0;\nif (a_prime2 != 0) [ h2 = atan2(b2, a_prime2); ];\nif (b2 != 0) [ h2 = atan2(b2, a_prime2); ];\nif (a_prime2 == 0) [\n if (b2 == 0) [ h2 = 0; ] else [ h2 = atan2(b2, a_prime2); ];\n];\nh2 = h2 * r2d;\nif (h2 < 0) [ h2 = h2 + 360; ];\n\n// Lightness and Chroma differences\nvariable delta_l: Number = l2 - l1;\nvariable delta_c: Number = c_prime2 - c_prime1;\n\n// Hue difference (getting the sign correct)\nvariable h_diff: Number = h2 - h1;\nvariable h_sum: Number = h1 + h2;\nvariable h_abs: Number = h_diff;\nif (h_abs < 0) [ h_abs = 0 - h_abs; ];\n\nvariable delta_h: Number = 0;\nvariable c_product: Number = c_prime1 * c_prime2;\n\nif (c_product == 0) [\n delta_h = 0;\n] else [\n if (h_abs <= 180) [\n delta_h = h_diff;\n ] else [\n if (h_diff > 180) [\n delta_h = h_diff - 360;\n ] else [\n if (h_diff < -180) [\n delta_h = h_diff + 360;\n ] else [\n delta_h = h_diff;\n ];\n ];\n ];\n];\n\n// Weighted hue difference (ΔH')\nvariable delta_h_prime: Number = 2 * sqrt(c_prime2 * c_prime1) * sin(delta_h * d2r / 2);\n\n// Mean lightness and chroma\nvariable l_bar: Number = (l1 + l2) / 2;\nvariable c_bar_prime: Number = (c_prime1 + c_prime2) / 2;\nvariable c_bar_prime7: Number = c_bar_prime * c_bar_prime * c_bar_prime * c_bar_prime * c_bar_prime * c_bar_prime * c_bar_prime;\n\n// Mean hue (handling the 0/360 wraparound)\nvariable h_bar: Number = 0;\nif (c_product == 0) [\n h_bar = h_sum;\n] else [\n if (h_abs <= 180) [\n h_bar = h_sum / 2;\n ] else [\n if (h_sum < 360) [\n h_bar = (h_sum + 360) / 2;\n ] else [\n h_bar = (h_sum - 360) / 2;\n ];\n ];\n];\n\n// SL - Lightness crispening factor (assumes L=50 background)\nvariable l_bar_minus_50: Number = l_bar - 50;\nvariable l_sq: Number = l_bar_minus_50 * l_bar_minus_50;\nvariable s_l: Number = 1 + (0.015 * l_sq) / sqrt(20 + l_sq);\n\n// SC - Chroma factor\nvariable s_c: Number = 1 + 0.045 * c_bar_prime;\n\n// T - Cross term for blue non-linearity\nvariable t: Number = 1;\nt = t - 0.17 * cos((h_bar - 30) * d2r);\nt = t + 0.24 * cos(2 * h_bar * d2r);\nt = t + 0.32 * cos((3 * h_bar + 6) * d2r);\nt = t - 0.20 * cos((4 * h_bar - 63) * d2r);\n\n// SH - Hue factor\nvariable s_h: Number = 1 + 0.015 * c_bar_prime * t;\n\n// RT - Hue rotation term (for blue region 225-315 degrees)\nvariable h_bar_minus_275: Number = h_bar - 275;\nvariable exp_arg: Number = -1 * (h_bar_minus_275 / 25) * (h_bar_minus_275 / 25);\nvariable delta_theta: Number = 30 * pow(e, exp_arg);\nvariable r_c: Number = 2 * sqrt(c_bar_prime7 / (c_bar_prime7 + g_factor));\nvariable r_t: Number = -1 * sin(2 * delta_theta * d2r) * r_c;\n\n// Calculate final ΔE00\nvariable term_l: Number = delta_l / (k_l * s_l);\nvariable term_c: Number = delta_c / (k_c * s_c);\nvariable term_h: Number = delta_h_prime / (k_h * s_h);\n\nvariable de: Number = term_l * term_l + term_c * term_c + term_h * term_h;\nde = de + r_t * (delta_c / (k_c * s_c)) * (delta_h_prime / (k_h * s_h));\n\nvariable result: Number = sqrt(de);\n\nreturn result;"
|
|
34
|
-
},
|
|
35
|
-
"requirements": [
|
|
36
|
-
"https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/lab-color/0/",
|
|
37
|
-
"https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/lch-color/0/"
|
|
38
|
-
],
|
|
39
|
-
"slug": "delta_e_2000"
|
|
40
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "Delta E 76",
|
|
3
|
-
"type": "function",
|
|
4
|
-
"description": "Calculates color difference using CIE76 formula (ΔE*ab). Simple Euclidean distance in CIE Lab space. Less accurate than Delta E 2000 for small differences, but faster and adequate for many applications. Formula: sqrt((L1-L2)² + (a1-a2)² + (b1-b2)²).",
|
|
5
|
-
"keyword": "delta_e_76",
|
|
6
|
-
"input": {
|
|
7
|
-
"type": "object",
|
|
8
|
-
"properties": {
|
|
9
|
-
"color1": {
|
|
10
|
-
"type": "color",
|
|
11
|
-
"description": "First color (reference)"
|
|
12
|
-
},
|
|
13
|
-
"color2": {
|
|
14
|
-
"type": "color",
|
|
15
|
-
"description": "Second color (sample)"
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
},
|
|
19
|
-
"script": {
|
|
20
|
-
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
|
|
21
|
-
"script": "// Delta E 76 (CIE76 Color Difference)\n// Reference: CIE Publication 15.2 (1986)\n// Reference: ASTM E308 Standard\n//\n// The original CIE color difference formula from 1976.\n// Simple Euclidean distance in CIE Lab space.\n//\n// Formula: ΔE*ab = sqrt((L1-L2)² + (a1-a2)² + (b1-b2)²)\n//\n// Interpretation:\n// 0 - 1: Not perceptible by human eye\n// 1 - 2: Perceptible through close observation\n// 2 - 10: Perceptible at a glance\n// 11 - 49: Colors are more similar than opposite\n// 100+: Colors are exact opposite\n//\n// Limitations:\n// - Lab is not perfectly perceptually uniform\n// - Overestimates differences for saturated colors\n// - Use Delta E 2000 for critical color matching\n\nvariable input: List = {input};\nvariable color1: Color.Lab = input.get(0).to.lab();\nvariable color2: Color.Lab = input.get(1).to.lab();\n\n// Get Lab components\nvariable l1: Number = color1.l;\nvariable a1: Number = color1.a;\nvariable b1: Number = color1.b;\n\nvariable l2: Number = color2.l;\nvariable a2: Number = color2.a;\nvariable b2: Number = color2.b;\n\n// Calculate differences\nvariable delta_l: Number = l1 - l2;\nvariable delta_a: Number = a1 - a2;\nvariable delta_b: Number = b1 - b2;\n\n// Euclidean distance\nvariable sum_squares: Number = delta_l * delta_l + delta_a * delta_a + delta_b * delta_b;\nvariable result: Number = sqrt(sum_squares);\n\nreturn result;"
|
|
22
|
-
},
|
|
23
|
-
"requirements": [
|
|
24
|
-
"https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/lab-color/0/"
|
|
25
|
-
],
|
|
26
|
-
"slug": "delta_e_76"
|
|
27
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "Delta E OK",
|
|
3
|
-
"type": "function",
|
|
4
|
-
"description": "Calculates perceptual color difference using the OKLab color space (ΔE_OK). This is the Euclidean distance in OKLab space, providing excellent perceptual uniformity. Values: 0 = identical, <0.02 = imperceptible, <0.05 = very close, <0.1 = noticeable, >0.5 = very different.",
|
|
5
|
-
"keyword": "delta_e_ok",
|
|
6
|
-
"input": {
|
|
7
|
-
"type": "object",
|
|
8
|
-
"properties": {
|
|
9
|
-
"color1": {
|
|
10
|
-
"type": "color",
|
|
11
|
-
"description": "First color (reference)"
|
|
12
|
-
},
|
|
13
|
-
"color2": {
|
|
14
|
-
"type": "color",
|
|
15
|
-
"description": "Second color (sample)"
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
},
|
|
19
|
-
"script": {
|
|
20
|
-
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
|
|
21
|
-
"script": "// Delta E OK (ΔE_OK)\n// Perceptual color difference in OKLab space\n// Reference: Björn Ottosson's OKLab specification\n// Reference: Color.js deltaEOK implementation\n//\n// This is simply the Euclidean distance in OKLab space.\n// OKLab is designed to be perceptually uniform, making this\n// a reliable measure of perceived color difference.\n//\n// Interpretation:\n// 0.00 - Identical colors\n// < 0.02 - Imperceptible difference (JND threshold)\n// < 0.05 - Very close colors\n// < 0.1 - Noticeable but small difference\n// 0.1 - 0.5 - Moderate difference\n// > 0.5 - Very different colors\n//\n// Formula: sqrt((L1-L2)² + (a1-a2)² + (b1-b2)²)\n\nvariable input: List = {input};\nvariable color1: Color.OKLab = input.get(0).to.oklab();\nvariable color2: Color.OKLab = input.get(1).to.oklab();\n\n// Get OKLab components\nvariable l1: Number = color1.l;\nvariable a1: Number = color1.a;\nvariable b1: Number = color1.b;\n\nvariable l2: Number = color2.l;\nvariable a2: Number = color2.a;\nvariable b2: Number = color2.b;\n\n// Calculate differences\nvariable delta_l: Number = l1 - l2;\nvariable delta_a: Number = a1 - a2;\nvariable delta_b: Number = b1 - b2;\n\n// Calculate Euclidean distance (sqrt of sum of squares)\nvariable sum_squares: Number = delta_l * delta_l + delta_a * delta_a + delta_b * delta_b;\nvariable result: Number = sqrt(sum_squares);\n\nreturn result;"
|
|
22
|
-
},
|
|
23
|
-
"requirements": [
|
|
24
|
-
"https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/oklab-color/0/"
|
|
25
|
-
],
|
|
26
|
-
"slug": "delta_e_ok"
|
|
27
|
-
}
|