1 2 3 4 5 6 7 8 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
|
# frozen_string_literal: true
# A \Color object representing YIQ (NTSC) color encoding, where Y is the luma
# (brightness) value, and I (orange-blue) and Q (purple-green) are chrominance.
#
# All values are clamped between 0 and 1 inclusive.
#
# More more details, see [YIQ][wikiyiq].
#
# [wikiyiq]: https://en.wikipedia.org/wiki/YIQ
#
# \YIQ colors are immutable Data class instances. Array deconstruction is `[y, i, q]` and
# hash deconstruction is `{y:, i:, q:}` (see #y, #i, #q).
#
# \YIQ is only partially implemented: other \Color objects can only be converted _to_
# \YIQ, but it has few conversion functions for converting _from_ \YIQ.
class Color::YIQ
include Color
##
# :attr_reader: y
# The `y` (luma) attribute of this \YIQ color expressed as a value 0..1.
##
# :attr_reader: i
# The `i` (orange-blue chrominance) attribute of this \YIQ color expressed as a value
# 0..1.
##
# :attr_reader: q
# The `q` (purple-green chrominance) attribute of this \YIQ color expressed as a value
# 0..1.
##
# Creates a YIQ color object from percentage values 0 .. 1.
#
# ```ruby
# Color::YIQ.from_percentage(30, 20, 10) # => YIQ [30% 20% 10%]
# Color::YIQ.from_percentage(y: 30, i: 20, q: 10) # => YIQ [30% 20% 10%]
# Color::YIQ.from_values(30, 20, 10) # => YIQ [30% 20% 10%]
# Color::YIQ.from_values(y: 30, i: 20, q: 10) # => YIQ [30% 20% 10%]
# ```
def self.from_percentage(*args, **kwargs)
y, i, q =
case [args, kwargs]
in [[_, _, _], {}]
args
in [[], {y:, i:, q:}]
[y, i, q]
else
new(*args, **kwargs)
end
new(y: y / 100.0, i: i / 100.0, q: q / 100.0)
end
class << self
alias_method :from_values, :from_percentage
alias_method :from_fraction, :new # :nodoc:
alias_method :from_internal, :new
end
##
# Creates a YIQ color object from fractional values 0 .. 1.
#
# ```ruby
# Color::YIQ.from_fraction(0.3, 0.2, 0.1) # => YIQ [30% 20% 10%]
# Color::YIQ.new(0.3, 0.2, 0.1) # => YIQ [30% 20% 10%]
# Color::YIQ[y: 0.3, i: 0.2, q: 0.1] # => YIQ [30% 20% 10%]
# ```
def initialize(y:, i:, q:) # :nodoc:
super(y: normalize(y), i: normalize(i), q: normalize(q))
end
##
# Coerces the other Color object into \YIQ.
def coerce(other) = other.to_yiq
##
def to_yiq = self
##
# Convert \YIQ to Color::Grayscale using the luma (#y) value.
def to_grayscale = Color::Grayscale.from_fraction(y)
##
alias_method :brightness, :y
def inspect = "YIQ [%.2f%% %.2f%% %.2f%%]" % [y * 100, i * 100, q * 100] # :nodoc:
def pretty_print(pq) # :nodoc:
pq.text "YIQ"
pq.breakable
pq.group 2, "[", "]" do
pq.text "%.2f%%" % (y * 100)
pq.fill_breakable
pq.text "%.2f%%" % (i * 100)
pq.fill_breakable
pq.text "%.2f%%" % (q * 100)
end
end
alias_method :to_a, :deconstruct # :nodoc:
alias_method :to_internal, :deconstruct # :nodoc:
def deconstruct_keys(_keys) = {y:, i:, q:} # :nodoc:
end
|