@tokens-studio/tokenscript-schemas 0.0.11 → 0.0.13
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/dist/cli/index.cjs +31 -8
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +30 -8
- package/dist/cli/index.js.map +1 -1
- package/package.json +2 -1
- package/src/bundler/bundle-schema.ts +146 -0
- package/src/bundler/index.ts +151 -0
- package/src/bundler/schema-dependency-resolver.ts +299 -0
- package/src/bundler/selective-bundler.test.ts +94 -0
- package/src/bundler/selective-bundler.ts +159 -0
- package/src/bundler/types.ts +93 -0
- package/src/bundler/utils.ts +74 -0
- package/src/cli/commands/bundle.integration.test.ts +153 -0
- package/src/cli/commands/bundle.test.ts +57 -0
- package/src/cli/commands/bundle.ts +237 -0
- package/src/cli/commands/list.ts +109 -0
- package/src/cli/config-schema.ts +36 -0
- package/src/cli/index.ts +50 -0
- package/src/cli/output-generator.ts +63 -0
- package/src/downloader/index.ts +248 -0
- package/src/downloader/types.ts +48 -0
- package/src/index.ts +8 -0
- package/src/schemas/functions/adjust_chroma/adjust-chroma.tokenscript +27 -0
- package/src/schemas/functions/adjust_chroma/schema.json +48 -0
- package/src/schemas/functions/adjust_chroma/unit.test.ts +76 -0
- package/src/schemas/functions/adjust_hue/adjust-hue.tokenscript +32 -0
- package/src/schemas/functions/adjust_hue/schema.json +48 -0
- package/src/schemas/functions/adjust_hue/unit.test.ts +68 -0
- package/src/schemas/functions/adjust_lightness/adjust-lightness.tokenscript +31 -0
- package/src/schemas/functions/adjust_lightness/schema.json +48 -0
- package/src/schemas/functions/adjust_lightness/unit.test.ts +88 -0
- package/src/schemas/functions/adjust_to_contrast/adjust-to-contrast.tokenscript +131 -0
- package/src/schemas/functions/adjust_to_contrast/schema.json +56 -0
- package/src/schemas/functions/adjust_to_contrast/unit.test.ts +81 -0
- package/src/schemas/functions/alpha_blend/alpha-blend.tokenscript +46 -0
- package/src/schemas/functions/alpha_blend/schema.json +28 -0
- package/src/schemas/functions/alpha_blend/unit.test.ts +135 -0
- package/src/schemas/functions/alpha_scale/alpha-scale.tokenscript +38 -0
- package/src/schemas/functions/alpha_scale/schema.json +24 -0
- package/src/schemas/functions/alpha_scale/unit.test.ts +50 -0
- package/src/schemas/functions/analogous/analogous.tokenscript +47 -0
- package/src/schemas/functions/analogous/schema.json +28 -0
- package/src/schemas/functions/analogous/unit.test.ts +64 -0
- package/src/schemas/functions/apca_contrast/apca-contrast.tokenscript +129 -0
- package/src/schemas/functions/apca_contrast/schema.json +24 -0
- package/src/schemas/functions/apca_contrast/unit.test.ts +259 -0
- package/src/schemas/functions/are_similar/are-similar.tokenscript +24 -0
- package/src/schemas/functions/are_similar/schema.json +57 -0
- package/src/schemas/functions/are_similar/unit.test.ts +57 -0
- package/src/schemas/functions/auto_text_color/auto-text-color.tokenscript +41 -0
- package/src/schemas/functions/auto_text_color/schema.json +53 -0
- package/src/schemas/functions/auto_text_color/unit.test.ts +122 -0
- package/src/schemas/functions/best_contrast/best-contrast.tokenscript +66 -0
- package/src/schemas/functions/best_contrast/schema.json +24 -0
- package/src/schemas/functions/best_contrast/unit.test.ts +64 -0
- package/src/schemas/functions/chroma/chroma.tokenscript +12 -0
- package/src/schemas/functions/chroma/schema.json +44 -0
- package/src/schemas/functions/chroma/unit.test.ts +86 -0
- package/src/schemas/functions/clamp_chroma/clamp-chroma.tokenscript +21 -0
- package/src/schemas/functions/clamp_chroma/schema.json +52 -0
- package/src/schemas/functions/clamp_chroma/unit.test.ts +60 -0
- package/src/schemas/functions/clamp_lightness/clamp-lightness.tokenscript +21 -0
- package/src/schemas/functions/clamp_lightness/schema.json +52 -0
- package/src/schemas/functions/clamp_lightness/unit.test.ts +76 -0
- package/src/schemas/functions/clamp_to_gamut/clamp-to-gamut.tokenscript +41 -0
- package/src/schemas/functions/clamp_to_gamut/schema.json +20 -0
- package/src/schemas/functions/clamp_to_gamut/unit.test.ts +167 -0
- package/src/schemas/functions/complement/complement.tokenscript +21 -0
- package/src/schemas/functions/complement/schema.json +20 -0
- package/src/schemas/functions/complement/unit.test.ts +81 -0
- package/src/schemas/functions/contrast_ratio/contrast-ratio.tokenscript +36 -0
- package/src/schemas/functions/contrast_ratio/schema.json +24 -0
- package/src/schemas/functions/contrast_ratio/unit.test.ts +91 -0
- package/src/schemas/functions/cooler/cooler.tokenscript +45 -0
- package/src/schemas/functions/cooler/schema.json +43 -0
- package/src/schemas/functions/cooler/unit.test.ts +69 -0
- package/src/schemas/functions/darken/darken.tokenscript +37 -0
- package/src/schemas/functions/darken/schema.json +24 -0
- package/src/schemas/functions/darken/unit.test.ts +105 -0
- package/src/schemas/functions/delta_e_2000/delta-e-2000.tokenscript +184 -0
- package/src/schemas/functions/delta_e_2000/schema.json +36 -0
- package/src/schemas/functions/delta_e_2000/unit.test.ts +243 -0
- package/src/schemas/functions/delta_e_76/delta-e-76.tokenscript +45 -0
- package/src/schemas/functions/delta_e_76/schema.json +24 -0
- package/src/schemas/functions/delta_e_76/unit.test.ts +123 -0
- package/src/schemas/functions/delta_e_ok/delta-e-ok.tokenscript +43 -0
- package/src/schemas/functions/delta_e_ok/schema.json +24 -0
- package/src/schemas/functions/delta_e_ok/unit.test.ts +235 -0
- package/src/schemas/functions/desaturate/desaturate.tokenscript +32 -0
- package/src/schemas/functions/desaturate/schema.json +24 -0
- package/src/schemas/functions/desaturate/unit.test.ts +54 -0
- package/src/schemas/functions/distributed/distributed.tokenscript +54 -0
- package/src/schemas/functions/distributed/schema.json +32 -0
- package/src/schemas/functions/distributed/unit.test.ts +58 -0
- package/src/schemas/functions/diverging/diverging.tokenscript +58 -0
- package/src/schemas/functions/diverging/schema.json +32 -0
- package/src/schemas/functions/diverging/unit.test.ts +70 -0
- package/src/schemas/functions/grayscale/grayscale.tokenscript +17 -0
- package/src/schemas/functions/grayscale/schema.json +20 -0
- package/src/schemas/functions/grayscale/unit.test.ts +79 -0
- package/src/schemas/functions/harmonize/harmonize.tokenscript +61 -0
- package/src/schemas/functions/harmonize/schema.json +52 -0
- package/src/schemas/functions/harmonize/unit.test.ts +56 -0
- package/src/schemas/functions/hue/hue.tokenscript +12 -0
- package/src/schemas/functions/hue/schema.json +44 -0
- package/src/schemas/functions/hue/unit.test.ts +75 -0
- package/src/schemas/functions/hue_difference/hue-difference.tokenscript +42 -0
- package/src/schemas/functions/hue_difference/schema.json +24 -0
- package/src/schemas/functions/hue_difference/unit.test.ts +125 -0
- package/src/schemas/functions/in_gamut/in-gamut.tokenscript +51 -0
- package/src/schemas/functions/in_gamut/schema.json +24 -0
- package/src/schemas/functions/in_gamut/unit.test.ts +178 -0
- package/src/schemas/functions/interpolate/interpolate.tokenscript +61 -0
- package/src/schemas/functions/interpolate/schema.json +52 -0
- package/src/schemas/functions/interpolate/unit.test.ts +96 -0
- package/src/schemas/functions/invert/invert-initializer.tokenscript +29 -0
- package/src/schemas/functions/invert/schema.json +20 -0
- package/src/schemas/functions/invert/unit.test.ts +216 -0
- package/src/schemas/functions/is_cool/is-cool.tokenscript +41 -0
- package/src/schemas/functions/is_cool/schema.json +20 -0
- package/src/schemas/functions/is_cool/unit.test.ts +189 -0
- package/src/schemas/functions/is_dark/is-dark.tokenscript +16 -0
- package/src/schemas/functions/is_dark/schema.json +24 -0
- package/src/schemas/functions/is_dark/unit.test.ts +87 -0
- package/src/schemas/functions/is_light/is-light.tokenscript +16 -0
- package/src/schemas/functions/is_light/schema.json +24 -0
- package/src/schemas/functions/is_light/unit.test.ts +86 -0
- package/src/schemas/functions/is_neutral/is-neutral.tokenscript +16 -0
- package/src/schemas/functions/is_neutral/schema.json +53 -0
- package/src/schemas/functions/is_neutral/unit.test.ts +85 -0
- package/src/schemas/functions/is_warm/is-warm.tokenscript +62 -0
- package/src/schemas/functions/is_warm/schema.json +20 -0
- package/src/schemas/functions/is_warm/unit.test.ts +161 -0
- package/src/schemas/functions/lighten/lighten.tokenscript +37 -0
- package/src/schemas/functions/lighten/schema.json +24 -0
- package/src/schemas/functions/lighten/unit.test.ts +109 -0
- package/src/schemas/functions/lightness/lightness.tokenscript +12 -0
- package/src/schemas/functions/lightness/schema.json +49 -0
- package/src/schemas/functions/lightness/unit.test.ts +99 -0
- package/src/schemas/functions/luminance/luminance.tokenscript +16 -0
- package/src/schemas/functions/luminance/schema.json +20 -0
- package/src/schemas/functions/luminance/unit.test.ts +105 -0
- package/src/schemas/functions/meets_contrast/meets-contrast.tokenscript +49 -0
- package/src/schemas/functions/meets_contrast/schema.json +28 -0
- package/src/schemas/functions/meets_contrast/unit.test.ts +170 -0
- package/src/schemas/functions/mix/mix.tokenscript +47 -0
- package/src/schemas/functions/mix/schema.json +28 -0
- package/src/schemas/functions/mix/unit.test.ts +95 -0
- package/src/schemas/functions/monochromatic/monochromatic.tokenscript +72 -0
- package/src/schemas/functions/monochromatic/schema.json +24 -0
- package/src/schemas/functions/monochromatic/unit.test.ts +91 -0
- package/src/schemas/functions/muted/muted.tokenscript +25 -0
- package/src/schemas/functions/muted/schema.json +48 -0
- package/src/schemas/functions/muted/unit.test.ts +100 -0
- package/src/schemas/functions/neutral_variant/neutral-variant.tokenscript +23 -0
- package/src/schemas/functions/neutral_variant/schema.json +48 -0
- package/src/schemas/functions/neutral_variant/unit.test.ts +102 -0
- package/src/schemas/functions/relative_luminance/relative-luminance.tokenscript +15 -0
- package/src/schemas/functions/relative_luminance/schema.json +49 -0
- package/src/schemas/functions/relative_luminance/unit.test.ts +104 -0
- package/src/schemas/functions/rotate_hue/rotate-hue.tokenscript +20 -0
- package/src/schemas/functions/rotate_hue/schema.json +24 -0
- package/src/schemas/functions/rotate_hue/unit.test.ts +86 -0
- package/src/schemas/functions/saturate/saturate.tokenscript +33 -0
- package/src/schemas/functions/saturate/schema.json +24 -0
- package/src/schemas/functions/saturate/unit.test.ts +59 -0
- package/src/schemas/functions/scale_chroma/scale-chroma.tokenscript +22 -0
- package/src/schemas/functions/scale_chroma/schema.json +48 -0
- package/src/schemas/functions/scale_chroma/unit.test.ts +79 -0
- package/src/schemas/functions/scale_lightness/scale-lightness.tokenscript +23 -0
- package/src/schemas/functions/scale_lightness/schema.json +48 -0
- package/src/schemas/functions/scale_lightness/unit.test.ts +73 -0
- package/src/schemas/functions/sepia/schema.json +48 -0
- package/src/schemas/functions/sepia/sepia.tokenscript +54 -0
- package/src/schemas/functions/sepia/unit.test.ts +88 -0
- package/src/schemas/functions/set_chroma/schema.json +24 -0
- package/src/schemas/functions/set_chroma/set-chroma.tokenscript +18 -0
- package/src/schemas/functions/set_chroma/unit.test.ts +79 -0
- package/src/schemas/functions/set_hue/schema.json +24 -0
- package/src/schemas/functions/set_hue/set-hue.tokenscript +18 -0
- package/src/schemas/functions/set_hue/unit.test.ts +90 -0
- package/src/schemas/functions/set_lightness/schema.json +24 -0
- package/src/schemas/functions/set_lightness/set-lightness.tokenscript +18 -0
- package/src/schemas/functions/set_lightness/unit.test.ts +80 -0
- package/src/schemas/functions/shade_scale/schema.json +24 -0
- package/src/schemas/functions/shade_scale/shade-scale.tokenscript +61 -0
- package/src/schemas/functions/shade_scale/unit.test.ts +64 -0
- package/src/schemas/functions/split_complement/schema.json +24 -0
- package/src/schemas/functions/split_complement/split-complement.tokenscript +38 -0
- package/src/schemas/functions/split_complement/unit.test.ts +53 -0
- package/src/schemas/functions/steps/schema.json +28 -0
- package/src/schemas/functions/steps/steps.tokenscript +54 -0
- package/src/schemas/functions/steps/unit.test.ts +71 -0
- package/src/schemas/functions/tetradic/schema.json +20 -0
- package/src/schemas/functions/tetradic/tetradic.tokenscript +40 -0
- package/src/schemas/functions/tetradic/unit.test.ts +50 -0
- package/src/schemas/functions/tint_scale/schema.json +32 -0
- package/src/schemas/functions/tint_scale/tint-scale.tokenscript +71 -0
- package/src/schemas/functions/tint_scale/unit.test.ts +64 -0
- package/src/schemas/functions/to_gamut/schema.json +48 -0
- package/src/schemas/functions/to_gamut/to-gamut.tokenscript +96 -0
- package/src/schemas/functions/to_gamut/unit.test.ts +97 -0
- package/src/schemas/functions/triadic/schema.json +20 -0
- package/src/schemas/functions/triadic/triadic.tokenscript +33 -0
- package/src/schemas/functions/triadic/unit.test.ts +64 -0
- package/src/schemas/functions/vibrant/schema.json +48 -0
- package/src/schemas/functions/vibrant/unit.test.ts +55 -0
- package/src/schemas/functions/vibrant/vibrant.tokenscript +29 -0
- package/src/schemas/functions/warmer/schema.json +43 -0
- package/src/schemas/functions/warmer/unit.test.ts +69 -0
- package/src/schemas/functions/warmer/warmer.tokenscript +45 -0
- package/src/schemas/functions/wcag_level/schema.json +48 -0
- package/src/schemas/functions/wcag_level/unit.test.ts +75 -0
- package/src/schemas/functions/wcag_level/wcag-level.tokenscript +50 -0
- package/src/schemas/types/css-color/from-hsl-color.tokenscript +16 -0
- package/src/schemas/types/css-color/from-hwb-color.tokenscript +16 -0
- package/src/schemas/types/css-color/from-lab-color.tokenscript +16 -0
- package/src/schemas/types/css-color/from-lch-color.tokenscript +16 -0
- package/src/schemas/types/css-color/from-oklab-color.tokenscript +16 -0
- package/src/schemas/types/css-color/from-oklch-color.tokenscript +16 -0
- package/src/schemas/types/css-color/from-p3-color.tokenscript +16 -0
- package/src/schemas/types/css-color/from-rgb-color.tokenscript +15 -0
- package/src/schemas/types/css-color/from-srgb-color.tokenscript +16 -0
- package/src/schemas/types/css-color/from-srgb-linear-color.tokenscript +16 -0
- package/src/schemas/types/css-color/from-xyz-d50-color.tokenscript +16 -0
- package/src/schemas/types/css-color/from-xyz-d65-color.tokenscript +16 -0
- package/src/schemas/types/css-color/initializer.tokenscript +13 -0
- package/src/schemas/types/css-color/schema.json +148 -0
- package/src/schemas/types/css-color/unit.test.ts +402 -0
- package/src/schemas/types/hex-color/initializer.tokenscript +3 -0
- package/src/schemas/types/hex-color/schema.json +24 -0
- package/src/schemas/types/hex-color/unit.test.ts +123 -0
- package/src/schemas/types/hsl-color/from-srgb.tokenscript +87 -0
- package/src/schemas/types/hsl-color/initializer.tokenscript +16 -0
- package/src/schemas/types/hsl-color/schema.json +48 -0
- package/src/schemas/types/hsl-color/unit.test.ts +201 -0
- package/src/schemas/types/hsv-color/from-srgb.tokenscript +80 -0
- package/src/schemas/types/hsv-color/initializer.tokenscript +16 -0
- package/src/schemas/types/hsv-color/schema.json +48 -0
- package/src/schemas/types/hsv-color/unit.test.ts +162 -0
- package/src/schemas/types/hwb-color/from-hsv.tokenscript +31 -0
- package/src/schemas/types/hwb-color/initializer.tokenscript +16 -0
- package/src/schemas/types/hwb-color/schema.json +48 -0
- package/src/schemas/types/hwb-color/unit.test.ts +150 -0
- package/src/schemas/types/lab-color/from-xyz-d50.tokenscript +78 -0
- package/src/schemas/types/lab-color/initializer.tokenscript +16 -0
- package/src/schemas/types/lab-color/schema.json +48 -0
- package/src/schemas/types/lab-color/unit.test.ts +263 -0
- package/src/schemas/types/lch-color/from-lab.tokenscript +44 -0
- package/src/schemas/types/lch-color/initializer.tokenscript +16 -0
- package/src/schemas/types/lch-color/schema.json +48 -0
- package/src/schemas/types/lch-color/unit.test.ts +173 -0
- package/src/schemas/types/okhsl-color/from-oklab.tokenscript +410 -0
- package/src/schemas/types/okhsl-color/initializer.tokenscript +24 -0
- package/src/schemas/types/okhsl-color/schema.json +48 -0
- package/src/schemas/types/okhsl-color/unit.test.ts +514 -0
- package/src/schemas/types/okhsv-color/from-oklab.tokenscript +286 -0
- package/src/schemas/types/okhsv-color/initializer.tokenscript +24 -0
- package/src/schemas/types/okhsv-color/schema.json +48 -0
- package/src/schemas/types/okhsv-color/unit.test.ts +499 -0
- package/src/schemas/types/oklab-color/from-okhsl.tokenscript +195 -0
- package/src/schemas/types/oklab-color/from-okhsv.tokenscript +197 -0
- package/src/schemas/types/oklab-color/from-oklch.tokenscript +39 -0
- package/src/schemas/types/oklab-color/from-xyz-d65.tokenscript +43 -0
- package/src/schemas/types/oklab-color/initializer.tokenscript +16 -0
- package/src/schemas/types/oklab-color/schema.json +78 -0
- package/src/schemas/types/oklab-color/unit.test.ts +345 -0
- package/src/schemas/types/oklch-color/from-oklab.tokenscript +45 -0
- package/src/schemas/types/oklch-color/initializer.tokenscript +16 -0
- package/src/schemas/types/oklch-color/schema.json +48 -0
- package/src/schemas/types/oklch-color/unit.test.ts +267 -0
- package/src/schemas/types/p3-color/from-p3-linear.tokenscript +59 -0
- package/src/schemas/types/p3-color/initializer.tokenscript +16 -0
- package/src/schemas/types/p3-color/schema.json +48 -0
- package/src/schemas/types/p3-color/unit.test.ts +119 -0
- package/src/schemas/types/p3-linear-color/from-xyz-d65.tokenscript +47 -0
- package/src/schemas/types/p3-linear-color/initializer.tokenscript +16 -0
- package/src/schemas/types/p3-linear-color/schema.json +48 -0
- package/src/schemas/types/p3-linear-color/unit.test.ts +82 -0
- package/src/schemas/types/rgb-color/from-hex.tokenscript +43 -0
- package/src/schemas/types/rgb-color/initializer.tokenscript +16 -0
- package/src/schemas/types/rgb-color/schema.json +55 -0
- package/src/schemas/types/rgb-color/to-hex.tokenscript +42 -0
- package/src/schemas/types/rgb-color/unit.test.ts +302 -0
- package/src/schemas/types/srgb-color/from-hsl.tokenscript +106 -0
- package/src/schemas/types/srgb-color/from-linear.tokenscript +58 -0
- package/src/schemas/types/srgb-color/from-rgb.tokenscript +20 -0
- package/src/schemas/types/srgb-color/initializer.tokenscript +16 -0
- package/src/schemas/types/srgb-color/schema.json +68 -0
- package/src/schemas/types/srgb-color/unit.test.ts +303 -0
- package/src/schemas/types/srgb-linear-color/from-srgb.tokenscript +55 -0
- package/src/schemas/types/srgb-linear-color/from-xyz-d65.tokenscript +34 -0
- package/src/schemas/types/srgb-linear-color/initializer.tokenscript +13 -0
- package/src/schemas/types/srgb-linear-color/schema.json +58 -0
- package/src/schemas/types/srgb-linear-color/unit.test.ts +291 -0
- package/src/schemas/types/xyz-d50-color/from-xyz-d65.tokenscript +36 -0
- package/src/schemas/types/xyz-d50-color/initializer.tokenscript +16 -0
- package/src/schemas/types/xyz-d50-color/schema.json +48 -0
- package/src/schemas/types/xyz-d50-color/unit.test.ts +240 -0
- package/src/schemas/types/xyz-d65-color/from-linear-p3.tokenscript +47 -0
- package/src/schemas/types/xyz-d65-color/from-linear-srgb.tokenscript +38 -0
- package/src/schemas/types/xyz-d65-color/from-oklab.tokenscript +44 -0
- package/src/schemas/types/xyz-d65-color/initializer.tokenscript +16 -0
- package/src/schemas/types/xyz-d65-color/schema.json +68 -0
- package/src/schemas/types/xyz-d65-color/unit.test.ts +319 -0
- package/src/utils/schema-uri.ts +192 -0
- package/src/utils/type.ts +194 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { executeWithSchema } from "@tests/helpers/schema-test-utils";
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
|
+
|
|
4
|
+
describe("Hue Difference Function", () => {
|
|
5
|
+
describe("Schema Definition", () => {
|
|
6
|
+
it("should have correct schema structure", async () => {
|
|
7
|
+
const { getBundledSchema } = await import("@tests/helpers/schema-test-utils");
|
|
8
|
+
const schema = await getBundledSchema("hue_difference", "function");
|
|
9
|
+
|
|
10
|
+
expect(schema.name).toBe("Hue Difference");
|
|
11
|
+
expect(schema.type).toBe("function");
|
|
12
|
+
expect((schema as any).keyword).toBe("hue_difference");
|
|
13
|
+
});
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
describe("Same Hue", () => {
|
|
17
|
+
it("should return 0 for identical colors", async () => {
|
|
18
|
+
const result = await executeWithSchema(
|
|
19
|
+
"hue_difference",
|
|
20
|
+
"function",
|
|
21
|
+
`
|
|
22
|
+
variable c1: Color.SRGB;
|
|
23
|
+
c1.r = 1; c1.g = 0; c1.b = 0;
|
|
24
|
+
variable c2: Color.SRGB;
|
|
25
|
+
c2.r = 1; c2.g = 0; c2.b = 0;
|
|
26
|
+
hue_difference(c1, c2)
|
|
27
|
+
`,
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
expect(result.value).toBeCloseTo(0, 1);
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
describe("Complementary Colors", () => {
|
|
35
|
+
it("should return ~180 for complement colors", async () => {
|
|
36
|
+
// Red vs Cyan are complementary
|
|
37
|
+
const result = await executeWithSchema(
|
|
38
|
+
"hue_difference",
|
|
39
|
+
"function",
|
|
40
|
+
`
|
|
41
|
+
variable c1: Color.SRGB;
|
|
42
|
+
c1.r = 1; c1.g = 0; c1.b = 0;
|
|
43
|
+
variable c2: Color.SRGB;
|
|
44
|
+
c2.r = 0; c2.g = 1; c2.b = 1;
|
|
45
|
+
hue_difference(c1, c2)
|
|
46
|
+
`,
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
// Should be close to 180 (complementary)
|
|
50
|
+
expect(result.value).toBeGreaterThan(150);
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
describe("Shortest Path", () => {
|
|
55
|
+
it("should take shortest path around hue circle", async () => {
|
|
56
|
+
// Test with colors near the 0/360 boundary
|
|
57
|
+
// Magenta (high hue ~330) vs Red (low hue ~30)
|
|
58
|
+
// Should be ~60, not ~300
|
|
59
|
+
const result = await executeWithSchema(
|
|
60
|
+
"hue_difference",
|
|
61
|
+
"function",
|
|
62
|
+
`
|
|
63
|
+
variable c1: Color.SRGB;
|
|
64
|
+
c1.r = 1; c1.g = 0; c1.b = 0;
|
|
65
|
+
variable c2: Color.SRGB;
|
|
66
|
+
c2.r = 1; c2.g = 0; c2.b = 0.5;
|
|
67
|
+
hue_difference(c1, c2)
|
|
68
|
+
`,
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
// Should take short path
|
|
72
|
+
expect(result.value).toBeLessThan(180);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
describe("Adjacent Colors", () => {
|
|
77
|
+
it("should return small value for adjacent hues", async () => {
|
|
78
|
+
// Red and Orange are adjacent
|
|
79
|
+
const result = await executeWithSchema(
|
|
80
|
+
"hue_difference",
|
|
81
|
+
"function",
|
|
82
|
+
`
|
|
83
|
+
variable c1: Color.SRGB;
|
|
84
|
+
c1.r = 1; c1.g = 0; c1.b = 0;
|
|
85
|
+
variable c2: Color.SRGB;
|
|
86
|
+
c2.r = 1; c2.g = 0.5; c2.b = 0;
|
|
87
|
+
hue_difference(c1, c2)
|
|
88
|
+
`,
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
// Adjacent colors should have small difference
|
|
92
|
+
expect(result.value).toBeLessThan(60);
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
describe("Symmetry", () => {
|
|
97
|
+
it("should be symmetric", async () => {
|
|
98
|
+
const result1 = await executeWithSchema(
|
|
99
|
+
"hue_difference",
|
|
100
|
+
"function",
|
|
101
|
+
`
|
|
102
|
+
variable c1: Color.SRGB;
|
|
103
|
+
c1.r = 1; c1.g = 0; c1.b = 0;
|
|
104
|
+
variable c2: Color.SRGB;
|
|
105
|
+
c2.r = 0; c2.g = 1; c2.b = 0;
|
|
106
|
+
hue_difference(c1, c2)
|
|
107
|
+
`,
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
const result2 = await executeWithSchema(
|
|
111
|
+
"hue_difference",
|
|
112
|
+
"function",
|
|
113
|
+
`
|
|
114
|
+
variable c1: Color.SRGB;
|
|
115
|
+
c1.r = 0; c1.g = 1; c1.b = 0;
|
|
116
|
+
variable c2: Color.SRGB;
|
|
117
|
+
c2.r = 1; c2.g = 0; c2.b = 0;
|
|
118
|
+
hue_difference(c1, c2)
|
|
119
|
+
`,
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
expect(result1.value).toBeCloseTo(result2.value, 3);
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
});
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// In Gamut Check
|
|
2
|
+
// Checks if a color is within the sRGB gamut
|
|
3
|
+
// Reference: Color.js inGamut implementation
|
|
4
|
+
//
|
|
5
|
+
// sRGB gamut is defined by all RGB components being in [0, 1]
|
|
6
|
+
// This is critical for determining if colors can be displayed
|
|
7
|
+
// on standard monitors without clipping.
|
|
8
|
+
//
|
|
9
|
+
// An epsilon tolerance is used to handle floating-point precision
|
|
10
|
+
// issues near the gamut boundary.
|
|
11
|
+
|
|
12
|
+
variable input: List = {input};
|
|
13
|
+
variable color: Color.SRGB = input.get(0).to.srgb();
|
|
14
|
+
|
|
15
|
+
// Default epsilon from Color.js
|
|
16
|
+
variable epsilon: Number = 0.000075;
|
|
17
|
+
if (input.length() > 1) [
|
|
18
|
+
epsilon = input.get(1);
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
// Get RGB values
|
|
22
|
+
variable r: Number = color.r;
|
|
23
|
+
variable g: Number = color.g;
|
|
24
|
+
variable b: Number = color.b;
|
|
25
|
+
|
|
26
|
+
// Check if within gamut bounds with epsilon tolerance
|
|
27
|
+
variable min_bound: Number = 0 - epsilon;
|
|
28
|
+
variable max_bound: Number = 1 + epsilon;
|
|
29
|
+
|
|
30
|
+
// All channels must be within bounds
|
|
31
|
+
variable r_in: Boolean = r >= min_bound;
|
|
32
|
+
if (r_in) [ r_in = r <= max_bound; ];
|
|
33
|
+
|
|
34
|
+
variable g_in: Boolean = g >= min_bound;
|
|
35
|
+
if (g_in) [ g_in = g <= max_bound; ];
|
|
36
|
+
|
|
37
|
+
variable b_in: Boolean = b >= min_bound;
|
|
38
|
+
if (b_in) [ b_in = b <= max_bound; ];
|
|
39
|
+
|
|
40
|
+
// Return true only if all channels are in gamut
|
|
41
|
+
variable result: Boolean = false;
|
|
42
|
+
if (r_in) [
|
|
43
|
+
if (g_in) [
|
|
44
|
+
if (b_in) [
|
|
45
|
+
result = true;
|
|
46
|
+
];
|
|
47
|
+
];
|
|
48
|
+
];
|
|
49
|
+
|
|
50
|
+
return result;
|
|
51
|
+
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "In Gamut",
|
|
3
|
+
"type": "function",
|
|
4
|
+
"description": "Checks if a color is within the sRGB gamut. Returns true if all RGB components are in [0,1] range, false otherwise. Useful for checking if colors from wider gamuts (P3, OKLab) can be displayed on standard monitors.",
|
|
5
|
+
"keyword": "in_gamut",
|
|
6
|
+
"input": {
|
|
7
|
+
"type": "object",
|
|
8
|
+
"properties": {
|
|
9
|
+
"color": {
|
|
10
|
+
"type": "color",
|
|
11
|
+
"description": "Color to check"
|
|
12
|
+
},
|
|
13
|
+
"epsilon": {
|
|
14
|
+
"type": "number",
|
|
15
|
+
"description": "Tolerance for near-gamut colors (default 0.000075)"
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"script": {
|
|
20
|
+
"type": "/api/v1/core/tokenscript/0/",
|
|
21
|
+
"script": "./in-gamut.tokenscript"
|
|
22
|
+
},
|
|
23
|
+
"requirements": ["/api/v1/core/srgb-color/0/"]
|
|
24
|
+
}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { executeWithSchema } from "@tests/helpers/schema-test-utils";
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
|
+
|
|
4
|
+
describe("In Gamut Function", () => {
|
|
5
|
+
describe("Schema Definition", () => {
|
|
6
|
+
it("should have correct schema structure", async () => {
|
|
7
|
+
const { getBundledSchema } = await import("@tests/helpers/schema-test-utils");
|
|
8
|
+
const schema = await getBundledSchema("in_gamut", "function");
|
|
9
|
+
|
|
10
|
+
expect(schema.name).toBe("In Gamut");
|
|
11
|
+
expect(schema.type).toBe("function");
|
|
12
|
+
expect((schema as any).keyword).toBe("in_gamut");
|
|
13
|
+
});
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
describe("Basic Checks", () => {
|
|
17
|
+
it("should return true for black (0,0,0)", async () => {
|
|
18
|
+
const result = await executeWithSchema(
|
|
19
|
+
"in_gamut",
|
|
20
|
+
"function",
|
|
21
|
+
`
|
|
22
|
+
variable c: Color.SRGB;
|
|
23
|
+
c.r = 0; c.g = 0; c.b = 0;
|
|
24
|
+
in_gamut(c)
|
|
25
|
+
`,
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
expect(result.value).toBe(true);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it("should return true for white (1,1,1)", async () => {
|
|
32
|
+
const result = await executeWithSchema(
|
|
33
|
+
"in_gamut",
|
|
34
|
+
"function",
|
|
35
|
+
`
|
|
36
|
+
variable c: Color.SRGB;
|
|
37
|
+
c.r = 1; c.g = 1; c.b = 1;
|
|
38
|
+
in_gamut(c)
|
|
39
|
+
`,
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
expect(result.value).toBe(true);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it("should return true for mid-gray (0.5,0.5,0.5)", async () => {
|
|
46
|
+
const result = await executeWithSchema(
|
|
47
|
+
"in_gamut",
|
|
48
|
+
"function",
|
|
49
|
+
`
|
|
50
|
+
variable c: Color.SRGB;
|
|
51
|
+
c.r = 0.5; c.g = 0.5; c.b = 0.5;
|
|
52
|
+
in_gamut(c)
|
|
53
|
+
`,
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
expect(result.value).toBe(true);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it("should return true for primary red (1,0,0)", async () => {
|
|
60
|
+
const result = await executeWithSchema(
|
|
61
|
+
"in_gamut",
|
|
62
|
+
"function",
|
|
63
|
+
`
|
|
64
|
+
variable c: Color.SRGB;
|
|
65
|
+
c.r = 1; c.g = 0; c.b = 0;
|
|
66
|
+
in_gamut(c)
|
|
67
|
+
`,
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
expect(result.value).toBe(true);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
describe("Out of Gamut Detection", () => {
|
|
75
|
+
it("should return false for negative R", async () => {
|
|
76
|
+
const result = await executeWithSchema(
|
|
77
|
+
"in_gamut",
|
|
78
|
+
"function",
|
|
79
|
+
`
|
|
80
|
+
variable c: Color.SRGB;
|
|
81
|
+
c.r = -0.1; c.g = 0.5; c.b = 0.5;
|
|
82
|
+
in_gamut(c)
|
|
83
|
+
`,
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
expect(result.value).toBe(false);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it("should return false for R > 1", async () => {
|
|
90
|
+
const result = await executeWithSchema(
|
|
91
|
+
"in_gamut",
|
|
92
|
+
"function",
|
|
93
|
+
`
|
|
94
|
+
variable c: Color.SRGB;
|
|
95
|
+
c.r = 1.1; c.g = 0.5; c.b = 0.5;
|
|
96
|
+
in_gamut(c)
|
|
97
|
+
`,
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
expect(result.value).toBe(false);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it("should return false for negative G", async () => {
|
|
104
|
+
const result = await executeWithSchema(
|
|
105
|
+
"in_gamut",
|
|
106
|
+
"function",
|
|
107
|
+
`
|
|
108
|
+
variable c: Color.SRGB;
|
|
109
|
+
c.r = 0.5; c.g = -0.05; c.b = 0.5;
|
|
110
|
+
in_gamut(c)
|
|
111
|
+
`,
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
expect(result.value).toBe(false);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it("should return false for B > 1", async () => {
|
|
118
|
+
const result = await executeWithSchema(
|
|
119
|
+
"in_gamut",
|
|
120
|
+
"function",
|
|
121
|
+
`
|
|
122
|
+
variable c: Color.SRGB;
|
|
123
|
+
c.r = 0.5; c.g = 0.5; c.b = 1.2;
|
|
124
|
+
in_gamut(c)
|
|
125
|
+
`,
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
expect(result.value).toBe(false);
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
describe("Epsilon Tolerance", () => {
|
|
133
|
+
it("should return true for values just within epsilon", async () => {
|
|
134
|
+
// Default epsilon is 0.000075
|
|
135
|
+
const result = await executeWithSchema(
|
|
136
|
+
"in_gamut",
|
|
137
|
+
"function",
|
|
138
|
+
`
|
|
139
|
+
variable c: Color.SRGB;
|
|
140
|
+
c.r = 1.00005; c.g = 0.5; c.b = 0.5;
|
|
141
|
+
in_gamut(c)
|
|
142
|
+
`,
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
expect(result.value).toBe(true);
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
it("should return false for values outside epsilon", async () => {
|
|
149
|
+
const result = await executeWithSchema(
|
|
150
|
+
"in_gamut",
|
|
151
|
+
"function",
|
|
152
|
+
`
|
|
153
|
+
variable c: Color.SRGB;
|
|
154
|
+
c.r = 1.001; c.g = 0.5; c.b = 0.5;
|
|
155
|
+
in_gamut(c)
|
|
156
|
+
`,
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
expect(result.value).toBe(false);
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
describe("Edge Cases", () => {
|
|
164
|
+
it("should handle exact boundary values", async () => {
|
|
165
|
+
const result = await executeWithSchema(
|
|
166
|
+
"in_gamut",
|
|
167
|
+
"function",
|
|
168
|
+
`
|
|
169
|
+
variable c: Color.SRGB;
|
|
170
|
+
c.r = 0; c.g = 1; c.b = 0;
|
|
171
|
+
in_gamut(c)
|
|
172
|
+
`,
|
|
173
|
+
);
|
|
174
|
+
|
|
175
|
+
expect(result.value).toBe(true);
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
});
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// interpolate: Blend between two colors in perceptual space
|
|
2
|
+
// Reference: CSS Color Level 4 Color Interpolation
|
|
3
|
+
// Reference: https://www.w3.org/TR/css-color-4/#interpolation
|
|
4
|
+
//
|
|
5
|
+
// Performs linear interpolation in OKLCH space with shortest-path
|
|
6
|
+
// hue interpolation. OKLCH provides perceptually uniform results.
|
|
7
|
+
//
|
|
8
|
+
// Parameters:
|
|
9
|
+
// start - First color (t=0)
|
|
10
|
+
// end - Second color (t=1)
|
|
11
|
+
// t - Interpolation factor [0, 1], default 0.5
|
|
12
|
+
//
|
|
13
|
+
// Input: Any color space (converted to OKLCH internally)
|
|
14
|
+
// Output: OKLCH (working space)
|
|
15
|
+
// To get sRGB: interpolate(start, end, 0.5).to.srgb()
|
|
16
|
+
|
|
17
|
+
variable input: List = {input};
|
|
18
|
+
variable start: Color.OKLCH = input.get(0).to.oklch();
|
|
19
|
+
variable end: Color.OKLCH = input.get(1).to.oklch();
|
|
20
|
+
|
|
21
|
+
// Default to midpoint
|
|
22
|
+
variable t: Number = 0.5;
|
|
23
|
+
if (input.length() > 2) [
|
|
24
|
+
t = input.get(2);
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
// Clamp t to valid range
|
|
28
|
+
if (t < 0) [ t = 0; ];
|
|
29
|
+
if (t > 1) [ t = 1; ];
|
|
30
|
+
|
|
31
|
+
// Interpolate lightness and chroma linearly
|
|
32
|
+
variable result_l: Number = start.l + (end.l - start.l) * t;
|
|
33
|
+
variable result_c: Number = start.c + (end.c - start.c) * t;
|
|
34
|
+
|
|
35
|
+
// Interpolate hue using shortest path
|
|
36
|
+
variable h1: Number = start.h;
|
|
37
|
+
variable h2: Number = end.h;
|
|
38
|
+
variable delta_h: Number = h2 - h1;
|
|
39
|
+
|
|
40
|
+
// Normalize to shortest path around the circle
|
|
41
|
+
if (delta_h > 180) [
|
|
42
|
+
delta_h = delta_h - 360;
|
|
43
|
+
];
|
|
44
|
+
if (delta_h < -180) [
|
|
45
|
+
delta_h = delta_h + 360;
|
|
46
|
+
];
|
|
47
|
+
|
|
48
|
+
variable result_h: Number = h1 + delta_h * t;
|
|
49
|
+
|
|
50
|
+
// Normalize result hue to 0-360
|
|
51
|
+
if (result_h < 0) [ result_h = result_h + 360; ];
|
|
52
|
+
if (result_h >= 360) [ result_h = result_h - 360; ];
|
|
53
|
+
|
|
54
|
+
// Create result
|
|
55
|
+
variable result: Color.OKLCH;
|
|
56
|
+
result.l = result_l;
|
|
57
|
+
result.c = result_c;
|
|
58
|
+
result.h = result_h;
|
|
59
|
+
|
|
60
|
+
return result;
|
|
61
|
+
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "interpolate",
|
|
3
|
+
"type": "function",
|
|
4
|
+
"description": "Interpolates between two colors at a given position in perceptual OKLCH space. Position of 0 returns the first color, 1 returns the second color, 0.5 returns the midpoint. Uses shortest-path hue interpolation for natural color transitions.",
|
|
5
|
+
"keyword": "interpolate",
|
|
6
|
+
"requirements": ["/api/v1/core/srgb-color/0/", "/api/v1/core/oklch-color/0/"],
|
|
7
|
+
"schema": {
|
|
8
|
+
"type": "object",
|
|
9
|
+
"properties": {
|
|
10
|
+
"input": {
|
|
11
|
+
"type": "array",
|
|
12
|
+
"items": [
|
|
13
|
+
{
|
|
14
|
+
"description": "Start color",
|
|
15
|
+
"type": "color"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"description": "End color",
|
|
19
|
+
"type": "color"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"description": "Position (0-1, default 0.5)",
|
|
23
|
+
"type": "number"
|
|
24
|
+
}
|
|
25
|
+
],
|
|
26
|
+
"minItems": 2,
|
|
27
|
+
"maxItems": 3
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"required": ["input"]
|
|
31
|
+
},
|
|
32
|
+
"returns": {
|
|
33
|
+
"type": "color",
|
|
34
|
+
"description": "Interpolated color"
|
|
35
|
+
},
|
|
36
|
+
"script": {
|
|
37
|
+
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
|
|
38
|
+
"script": "./interpolate.tokenscript"
|
|
39
|
+
},
|
|
40
|
+
"examples": [
|
|
41
|
+
{
|
|
42
|
+
"description": "Midpoint between red and blue",
|
|
43
|
+
"input": ["#ff0000", "#0000ff", 0.5],
|
|
44
|
+
"output": "Purple-ish color in OKLCH"
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"description": "Quarter way from black to white",
|
|
48
|
+
"input": ["#000000", "#ffffff", 0.25],
|
|
49
|
+
"output": "Dark gray"
|
|
50
|
+
}
|
|
51
|
+
]
|
|
52
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit tests for the interpolate function
|
|
3
|
+
* Interpolates between colors in perceptual space
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { executeWithSchema, getBundledSchema } from "@tests/helpers/schema-test-utils";
|
|
7
|
+
import { describe, expect, it } from "vitest";
|
|
8
|
+
import type { FunctionSpecification } from "@/bundler/types";
|
|
9
|
+
|
|
10
|
+
describe("interpolate function", () => {
|
|
11
|
+
describe("Schema Definition", () => {
|
|
12
|
+
it("should have correct schema structure", async () => {
|
|
13
|
+
const schema = (await getBundledSchema("interpolate", "function")) as FunctionSpecification;
|
|
14
|
+
|
|
15
|
+
expect(schema.name).toBe("interpolate");
|
|
16
|
+
expect(schema.type).toBe("function");
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
describe("Function Execution", () => {
|
|
21
|
+
it("should return start color at t=0", async () => {
|
|
22
|
+
const result = await executeWithSchema(
|
|
23
|
+
"interpolate",
|
|
24
|
+
"function",
|
|
25
|
+
`
|
|
26
|
+
variable black: Color.SRGB;
|
|
27
|
+
black.r = 0; black.g = 0; black.b = 0;
|
|
28
|
+
variable white: Color.SRGB;
|
|
29
|
+
white.r = 1; white.g = 1; white.b = 1;
|
|
30
|
+
interpolate(black, white, 0).to.srgb()
|
|
31
|
+
`,
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
expect(result).toBeDefined();
|
|
35
|
+
const r = (result as any).value?.r?.value ?? (result as any).value?.r;
|
|
36
|
+
expect(r).toBeCloseTo(0, 1);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it("should return end color at t=1", async () => {
|
|
40
|
+
const result = await executeWithSchema(
|
|
41
|
+
"interpolate",
|
|
42
|
+
"function",
|
|
43
|
+
`
|
|
44
|
+
variable black: Color.SRGB;
|
|
45
|
+
black.r = 0; black.g = 0; black.b = 0;
|
|
46
|
+
variable white: Color.SRGB;
|
|
47
|
+
white.r = 1; white.g = 1; white.b = 1;
|
|
48
|
+
interpolate(black, white, 1).to.srgb()
|
|
49
|
+
`,
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
expect(result).toBeDefined();
|
|
53
|
+
const r = (result as any).value?.r?.value ?? (result as any).value?.r;
|
|
54
|
+
expect(r).toBeCloseTo(1, 1);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it("should return midpoint at t=0.5", async () => {
|
|
58
|
+
const result = await executeWithSchema(
|
|
59
|
+
"interpolate",
|
|
60
|
+
"function",
|
|
61
|
+
`
|
|
62
|
+
variable black: Color.SRGB;
|
|
63
|
+
black.r = 0; black.g = 0; black.b = 0;
|
|
64
|
+
variable white: Color.SRGB;
|
|
65
|
+
white.r = 1; white.g = 1; white.b = 1;
|
|
66
|
+
interpolate(black, white, 0.5).to.srgb()
|
|
67
|
+
`,
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
expect(result).toBeDefined();
|
|
71
|
+
const r = (result as any).value?.r?.value ?? (result as any).value?.r;
|
|
72
|
+
// Should be medium gray
|
|
73
|
+
expect(r).toBeGreaterThan(0.3);
|
|
74
|
+
expect(r).toBeLessThan(0.7);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it("should use default t=0.5", async () => {
|
|
78
|
+
const result = await executeWithSchema(
|
|
79
|
+
"interpolate",
|
|
80
|
+
"function",
|
|
81
|
+
`
|
|
82
|
+
variable black: Color.SRGB;
|
|
83
|
+
black.r = 0; black.g = 0; black.b = 0;
|
|
84
|
+
variable white: Color.SRGB;
|
|
85
|
+
white.r = 1; white.g = 1; white.b = 1;
|
|
86
|
+
interpolate(black, white).to.srgb()
|
|
87
|
+
`,
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
expect(result).toBeDefined();
|
|
91
|
+
const r = (result as any).value?.r?.value ?? (result as any).value?.r;
|
|
92
|
+
expect(r).toBeGreaterThan(0.3);
|
|
93
|
+
expect(r).toBeLessThan(0.7);
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// Invert Color Function
|
|
2
|
+
// Returns the inverse/negative of a color by subtracting each RGB channel from 255
|
|
3
|
+
//
|
|
4
|
+
// Algorithm:
|
|
5
|
+
// R' = 255 - R
|
|
6
|
+
// G' = 255 - G
|
|
7
|
+
// B' = 255 - B
|
|
8
|
+
//
|
|
9
|
+
// Use cases:
|
|
10
|
+
// - Creating negative images
|
|
11
|
+
// - High contrast accessibility variants
|
|
12
|
+
// - Artistic color effects
|
|
13
|
+
//
|
|
14
|
+
// Input: Any color (converted to RGB internally)
|
|
15
|
+
// Output: Color.Rgb with inverted channels
|
|
16
|
+
|
|
17
|
+
variable input: List = {input};
|
|
18
|
+
|
|
19
|
+
// Convert input to RGB (0-255 range)
|
|
20
|
+
variable rgb_color: Color.Rgb = input.get(0).to.rgb();
|
|
21
|
+
|
|
22
|
+
// Invert each channel by subtracting from 255
|
|
23
|
+
variable inverted_r: Number = 255 - rgb_color.r;
|
|
24
|
+
variable inverted_g: Number = 255 - rgb_color.g;
|
|
25
|
+
variable inverted_b: Number = 255 - rgb_color.b;
|
|
26
|
+
|
|
27
|
+
// Create and return the inverted color
|
|
28
|
+
variable inverted_color: Color.Rgb = rgb(inverted_r, inverted_g, inverted_b);
|
|
29
|
+
return inverted_color;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Invert Color",
|
|
3
|
+
"type": "function",
|
|
4
|
+
"description": "Inverts a color by inverting each RGB channel (R' = 255 - R, G' = 255 - G, B' = 255 - B).",
|
|
5
|
+
"keyword": "invert",
|
|
6
|
+
"input": {
|
|
7
|
+
"type": "object",
|
|
8
|
+
"properties": {
|
|
9
|
+
"color": {
|
|
10
|
+
"type": "color",
|
|
11
|
+
"description": "The color to invert."
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"script": {
|
|
16
|
+
"type": "/api/v1/core/tokenscript/0/",
|
|
17
|
+
"script": "./invert-initializer.tokenscript"
|
|
18
|
+
},
|
|
19
|
+
"requirements": ["/api/v1/core/rgb-color/0/"]
|
|
20
|
+
}
|