跳转到内容
打开/关闭菜单
  • 451 条目
  • 798 文件
  • 22 用户
  • 8935 编辑
Blockland Wiki
打开/关闭外观设置菜单
打开/关闭个人菜单
未登录
未登录用户的IP地址会在进行任意编辑后公开展示。

模块:Background

来自Blockland Wiki
KK​(留言 | 贡献)2026年10月9日 (五) 22:34的版本 (创建页面,内容为“ local p = {} -- 清理参数 local function trim(value) return mw.text.trim(tostring(value or "")) end -- 透明度限制在 0 到 1 local function opacity(value, default) local number = tonumber(trim(value)) if not number then return default end number = math.max(0, math.min(1, number)) return tostring(number) end -- 只接受安全、常见的图片定位写法 local validPositions = { center = true, top = true, bottom = true, left = true,…”)
(差异) ←上一版本 | 最后版本 (差异) | 下一版本→ (差异)

此模块的文档可以在模块:Background/doc创建


local p = {}

-- 清理参数
local function trim(value)
	return mw.text.trim(tostring(value or ""))
end

-- 透明度限制在 0 到 1
local function opacity(value, default)
	local number = tonumber(trim(value))

	if not number then
		return default
	end

	number = math.max(0, math.min(1, number))
	return tostring(number)
end

-- 只接受安全、常见的图片定位写法
local validPositions = {
	center = true,
	top = true,
	bottom = true,
	left = true,
	right = true,
	["center top"] = true,
	["center bottom"] = true,
	["left center"] = true,
	["right center"] = true,
	["left top"] = true,
	["right top"] = true,
	["left bottom"] = true,
	["right bottom"] = true,
	["center center"] = true
}

local function validPositionToken(token)
	if token:match("^%-?%d+%.?%d*%%$") then
		return true
	end

	if token:match("^%-?%d+%.?%d*px$") then
		return true
	end

	return tonumber(token) == 0
end

local function position(value)
	value = trim(value)

	if validPositions[value] then
		return value
	end

	local x, y = value:match("^(%S+)%s+(%S+)$")

	if x and y
		and validPositionToken(x)
		and validPositionToken(y) then
		return x .. " " .. y
	end

	return "center center"
end

-- 限制颜色格式,避免把任意内容拼入 CSS
local colorNames = {
	white = true,
	black = true,
	transparent = true,
	red = true,
	blue = true,
	green = true,
	yellow = true,
	gray = true,
	grey = true,
	navy = true
}

local function safeColor(value)
	value = trim(value)

	if value:match("^#%x%x%x$") or
		value:match("^#%x%x%x%x%x%x$") then
		return value
	end

	local lower = value:lower()

	if colorNames[lower] then
		return lower
	end

	return ""
end

-- 解析外部图片 URL 或 Wiki 文件名
local function getImageSource(frame, image)
	image = trim(image)

	if image == "" then
		return ""
	end

	-- 允许 HTTPS、HTTP 或协议相对的外链
	if image:match("^https?://") or image:match("^//") then
		return image
	end

	-- 内部文件:支持 File:、Image:、文件: 前缀
	image = image:gsub("^[Ff]ile:", "")
	image = image:gsub("^[Ii]mage:", "")
	image = image:gsub("^文件:", "")

	local ok, result = pcall(function()
		return frame:callParserFunction("filepath", image)
	end)

	if ok and result and result ~= "" then
		return result
	end

	return ""
end

function p.main(frame)
	local parent = frame:getParent()
	local args = (parent or frame).args

	local image = args["图片"] or args["url"] or args[1] or ""
	local src = getImageSource(frame, image)

	local imageOpacity = opacity(args["透明度"] or args["opacity"], 1)
	local imagePosition = position(args["位置"] or args["position"] or "center")

	local baseColor = safeColor(args["背景色"] or args["颜色"] or args["color"])
	local shadeColor = safeColor(args["遮罩颜色"] or args["shadeColor"])
	local shadeOpacity = opacity(args["遮罩透明度"] or args["shade"], 0)

	-- 无图片、无背景色、无有效遮罩时不输出
	if src == "" and baseColor == "" then
		return ""
	end

	-- 最外层位于负层级;不需要 pointer-events
	local rootStyle =
		"position:fixed;" ..
		"top:0;" ..
		"left:0;" ..
		"width:100%;" ..
		"height:100%;" ..
		"z-index:-1;" ..
		"overflow:hidden;"

	if baseColor ~= "" then
		rootStyle = rootStyle .. "background-color:" .. baseColor .. ";"
	end

	local root = mw.html.create("div")
		:addClass("bl-page-bg-layer")
		:attr("aria-hidden", "true")
		:cssText(rootStyle)

	-- 图片层
	if src ~= "" then
		local img = mw.html.create("img")
			:addClass("bl-page-bg-image")
			:attr("src", src)
			:attr("alt", "")
			:cssText(
				"position:absolute;" ..
				"top:0;" ..
				"left:0;" ..
				"width:100%;" ..
				"height:100%;" ..
				"object-fit:cover;" ..
				"object-position:" .. imagePosition .. ";" ..
				"opacity:" .. imageOpacity .. ";"
			)

		root:wikitext(tostring(img))
	end

	-- 可选颜色遮罩
	if shadeColor ~= "" and tonumber(shadeOpacity) > 0 then
		local shade = mw.html.create("div")
			:addClass("bl-page-bg-shade")
			:cssText(
				"position:absolute;" ..
				"top:0;" ..
				"left:0;" ..
				"width:100%;" ..
				"height:100%;" ..
				"background-color:" .. shadeColor .. ";" ..
				"opacity:" .. shadeOpacity .. ";"
			)

		root:wikitext(tostring(shade))
	end

	return tostring(root)
end

return p