# `Color.HSLuv`

HSLuv — a perceptually-uniform alternative to HSL, built on CIELUV.

Reference: https://www.hsluv.org/ (Alexei Boronine, 2015).

HSLuv is a cylindrical reparameterisation of `LCHuv` where `S` is
rescaled so `S = 100` is always the maximum chroma achievable inside
the sRGB gamut for the given `L` and `H`. Equal steps in `S` therefore
produce perceptually similar saturation steps across the hue circle,
unlike plain HSL where equal steps in `S` mean wildly different
perceptual saturation for different hues.

Channels:

* `h ∈ [0, 360)` — hue in degrees.

* `s ∈ [0, 100]` — saturation (0 = gray, 100 = sRGB gamut edge).

* `l ∈ [0, 100]` — lightness.

# `t`

```elixir
@type t() :: %Color.HSLuv{
  alpha: Color.Types.alpha(),
  h: float() | nil,
  l: float() | nil,
  s: float() | nil
}
```

An HSLuv colour (Boronine 2015). Hue in degrees `[0.0, 360.0)`,
saturation and lightness as percentages `[0.0, 100.0]`. Built on
CIELUV, perceptually uniform.

# `from_lchuv`

Converts an `LCHuv` color to HSLuv.

### Arguments

* `lchuv` is a `Color.LCHuv` struct.

### Returns

* A `Color.HSLuv` struct.

# `from_xyz`

Converts a CIE `XYZ` color to HSLuv via `LCHuv`.

# `to_lchuv`

Converts an HSLuv color to `LCHuv`.

### Arguments

* `hsluv` is a `Color.HSLuv` struct.

### Returns

* A `Color.LCHuv` struct (D65/2°).

### Examples

    iex> {:ok, lch} = Color.HSLuv.to_lchuv(%Color.HSLuv{h: 12.177, s: 100.0, l: 53.237})
    iex> {Float.round(lch.l, 2), Float.round(lch.c, 2), Float.round(lch.h, 2)}
    {53.24, 179.04, 12.18}

# `to_xyz`

Converts an HSLuv color to CIE `XYZ` via `LCHuv`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
