Modul:Kontrast boja

Izvor: Hrvatska internetska enciklopedija
Prijeđi na navigaciju Prijeđi na pretraživanje
Dokumentacija modula
== Korištenje ==

To compute relative luminescence

{{ColorToLum|color}} or {{#invoke:Color contrast|lum|color}}

To compute a contrast ratio between two colors

{{Color contrast ratio|color1|color2|error=?}} or {{#invoke:Color contrast|ratio|color1|color2|error=?}}

To determine which of two colors (color2a and color2b) has the greater contrast ratio with a particular color (color1)

{{Greater color contrast ratio|color1|color2a|color2b}} or {{#invoke:Color contrast|greatercontrast|color1|color2a|color2b}}

To compute the contrast ratio between the background and text colors specified in a css style string

{{#invoke:Color contrast|styleratio|css style statement string|default background color|default text color}}


local p = {}
local HTMLcolor = mw.loadData('Modul:Kontrast_boja/boje')

-- lokalni cache za HEX u glavnom modulu
local hexCache = {}

local function sRGB(v)
    if v <= 0.03928 then
        return v / 12.92
    else
        return ((v + 0.055) / 1.055) ^ 2.4
    end
end

local function rgbdec2lum(R, G, B)
    if R and G and B and R>=0 and R<256 and G>=0 and G<256 and B>=0 and B<256 then
        return 0.2126 * sRGB(R/255) + 0.7152 * sRGB(G/255) + 0.0722 * sRGB(B/255)
    end
    return nil
end

local function hex2lum(hex)
    hex = hex:lower():gsub("^#", "")
    if hexCache[hex] then
        return hexCache[hex]
    end

    local r,g,b
    if #hex == 3 then
        r = tonumber(hex:sub(1,1)..hex:sub(1,1), 16)
        g = tonumber(hex:sub(2,2)..hex:sub(2,2), 16)
        b = tonumber(hex:sub(3,3)..hex:sub(3,3), 16)
    elseif #hex == 6 then
        r = tonumber(hex:sub(1,2), 16)
        g = tonumber(hex:sub(3,4), 16)
        b = tonumber(hex:sub(5,6), 16)
    else
        return nil
    end

    local L = rgbdec2lum(r, g, b)
    hexCache[hex] = L
    return L
end

local function hsl2lum(h, s, l)
    if not (h and s and l) then return nil end
    local c = (1 - math.abs(2*l - 1)) * s
    local x = c * (1 - math.abs((h/60)%2 - 1))
    local m = l - c/2
    local r,g,b = m,m,m

    if h < 60 then r=r+c; g=g+x
    elseif h < 120 then r=r+x; g=g+c
    elseif h < 180 then g=g+c; b=b+x
    elseif h < 240 then g=g+x; b=b+c
    elseif h < 300 then r=r+x; b=b+c
    else r=r+c; b=b+x end

    return rgbdec2lum(255*r, 255*g, 255*b)
end

local function color2lum(c)
    if not c then return nil end

    c = mw.text.unstripNoWiki(c):lower():gsub("&#35;", "#"):match("^%s*(.-)%s*$")

    -- 1) ime boje
    if HTMLcolor[c] then
        return HTMLcolor[c]
    end

    -- 2) HEX
    local hex = c:match("^#?([a-f0-9]+)$")
    if hex then
        return hex2lum(hex)
    end

    -- 3) rgb()
    local R,G,B = c:match("^rgb%(%s*(%d+)%s*,%s*(%d+)%s*,%s*(%d+)%s*%)$")
    if R then
        return rgbdec2lum(tonumber(R), tonumber(G), tonumber(B))
    end

    -- 4) rgb%()
    local Rp,Gp,Bp = c:match("^rgb%(%s*([%d%.]+)%%%s*,%s*([%d%.]+)%%%s*,%s*([%d%.]+)%%%s*%)$")
    if Rp then
        return rgbdec2lum(255*Rp/100, 255*Gp/100, 255*Bp/100)
    end

    -- 5) hsl()
    local h,s,l = c:match("^hsl%(%s*([%d%.]+)%s*,%s*([%d%.]+)%%%s*,%s*([%d%.]+)%%%s*%)$")
    if h then
        return hsl2lum(tonumber(h), tonumber(s)/100, tonumber(l)/100)
    end

    return nil
end

function p._lum(color)
    return color2lum(color)
end

function p._jacikontrast(args)
    local bias = tonumber(args.bias or 0) or 0
    local css = args.css and args.css ~= ""

    local c1 = args[1] or ""
    local c2 = args[2] or "#ffffff"
    local c3 = args[3] or "#000000"

    local v1 = color2lum(c1)
    local v2 = color2lum(c2)
    local v3 = color2lum(c3)

    if not (v1 and v2 and v3) then
        return css and "" or ""
    end

    local r1 = (v2+0.05)/(v1+0.05)
    local r2 = (v3+0.05)/(v1+0.05)
    if r1 < 1 then r1 = 1/r1 end
    if r2 < 1 then r2 = 1/r2 end

    local best = (r1 + bias > r2) and c2 or c3

    if css then
        return string.format("background-color:%s; color:%s;", c1, best)
    end

    return best
end

function p.lum(frame)
    local color = frame.args[1] or frame:getParent().args[1]
    return p._lum(color) or ''
end

function p.ratio(frame)
    local args = frame.args[1] and frame.args or frame:getParent().args
    local v1 = color2lum(args[1])
    local v2 = color2lum(args[2])
    if v1 and v2 then
        if v2 > v1 then v1, v2 = v2, v1 end
        return (v1 + 0.05)/(v2 + 0.05)
    end
    return args.error or '?'
end

function p.jacikontrast(frame)
    local args = frame.args[1] and frame.args or frame:getParent().args
    return p._jacikontrast(args)
end

return p