Module:Color

From Puella Magi Wiki
Jump to navigation Jump to search

A utility module for dealing with colors.

Usage

local color = require('Module:Color')
local p = {}

function p.main(frame)
	local newColor = color.darken(frame.args[1])
	-- Main module code goes here.
end

return p

Darken

Darken the color.

{{#invoke:Color|darken|#ffffff}}

Lighten

Lighten the color.

{{#invoke:Color|lighten|#000000}}

At

Returns color at a given Bootstrap/Tailwind-like brightness level, where 0 is the brightest and 1000 is the darkest.

{{#invoke:Color|at|#ffffff|500}}

Invert

Invert the brightness level.

{{#invoke:Color|invert|#ffffff}}

-- ------------------------------------------------------------------
-- Main routine
--

local function rgbFromHex(hex)
	hex = hex:gsub("#", "")
	local r = tonumber(hex:sub(1,2), 16) / 255
	local g = tonumber(hex:sub(3,4), 16) / 255
	local b = tonumber(hex:sub(5,6), 16) / 255
	return r, g, b
end

local function hexFromRGB(r, g, b)
	r = math.floor(r * 255)
	g = math.floor(g * 255)
	b = math.floor(b * 255)
	return string.format("#%02X%02X%02X", r, g, b)
end

local function hslFromRGB(r, g, b)
	local max = math.max(r, g, b)
	local min = math.min(r, g, b)
	local h, s, l
	l = (max + min) / 2
	if max == min then
		h = 0
		s = 0
	else
		local d = max - min
		s = l > 0.5 and d / (2 - max - min) or d / (max + min)
		if max == r then
			h = (g - b) / d + (g < b and 6 or 0)
		elseif max == g then
			h = (b - r) / d + 2
		else
			h = (r - g) / d + 4
		end
		h = h / 6
	end

	return h * 360, s * 100, l * 100
end

local function rgbFromHSL(h, s, l)
	local h = h / 360
	local s = s / 100
	local l = l / 100
	local function hue2rgb(p, q, t)
		if t < 0 then t = t + 1 end
		if t > 1 then t = t - 1 end
		if t < 1/6 then return p + (q - p) * 6 * t end
		if t < 1/2 then return q end
		if t < 2/3 then return p + (q - p) * (2/3 - t) * 6 end
		return p
	end

	local r, g, b
	if s == 0 then
		r, g, b = l, l, l
	else
		local q = l < 0.5 and l * (1 + s) or l + s - l * s
		local p = 2 * l - q

		r = hue2rgb(p, q, h + 1/3)
		g = hue2rgb(p, q, h)
		b = hue2rgb(p, q, h - 1/3)
	end

	return r, g, b
end

local function lighten(hex, intensity)
	local r, g, b = rgbFromHex(hex)
	local h, s, l = hslFromRGB(r, g, b)
	intensity = intensity or 15
	l = math.min(100, math.max(0, l + intensity))
	r, g, b = rgbFromHSL(h, s, l)
	return hexFromRGB(r, g, b)
end

local function darken(hex, intensity)
	local r, g, b = rgbFromHex(hex)
	local h, s, l = hslFromRGB(r, g, b)
	intensity = intensity or 15
	l = math.min(100, math.max(0, l - intensity))
	r, g, b = rgbFromHSL(h, s, l)
	return hexFromRGB(r, g, b)
end

local function invert(hex)
	local r, g, b = rgbFromHex(hex)
	local h, s, l = hslFromRGB(r, g, b)
	l = math.min(100, math.max(0, 100 - l))
	r, g, b = rgbFromHSL(h, s, l)
	return hexFromRGB(r, g, b)
end

local function colorAt(hex, brightness)
	local r, g, b = rgbFromHex(hex)
	local h, s, l = hslFromRGB(r, g, b)
	l = math.min(1000, math.max(0, 1000 - brightness)) / 10
	r, g, b = rgbFromHSL(h, s, l)
	return hexFromRGB(r, g, b)
end

-- ------------------------------------------------------------------
-- MediaWiki
--

local getArgs = require('Module:Arguments').getArgs
local p = {}

function p.darken(...)
	local args = getArgs(...)
	return darken(unpack(args))
end

function p.lighten(...)
	local args = getArgs(...)
	return lighten(unpack(args))
end

function p.invert(...)
	local args = getArgs(...)
	return invert(unpack(args))
end

function p.at(...)
	local args = getArgs(...)
	return colorAt(unpack(args))
end

return p