abachrome 0.1.0 → 0.1.2
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.
- checksums.yaml +4 -4
- data/.envrc +3 -0
- data/README.md +10 -0
- data/Rakefile +15 -0
- data/devenv.lock +88 -17
- data/devenv.nix +2 -1
- data/devenv.yaml +5 -12
- data/lib/abachrome/abc_decimal.rb +201 -7
- data/lib/abachrome/color.rb +88 -1
- data/lib/abachrome/color_mixins/blend.rb +53 -2
- data/lib/abachrome/color_mixins/lighten.rb +49 -2
- data/lib/abachrome/color_mixins/to_colorspace.rb +67 -2
- data/lib/abachrome/color_mixins/to_lrgb.rb +70 -2
- data/lib/abachrome/color_mixins/to_oklab.rb +67 -2
- data/lib/abachrome/color_mixins/to_oklch.rb +60 -2
- data/lib/abachrome/color_mixins/to_srgb.rb +77 -2
- data/lib/abachrome/color_models/hsv.rb +25 -2
- data/lib/abachrome/color_models/lms.rb +34 -0
- data/lib/abachrome/color_models/oklab.rb +19 -2
- data/lib/abachrome/color_models/oklch.rb +42 -2
- data/lib/abachrome/color_models/rgb.rb +28 -2
- data/lib/abachrome/color_models/xyz.rb +28 -0
- data/lib/abachrome/color_space.rb +88 -2
- data/lib/abachrome/converter.rb +56 -2
- data/lib/abachrome/converters/base.rb +69 -2
- data/lib/abachrome/converters/lms_to_lrgb.rb +36 -0
- data/lib/abachrome/converters/lms_to_srgb.rb +23 -0
- data/lib/abachrome/converters/lms_to_xyz.rb +30 -0
- data/lib/abachrome/converters/lrgb_to_lms.rb +0 -0
- data/lib/abachrome/converters/lrgb_to_oklab.rb +28 -2
- data/lib/abachrome/converters/lrgb_to_srgb.rb +27 -2
- data/lib/abachrome/converters/lrgb_to_xyz.rb +29 -0
- data/lib/abachrome/converters/oklab_to_lms.rb +41 -0
- data/lib/abachrome/converters/oklab_to_lrgb.rb +56 -29
- data/lib/abachrome/converters/oklab_to_oklch.rb +31 -2
- data/lib/abachrome/converters/oklab_to_srgb.rb +27 -2
- data/lib/abachrome/converters/oklch_to_lrgb.rb +66 -6
- data/lib/abachrome/converters/oklch_to_oklab.rb +29 -4
- data/lib/abachrome/converters/oklch_to_srgb.rb +26 -2
- data/lib/abachrome/converters/oklch_to_xyz.rb +66 -0
- data/lib/abachrome/converters/srgb_to_lrgb.rb +26 -2
- data/lib/abachrome/converters/srgb_to_oklab.rb +28 -2
- data/lib/abachrome/converters/srgb_to_oklch.rb +27 -2
- data/lib/abachrome/converters/xyz_to_lms.rb +30 -0
- data/lib/abachrome/converters/xyz_to_oklab.rb +38 -0
- data/lib/abachrome/gamut/base.rb +2 -2
- data/lib/abachrome/gamut/p3.rb +2 -2
- data/lib/abachrome/gamut/rec2020.rb +2 -2
- data/lib/abachrome/gamut/srgb.rb +20 -2
- data/lib/abachrome/illuminants/base.rb +2 -2
- data/lib/abachrome/illuminants/d50.rb +2 -2
- data/lib/abachrome/illuminants/d55.rb +2 -2
- data/lib/abachrome/illuminants/d65.rb +2 -2
- data/lib/abachrome/illuminants/d75.rb +2 -2
- data/lib/abachrome/named/css.rb +149 -158
- data/lib/abachrome/outputs/css.rb +2 -2
- data/lib/abachrome/palette.rb +112 -2
- data/lib/abachrome/palette_mixins/interpolate.rb +20 -2
- data/lib/abachrome/palette_mixins/resample.rb +2 -2
- data/lib/abachrome/palette_mixins/stretch_luminance.rb +2 -2
- data/lib/abachrome/parsers/hex.rb +2 -2
- data/lib/abachrome/to_abcd.rb +10 -2
- data/lib/abachrome/version.rb +2 -2
- data/lib/abachrome.rb +78 -2
- data/logo.png +0 -0
- data/logo.webp +0 -0
- metadata +26 -67
data/lib/abachrome/named/css.rb
CHANGED
@@ -1,164 +1,155 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# Colors courtesy of w3c:
|
4
|
-
# https://www.w3.org/wiki/CSS/Properties/color/keywords
|
5
1
|
#
|
2
|
+
|
6
3
|
module Abachrome
|
7
4
|
module Named
|
8
5
|
module CSS
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
"yellowgreen" => [154, 205, 50]
|
157
|
-
}.freeze
|
158
|
-
|
159
|
-
def method_missing(name, *args, &block)
|
160
|
-
ColorNames[name] || super
|
161
|
-
end
|
6
|
+
def self.aliceblue; [240, 248, 255] end
|
7
|
+
def self.antiquewhite; [250, 235, 215] end
|
8
|
+
def self.aqua; [0, 255, 255] end
|
9
|
+
def self.aquamarine; [127, 255, 212] end
|
10
|
+
def self.azure; [240, 255, 255] end
|
11
|
+
def self.beige; [245, 245, 220] end
|
12
|
+
def self.bisque; [255, 228, 196] end
|
13
|
+
def self.black; [0, 0, 0] end
|
14
|
+
def self.blanchedalmond; [255, 235, 205] end
|
15
|
+
def self.blue; [0, 0, 255] end
|
16
|
+
def self.blueviolet; [138, 43, 226] end
|
17
|
+
def self.brown; [165, 42, 42] end
|
18
|
+
def self.burlywood; [222, 184, 135] end
|
19
|
+
def self.cadetblue; [95, 158, 160] end
|
20
|
+
def self.chartreuse; [127, 255, 0] end
|
21
|
+
def self.chocolate; [210, 105, 30] end
|
22
|
+
def self.coral; [255, 127, 80] end
|
23
|
+
def self.cornflowerblue; [100, 149, 237] end
|
24
|
+
def self.cornsilk; [255, 248, 220] end
|
25
|
+
def self.crimson; [220, 20, 60] end
|
26
|
+
def self.cyan; [0, 255, 255] end
|
27
|
+
def self.darkblue; [0, 0, 139] end
|
28
|
+
def self.darkcyan; [0, 139, 139] end
|
29
|
+
def self.darkgoldenrod; [184, 134, 11] end
|
30
|
+
def self.darkgray; [169, 169, 169] end
|
31
|
+
def self.darkgreen; [0, 100, 0] end
|
32
|
+
def self.darkgrey; [169, 169, 169] end
|
33
|
+
def self.darkkhaki; [189, 183, 107] end
|
34
|
+
def self.darkmagenta; [139, 0, 139] end
|
35
|
+
def self.darkolivegreen; [85, 107, 47] end
|
36
|
+
def self.darkorange; [255, 140, 0] end
|
37
|
+
def self.darkorchid; [153, 50, 204] end
|
38
|
+
def self.darkred; [139, 0, 0] end
|
39
|
+
def self.darksalmon; [233, 150, 122] end
|
40
|
+
def self.darkseagreen; [143, 188, 143] end
|
41
|
+
def self.darkslateblue; [72, 61, 139] end
|
42
|
+
def self.darkslategray; [47, 79, 79] end
|
43
|
+
def self.darkslategrey; [47, 79, 79] end
|
44
|
+
def self.darkturquoise; [0, 206, 209] end
|
45
|
+
def self.darkviolet; [148, 0, 211] end
|
46
|
+
def self.deeppink; [255, 20, 147] end
|
47
|
+
def self.deepskyblue; [0, 191, 255] end
|
48
|
+
def self.dimgray; [105, 105, 105] end
|
49
|
+
def self.dimgrey; [105, 105, 105] end
|
50
|
+
def self.dodgerblue; [30, 144, 255] end
|
51
|
+
def self.firebrick; [178, 34, 34] end
|
52
|
+
def self.floralwhite; [255, 250, 240] end
|
53
|
+
def self.forestgreen; [34, 139, 34] end
|
54
|
+
def self.fuchsia; [255, 0, 255] end
|
55
|
+
def self.gainsboro; [220, 220, 220] end
|
56
|
+
def self.ghostwhite; [248, 248, 255] end
|
57
|
+
def self.gold; [255, 215, 0] end
|
58
|
+
def self.goldenrod; [218, 165, 32] end
|
59
|
+
def self.gray; [128, 128, 128] end
|
60
|
+
def self.green; [0, 128, 0] end
|
61
|
+
def self.greenyellow; [173, 255, 47] end
|
62
|
+
def self.grey; [128, 128, 128] end
|
63
|
+
def self.honeydew; [240, 255, 240] end
|
64
|
+
def self.hotpink; [255, 105, 180] end
|
65
|
+
def self.indianred; [205, 92, 92] end
|
66
|
+
def self.indigo; [75, 0, 130] end
|
67
|
+
def self.ivory; [255, 255, 240] end
|
68
|
+
def self.khaki; [240, 230, 140] end
|
69
|
+
def self.lavender; [230, 230, 250] end
|
70
|
+
def self.lavenderblush; [255, 240, 245] end
|
71
|
+
def self.lawngreen; [124, 252, 0] end
|
72
|
+
def self.lemonchiffon; [255, 250, 205] end
|
73
|
+
def self.lightblue; [173, 216, 230] end
|
74
|
+
def self.lightcoral; [240, 128, 128] end
|
75
|
+
def self.lightcyan; [224, 255, 255] end
|
76
|
+
def self.lightgoldenrodyellow; [250, 250, 210] end
|
77
|
+
def self.lightgray; [211, 211, 211] end
|
78
|
+
def self.lightgreen; [144, 238, 144] end
|
79
|
+
def self.lightgrey; [211, 211, 211] end
|
80
|
+
def self.lightpink; [255, 182, 193] end
|
81
|
+
def self.lightsalmon; [255, 160, 122] end
|
82
|
+
def self.lightseagreen; [32, 178, 170] end
|
83
|
+
def self.lightskyblue; [135, 206, 250] end
|
84
|
+
def self.lightslategray; [119, 136, 153] end
|
85
|
+
def self.lightslategrey; [119, 136, 153] end
|
86
|
+
def self.lightsteelblue; [176, 196, 222] end
|
87
|
+
def self.lightyellow; [255, 255, 224] end
|
88
|
+
def self.lime; [0, 255, 0] end
|
89
|
+
def self.limegreen; [50, 205, 50] end
|
90
|
+
def self.linen; [250, 240, 230] end
|
91
|
+
def self.magenta; [255, 0, 255] end
|
92
|
+
def self.maroon; [128, 0, 0] end
|
93
|
+
def self.mediumaquamarine; [102, 205, 170] end
|
94
|
+
def self.mediumblue; [0, 0, 205] end
|
95
|
+
def self.mediumorchid; [186, 85, 211] end
|
96
|
+
def self.mediumpurple; [147, 112, 219] end
|
97
|
+
def self.mediumseagreen; [60, 179, 113] end
|
98
|
+
def self.mediumslateblue; [123, 104, 238] end
|
99
|
+
def self.mediumspringgreen; [0, 250, 154] end
|
100
|
+
def self.mediumturquoise; [72, 209, 204] end
|
101
|
+
def self.mediumvioletred; [199, 21, 133] end
|
102
|
+
def self.midnightblue; [25, 25, 112] end
|
103
|
+
def self.mintcream; [245, 255, 250] end
|
104
|
+
def self.mistyrose; [255, 228, 225] end
|
105
|
+
def self.moccasin; [255, 228, 181] end
|
106
|
+
def self.navajowhite; [255, 222, 173] end
|
107
|
+
def self.navy; [0, 0, 128] end
|
108
|
+
def self.oldlace; [253, 245, 230] end
|
109
|
+
def self.olive; [128, 128, 0] end
|
110
|
+
def self.olivedrab; [107, 142, 35] end
|
111
|
+
def self.orange; [255, 165, 0] end
|
112
|
+
def self.orangered; [255, 69, 0] end
|
113
|
+
def self.orchid; [218, 112, 214] end
|
114
|
+
def self.palegoldenrod; [238, 232, 170] end
|
115
|
+
def self.palegreen; [152, 251, 152] end
|
116
|
+
def self.paleturquoise; [175, 238, 238] end
|
117
|
+
def self.palevioletred; [219, 112, 147] end
|
118
|
+
def self.papayawhip; [255, 239, 213] end
|
119
|
+
def self.peachpuff; [255, 218, 185] end
|
120
|
+
def self.peru; [205, 133, 63] end
|
121
|
+
def self.pink; [255, 192, 203] end
|
122
|
+
def self.plum; [221, 160, 221] end
|
123
|
+
def self.powderblue; [176, 224, 230] end
|
124
|
+
def self.purple; [128, 0, 128] end
|
125
|
+
def self.red; [255, 0, 0] end
|
126
|
+
def self.rosybrown; [188, 143, 143] end
|
127
|
+
def self.royalblue; [65, 105, 225] end
|
128
|
+
def self.saddlebrown; [139, 69, 19] end
|
129
|
+
def self.salmon; [250, 128, 114] end
|
130
|
+
def self.sandybrown; [244, 164, 96] end
|
131
|
+
def self.seagreen; [46, 139, 87] end
|
132
|
+
def self.seashell; [255, 245, 238] end
|
133
|
+
def self.sienna; [160, 82, 45] end
|
134
|
+
def self.silver; [192, 192, 192] end
|
135
|
+
def self.skyblue; [135, 206, 235] end
|
136
|
+
def self.slateblue; [106, 90, 205] end
|
137
|
+
def self.slategray; [112, 128, 144] end
|
138
|
+
def self.slategrey; [112, 128, 144] end
|
139
|
+
def self.snow; [255, 250, 250] end
|
140
|
+
def self.springgreen; [0, 255, 127] end
|
141
|
+
def self.steelblue; [70, 130, 180] end
|
142
|
+
def self.tan; [210, 180, 140] end
|
143
|
+
def self.teal; [0, 128, 128] end
|
144
|
+
def self.thistle; [216, 191, 216] end
|
145
|
+
def self.tomato; [255, 99, 71] end
|
146
|
+
def self.turquoise; [64, 224, 208] end
|
147
|
+
def self.violet; [238, 130, 238] end
|
148
|
+
def self.wheat; [245, 222, 179] end
|
149
|
+
def self.white; [255, 255, 255] end
|
150
|
+
def self.whitesmoke; [245, 245, 245] end
|
151
|
+
def self.yellow; [255, 255, 0] end
|
152
|
+
def self.yellowgreen; [154, 205, 50] end
|
162
153
|
end
|
163
154
|
end
|
164
|
-
end
|
155
|
+
end
|
data/lib/abachrome/palette.rb
CHANGED
@@ -1,13 +1,26 @@
|
|
1
|
-
#
|
1
|
+
#
|
2
2
|
|
3
3
|
module Abachrome
|
4
4
|
class Palette
|
5
5
|
attr_reader :colors
|
6
6
|
|
7
|
+
# Initializes a new color palette with the given colors.
|
8
|
+
# Automatically converts non-Color objects to Color objects by parsing them as hex values.
|
9
|
+
#
|
10
|
+
# @param colors [Array] An array of colors to include in the palette. Each element can be
|
11
|
+
# either a Color object or a string-convertible object representing a hex color code.
|
12
|
+
# @return [Abachrome::Palette] A new palette instance containing the provided colors.
|
7
13
|
def initialize(colors = [])
|
8
14
|
@colors = colors.map { |c| c.is_a?(Color) ? c : Color.from_hex(c.to_s) }
|
9
15
|
end
|
10
16
|
|
17
|
+
# Adds a color to the palette.
|
18
|
+
# Accepts either an Abachrome::Color object or any object that can be
|
19
|
+
# converted to a string and parsed as a hex color code.
|
20
|
+
#
|
21
|
+
# @param color [Abachrome::Color, String, #to_s] The color to add to the palette.
|
22
|
+
# If not already an Abachrome::Color object, it will be converted using Color.from_hex
|
23
|
+
# @return [Abachrome::Palette] self, enabling method chaining
|
11
24
|
def add(color)
|
12
25
|
color = Color.from_hex(color.to_s) unless color.is_a?(Color)
|
13
26
|
@colors << color
|
@@ -16,64 +29,141 @@ module Abachrome
|
|
16
29
|
|
17
30
|
alias << add
|
18
31
|
|
32
|
+
# Removes the specified color from the palette.
|
33
|
+
#
|
34
|
+
# @param color [Abachrome::Color, Object] The color to be removed from the palette
|
35
|
+
# @return [Abachrome::Palette] Returns self for method chaining
|
19
36
|
def remove(color)
|
20
37
|
@colors.delete(color)
|
21
38
|
self
|
22
39
|
end
|
23
40
|
|
41
|
+
# Clears all colors from the palette.
|
42
|
+
#
|
43
|
+
# This method removes all stored colors in the palette. It provides a way to
|
44
|
+
# reset the palette to an empty state while maintaining the same palette object.
|
45
|
+
#
|
46
|
+
# @return [Abachrome::Palette] Returns self for method chaining
|
24
47
|
def clear
|
25
48
|
@colors.clear
|
26
49
|
self
|
27
50
|
end
|
28
51
|
|
52
|
+
# Returns the number of colors in the palette.
|
53
|
+
#
|
54
|
+
# @return [Integer] the number of colors in the palette
|
29
55
|
def size
|
30
56
|
@colors.size
|
31
57
|
end
|
32
58
|
|
59
|
+
# Returns whether the palette has no colors.
|
60
|
+
#
|
61
|
+
# @return [Boolean] true if the palette contains no colors, false otherwise
|
33
62
|
def empty?
|
34
63
|
@colors.empty?
|
35
64
|
end
|
36
65
|
|
66
|
+
# Yields each color in the palette to the given block.
|
67
|
+
#
|
68
|
+
# @param block [Proc] The block to be executed for each color in the palette.
|
69
|
+
# @yield [Abachrome::Color] Each color in the palette.
|
70
|
+
# @return [Enumerator] Returns an Enumerator if no block is given.
|
71
|
+
# @see Enumerable#each
|
37
72
|
def each(&block)
|
38
73
|
@colors.each(&block)
|
39
74
|
end
|
75
|
+
# Calls the given block once for each color in the palette, passing the color and its index as parameters.
|
76
|
+
#
|
77
|
+
# @example
|
78
|
+
# palette.each_with_index { |color, index| puts "Color #{index}: #{color}" }
|
79
|
+
#
|
80
|
+
# @param block [Proc] The block to be called for each color
|
81
|
+
# @yield [color, index] Yields a color and its index
|
82
|
+
# @yieldparam color [Abachrome::Color] The color at the current position
|
83
|
+
# @yieldparam index [Integer] The index of the current color
|
84
|
+
# @return [Enumerator] If no block is given, returns an Enumerator
|
85
|
+
# @return [Array<Abachrome::Color>] Returns the array of colors if a block is given
|
40
86
|
def each_with_index(&block)
|
41
87
|
@colors.each_with_index(&block)
|
42
88
|
end
|
43
89
|
|
90
|
+
# Maps the palette by applying a block to each color.
|
91
|
+
#
|
92
|
+
# @param block [Proc] A block that takes a color and returns a new color.
|
93
|
+
# @return [Abachrome::Palette] A new palette with the mapped colors.
|
94
|
+
# @example
|
95
|
+
# # Convert all colors in palette to grayscale
|
96
|
+
# palette.map { |color| color.grayscale }
|
44
97
|
def map(&block)
|
45
98
|
self.class.new(@colors.map(&block))
|
46
99
|
end
|
47
100
|
|
101
|
+
# Returns a duplicate of the internal colors array.
|
102
|
+
#
|
103
|
+
# @return [Array<Abachrome::Color>] A duplicate of the palette's color array
|
48
104
|
def to_a
|
49
105
|
@colors.dup
|
50
106
|
end
|
51
107
|
|
108
|
+
# Access a color in the palette at the specified index.
|
109
|
+
#
|
110
|
+
# @param index [Integer] The index of the color to retrieve from the palette
|
111
|
+
# @return [Abachrome::Color, nil] The color at the specified index, or nil if the index is out of bounds
|
52
112
|
def [](index)
|
53
113
|
@colors[index]
|
54
114
|
end
|
55
115
|
|
116
|
+
# Slices the palette to create a new palette with a subset of colors.
|
117
|
+
#
|
118
|
+
# @param start [Integer] The starting index (or range) from which to start the slice.
|
119
|
+
# @param length [Integer, nil] The number of colors to include in the slice. If nil and start is an Integer,
|
120
|
+
# returns a new palette containing the single color at that index. If start is a Range, length is ignored.
|
121
|
+
# @return [Abachrome::Palette] A new palette containing the selected colors.
|
56
122
|
def slice(start, length = nil)
|
57
123
|
new_colors = length ? @colors[start, length] : @colors[start]
|
58
124
|
self.class.new(new_colors)
|
59
125
|
end
|
60
126
|
|
127
|
+
# Returns the first color in the palette.
|
128
|
+
#
|
129
|
+
# @return [Abachrome::Color, nil] The first color in the palette, or nil if the palette is empty.
|
61
130
|
def first
|
62
131
|
@colors.first
|
63
132
|
end
|
64
133
|
|
134
|
+
# Returns the last color in the palette.
|
135
|
+
#
|
136
|
+
# @return [Abachrome::Color, nil] The last color in the palette or nil if palette is empty.
|
65
137
|
def last
|
66
138
|
@colors.last
|
67
139
|
end
|
68
140
|
|
141
|
+
# Returns a new palette with colors sorted by lightness.
|
142
|
+
# This method creates a new palette instance containing the same colors as the current
|
143
|
+
# palette but sorted in ascending order based on their lightness values.
|
144
|
+
#
|
145
|
+
# @return [Abachrome::Palette] a new palette with the same colors sorted by lightness
|
69
146
|
def sort_by_lightness
|
70
147
|
self.class.new(@colors.sort_by(&:lightness))
|
71
148
|
end
|
72
149
|
|
150
|
+
# Returns a new palette with colors sorted by saturation from lowest to highest.
|
151
|
+
# Saturation is determined by the second coordinate (a*) in the OKLAB color space.
|
152
|
+
# Lower values represent less saturated colors, higher values represent more saturated colors.
|
153
|
+
#
|
154
|
+
# @return [Abachrome::Palette] A new palette instance with the same colors sorted by saturation
|
73
155
|
def sort_by_saturation
|
74
156
|
self.class.new(@colors.sort_by { |c| c.to_oklab.coordinates[1] })
|
75
157
|
end
|
76
158
|
|
159
|
+
# Blends all colors in the palette together sequentially at the specified amount.
|
160
|
+
# This method takes each color in the palette and blends it with the accumulated result
|
161
|
+
# of previous blends. It starts with the first color and progressively blends each subsequent
|
162
|
+
# color at the specified blend amount.
|
163
|
+
#
|
164
|
+
# @param amount [Float] The blend amount to use between each color pair, between 0.0 and 1.0.
|
165
|
+
# Defaults to 0.5 (equal blend).
|
166
|
+
# @return [Abachrome::Color, nil] The final blended color result, or nil if the palette is empty.
|
77
167
|
def blend_all(amount = 0.5)
|
78
168
|
return nil if empty?
|
79
169
|
|
@@ -84,6 +174,13 @@ module Abachrome
|
|
84
174
|
result
|
85
175
|
end
|
86
176
|
|
177
|
+
# Calculates the average color of the palette by finding the centroid in OKLAB space.
|
178
|
+
# This method converts each color in the palette to OKLAB coordinates,
|
179
|
+
# calculates the arithmetic mean of these coordinates, and creates a new
|
180
|
+
# color from the average values. Alpha values are also averaged.
|
181
|
+
#
|
182
|
+
# @return [Abachrome::Color, nil] The average color of all colors in the palette,
|
183
|
+
# or nil if the palette is empty
|
87
184
|
def average
|
88
185
|
return nil if empty?
|
89
186
|
|
@@ -100,6 +197,16 @@ module Abachrome
|
|
100
197
|
)
|
101
198
|
end
|
102
199
|
|
200
|
+
# Converts the colors in the palette to CSS-formatted strings.
|
201
|
+
#
|
202
|
+
# The format of the output can be specified with the format parameter.
|
203
|
+
#
|
204
|
+
# @param format [Symbol] The format to use for the CSS color strings.
|
205
|
+
# :hex - Outputs colors in hexadecimal format (e.g., "#RRGGBB")
|
206
|
+
# :rgb - Outputs colors in rgb() function format
|
207
|
+
# :oklab - Outputs colors in oklab() function format
|
208
|
+
# When any other value is provided, a default format is used.
|
209
|
+
# @return [Array<String>] An array of CSS-formatted color strings
|
103
210
|
def to_css(format: :hex)
|
104
211
|
to_a.map do |color|
|
105
212
|
case format
|
@@ -115,6 +222,9 @@ module Abachrome
|
|
115
222
|
end
|
116
223
|
end
|
117
224
|
|
225
|
+
# Returns a string representation of the palette for inspection purposes.
|
226
|
+
#
|
227
|
+
# @return [String] A string containing the class name and a list of colors in the palette
|
118
228
|
def inspect
|
119
229
|
"#<#{self.class} colors=#{@colors.map(&:to_s)}>"
|
120
230
|
end
|
@@ -128,4 +238,4 @@ module Abachrome
|
|
128
238
|
include mixin_module
|
129
239
|
end
|
130
240
|
end
|
131
|
-
end
|
241
|
+
end
|
@@ -1,4 +1,22 @@
|
|
1
|
-
#
|
1
|
+
# Abachrome::PaletteMixins::Interpolate - Color palette interpolation functionality
|
2
|
+
#
|
3
|
+
# This mixin provides methods for interpolating between adjacent colors in a palette to create
|
4
|
+
# smooth color transitions and gradients. The interpolation process inserts new colors between
|
5
|
+
# existing palette colors by blending them at calculated intervals, creating smoother color
|
6
|
+
# progressions ideal for gradients, color ramps, and visual transitions.
|
7
|
+
#
|
8
|
+
# Key features:
|
9
|
+
# - Insert specified number of interpolated colors between each adjacent color pair
|
10
|
+
# - Both non-destructive (interpolate) and destructive (interpolate!) variants
|
11
|
+
# - Uses color blending in the current color space for smooth transitions
|
12
|
+
# - Maintains original colors as anchor points in the interpolated result
|
13
|
+
# - High-precision decimal arithmetic for accurate color calculations
|
14
|
+
# - Preserves alpha values during interpolation process
|
15
|
+
#
|
16
|
+
# The mixin includes both immutable methods that return new palette instances and mutable
|
17
|
+
# methods that modify the current palette object in place, providing flexibility for
|
18
|
+
# different use cases and performance requirements. Interpolation is essential for creating
|
19
|
+
# smooth color gradients and ensuring adequate color resolution in palette-based applications.
|
2
20
|
|
3
21
|
module Abachrome
|
4
22
|
module PaletteMixins
|
@@ -28,4 +46,4 @@ module Abachrome
|
|
28
46
|
end
|
29
47
|
end
|
30
48
|
end
|
31
|
-
end
|
49
|
+
end
|