Module: Guardrails::HexNormalizer
- Defined in:
- lib/guardrails/hex_normalizer.rb
Class Method Summary collapse
-
.distance(a, b) ⇒ Object
Maximum per-channel (R / G / B) difference between two normalized hex colors, on a 0..255 scale.
-
.normalize(value) ⇒ Object
Normalize a hex color literal for equality comparison: - lowercase - expand 3-char shorthand (#fa3 -> #ffaa33) - strip alpha channel (#ffaa3380 -> #ffaa33) - return non-hex input unchanged (after lowercasing).
Class Method Details
.distance(a, b) ⇒ Object
Maximum per-channel (R / G / B) difference between two normalized hex colors, on a 0..255 scale. Returns nil if either value isn’t a 7-char hex after normalization. Distance 0 = identical color.
33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/guardrails/hex_normalizer.rb', line 33 def distance(a, b) a_norm = normalize(a) b_norm = normalize(b) return nil unless a_norm.length == 7 && a_norm.start_with?("#") return nil unless b_norm.length == 7 && b_norm.start_with?("#") diffs = [ (a_norm[1..2].to_i(16) - b_norm[1..2].to_i(16)).abs, (a_norm[3..4].to_i(16) - b_norm[3..4].to_i(16)).abs, (a_norm[5..6].to_i(16) - b_norm[5..6].to_i(16)).abs ] diffs.max end |
.normalize(value) ⇒ Object
Normalize a hex color literal for equality comparison:
-
lowercase
-
expand 3-char shorthand (#fa3 -> #ffaa33)
-
strip alpha channel (#ffaa3380 -> #ffaa33)
-
return non-hex input unchanged (after lowercasing)
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/guardrails/hex_normalizer.rb', line 12 def normalize(value) v = value.to_s.downcase.strip return v unless v.start_with?("#") case v.length when 4 # #fa3 -> #ffaa33 "#" + v[1..].chars.map { |c| c * 2 }.join when 5 # #fa3a -> #ffaa33 (drop alpha) ("#" + v[1..].chars.map { |c| c * 2 }.join)[0..6] when 7 # #ffaa33 (canonical) v when 9 # #ffaa3380 -> #ffaa33 v[0..6] else v end end |