unmagic-color 0.1.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.
- checksums.yaml +7 -0
- data/README.md +274 -0
- data/data/rgb.txt +164 -0
- data/lib/unmagic/color/hsl.rb +421 -0
- data/lib/unmagic/color/oklch.rb +433 -0
- data/lib/unmagic/color/rgb/hex.rb +104 -0
- data/lib/unmagic/color/rgb/named.rb +112 -0
- data/lib/unmagic/color/rgb.rb +390 -0
- data/lib/unmagic/color/string/hash_function.rb +316 -0
- data/lib/unmagic/color/util/percentage.rb +143 -0
- data/lib/unmagic/color.rb +402 -0
- data/lib/unmagic_color.rb +3 -0
- metadata +55 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: c7be12ac8d10a2afce0fb4b18e79bd8636f7000e154a6cd55254ef0284498ca4
|
|
4
|
+
data.tar.gz: 55be4881e50f7adad3adcd12dcb85d03c2a35bea2a26cfe6c1db16a0fe567d68
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 9ffad3c4830a9d79c9603fde9a59fcab9714a5cbc7fa91fa2857b2665cea5f3796b7842f89627c24765d9996fd28a80562f4756f7392764ad620f512e3b4d543
|
|
7
|
+
data.tar.gz: dbdfb73585f752f60089658c273b65a69a2189746f8379133db427038af006667589f199e6fd00eeeb6a8dda47142fd5f4aa9c25f1279d1f00864309fbfc0903
|
data/README.md
ADDED
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
# Unmagic Color
|
|
2
|
+
|
|
3
|
+
A comprehensive Ruby color manipulation library with support for RGB, HSL, and OKLCH color spaces. Parse, convert, and manipulate colors with an intuitive API.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
Add this line to your application's Gemfile:
|
|
8
|
+
|
|
9
|
+
```ruby
|
|
10
|
+
gem 'unmagic-color'
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
And then execute:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
bundle install
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Or install it yourself as:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
gem install unmagic-color
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Features
|
|
26
|
+
|
|
27
|
+
- **Multiple Color Spaces**: RGB, HSL, and OKLCH support
|
|
28
|
+
- **Flexible Parsing**: Parse colors from hex, CSS format strings, named colors, or component values
|
|
29
|
+
- **Named Colors**: Support for [X11 color names](https://en.wikipedia.org/wiki/X11_color_names) (red, blue, goldenrod, etc.)
|
|
30
|
+
- **Color Conversions**: Seamlessly convert between color spaces
|
|
31
|
+
- **Color Manipulation**: Lighten, darken, and blend colors
|
|
32
|
+
- **Deterministic Generation**: Generate consistent colors from strings or seeds
|
|
33
|
+
- **Luminance Calculation**: Determine if colors are light or dark
|
|
34
|
+
- **Color Progressions**: Create color scales and palettes
|
|
35
|
+
|
|
36
|
+
## Quick Start
|
|
37
|
+
|
|
38
|
+
```ruby
|
|
39
|
+
require 'unmagic/color'
|
|
40
|
+
|
|
41
|
+
# Parse a color
|
|
42
|
+
color = Unmagic::Color.parse("#FF5733")
|
|
43
|
+
|
|
44
|
+
# Convert to different color spaces
|
|
45
|
+
hsl = color.to_hsl
|
|
46
|
+
oklch = color.to_oklch
|
|
47
|
+
|
|
48
|
+
# Manipulate colors
|
|
49
|
+
lighter = color.lighten(0.2)
|
|
50
|
+
darker = color.darken(0.1)
|
|
51
|
+
|
|
52
|
+
# Check luminance
|
|
53
|
+
color.light? # => false
|
|
54
|
+
color.dark? # => true
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Usage Examples
|
|
58
|
+
|
|
59
|
+
### Parsing Colors
|
|
60
|
+
|
|
61
|
+
```ruby
|
|
62
|
+
# From hex
|
|
63
|
+
color = Unmagic::Color.parse("#FF5733")
|
|
64
|
+
color = Unmagic::Color["#F57"] # Short form
|
|
65
|
+
|
|
66
|
+
# From RGB
|
|
67
|
+
color = Unmagic::Color.parse("rgb(255, 87, 51)")
|
|
68
|
+
color = Unmagic::Color::RGB.new(red: 255, green: 87, blue: 51)
|
|
69
|
+
|
|
70
|
+
# From HSL
|
|
71
|
+
color = Unmagic::Color.parse("hsl(9, 100%, 60%)")
|
|
72
|
+
color = Unmagic::Color::HSL.new(hue: 9, saturation: 100, lightness: 60)
|
|
73
|
+
|
|
74
|
+
# From OKLCH
|
|
75
|
+
color = Unmagic::Color.parse("oklch(0.65 0.15 30)")
|
|
76
|
+
color = Unmagic::Color::OKLCH.new(lightness: 0.65, chroma: 0.15, hue: 30)
|
|
77
|
+
|
|
78
|
+
# From X11 named colors (https://en.wikipedia.org/wiki/X11_color_names)
|
|
79
|
+
color = Unmagic::Color.parse("goldenrod")
|
|
80
|
+
color = Unmagic::Color["red"]
|
|
81
|
+
|
|
82
|
+
# Named colors are case-insensitive and whitespace-tolerant
|
|
83
|
+
color = Unmagic::Color.parse("Golden Rod") # Same as "goldenrod"
|
|
84
|
+
color = Unmagic::Color.parse("DARK SLATE BLUE") # Same as "darkslateblue"
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Converting Between Color Spaces
|
|
88
|
+
|
|
89
|
+
```ruby
|
|
90
|
+
rgb = Unmagic::Color.parse("#FF5733")
|
|
91
|
+
|
|
92
|
+
# Convert to HSL
|
|
93
|
+
hsl = rgb.to_hsl
|
|
94
|
+
puts hsl.hue.to_f # => 9.0
|
|
95
|
+
puts hsl.saturation.to_f # => 100.0
|
|
96
|
+
puts hsl.lightness.to_f # => 60.0
|
|
97
|
+
|
|
98
|
+
# Convert to OKLCH
|
|
99
|
+
oklch = rgb.to_oklch
|
|
100
|
+
|
|
101
|
+
# Convert back to hex
|
|
102
|
+
hex = hsl.to_rgb.to_hex
|
|
103
|
+
puts hex # => "#FF5733"
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Color Manipulation
|
|
107
|
+
|
|
108
|
+
```ruby
|
|
109
|
+
color = Unmagic::Color.parse("#336699")
|
|
110
|
+
|
|
111
|
+
# Make it lighter or darker
|
|
112
|
+
lighter = color.lighten(0.2) # 20% lighter
|
|
113
|
+
darker = color.darken(0.1) # 10% darker
|
|
114
|
+
|
|
115
|
+
# Blend two colors
|
|
116
|
+
red = Unmagic::Color.parse("#FF0000")
|
|
117
|
+
blue = Unmagic::Color.parse("#0000FF")
|
|
118
|
+
purple = red.blend(blue, 0.5) # 50/50 mix
|
|
119
|
+
|
|
120
|
+
# Check if color is light or dark
|
|
121
|
+
if color.light?
|
|
122
|
+
text_color = "#000000" # Use dark text
|
|
123
|
+
else
|
|
124
|
+
text_color = "#FFFFFF" # Use light text
|
|
125
|
+
end
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### HSL-Specific Features
|
|
129
|
+
|
|
130
|
+
```ruby
|
|
131
|
+
hsl = Unmagic::Color::HSL.new(hue: 200, saturation: 70, lightness: 50)
|
|
132
|
+
|
|
133
|
+
# Adjust individual components
|
|
134
|
+
brighter = hsl.lighten(0.15)
|
|
135
|
+
muted = hsl.desaturate(0.3)
|
|
136
|
+
shifted = hsl.adjust_hue(30)
|
|
137
|
+
|
|
138
|
+
# Create color progressions
|
|
139
|
+
palette = hsl.progression(
|
|
140
|
+
steps: 5,
|
|
141
|
+
lightness: [30, 50, 70, 85, 95]
|
|
142
|
+
)
|
|
143
|
+
# => Array of 5 HSL colors with varying lightness
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Generating Colors from Strings
|
|
147
|
+
|
|
148
|
+
Generate consistent, deterministic colors from any string:
|
|
149
|
+
|
|
150
|
+
```ruby
|
|
151
|
+
# Generate from a user ID or name
|
|
152
|
+
color = Unmagic::Color::RGB.derive("user_12345".hash)
|
|
153
|
+
color = Unmagic::Color::HSL.derive("john.doe@example.com".hash)
|
|
154
|
+
|
|
155
|
+
# Customize the output
|
|
156
|
+
color = Unmagic::Color::RGB.derive(
|
|
157
|
+
"project_alpha".hash,
|
|
158
|
+
brightness: 200, # Brighter colors
|
|
159
|
+
saturation: 0.8 # More saturated
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
color = Unmagic::Color::HSL.derive(
|
|
163
|
+
"team_rocket".hash,
|
|
164
|
+
lightness: 60, # Target lightness
|
|
165
|
+
saturation_range: (50..70) # Saturation range
|
|
166
|
+
)
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Advanced: Hash Functions for Color Generation
|
|
170
|
+
|
|
171
|
+
For more control over how strings map to colors, use hash functions:
|
|
172
|
+
|
|
173
|
+
```ruby
|
|
174
|
+
# Use different hash algorithms
|
|
175
|
+
hash_value = Unmagic::Color::String::HashFunction::DJB2.call("username")
|
|
176
|
+
color = Unmagic::Color::RGB.derive(hash_value)
|
|
177
|
+
|
|
178
|
+
# Color-aware hashing (biases toward color names in string)
|
|
179
|
+
hash_value = Unmagic::Color::String::HashFunction::COLOR_AWARE.call("red_team")
|
|
180
|
+
# Will produce a reddish color
|
|
181
|
+
|
|
182
|
+
# Available hash functions:
|
|
183
|
+
# - SUM: Simple, anagrams get same color
|
|
184
|
+
# - DJB2: Good general-purpose distribution
|
|
185
|
+
# - BKDR: Excellent distribution (default)
|
|
186
|
+
# - FNV1A: Maximum variety for sequential strings
|
|
187
|
+
# - SDBM: Good for database IDs
|
|
188
|
+
# - JAVA: Compatible with Java's hashCode
|
|
189
|
+
# - CRC32: Most uniform distribution
|
|
190
|
+
# - MD5: Cryptographic hash (slower)
|
|
191
|
+
# - POSITION: Order-sensitive
|
|
192
|
+
# - PERCEPTUAL: Case-insensitive
|
|
193
|
+
# - COLOR_AWARE: Detects color names
|
|
194
|
+
# - MURMUR3: Fast with excellent distribution
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### Working with Color Components
|
|
198
|
+
|
|
199
|
+
```ruby
|
|
200
|
+
rgb = Unmagic::Color::RGB.new(red: 255, green: 87, blue: 51)
|
|
201
|
+
|
|
202
|
+
# Access components
|
|
203
|
+
puts rgb.red.to_i # => 255
|
|
204
|
+
puts rgb.green.to_i # => 87
|
|
205
|
+
puts rgb.blue.to_i # => 51
|
|
206
|
+
|
|
207
|
+
hsl = Unmagic::Color::HSL.new(hue: 180, saturation: 50, lightness: 60)
|
|
208
|
+
|
|
209
|
+
# Access components
|
|
210
|
+
puts hsl.hue.to_f # => 180.0
|
|
211
|
+
puts hsl.saturation.to_f # => 50.0
|
|
212
|
+
puts hsl.lightness.to_f # => 60.0
|
|
213
|
+
|
|
214
|
+
# Components support arithmetic
|
|
215
|
+
new_hue = hsl.hue + 30 # Shift hue by 30 degrees
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Luminance and Contrast
|
|
219
|
+
|
|
220
|
+
```ruby
|
|
221
|
+
color = Unmagic::Color.parse("#336699")
|
|
222
|
+
|
|
223
|
+
# Get luminance (0.0 = black, 1.0 = white)
|
|
224
|
+
lum = color.luminance # => ~0.2
|
|
225
|
+
|
|
226
|
+
# Check if light or dark
|
|
227
|
+
color.light? # => false
|
|
228
|
+
color.dark? # => true
|
|
229
|
+
|
|
230
|
+
# Choose contrasting text color
|
|
231
|
+
text_color = color.light? ? "#000000" : "#FFFFFF"
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
## Color Spaces
|
|
235
|
+
|
|
236
|
+
### RGB (Red, Green, Blue)
|
|
237
|
+
Standard color space for displays. Values range from 0-255 for each component.
|
|
238
|
+
|
|
239
|
+
```ruby
|
|
240
|
+
Unmagic::Color::RGB.new(red: 255, green: 87, blue: 51)
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### HSL (Hue, Saturation, Lightness)
|
|
244
|
+
Intuitive color space for human-friendly color manipulation.
|
|
245
|
+
- Hue: 0-360 degrees (color wheel position)
|
|
246
|
+
- Saturation: 0-100% (color intensity)
|
|
247
|
+
- Lightness: 0-100% (brightness)
|
|
248
|
+
|
|
249
|
+
```ruby
|
|
250
|
+
Unmagic::Color::HSL.new(hue: 180, saturation: 70, lightness: 50)
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### OKLCH (Lightness, Chroma, Hue)
|
|
254
|
+
Perceptually uniform color space that better matches human color perception.
|
|
255
|
+
|
|
256
|
+
```ruby
|
|
257
|
+
Unmagic::Color::OKLCH.new(lightness: 0.65, chroma: 0.15, hue: 180)
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
## Requirements
|
|
261
|
+
|
|
262
|
+
- Ruby >= 3.0
|
|
263
|
+
|
|
264
|
+
## Development
|
|
265
|
+
|
|
266
|
+
After checking out the repo, run `bundle install` to install dependencies. Then, run `bundle exec rspec` to run the tests.
|
|
267
|
+
|
|
268
|
+
## Contributing
|
|
269
|
+
|
|
270
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/unreasonable-magic/unmagic-color.
|
|
271
|
+
|
|
272
|
+
## License
|
|
273
|
+
|
|
274
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/data/rgb.txt
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
black #000000
|
|
2
|
+
silver #c0c0c0
|
|
3
|
+
gray #808080
|
|
4
|
+
white #ffffff
|
|
5
|
+
maroon #800000
|
|
6
|
+
red #ff0000
|
|
7
|
+
purple #800080
|
|
8
|
+
fuchsia #ff00ff
|
|
9
|
+
green #008000
|
|
10
|
+
lime #00ff00
|
|
11
|
+
olive #808000
|
|
12
|
+
yellow #ffff00
|
|
13
|
+
navy #000080
|
|
14
|
+
blue #0000ff
|
|
15
|
+
teal #008080
|
|
16
|
+
aqua #00ffff
|
|
17
|
+
aliceblue #f0f8ff
|
|
18
|
+
antiquewhite #faebd7
|
|
19
|
+
aqua #00ffff
|
|
20
|
+
aquamarine #7fffd4
|
|
21
|
+
azure #f0ffff
|
|
22
|
+
beige #f5f5dc
|
|
23
|
+
bisque #ffe4c4
|
|
24
|
+
black #000000
|
|
25
|
+
blanchedalmond #ffebcd
|
|
26
|
+
blue #0000ff
|
|
27
|
+
blueviolet #8a2be2
|
|
28
|
+
brown #a52a2a
|
|
29
|
+
burlywood #deb887
|
|
30
|
+
cadetblue #5f9ea0
|
|
31
|
+
chartreuse #7fff00
|
|
32
|
+
chocolate #d2691e
|
|
33
|
+
coral #ff7f50
|
|
34
|
+
cornflowerblue #6495ed
|
|
35
|
+
cornsilk #fff8dc
|
|
36
|
+
crimson #dc143c
|
|
37
|
+
cyan ##00ffff
|
|
38
|
+
darkblue #00008b
|
|
39
|
+
darkcyan #008b8b
|
|
40
|
+
darkgoldenrod #b8860b
|
|
41
|
+
darkgray #a9a9a9
|
|
42
|
+
darkgreen #006400
|
|
43
|
+
darkgrey #a9a9a9
|
|
44
|
+
darkkhaki #bdb76b
|
|
45
|
+
darkmagenta #8b008b
|
|
46
|
+
darkolivegreen #556b2f
|
|
47
|
+
darkorange #ff8c00
|
|
48
|
+
darkorchid #9932cc
|
|
49
|
+
darkred #8b0000
|
|
50
|
+
darksalmon #e9967a
|
|
51
|
+
darkseagreen #8fbc8f
|
|
52
|
+
darkslateblue #483d8b
|
|
53
|
+
darkslategray #2f4f4f
|
|
54
|
+
darkslategrey #2f4f4f
|
|
55
|
+
darkturquoise #00ced1
|
|
56
|
+
darkviolet #9400d3
|
|
57
|
+
deeppink #ff1493
|
|
58
|
+
deepskyblue #00bfff
|
|
59
|
+
dimgray #696969
|
|
60
|
+
dimgrey #696969
|
|
61
|
+
dodgerblue #1e90ff
|
|
62
|
+
firebrick #b22222
|
|
63
|
+
floralwhite #fffaf0
|
|
64
|
+
forestgreen #228b22
|
|
65
|
+
fuchsia #ff00ff
|
|
66
|
+
gainsboro #dcdcdc
|
|
67
|
+
ghostwhite #f8f8ff
|
|
68
|
+
gold #ffd700
|
|
69
|
+
goldenrod #daa520
|
|
70
|
+
gray #808080
|
|
71
|
+
green #008000
|
|
72
|
+
greenyellow #adff2f
|
|
73
|
+
grey #808080
|
|
74
|
+
honeydew #f0fff0
|
|
75
|
+
hotpink #ff69b4
|
|
76
|
+
indianred #cd5c5c
|
|
77
|
+
indigo #4b0082
|
|
78
|
+
ivory #fffff0
|
|
79
|
+
khaki #f0e68c
|
|
80
|
+
lavender #e6e6fa
|
|
81
|
+
lavenderblush #fff0f5
|
|
82
|
+
lawngreen #7cfc00
|
|
83
|
+
lemonchiffon #fffacd
|
|
84
|
+
lightblue #add8e6
|
|
85
|
+
lightcoral #f08080
|
|
86
|
+
lightcyan #e0ffff
|
|
87
|
+
lightgoldenrodyellow #fafad2
|
|
88
|
+
lightgray #d3d3d3
|
|
89
|
+
lightgreen #90ee90
|
|
90
|
+
lightgrey #d3d3d3
|
|
91
|
+
lightpink #ffb6c1
|
|
92
|
+
lightsalmon #ffa07a
|
|
93
|
+
lightseagreen #20b2aa
|
|
94
|
+
lightskyblue #87cefa
|
|
95
|
+
lightslategray #778899
|
|
96
|
+
lightslategrey #778899
|
|
97
|
+
lightsteelblue #b0c4de
|
|
98
|
+
lightyellow #ffffe0
|
|
99
|
+
lime #00ff00
|
|
100
|
+
limegreen #32cd32
|
|
101
|
+
linen #faf0e6
|
|
102
|
+
magenta #ff00ff
|
|
103
|
+
maroon #800000
|
|
104
|
+
mediumaquamarine #66cdaa
|
|
105
|
+
mediumblue #0000cd
|
|
106
|
+
mediumorchid #ba55d3
|
|
107
|
+
mediumpurple #9370db
|
|
108
|
+
mediumseagreen #3cb371
|
|
109
|
+
mediumslateblue #7b68ee
|
|
110
|
+
mediumspringgreen #00fa9a
|
|
111
|
+
mediumturquoise #48d1cc
|
|
112
|
+
mediumvioletred #c71585
|
|
113
|
+
midnightblue #191970
|
|
114
|
+
mintcream #f5fffa
|
|
115
|
+
mistyrose #ffe4e1
|
|
116
|
+
moccasin #ffe4b5
|
|
117
|
+
navajowhite #ffdead
|
|
118
|
+
navy #000080
|
|
119
|
+
oldlace #fdf5e6
|
|
120
|
+
olive #808000
|
|
121
|
+
olivedrab #6b8e23
|
|
122
|
+
orange #ffa500
|
|
123
|
+
orangered #ff4500
|
|
124
|
+
orchid #da70d6
|
|
125
|
+
palegoldenrod #eee8aa
|
|
126
|
+
palegreen #98fb98
|
|
127
|
+
paleturquoise #afeeee
|
|
128
|
+
palevioletred #db7093
|
|
129
|
+
papayawhip #ffefd5
|
|
130
|
+
peachpuff #ffdab9
|
|
131
|
+
peru #cd853f
|
|
132
|
+
pink #ffc0cb
|
|
133
|
+
plum #dda0dd
|
|
134
|
+
powderblue #b0e0e6
|
|
135
|
+
purple #800080
|
|
136
|
+
rebeccapurple #663399
|
|
137
|
+
red #ff0000
|
|
138
|
+
rosybrown #bc8f8f
|
|
139
|
+
royalblue #4169e1
|
|
140
|
+
saddlebrown #8b4513
|
|
141
|
+
salmon #fa8072
|
|
142
|
+
sandybrown #f4a460
|
|
143
|
+
seagreen #2e8b57
|
|
144
|
+
seashell #fff5ee
|
|
145
|
+
sienna #a0522d
|
|
146
|
+
silver #c0c0c0
|
|
147
|
+
skyblue #87ceeb
|
|
148
|
+
slateblue #6a5acd
|
|
149
|
+
slategray #708090
|
|
150
|
+
slategrey #708090
|
|
151
|
+
snow #fffafa
|
|
152
|
+
springgreen #00ff7f
|
|
153
|
+
steelblue #4682b4
|
|
154
|
+
tan #d2b48c
|
|
155
|
+
teal #008080
|
|
156
|
+
thistle #d8bfd8
|
|
157
|
+
tomato #ff6347
|
|
158
|
+
turquoise #40e0d0
|
|
159
|
+
violet #ee82ee
|
|
160
|
+
wheat #f5deb3
|
|
161
|
+
white #ffffff
|
|
162
|
+
whitesmoke #f5f5f5
|
|
163
|
+
yellow #ffff00
|
|
164
|
+
yellowgreen #9acd32
|