abachrome 0.1.5 → 0.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.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/abachrome.gemspec +1 -0
  3. data/devenv.nix +1 -1
  4. data/lib/abachrome/abc_decimal.rb +42 -35
  5. data/lib/abachrome/color.rb +61 -10
  6. data/lib/abachrome/color_mixins/blend.rb +7 -5
  7. data/lib/abachrome/color_mixins/harmonies.rb +187 -0
  8. data/lib/abachrome/color_mixins/lighten.rb +8 -6
  9. data/lib/abachrome/color_mixins/spectral_mix.rb +70 -0
  10. data/lib/abachrome/color_mixins/to_colorspace.rb +10 -8
  11. data/lib/abachrome/color_mixins/to_grayscale.rb +87 -0
  12. data/lib/abachrome/color_mixins/to_lms.rb +106 -0
  13. data/lib/abachrome/color_mixins/to_lrgb.rb +14 -12
  14. data/lib/abachrome/color_mixins/to_oklab.rb +16 -14
  15. data/lib/abachrome/color_mixins/to_oklch.rb +12 -10
  16. data/lib/abachrome/color_mixins/to_srgb.rb +17 -15
  17. data/lib/abachrome/color_mixins/to_xyz.rb +106 -0
  18. data/lib/abachrome/color_mixins/wcag.rb +126 -0
  19. data/lib/abachrome/color_models/cmyk.rb +160 -0
  20. data/lib/abachrome/color_models/hsv.rb +5 -3
  21. data/lib/abachrome/color_models/lms.rb +3 -1
  22. data/lib/abachrome/color_models/oklab.rb +3 -1
  23. data/lib/abachrome/color_models/oklch.rb +6 -4
  24. data/lib/abachrome/color_models/rgb.rb +4 -2
  25. data/lib/abachrome/color_models/xyz.rb +11 -1
  26. data/lib/abachrome/color_models/yiq.rb +37 -0
  27. data/lib/abachrome/color_space.rb +28 -14
  28. data/lib/abachrome/converter.rb +10 -8
  29. data/lib/abachrome/converters/base.rb +13 -11
  30. data/lib/abachrome/converters/cmyk_to_srgb.rb +42 -0
  31. data/lib/abachrome/converters/lms_to_lrgb.rb +5 -3
  32. data/lib/abachrome/converters/lms_to_oklab.rb +28 -0
  33. data/lib/abachrome/converters/lms_to_srgb.rb +6 -4
  34. data/lib/abachrome/converters/lms_to_xyz.rb +5 -3
  35. data/lib/abachrome/converters/lrgb_to_lms.rb +29 -1
  36. data/lib/abachrome/converters/lrgb_to_oklab.rb +5 -3
  37. data/lib/abachrome/converters/lrgb_to_srgb.rb +6 -4
  38. data/lib/abachrome/converters/lrgb_to_xyz.rb +5 -3
  39. data/lib/abachrome/converters/oklab_to_lms.rb +9 -7
  40. data/lib/abachrome/converters/oklab_to_lrgb.rb +7 -7
  41. data/lib/abachrome/converters/oklab_to_oklch.rb +4 -2
  42. data/lib/abachrome/converters/oklab_to_srgb.rb +4 -2
  43. data/lib/abachrome/converters/oklab_to_xyz.rb +29 -0
  44. data/lib/abachrome/converters/oklch_to_lms.rb +28 -0
  45. data/lib/abachrome/converters/oklch_to_lrgb.rb +5 -3
  46. data/lib/abachrome/converters/oklch_to_oklab.rb +5 -3
  47. data/lib/abachrome/converters/oklch_to_srgb.rb +6 -4
  48. data/lib/abachrome/converters/oklch_to_xyz.rb +6 -4
  49. data/lib/abachrome/converters/srgb_to_cmyk.rb +64 -0
  50. data/lib/abachrome/converters/srgb_to_lms.rb +29 -0
  51. data/lib/abachrome/converters/srgb_to_lrgb.rb +5 -3
  52. data/lib/abachrome/converters/srgb_to_oklab.rb +4 -2
  53. data/lib/abachrome/converters/srgb_to_oklch.rb +5 -3
  54. data/lib/abachrome/converters/srgb_to_xyz.rb +30 -0
  55. data/lib/abachrome/converters/srgb_to_yiq.rb +49 -0
  56. data/lib/abachrome/converters/xyz_to_lms.rb +5 -3
  57. data/lib/abachrome/converters/xyz_to_lrgb.rb +33 -0
  58. data/lib/abachrome/converters/xyz_to_oklab.rb +5 -3
  59. data/lib/abachrome/converters/xyz_to_srgb.rb +30 -0
  60. data/lib/abachrome/converters/yiq_to_srgb.rb +47 -0
  61. data/lib/abachrome/floatify.rb +282 -0
  62. data/lib/abachrome/gamut/base.rb +3 -3
  63. data/lib/abachrome/gamut/p3.rb +3 -3
  64. data/lib/abachrome/gamut/rec2020.rb +2 -2
  65. data/lib/abachrome/gamut/srgb.rb +4 -2
  66. data/lib/abachrome/illuminants/base.rb +2 -2
  67. data/lib/abachrome/illuminants/d50.rb +2 -2
  68. data/lib/abachrome/illuminants/d55.rb +2 -2
  69. data/lib/abachrome/illuminants/d65.rb +2 -2
  70. data/lib/abachrome/illuminants/d75.rb +2 -2
  71. data/lib/abachrome/named/css.rb +149 -149
  72. data/lib/abachrome/named/tailwind.rb +265 -265
  73. data/lib/abachrome/outputs/css.rb +2 -2
  74. data/lib/abachrome/palette.rb +26 -25
  75. data/lib/abachrome/palette_mixins/interpolate.rb +3 -1
  76. data/lib/abachrome/palette_mixins/resample.rb +2 -2
  77. data/lib/abachrome/palette_mixins/stretch_luminance.rb +2 -2
  78. data/lib/abachrome/parsers/css.rb +86 -71
  79. data/lib/abachrome/parsers/hex.rb +2 -2
  80. data/lib/abachrome/parsers/tailwind.rb +8 -8
  81. data/lib/abachrome/spectral.rb +277 -0
  82. data/lib/abachrome/to_abcd.rb +4 -4
  83. data/lib/abachrome/version.rb +2 -2
  84. data/lib/abachrome.rb +66 -10
  85. metadata +41 -3
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Abachrome::ColorMixins::Lighten - Color lightness adjustment functionality
2
4
  #
3
5
  # This mixin provides methods for adjusting the lightness of colors by manipulating
@@ -23,7 +25,7 @@ module Abachrome
23
25
  # This method works by extracting the L (lightness) component from the OKLab
24
26
  # representation of the color and increasing it by the given amount, ensuring
25
27
  # the result stays within the valid range of [0, 1].
26
- #
28
+ #
27
29
  # @param amount [Numeric] The amount to increase the lightness by, as a decimal
28
30
  # value between 0 and 1. Defaults to 0.1 (10% increase).
29
31
  # @return [Abachrome::Color] A new Color instance with increased lightness.
@@ -46,7 +48,7 @@ module Abachrome
46
48
  # Increases the lightness of the color by the specified amount and modifies the current color object.
47
49
  # This method changes the color in-place, mutating the current object. The color
48
50
  # is converted to a lightness-based color space if needed to perform the operation.
49
- #
51
+ #
50
52
  # @param amount [Float] The amount to increase the lightness by, as a decimal value
51
53
  # between 0 and 1. Default is 0.1 (10% increase).
52
54
  # @return [Abachrome::Color] Returns self for method chaining.
@@ -59,10 +61,10 @@ module Abachrome
59
61
  end
60
62
 
61
63
  # Darkens a color by decreasing its lightness value.
62
- #
64
+ #
63
65
  # This method is effectively a convenience wrapper around the {#lighten} method,
64
66
  # passing a negative amount value to decrease the lightness instead of increasing it.
65
- #
67
+ #
66
68
  # @param amount [Float] The amount to darken the color by, between 0 and 1.
67
69
  # Defaults to 0.1 (10% darker).
68
70
  # @return [Color] A new color instance with decreased lightness.
@@ -73,7 +75,7 @@ module Abachrome
73
75
 
74
76
  # Decreases the lightness value of the color by the specified amount.
75
77
  # Modifies the color in place.
76
- #
78
+ #
77
79
  # @param amount [Float] The amount to darken the color by, as a value between 0 and 1.
78
80
  # Defaults to 0.1 (10% darker).
79
81
  # @return [Abachrome::Color] Returns self with the modified lightness value.
@@ -85,4 +87,4 @@ module Abachrome
85
87
  end
86
88
  end
87
89
 
88
- # Copyright (c) 2025 Durable Programming, LLC. All rights reserved.
90
+ # Copyright (c) 2025 Durable Programming, LLC. All rights reserved.
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Abachrome::ColorMixins::SpectralMix - Kubelka-Munk spectral color mixing
4
+ #
5
+ # This mixin adds spectral mixing capabilities to Color objects using the
6
+ # Kubelka-Munk theory for realistic paint-like color mixing.
7
+ #
8
+ # Unlike simple RGB blending or interpolation in perceptual color spaces,
9
+ # spectral mixing simulates how real pigments interact with light through
10
+ # absorption and scattering. This produces more realistic results, especially
11
+ # when mixing complementary colors.
12
+ #
13
+ # Key features:
14
+ # - Physics-based color mixing using Kubelka-Munk theory
15
+ # - Avoids muddy browns when mixing complementary colors
16
+ # - Supports tinting strength for different pigment concentrations
17
+ # - More realistic than linear RGB or LAB interpolation
18
+
19
+ module Abachrome
20
+ module ColorMixins
21
+ module SpectralMix
22
+ # Mix this color with another color using Kubelka-Munk spectral mixing.
23
+ #
24
+ # This method produces more realistic color mixing than simple RGB or LAB
25
+ # interpolation by simulating how real pigments absorb and scatter light.
26
+ #
27
+ # @param other [Abachrome::Color] The color to mix with
28
+ # @param amount [Float] The mix ratio, between 0 and 1. 0.5 means equal mixing.
29
+ # Values closer to 0 favor this color, values closer to 1 favor the other color.
30
+ # @param tinting_strength_self [Float] Tinting strength of this color (default: 1.0)
31
+ # Higher values mean stronger pigment concentration
32
+ # @param tinting_strength_other [Float] Tinting strength of other color (default: 1.0)
33
+ # @return [Abachrome::Color] A new color representing the spectral mix
34
+ #
35
+ # @example Mix red and blue equally
36
+ # red = Abachrome.from_rgb(1, 0, 0)
37
+ # blue = Abachrome.from_rgb(0, 0, 1)
38
+ # purple = red.spectral_mix(blue, 0.5)
39
+ #
40
+ # @example Mix with 25% of blue
41
+ # mostly_red = red.spectral_mix(blue, 0.25)
42
+ #
43
+ # @example Mix with different tinting strengths
44
+ # # Stronger blue pigment
45
+ # purple = red.spectral_mix(blue, 0.5, tinting_strength_other: 2.0)
46
+ def spectral_mix(other, amount = 0.5, tinting_strength_self: 1.0, tinting_strength_other: 1.0)
47
+ require_relative "../spectral"
48
+
49
+ # Convert amount to weights
50
+ # amount = 0 means 100% self, 0% other
51
+ # amount = 0.5 means 50% self, 50% other
52
+ # amount = 1 means 0% self, 100% other
53
+ weight_self = 1.0 - amount.to_f
54
+ weight_other = amount.to_f
55
+
56
+ colors = [
57
+ { color: self, weight: weight_self },
58
+ { color: other, weight: weight_other }
59
+ ]
60
+
61
+ tinting_strengths = {
62
+ self => tinting_strength_self.to_f,
63
+ other => tinting_strength_other.to_f
64
+ }
65
+
66
+ Spectral.mix(colors, tinting_strengths: tinting_strengths)
67
+ end
68
+ end
69
+ end
70
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Abachrome::ColorMixins::ToColorspace - Color space conversion functionality
2
4
  #
3
5
  # This mixin provides methods for converting colors between different color spaces within
@@ -20,11 +22,11 @@ module Abachrome
20
22
  module ColorMixins
21
23
  module ToColorspace
22
24
  # Converts the current color to the specified target color space.
23
- #
25
+ #
24
26
  # This method transforms the current color into an equivalent color in a different
25
27
  # color space. If the target space is the same as the current color space, no
26
28
  # conversion is performed and the current color is returned.
27
- #
29
+ #
28
30
  # @param target_space [Abachrome::ColorSpace] The target color space to convert to
29
31
  # @return [Abachrome::Color] A new color object in the target color space, or self
30
32
  # if the target space is the same as the current color space
@@ -37,7 +39,7 @@ module Abachrome
37
39
  # Converts the color object to the specified target color space in-place.
38
40
  # This method modifies the current object by changing its color space and
39
41
  # coordinates to match the target color space.
40
- #
42
+ #
41
43
  # @param target_space [Abachrome::ColorSpace] The color space to convert to
42
44
  # @return [Abachrome::Color] Returns self with modified color space and coordinates
43
45
  # @see #to_color_space The non-destructive version that returns a new color object
@@ -51,7 +53,7 @@ module Abachrome
51
53
  end
52
54
 
53
55
  # Convert this color to a different color space.
54
- #
56
+ #
55
57
  # @param space_name [String, Symbol] The name of the target color space to convert to.
56
58
  # @return [Abachrome::Color] A new Color object in the specified color space.
57
59
  # @example
@@ -64,7 +66,7 @@ module Abachrome
64
66
  end
65
67
 
66
68
  # Converts this color to the specified color space in place.
67
- #
69
+ #
68
70
  # @param space_name [String, Symbol] The name or identifier of the target color space to convert to.
69
71
  # @return [Abachrome::Color] Returns self with its values converted to the specified color space.
70
72
  # @raise [Abachrome::ColorSpaceNotFoundError] If the specified color space is not registered.
@@ -77,7 +79,7 @@ module Abachrome
77
79
  end
78
80
 
79
81
  # Convert a color to a specified color space.
80
- #
82
+ #
81
83
  # @param space_name [Symbol, String] The name of the color space to convert to.
82
84
  # @return [Abachrome::Color] A new Color instance in the specified color space.
83
85
  # @example
@@ -88,7 +90,7 @@ module Abachrome
88
90
  end
89
91
 
90
92
  # Converts the color to the specified color space and mutates the current object.
91
- #
93
+ #
92
94
  # @param space_name [Symbol, String] The target color space to convert to (e.g., :oklch, :rgb, :lab)
93
95
  # @return [Abachrome::Color] Returns self after conversion
94
96
  # @see #convert_to!
@@ -102,4 +104,4 @@ module Abachrome
102
104
  end
103
105
  end
104
106
 
105
- # Copyright (c) 2025 Durable Programming, LLC. All rights reserved.
107
+ # Copyright (c) 2025 Durable Programming, LLC. All rights reserved.
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Abachrome::ColorMixins::ToGrayscale - Grayscale conversion mixin
4
+ #
5
+ # This mixin provides methods for converting colors to grayscale using various
6
+ # standard luma calculations. It supports both legacy Rec. 601 (SDTV) and modern
7
+ # Rec. 709 (HDTV) coefficients for accurate grayscale conversion based on human
8
+ # eye sensitivity.
9
+ #
10
+ # Key features:
11
+ # - Rec. 601 luma: Y = 0.299R + 0.587G + 0.114B (NTSC/SDTV standard)
12
+ # - Rec. 709 luma: Y = 0.2126R + 0.7152G + 0.0722B (HDTV standard)
13
+ # - Maintains alpha channel during conversion
14
+ # - Uses BigDecimal for precise calculations
15
+ #
16
+ # This is essential for image processing, accessibility checks, and any application
17
+ # that needs perceptually accurate grayscale conversion rather than simple averaging.
18
+
19
+ module Abachrome
20
+ module ColorMixins
21
+ module ToGrayscale
22
+ # Converts the color to grayscale using Rec. 601 luma coefficients (legacy NTSC standard).
23
+ # This is the same calculation used in the YIQ color space's Y component.
24
+ #
25
+ # @return [Abachrome::Color] A grayscale version of the color in sRGB space
26
+ def to_grayscale_601
27
+ rgb_color = to_srgb
28
+ r, g, b = rgb_color.coordinates
29
+
30
+ # Rec. 601 luma: Y = 0.299R + 0.587G + 0.114B
31
+ luma = (AD("0.299") * r) + (AD("0.587") * g) + (AD("0.114") * b)
32
+
33
+ Color.from_rgb(luma, luma, luma, alpha)
34
+ end
35
+
36
+ # Converts the color to grayscale using Rec. 709 luma coefficients (HDTV standard).
37
+ #
38
+ # @return [Abachrome::Color] A grayscale version of the color in sRGB space
39
+ def to_grayscale_709
40
+ rgb_color = to_srgb
41
+ r, g, b = rgb_color.coordinates
42
+
43
+ # Rec. 709 luma: Y = 0.2126R + 0.7152G + 0.0722B
44
+ luma = (AD("0.2126") * r) + (AD("0.7152") * g) + (AD("0.0722") * b)
45
+
46
+ Color.from_rgb(luma, luma, luma, alpha)
47
+ end
48
+
49
+ # Converts the color to grayscale using the default Rec. 601 standard.
50
+ # This is an alias for to_grayscale_601 and matches the legacy behavior
51
+ # expected by most image processing applications.
52
+ #
53
+ # @return [Abachrome::Color] A grayscale version of the color in sRGB space
54
+ def to_grayscale
55
+ to_grayscale_601
56
+ end
57
+
58
+ # Calculates the relative luminance (luma) value using Rec. 601 coefficients.
59
+ # This returns just the Y component without creating a new color.
60
+ #
61
+ # @return [AbcDecimal] The luma value in range [0, 1]
62
+ def luma_601
63
+ rgb_color = to_srgb
64
+ r, g, b = rgb_color.coordinates
65
+ (AD("0.299") * r) + (AD("0.587") * g) + (AD("0.114") * b)
66
+ end
67
+
68
+ # Calculates the relative luminance (luma) value using Rec. 709 coefficients.
69
+ # This returns just the Y component without creating a new color.
70
+ #
71
+ # @return [AbcDecimal] The luma value in range [0, 1]
72
+ def luma_709
73
+ rgb_color = to_srgb
74
+ r, g, b = rgb_color.coordinates
75
+ (AD("0.2126") * r) + (AD("0.7152") * g) + (AD("0.0722") * b)
76
+ end
77
+
78
+ # Calculates the relative luminance using the default Rec. 601 standard.
79
+ # Alias for luma_601.
80
+ #
81
+ # @return [AbcDecimal] The luma value in range [0, 1]
82
+ def luma
83
+ luma_601
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,106 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Abachrome::ColorMixins::ToLms - LMS color space conversion functionality
4
+ #
5
+ # This mixin provides methods for converting colors to the LMS color space, which represents
6
+ # the response of the three types of cone cells in the human eye (Long, Medium, Short wavelength
7
+ # sensitivity). LMS serves as an intermediate color space in the OKLAB transformation pipeline
8
+ # and provides a foundation for perceptually uniform color representations.
9
+ #
10
+ # Key features:
11
+ # - Convert colors to LMS with automatic converter lookup
12
+ # - Both non-destructive (to_lms) and destructive (to_lms!) conversion methods
13
+ # - Direct access to LMS components (long, medium, short)
14
+ # - Utility methods for LMS array and value extraction
15
+ # - Optimized to return the same object when no conversion is needed
16
+ # - High-precision decimal arithmetic for accurate color science calculations
17
+ #
18
+ # The LMS color space uses three components: L (long wavelength), M (medium wavelength),
19
+ # and S (short wavelength), representing cone cell responses that bridge the gap between
20
+ # linear RGB and perceptually uniform color spaces like OKLAB.
21
+
22
+ require_relative "../converter"
23
+
24
+ module Abachrome
25
+ module ColorMixins
26
+ module ToLms
27
+ # Converts the current color to the LMS color space.
28
+ #
29
+ # If the color is already in LMS, it returns the color unchanged.
30
+ # Otherwise, it uses the Converter to transform the color to LMS.
31
+ #
32
+ # @return [Abachrome::Color] A new Color object in the LMS color space
33
+ def to_lms
34
+ return self if color_space.name == :lms
35
+
36
+ Converter.convert(self, :lms)
37
+ end
38
+
39
+ # Converts the color to the LMS color space in place.
40
+ # This method transforms the current color into LMS space,
41
+ # modifying the original object by updating its color space
42
+ # and coordinates if not already in LMS.
43
+ #
44
+ # @example
45
+ # color = Abachrome::Color.from_hex("#ff5500")
46
+ # color.to_lms! # Color now uses LMS color space
47
+ #
48
+ # @return [Abachrome::Color] self, with updated color space and coordinates
49
+ def to_lms!
50
+ unless color_space.name == :lms
51
+ lms_color = to_lms
52
+ @color_space = lms_color.color_space
53
+ @coordinates = lms_color.coordinates
54
+ end
55
+ self
56
+ end
57
+
58
+ # Returns the L component (long wavelength) from the LMS color space.
59
+ #
60
+ # The L component represents the response of long-wavelength sensitive cone cells
61
+ # in the human eye, which are most sensitive to red light.
62
+ #
63
+ # @return [AbcDecimal] The L (long wavelength) value from the LMS color space
64
+ def long
65
+ to_lms.coordinates[0]
66
+ end
67
+
68
+ # Returns the M component (medium wavelength) from the LMS color space.
69
+ #
70
+ # The M component represents the response of medium-wavelength sensitive cone cells
71
+ # in the human eye, which are most sensitive to green light.
72
+ #
73
+ # @return [AbcDecimal] The M (medium wavelength) value from the LMS color space
74
+ def medium
75
+ to_lms.coordinates[1]
76
+ end
77
+
78
+ # Returns the S component (short wavelength) from the LMS color space.
79
+ #
80
+ # The S component represents the response of short-wavelength sensitive cone cells
81
+ # in the human eye, which are most sensitive to blue light.
82
+ #
83
+ # @return [AbcDecimal] The S (short wavelength) value from the LMS color space
84
+ def short
85
+ to_lms.coordinates[2]
86
+ end
87
+
88
+ # Returns the LMS color space coordinates for this color.
89
+ #
90
+ # @return [Array<AbcDecimal>] An array of LMS coordinates [L, M, S] representing the color in LMS color space
91
+ def lms_values
92
+ to_lms.coordinates
93
+ end
94
+
95
+ # Returns an array representation of the color's coordinates in the LMS color space.
96
+ #
97
+ # @return [Array<AbcDecimal>] An array containing the coordinates of the color
98
+ # in the LMS color space in the order [L, M, S]
99
+ def lms_array
100
+ to_lms.coordinates
101
+ end
102
+ end
103
+ end
104
+ end
105
+
106
+ # Copyright (c) 2025 Durable Programming, LLC. All rights reserved.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Abachrome::ColorMixins::ToLrgb - Linear RGB color space conversion functionality
2
4
  #
3
5
  # This mixin provides methods for converting colors to the linear RGB (LRGB) color space,
@@ -28,7 +30,7 @@ module Abachrome
28
30
  # which uses a linear relationship between the stored numeric value and
29
31
  # the actual light intensity. If the color is already in the LRGB space,
30
32
  # it returns the current object without conversion.
31
- #
33
+ #
32
34
  # @return [Abachrome::Color] A new color object in the LRGB color space,
33
35
  # or the original object if already in LRGB space
34
36
  def to_lrgb
@@ -39,10 +41,10 @@ module Abachrome
39
41
 
40
42
  # Converts the current color to the linear RGB (LRGB) color space and updates
41
43
  # the receiver's state. If the color is already in LRGB space, this is a no-op.
42
- #
44
+ #
43
45
  # Unlike #to_lrgb which returns a new color instance, this method modifies the
44
46
  # current object by changing its color space and coordinates to the LRGB equivalent.
45
- #
47
+ #
46
48
  # @return [Abachrome::Color] the receiver itself, now in LRGB color space
47
49
  def to_lrgb!
48
50
  unless color_space.name == :lrgb
@@ -54,11 +56,11 @@ module Abachrome
54
56
  end
55
57
 
56
58
  # Returns the linear red component value of the color.
57
- #
59
+ #
58
60
  # This method accesses the first coordinate from the color in linear RGB space.
59
61
  # Linear RGB values differ from standard RGB by using a non-gamma-corrected
60
62
  # linear representation of luminance.
61
- #
63
+ #
62
64
  # @return [AbcDecimal] The linear red component value, typically in range [0, 1]
63
65
  def lred
64
66
  to_lrgb.coordinates[0]
@@ -68,7 +70,7 @@ module Abachrome
68
70
  # linear RGB color space first. Linear RGB uses a different scale than standard
69
71
  # sRGB, with values representing linear light energy rather than gamma-corrected
70
72
  # values.
71
- #
73
+ #
72
74
  # @return [AbcDecimal] The linear green component value from the color's linear
73
75
  # RGB representation
74
76
  def lgreen
@@ -76,17 +78,17 @@ module Abachrome
76
78
  end
77
79
 
78
80
  # Returns the linear blue channel value of this color after conversion to linear RGB color space.
79
- #
81
+ #
80
82
  # This method converts the current color to the linear RGB color space and extracts the blue
81
83
  # component (the third coordinate).
82
- #
84
+ #
83
85
  # @return [AbcDecimal] The linear blue component value, typically in the range [0, 1]
84
86
  def lblue
85
87
  to_lrgb.coordinates[2]
86
88
  end
87
89
 
88
90
  # Returns the coordinates of the color in the linear RGB color space.
89
- #
91
+ #
90
92
  # @return [Array<AbcDecimal>] An array of three AbcDecimal values representing
91
93
  # the red, green, and blue components in linear RGB color space.
92
94
  def lrgb_values
@@ -96,14 +98,14 @@ module Abachrome
96
98
  # Returns an array of sRGB values as integers in the 0-255 range.
97
99
  # This method converts the color to RGB, scales the values to the 0-255 range,
98
100
  # rounds to integers, and ensures they are clamped within the valid range.
99
- #
101
+ #
100
102
  # @return [Array<Integer>] An array of three RGB integer values between 0-255
101
103
  def rgb_array
102
104
  to_rgb.coordinates.map { |c| (c * 255).round.clamp(0, 255) }
103
105
  end
104
106
 
105
107
  # Returns a hexadecimal string representation of the color in RGB format.
106
- #
108
+ #
107
109
  # @return [String] A hexadecimal color code in the format '#RRGGBB' where RR, GG, and BB
108
110
  # are two-digit hexadecimal values for the red, green, and blue components respectively.
109
111
  # @example
@@ -116,4 +118,4 @@ module Abachrome
116
118
  end
117
119
  end
118
120
 
119
- # Copyright (c) 2025 Durable Programming, LLC. All rights reserved.
121
+ # Copyright (c) 2025 Durable Programming, LLC. All rights reserved.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Abachrome::ColorMixins::ToOklab - OKLAB color space conversion functionality
2
4
  #
3
5
  # This mixin provides methods for converting colors to the OKLAB color space, which is a
@@ -23,10 +25,10 @@ module Abachrome
23
25
  module ColorMixins
24
26
  module ToOklab
25
27
  # Converts the current color to the OKLAB color space.
26
- #
28
+ #
27
29
  # If the color is already in OKLAB, it returns the color unchanged.
28
30
  # Otherwise, it uses the Converter to transform the color to OKLAB.
29
- #
31
+ #
30
32
  # @return [Abachrome::Color] A new Color object in the OKLAB color space
31
33
  def to_oklab
32
34
  return self if color_space.name == :oklab
@@ -38,11 +40,11 @@ module Abachrome
38
40
  # This method transforms the current color into OKLAB space,
39
41
  # modifying the original object by updating its color space
40
42
  # and coordinates if not already in OKLAB.
41
- #
43
+ #
42
44
  # @example
43
45
  # color = Abachrome::Color.from_hex("#ff5500")
44
46
  # color.to_oklab! # Color now uses OKLAB color space
45
- #
47
+ #
46
48
  # @return [Abachrome::Color] self, with updated color space and coordinates
47
49
  def to_oklab!
48
50
  unless color_space.name == :oklab
@@ -56,27 +58,27 @@ module Abachrome
56
58
  # Returns the lightness component (L) of the color in the OKLAB color space.
57
59
  # The lightness value ranges from 0 (black) to 1 (white) and represents
58
60
  # the perceived lightness of the color.
59
- #
61
+ #
60
62
  # @return [AbcDecimal] The lightness (L) value from the OKLAB color space
61
63
  def lightness
62
64
  to_oklab.coordinates[0]
63
65
  end
64
66
 
65
67
  # Returns the L (Lightness) component from the OKLAB color space.
66
- #
68
+ #
67
69
  # The L value represents perceptual lightness in the OKLAB color space,
68
70
  # typically ranging from 0 (black) to 1 (white).
69
- #
71
+ #
70
72
  # @return [AbcDecimal] The L (Lightness) component from the OKLAB color space
71
73
  def l
72
74
  to_oklab.coordinates[0]
73
75
  end
74
76
 
75
77
  # Returns the 'a' component from the OKLAB color space (green-red axis).
76
- #
78
+ #
77
79
  # The 'a' component in OKLAB represents the position on the green-red axis,
78
80
  # with negative values being more green and positive values being more red.
79
- #
81
+ #
80
82
  # @return [AbcDecimal] The 'a' component value from the OKLAB color space.
81
83
  # @see #to_oklab For the full conversion to OKLAB color space
82
84
  def a
@@ -84,25 +86,25 @@ module Abachrome
84
86
  end
85
87
 
86
88
  # Returns the B value of the color in OKLAB color space.
87
- #
89
+ #
88
90
  # This method first converts the color to OKLAB color space if needed,
89
91
  # then extracts the B component (blue-yellow axis), which is the third
90
92
  # coordinate in the OKLAB model.
91
- #
93
+ #
92
94
  # @return [AbcDecimal] The B component value in OKLAB color space
93
95
  def b
94
96
  to_oklab.coordinates[2]
95
97
  end
96
98
 
97
99
  # Returns the OKLAB color space coordinates for this color.
98
- #
100
+ #
99
101
  # @return [Array] An array of OKLAB coordinates [L, a, b] representing the color in OKLAB color space
100
102
  def oklab_values
101
103
  to_oklab.coordinates
102
104
  end
103
105
 
104
106
  # Returns an array representation of the color's coordinates in the OKLAB color space.
105
- #
107
+ #
106
108
  # @return [Array<AbcDecimal>] An array containing the coordinates of the color
107
109
  # in the OKLAB color space in the order [L, a, b]
108
110
  def oklab_array
@@ -112,4 +114,4 @@ module Abachrome
112
114
  end
113
115
  end
114
116
 
115
- # Copyright (c) 2025 Durable Programming, LLC. All rights reserved.
117
+ # Copyright (c) 2025 Durable Programming, LLC. All rights reserved.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Abachrome::ColorMixins::ToOklch - OKLCH color space conversion functionality
2
4
  #
3
5
  # This mixin provides methods for converting colors to the OKLCH color space, which is a
@@ -21,12 +23,12 @@ module Abachrome
21
23
  module ColorMixins
22
24
  module ToOklch
23
25
  # Converts the current color to the OKLCH color space.
24
- #
26
+ #
25
27
  # This method transforms the color into the perceptually uniform OKLCH color space.
26
28
  # If the color is already in OKLCH, it returns itself unchanged. If the color is in
27
29
  # OKLAB, it directly converts from OKLAB to OKLCH. For all other color spaces, it
28
30
  # first converts to OKLAB as an intermediate step, then converts to OKLCH.
29
- #
31
+ #
30
32
  # @return [Abachrome::Color] A new Color object in the OKLCH color space
31
33
  def to_oklch
32
34
  return self if color_space.name == :oklch
@@ -44,7 +46,7 @@ module Abachrome
44
46
  # This method transforms the current color to OKLCH color space, modifying
45
47
  # the original object instead of creating a new one. If the color is already
46
48
  # in OKLCH space, no conversion is performed.
47
- #
49
+ #
48
50
  # @return [Abachrome::Color] self, allowing for method chaining
49
51
  def to_oklch!
50
52
  unless color_space.name == :oklch
@@ -58,7 +60,7 @@ module Abachrome
58
60
  # Returns the lightness component of the color in the OKLCH color space.
59
61
  # This method provides direct access to the first coordinate of the OKLCH
60
62
  # representation of the color, which represents perceptual lightness.
61
- #
63
+ #
62
64
  # @return [AbcDecimal] the lightness value in the OKLCH color space,
63
65
  # typically in the range of 0.0 to 1.0, where 0.0 is black and 1.0 is white
64
66
  def lightness
@@ -67,14 +69,14 @@ module Abachrome
67
69
 
68
70
  # Returns the chroma value of the color by converting it to the OKLCH color space.
69
71
  # Chroma represents color intensity or saturation in the OKLCH color space.
70
- #
72
+ #
71
73
  # @return [AbcDecimal] The chroma value (second coordinate) from the OKLCH color space
72
74
  def chroma
73
75
  to_oklch.coordinates[1]
74
76
  end
75
77
 
76
78
  # Returns the hue value of the color in the OKLCH color space.
77
- #
79
+ #
78
80
  # @return [AbcDecimal] The hue component of the color in degrees (0-360)
79
81
  # from the OKLCH color space representation.
80
82
  def hue
@@ -82,7 +84,7 @@ module Abachrome
82
84
  end
83
85
 
84
86
  # Returns the OKLCH coordinates of the color.
85
- #
87
+ #
86
88
  # @return [Array<AbcDecimal>] Array of OKLCH coordinates [lightness, chroma, hue] where:
87
89
  # - lightness: perceptual lightness component (0-1)
88
90
  # - chroma: colorfulness/saturation component
@@ -92,11 +94,11 @@ module Abachrome
92
94
  end
93
95
 
94
96
  # Returns the OKLCH coordinates of the color as an array.
95
- #
97
+ #
96
98
  # Converts the current color to OKLCH color space and returns its coordinates
97
99
  # as an array. The OKLCH color space represents colors using Lightness,
98
100
  # Chroma, and Hue components in a perceptually uniform way.
99
- #
101
+ #
100
102
  # @return [Array<Numeric>] An array containing the OKLCH coordinates [lightness, chroma, hue]
101
103
  def oklch_array
102
104
  to_oklch.coordinates
@@ -105,4 +107,4 @@ module Abachrome
105
107
  end
106
108
  end
107
109
 
108
- # Copyright (c) 2025 Durable Programming, LLC. All rights reserved.
110
+ # Copyright (c) 2025 Durable Programming, LLC. All rights reserved.