Scales.ColorOperations (scales v0.1.0)

Copy Markdown View Source

Colours as a user writes them and as R's palettes make them: a colour read as CSS reads one (parse/1); one made from a hue, chroma and luminance (from_hcl/3) or from CIE Lab (from_lab/2), and a colour's Lab (to_lab/1) and alpha (opacity/1), each exactly as R's farver makes it; two mixed (mix/3), R's col_mix(); one changed, R's colour helpers: its alpha set (alpha/2), its hue, chroma or luminance set (with_hcl/2, muted/2), made lighter, darker or more saturated (lighter/2, darker/2, saturate/2) or its hue turned (shift/2); and the viridis palettes' colours (viridis/2), R's viridisLite::viridis().

A colour is uppercase #RRGGBB, or #RRGGBBAA with an alpha of its own, an alpha of FF dropped as opaque, so a colour has one spelling; or :none, R's NA, no colour. A helper takes one colour, as mix/3 takes two, and gives no colour back for none, as R gives NA.

Summary

Types

t()

A colour: uppercase #RRGGBB, or #RRGGBBAA with an alpha of its own, or :none.

Functions

The colour with its alpha set to alpha, from 0 to 1, R's alpha(): one below 0 is 0 and one above 1 is 1, as farver writes the byte; nil, R's NA, keeps the colour's own; no colour stays none. An alpha whose byte is 1 is written 01, as R writes it for several colours, where R writes one colour opaque.

The colour amount darker, R's col_darker(): lighter/2 by minus amount.

The colour, uppercase #RRGGBB, that R's farver encodes from hue in degrees, chroma and luminance, CIE LCh(uv), as R's pal_hue() makes its colours: each first taken into farver's bounds as farver caps it, a hue outside 0 to 360 and a luminance outside 0 to 100 at the nearer end, a chroma below 0 at 0.

The colour that R's farver encodes from CIE L, a and b and an alpha from 0 to 1, as R's gradients blend their colours in Lab: uppercase #RRGGBB, its alpha's byte appended unless it is opaque, alpha times 255 rounded half to even.

The colour amount lighter, R's col_lighter(): its HSL lightness, from 0 to 100, raised by amount and taken into 0 to 100, its alpha kept; no colour stays none. The library's HSL, which R's farver works out in another order, lands a byte away from R's where a channel falls exactly between two, as the module's opening comment says.

The colour amount of the way from from to to, each in its one spelling, R's col_mix(): each of red, green, blue and alpha that share of the way from the one to the other, rounded to a byte; 0 is from and 1 is to.

The colour of the same hue at another chroma and luminance, R's muted(): with_hcl/2 with the chroma and luminance given, its own alpha dropped, as R drops it; no colour stays none.

A colour's own alpha, from 0 to 1, its byte over 255 as R's farver decodes it; 1 for a colour without one.

The colour color names, in its one spelling, or :error where CSS names none: a CSS colour name in any case; a hex colour in one of CSS's four forms, #RGB, #RGBA, #RRGGBB and #RRGGBBAA, its digits in either case; transparent, R's white with no alpha, #FFFFFF00, where CSS's is black; or :none. R's own names that CSS lacks (grey50), CSS's functions (rgb()) and hex without its # are refused.

The colour amount more saturated, R's col_saturate(): its HSL saturation, from 0 to 100, raised by amount and taken into 0 to 100, its alpha kept; no colour stays none. A byte may land away from R's as lighter/2 says.

The colour with its hue turned amount degrees round the circle, R's col_shift(): its hue, as farver decodes it, plus amount, taken modulo 360 as R's %% takes it, its chroma, luminance and alpha kept; nil, R's NA, gives none, and no colour stays none.

The CIE Lab* of a #RRGGBB or #RRGGBBAA colour, as R's farver decodes it; an alpha is not part of it (opacity/1).

count colours of the viridis palette option, one of viridis_options/0, as R's viridisLite::viridis() makes them: spaced from begin to end, each from 0 to 1, in that order for a direction of 1 and the other for -1, with an alpha from 0 to 1.

viridisLite's palettes by name, in the order of its options A to H.

The colour with its hue, chroma or luminance set, R's col2hcl(): the colour's own, as farver decodes it, where an option is not given; each taken into farver's bounds as from_hcl/3 says. The colour's own alpha is dropped, as R drops it, unless alpha: sets one, from 0 to 1, as alpha/2 does; no colour stays none.

Types

t()

@type t() :: String.t() | :none

A colour: uppercase #RRGGBB, or #RRGGBBAA with an alpha of its own, or :none.

Functions

alpha(color, alpha)

@spec alpha(t(), number() | nil) :: t()

The colour with its alpha set to alpha, from 0 to 1, R's alpha(): one below 0 is 0 and one above 1 is 1, as farver writes the byte; nil, R's NA, keeps the colour's own; no colour stays none. An alpha whose byte is 1 is written 01, as R writes it for several colours, where R writes one colour opaque.

Examples

iex> Scales.ColorOperations.alpha("#4682B4", 0.5)
"#4682B480"

iex> Scales.ColorOperations.alpha("#4682B480", nil)
"#4682B480"

darker(color, amount \\ 10)

@spec darker(t(), number()) :: t()

The colour amount darker, R's col_darker(): lighter/2 by minus amount.

Examples

iex> Scales.ColorOperations.darker("#4682B4")
"#38678F"

from_hcl(hue, chroma, luminance)

@spec from_hcl(number(), number(), number()) :: String.t()

The colour, uppercase #RRGGBB, that R's farver encodes from hue in degrees, chroma and luminance, CIE LCh(uv), as R's pal_hue() makes its colours: each first taken into farver's bounds as farver caps it, a hue outside 0 to 360 and a luminance outside 0 to 100 at the nearer end, a chroma below 0 at 0.

Examples

iex> Scales.ColorOperations.from_hcl(15.0, 100.0, 65.0)
"#F8766D"

iex> Scales.ColorOperations.from_hcl(15.0, -40.0, 65.0)
"#9E9E9E"

from_lab(lab, alpha \\ 1)

@spec from_lab({number(), number(), number()}, number()) :: String.t()

The colour that R's farver encodes from CIE L, a and b and an alpha from 0 to 1, as R's gradients blend their colours in Lab: uppercase #RRGGBB, its alpha's byte appended unless it is opaque, alpha times 255 rounded half to even.

Examples

iex> Scales.ColorOperations.from_lab({52.4664, -4.0763, -32.1991})
"#4682B4"

iex> Scales.ColorOperations.from_lab({52.4664, -4.0763, -32.1991}, 0.5)
"#4682B480"

lighter(color, amount \\ 10)

@spec lighter(t(), number()) :: t()

The colour amount lighter, R's col_lighter(): its HSL lightness, from 0 to 100, raised by amount and taken into 0 to 100, its alpha kept; no colour stays none. The library's HSL, which R's farver works out in another order, lands a byte away from R's where a channel falls exactly between two, as the module's opening comment says.

Examples

iex> Scales.ColorOperations.lighter("#4682B4")
"#699BC4"

iex> Scales.ColorOperations.lighter("#4682B480", 200)
"#FFFFFF80"

mix(from, to, amount)

@spec mix(String.t(), String.t(), number()) :: String.t()

The colour amount of the way from from to to, each in its one spelling, R's col_mix(): each of red, green, blue and alpha that share of the way from the one to the other, rounded to a byte; 0 is from and 1 is to.

Examples

iex> Scales.ColorOperations.mix("#000000", "#FFFFFF", 0.5)
"#808080"

muted(color, options \\ [])

@spec muted(t(), keyword()) :: t()

The colour of the same hue at another chroma and luminance, R's muted(): with_hcl/2 with the chroma and luminance given, its own alpha dropped, as R drops it; no colour stays none.

Options

  • :luminance - The luminance, from 0, black, to 100, white; one outside them is the nearer. The default value is 30.

  • :chroma - The chroma, from 0, grey; one below 0 is 0. The default value is 70.

Examples

iex> Scales.ColorOperations.muted("#FF0000")
"#832424"

iex> Scales.ColorOperations.muted("#4682B480", luminance: 60, chroma: 40)
"#7094BA"

opacity(color)

@spec opacity(String.t()) :: float()

A colour's own alpha, from 0 to 1, its byte over 255 as R's farver decodes it; 1 for a colour without one.

Examples

iex> Scales.ColorOperations.opacity("#4682B4")
1.0

iex> Scales.ColorOperations.opacity("#FFFFFF00")
0.0

parse(hex)

@spec parse(term()) :: {:ok, t()} | :error

The colour color names, in its one spelling, or :error where CSS names none: a CSS colour name in any case; a hex colour in one of CSS's four forms, #RGB, #RGBA, #RRGGBB and #RRGGBBAA, its digits in either case; transparent, R's white with no alpha, #FFFFFF00, where CSS's is black; or :none. R's own names that CSS lacks (grey50), CSS's functions (rgb()) and hex without its # are refused.

Examples

iex> Scales.ColorOperations.parse("SteelBlue")
{:ok, "#4682B4"}

iex> Scales.ColorOperations.parse("#abc")
{:ok, "#AABBCC"}

iex> Scales.ColorOperations.parse("grey50")
:error

saturate(color, amount \\ 10)

@spec saturate(t(), number()) :: t()

The colour amount more saturated, R's col_saturate(): its HSL saturation, from 0 to 100, raised by amount and taken into 0 to 100, its alpha kept; no colour stays none. A byte may land away from R's as lighter/2 says.

Examples

iex> Scales.ColorOperations.saturate("#4682B4")
"#3983C1"

iex> Scales.ColorOperations.saturate("#4682B4", -200)
"#7D7D7D"

shift(color, amount \\ 10)

@spec shift(t(), number() | nil) :: t()

The colour with its hue turned amount degrees round the circle, R's col_shift(): its hue, as farver decodes it, plus amount, taken modulo 360 as R's %% takes it, its chroma, luminance and alpha kept; nil, R's NA, gives none, and no colour stays none.

Examples

iex> Scales.ColorOperations.shift("#4682B4")
"#5E7DB7"

iex> Scales.ColorOperations.shift("#4682B4", -30)
"#008CA2"

to_lab(color)

@spec to_lab(String.t()) :: {float(), float(), float()}

The CIE Lab* of a #RRGGBB or #RRGGBBAA colour, as R's farver decodes it; an alpha is not part of it (opacity/1).

Examples

iex> Scales.ColorOperations.to_lab("#4682B4")
{52.46551718768575, -4.073239774469551, -32.18862480122369}

viridis(count, parameters)

@spec viridis(non_neg_integer(), %{
  option: atom(),
  begin: number(),
  end: number(),
  direction: 1 | -1,
  alpha: number()
}) :: [t()]

count colours of the viridis palette option, one of viridis_options/0, as R's viridisLite::viridis() makes them: spaced from begin to end, each from 0 to 1, in that order for a direction of 1 and the other for -1, with an alpha from 0 to 1.

Examples

iex> Scales.ColorOperations.viridis(3, %{option: :viridis, begin: 0.0, end: 1.0, direction: 1, alpha: 1.0})
["#440154", "#21908C", "#FDE725"]

viridis_options()

@spec viridis_options() :: [atom(), ...]

viridisLite's palettes by name, in the order of its options A to H.

Examples

iex> Scales.ColorOperations.viridis_options()
[:magma, :inferno, :plasma, :viridis, :cividis, :rocket, :mako, :turbo]

with_hcl(color, options)

@spec with_hcl(t(), keyword()) :: t()

The colour with its hue, chroma or luminance set, R's col2hcl(): the colour's own, as farver decodes it, where an option is not given; each taken into farver's bounds as from_hcl/3 says. The colour's own alpha is dropped, as R drops it, unless alpha: sets one, from 0 to 1, as alpha/2 does; no colour stays none.

Black's hue is 180 degrees, as farver decodes it.

Options

  • :hue - The hue in degrees; one outside 0 to 360 is the nearer end.

  • :chroma - The chroma, from 0, grey; one below 0 is 0.

  • :luminance - The luminance, from 0, black, to 100, white; one outside them is the nearer.

  • :alpha - An alpha from 0 to 1, as alpha/2 takes it; nil, or none given, writes the colour opaque.

Examples

iex> Scales.ColorOperations.with_hcl("#4682B4", hue: 320)
"#B162A0"

iex> Scales.ColorOperations.with_hcl("#4682B480", [])
"#4682B4"

iex> Scales.ColorOperations.with_hcl("#4682B4", luminance: 120)
"#D4FFFF"