Module:ColorSwatch

From Wiki of ZZT
Revision as of 07:50, 15 January 2021 by Quantum (talk | contribs) (Draw blinking-color symbol with triangular borders; vary drop shadow for contrast)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

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

local p = {}

local color = require("Module:EGAColor")

function p.swatch(frame)
	local bg = color.to_index(frame.args.bg)
	local fg = color.to_index(frame.args.fg)
	local blinking = false
	for _, arg in ipairs(frame.args) do
		if string.lower(arg) == "blinking" then
			blinking = true
			break
		end
	end

	local name = get_name(bg, fg, blinking)
	local swatch = get_swatch(bg, fg, blinking)
	local hex = get_hex(bg, fg, blinking)
	return string.format("%s %s (%s)", name, tostring(swatch), hex)
end

function get_name(bg, fg, blinking)
	local result = color.to_name(fg) .. " on " .. color.to_name(bg)
	if blinking then
		result = "blinking " .. result
	end
	return result
end

function get_swatch(bg, fg, blinking)
	local bg = color.to_hex_color(bg)
	local fg = color.to_hex_color(fg)

	-- Use a drop shadow that contrasts with bg
	local shadow_color = "#808080"
	if bg == 7 then
		shadow_color = "#000"
	end

	local outer = mw.html.create("span")
	outer:css({
		width = "1.25em",
		height = "1em",
		["background-color"] = bg,
		["box-shadow"] = "0 0 1px " .. shadow_color,
		display = "inline-flex",
		["align-items"] = "center",
		["justify-content"] = "center"
	})
	local inner = outer:tag("span")
	inner:css({
		display = "inline-block",
		width = "0",
		height = "0",
		border = "0.25em solid",
	})
	if blinking then
		inner:css({
			["border-color"] = string.format("%s %s0 %s0 %s", fg, fg, fg, fg),
			["box-shadow"] = "0 0 0 1px " .. fg
		})
	else
		inner:css("border-color", fg)
	end
	return outer
end

function get_hex(bg, fg, blinking)
	if bg < 8 and blinking then
		bg = bg + 8
	end
	return string.format("0x%02X", bg*16 + fg)
end

return p