dev
Documentation icon Module documentation
[view] [edit] [history] [purge]

Color item class, used for color processing. The class provides color prop getter-setters, procedures for color computation, compositing methods and serialisation into CSS color formats.

Documentation

Package items

Color.tup (table)
Color tuple.
Color.typ (member • string)
Color space type.
Color.alp (member • number)
Color alpha channel value.
Color:new(typ, tup, alp) (function • constructor)
Color instance constructor.
Parameters:
typ Color space type ('hsl' or 'rgb'). (string)
tup Color tuple in HSL or RGB (table)
alp Alpha value range (0 - 1). (number)
Errors:
'no color data provided' (line 304)
'invalid color type "$1" specified' (line 309)
Returns: Color instance. (Color)
Color:string() (function)
Color string default output.
Returns: Hexadecimal 6-digit or HSLA color string. (string)
Usage:
colors.parse('hsl(214, 15%, 30%)'):string() == '#404a57'
colors.parse('#404a5780'):string() == 'hsl(214, 15%, 30%, 0.5)'
Color:hex() (function)
Color hexadecimal string output.
Returns: Hexadecimal color string. (string)
Usage: colors.parse('hsl(214, 15%, 30%)'):hex() == '#404a57'
Color:rgb() (function)
RGBA functional color string output.
Returns: RGBA color string. (string)
Usage: colors.parse('hsl(214, 15%, 30%)'):rgb() == 'rgb(64, 74, 87)'
See also: https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#rgb()_and_rgba()
Color:hsl() (function)
HSL functional color string output.
Returns: HSLA color string. (string)
Usage: colors.parse('rgb(64, 74, 87)'):hsl() == 'hsl(214, 15%, 30%)'
See also: https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#hsl()_and_hsla()



--- Color item class, used for color processing.
--  The class provides color prop getter-setters, procedures for color computation,
--  compositing methods and serialisation into CSS color formats.
--  @classmod           Color
Color = {}
Color.__index = Color
Color.__tostring = function() return 'Color' end

--- Message string collection for color errors.
--  @variable           i18n
--  @local
local i18n = require('Dev:I18n').loadMessages('Colors')

--- Color tuple.
--  @table              Color.tup
Color.tup = {}

--- Color space type.
--  @member             {string} Color.typ
Color.typ = ''

--- Color alpha channel value.
--  @member             {number} Color.alp
Color.alp = 1

--- Color instance constructor.
--  @function           Color:new
--  @param              {string} typ Color space type (`'hsl'` or `'rgb'`).
--  @param              {table} tup Color tuple in HSL or RGB
--  @param              {number} alp Alpha value range (`0` - `1`).
--  @error[304]         {string} 'no color data provided'
--  @error[309]         {string} 'invalid color type "$1" specified'
--  @return             {Color} Color instance.
--  @constructor
function Color:new(tup, typ, alp)
    local o = {}
    setmetatable(o, self)

    -- is color tuple valid?
    if type(tup) ~= 'table' or #tup ~= 3 then
        error(i18n:msg('no-data'))
    end

    -- is color type valid?
    if typ ~= 'rgb' and typ ~= 'hsl' then
        error(i18n:msg('invalid-type', typ))
    end

    -- are color tuple entries valid?
    for n = 1, 3 do
        utils.check( (n == 1 and typ == 'hsl') and 'hue' or typ, tup[n])
    end
    utils.check('hsl', alp)

    o.tup = tup
    o.typ = typ
    o.alp = alp
    return o
end

--- Color string default output.
--  @function           Color:string
--  @return             {string} Hexadecimal 6-digit or HSLA color string.
--  @usage              colors.parse('hsl(214, 15%, 30%)'):string() == '#404a57'
--  @usage              colors.parse('#404a5780'):string() == 'hsl(214, 15%, 30%, 0.5)'
function Color:string()
    return self.alp ~= 1 and self:hsl() or self:hex()
end

--- Color hexadecimal string output.
--  @function           Color:hex
--  @return             {string} Hexadecimal color string.
--  @usage              colors.parse('hsl(214, 15%, 30%)'):hex() == '#404a57'
function Color:hex()
    local this = utils.clone(self, 'rgb')
    local hex = '#'

    for i, t in ipairs(this.tup) do
        -- Hexadecimal conversion.
        hex = #string.format('%x', t) == 1 -- leftpad
            and hex .. '0' .. string.format('%x', t)
            or hex .. string.format('%x', t)
    end

    local alp = string.format('%x', this.alp * 255)
    if alp ~= 'ff' then
        hex = #alp == 1 and hex .. '0' .. alp or hex .. alp
    end

    return hex
end

--- RGBA functional color string output.
--  @function           Color:rgb
--  @return             {string} RGBA color string.
--  @see                https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#rgb()_and_rgba()
--  @usage              colors.parse('hsl(214, 15%, 30%)'):rgb() == 'rgb(64, 74, 87)'
function Color:rgb()
    local this = utils.clone(self, 'rgb')

    return this.alp ~= 1
        and 'rgba(' .. table.concat(this.tup, ', ') .. ', ' .. this.alp .. ')'
        or  'rgb(' .. table.concat(this.tup, ', ') .. ')'
end

--- HSL functional color string output.
--  @function           Color:hsl
--  @return             {string} HSLA color string.
--  @see                https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#hsl()_and_hsla()
--  @usage              colors.parse('rgb(64, 74, 87)'):hsl() == 'hsl(214, 15%, 30%)'
function Color:hsl()
    local this = utils.clone(self, 'hsl')

    for i, t in ipairs(this.tup) do
        if i == 2 or i == 3 then
            this.tup[i] = tostring(t*100) .. '%'
        end
    end

    return this.alp ~= 1
        and 'hsla(' .. table.concat(this.tup, ', ') .. ', ' .. this.alp .. ')'
        or  'hsl(' .. table.concat(this.tup, ', ') .. ')' 
end

return Color