Diferencia entre revisiones de «Módulo:Color contrast»
De Familia Sanchez Arjona
m (Protected Module:Color contrast: High-risk Lua module ([Edit=Allow only autoconfirmed users] (indefinite) [Move=Allow only autoconfirmed users] (indefinite))) |
(add support for hsl) |
||
Línea 16: | Línea 16: | ||
end | end | ||
return v | return v | ||
+ | end | ||
+ | |||
+ | local function hsl2lum( h, s, l ) | ||
+ | local lum = '' | ||
+ | if ( 0 <= h and h < 360 and 0 <= s and s <= 1 and 0 <= l and l <= 1 ) then | ||
+ | local c = (1 - abs(2*l - 1))*s | ||
+ | local x = c*(1 - abs( mod(h/60, 2) - 1) ) | ||
+ | local m = l - c/2 | ||
+ | |||
+ | local R, G, B = m, m, m | ||
+ | if( 0 <= h and h < 60 ) then | ||
+ | R = R + c | ||
+ | G = G + x | ||
+ | elseif( 60 <= h and h < 120 ) then | ||
+ | R = R + x | ||
+ | G = G + c | ||
+ | elseif( 120 <= h and h < 180 ) then | ||
+ | G = R + c | ||
+ | B = G + x | ||
+ | elseif( 180 <= h and h < 240 ) then | ||
+ | G = R + x | ||
+ | B = G + c | ||
+ | elseif( 240 <= h and h < 300 ) then | ||
+ | R = R + x | ||
+ | B = G + c | ||
+ | elseif( 300 <= h and h < 360 ) then | ||
+ | R = R + c | ||
+ | B = G + x | ||
+ | end | ||
+ | lum = 0.2126 * sRGB(R) + 0.7152 * sRGB(G) + 0.0722 * sRGB(B) | ||
+ | end | ||
+ | return lum | ||
end | end | ||
Línea 35: | Línea 67: | ||
end | end | ||
-- remove leading # (if there is one) and whitespace | -- remove leading # (if there is one) and whitespace | ||
− | c = mw.ustring.match(c, '^[%s#]*([a-f0-9]*)[%s]*$') | + | c = mw.ustring.match(c, '^[%s#]*([a-f0-9]*)[%s;]*$') |
+ | |||
+ | -- convert from hsl | ||
+ | if mw.ustring.match(c,'^hsl%([%s]*[0-9][0-9]*[%s]*,[%s]*[0-9][0-9]*%%[%s]*,[%s]*[0-9][0-9]*%%[%s]*%)$') then | ||
+ | local h = mw.ustring.match(c,'^hsl%[%s]*([0-9][0-9]*)[%s]*,[%s]*[0-9][0-9]*%%[%s]*,[%s]*[0-9][0-9]*%%[%s]*%$') | ||
+ | local s = mw.ustring.match(c,'^hsl%[%s]*[0-9][0-9]*[%s]*,[%s]*([0-9][0-9]*)%%[%s]*,[%s]*[0-9][0-9]*%%[%s]*%$') | ||
+ | local l = mw.ustring.match(c,'^hsl%[%s]*[0-9][0-9]*[%s]*,[%s]*[0-9][0-9]*%%[%s]*,[%s]*([0-9][0-9]*)%%[%s]*%$') | ||
+ | return hsl2rgb(tonumber(h), tonumber(s)/100, tonumber(l)/100) | ||
+ | end | ||
-- split into rgb | -- split into rgb |
Revisión del 19:41 30 jul 2015
40x40px | This module is rated as beta, and is ready for widespread use. It is still new and should be used with some caution to ensure the results are as expected. |
This module is used primarily by
- {{Color contrast ratio}}
- {{ColorToLum}} / {{RGBColorToLum}}
- {{Color contrast conformance}}
- {{Ensure AAA contrast ratio}}
- {{Greater color contrast ratio}}
It is also used for tracking within
and for documentation in
Usage
To use this module, you may use one of the above listed templates or invoke the module directly
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}}
-- -- This module implements -- {{Color contrast ratio}} -- {{Greater color contrast ratio}} -- {{ColorToLum}} -- {{RGBColorToLum}} -- local p = {} local HTMLcolor = mw.loadData( 'Module:Color contrast/colors' ) local function sRGB ( v ) if (v <= 0.03928) then v = v / 12.92 else v = math.pow((v+0.055)/1.055, 2.4) end return v end local function hsl2lum( h, s, l ) local lum = '' if ( 0 <= h and h < 360 and 0 <= s and s <= 1 and 0 <= l and l <= 1 ) then local c = (1 - abs(2*l - 1))*s local x = c*(1 - abs( mod(h/60, 2) - 1) ) local m = l - c/2 local R, G, B = m, m, m if( 0 <= h and h < 60 ) then R = R + c G = G + x elseif( 60 <= h and h < 120 ) then R = R + x G = G + c elseif( 120 <= h and h < 180 ) then G = R + c B = G + x elseif( 180 <= h and h < 240 ) then G = R + x B = G + c elseif( 240 <= h and h < 300 ) then R = R + x B = G + c elseif( 300 <= h and h < 360 ) then R = R + c B = G + x end lum = 0.2126 * sRGB(R) + 0.7152 * sRGB(G) + 0.0722 * sRGB(B) end return lum end local function color2lum( c ) if (c == nil) then return '' end -- whitespace c = c:match( '^%s*(.-)%s*$' ) -- lowercase c = c:lower() -- first try to look it up local L = HTMLcolor[c] if (L ~= nil) then return L end -- remove leading # (if there is one) and whitespace c = mw.ustring.match(c, '^[%s#]*([a-f0-9]*)[%s;]*$') -- convert from hsl if mw.ustring.match(c,'^hsl%([%s]*[0-9][0-9]*[%s]*,[%s]*[0-9][0-9]*%%[%s]*,[%s]*[0-9][0-9]*%%[%s]*%)$') then local h = mw.ustring.match(c,'^hsl%[%s]*([0-9][0-9]*)[%s]*,[%s]*[0-9][0-9]*%%[%s]*,[%s]*[0-9][0-9]*%%[%s]*%$') local s = mw.ustring.match(c,'^hsl%[%s]*[0-9][0-9]*[%s]*,[%s]*([0-9][0-9]*)%%[%s]*,[%s]*[0-9][0-9]*%%[%s]*%$') local l = mw.ustring.match(c,'^hsl%[%s]*[0-9][0-9]*[%s]*,[%s]*[0-9][0-9]*%%[%s]*,[%s]*([0-9][0-9]*)%%[%s]*%$') return hsl2rgb(tonumber(h), tonumber(s)/100, tonumber(l)/100) end -- split into rgb local cs = mw.text.split(c or '', '') if( #cs == 6 ) then local R = sRGB( (16*tonumber('0x' .. cs[1]) + tonumber('0x' .. cs[2]))/255 ) local G = sRGB( (16*tonumber('0x' .. cs[3]) + tonumber('0x' .. cs[4]))/255 ) local B = sRGB( (16*tonumber('0x' .. cs[5]) + tonumber('0x' .. cs[6]))/255 ) L = 0.2126 * R + 0.7152 * G + 0.0722 * B return L elseif ( #cs == 3 ) then local R = sRGB( (16*tonumber('0x' .. cs[1]) + tonumber('0x' .. cs[1]))/255 ) local G = sRGB( (16*tonumber('0x' .. cs[2]) + tonumber('0x' .. cs[2]))/255 ) local B = sRGB( (16*tonumber('0x' .. cs[3]) + tonumber('0x' .. cs[3]))/255 ) L = 0.2126 * R + 0.7152 * G + 0.0722 * B return L end -- failure, return blank return '' end function p._greatercontrast(args) local bias = tonumber(args['bias'] or '0') or 0 local v1 = color2lum(args[1] or '') local c2 = args[2] or '#FFFFFF' local v2 = color2lum(c2) local c3 = args[3] or '#000000' local v3 = color2lum(c3) local ratio1 = 0; local ratio2 = 0; if (type(v1) == 'number' and type(v2) == 'number') then ratio1 = (v2 + 0.05)/(v1 + 0.05) ratio1 = (ratio1 < 1) and 1/ratio1 or ratio1 end if (type(v1) == 'number' and type(v3) == 'number') then ratio2 = (v3 + 0.05)/(v1 + 0.05) ratio2 = (ratio2 < 1) and 1/ratio2 or ratio2 end return (ratio1 + bias > ratio2) and c2 or c3 end function p._ratio(args) local v1 = color2lum(args[1]) local v2 = color2lum(args[2]) if (type(v1) == 'number' and type(v2) == 'number') then -- v1 should be the brighter of the two. if v2 > v1 then v1, v2 = v2, v1 end return (v1 + 0.05)/(v2 + 0.05) else return args['error'] or '?' end end function p.lum(frame) return color2lum(frame.args[1] or frame:getParent().args[1]) end function p.ratio(frame) local args = frame.args[1] and frame.args or frame:getParent().args return p._ratio(args) end function p.greatercontrast(frame) local args = frame.args[1] and frame.args or frame:getParent().args return p._greatercontrast(args) end return p