Module:Color contrast: Difference between revisions

From the Croc Wiki, the Croc encyclopedia
Jump to navigationJump to search
Content added Content deleted
No edit summary
(v1 should be the brighter of the two)
Line 147: Line 147:
local v2 = color2lum(args[2])
local v2 = color2lum(args[2])
if (type(v1) == 'number' and type(v2) == 'number') then
if (type(v1) == 'number' and type(v2) == 'number') then
-- v1 should be the brighter of the two.
return (v2 + 0.05)/(v1 + 0.05)
if v2 > v1 then
v1, v2 = v2, v1
end
return (v1 + 0.05)/(v2 + 0.05)
else
else
return args['error'] or '?'
return args['error'] or '?'

Revision as of 19:13, July 18, 2015

Documentation for this module may be created at Module:Color contrast/doc

--
-- This module implements 
--  {{Color contrast ratio}}
--  {{Greater color contrast ratio}}
--  {{ColorToLum}}
--  {{RGBColorToLum}}
--
local p = {}

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 color2lum( c )
	
	if (c == nil) then
		return ''
	end

local HTMLcolor = {
white = 1,
silver = 0.52711512570581,
gray = 0.2158605001139,
black = 0,
red = 0.2126,
maroon = 0.045891942324215,
yellow = 0.9278,
olive = 0.20027537200568,
lime = 0.7152,
green = 0.15438342968146,
aqua = 0.7874,
teal = 0.16996855778968,
blue = 0.0722,
navy = 0.015585128108224,
fuchsia = 0.2848,
purple = 0.061477070432439,
orange = 0.4817026703631,

gold = 0.69860877428159, 
pink = 0.63271070702466, 
lightpink = 0.58566152734898, 
hotpink = 0.34658438169715, 
deeppink = 0.23866895828276, 
palevioletred = 0.28754994117889, 
mediumvioletred = 0.14371899849357, 
lightsalmon = 0.4780675225206, 
salmon = 0.36977241527596, 
darksalmon = 0.40541471563381, 
lightcoral = 0.35522120733135, 
indianred = 0.21406134963884, 
crimson = 0.16042199953026, 
firebrick = 0.10724525535015, 
darkred = 0.054889674531132, 
orangered = 0.25516243753416, 
tomato = 0.30638612719415, 
coral = 0.37017930872924, 
darkorange = 0.40016167026524, 
lightyellow = 0.98161818392882, 
lemonchiffon = 0.94038992245622, 
lightgoldenrodyellow = 0.93348351018297, 
papayawhip = 0.87797100199835, 
moccasin = 0.80083000991567, 
peachpuff = 0.74905589878251, 
palegoldenrod = 0.78792647887614, 
khaki = 0.77012343394121, 
darkkhaki = 0.45747326349994, 
cornsilk = 0.93562110372965, 
blanchedalmond = 0.85084439608156, 
bisque = 0.80732327372979, 
navajowhite = 0.76519682342785, 
wheat = 0.74909702820482, 
burlywood = 0.51559844533893, 
tan = 0.48237604163921, 
rosybrown = 0.32319457649407, 
sandybrown = 0.46628543696283, 
goldenrod = 0.41919977809569, 
darkgoldenrod = 0.27264703559993, 
peru = 0.30113074877936, 
chocolate = 0.23898526114557, 
saddlebrown = 0.097922285020521, 
sienna = 0.13697631337098, 
brown = 0.098224287876511,
}
    -- 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]*$')

	-- 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