本模块是{{背景图片}}的模块,大约在这两年处于测试阶段,原模板除模板样式表皆封装入本模块。
响应式布局
背景图片模板启用了响应式布局,通过比较内部图片尺寸和数组中的尺寸值,加载比原始内部图片宽度小的缩略图以提高图片加载速度。该布局实际上在模板中调用了{{array}}、{{loop}}和fileInfo这三个模块来实现,本模块直接实现了组装效果。
动画效果
背景图片模板预设了大量动画效果,用户也可以通过定制css动画样式来实现想要的效果,本模块将{{#switch}}提供的动画动作组装成表供查询。
图片数据
本模块对使用内部图片,使用外部图片,没填图片三种情况进行判断。
local p = {}
local getArgs = require('Module:Arguments').getArgs
local html = mw.html.create()
-- 内部图片响应式布局
function p.width(imgname, srcset, imgtitle, frame)
if not imgtitle.file.exists then return srcset end
local width = {800, 1024, 1280, 1366, 1400, 1440, 1600, 1680, 1920} -- 常见屏幕宽度
local imgwidth = imgtitle.file.width
local pieces = {}
for i, v in ipairs(width) do
if v < imgwidth then -- 比较屏宽与图片尺寸
local filepath = frame:callParserFunction('filepath', imgname, v)
table.insert(pieces, filepath.." "..v.."w, ") -- 缩略图生成
else break
end
end
srcset = table.concat(pieces)..srcset -- 组装缩略图
return srcset
end
-- 动画效果
function p.animate(animate, position, action)
if animate == "none" then return end
local animateName = animate
local actionhub={
['show'] = "2s",
['shrink'] = "4s ease-out",
['clear'] = "2s",
['appear'] = "5s ease",
['look'] = "5s ease",
['look-top'] = "5s ease",
['look-bottom'] = "5s ease",
}
local effect
if animate == "look" then
effect = (position == "top") and "look-bottom" or "look-top"
else
effect = action or animateName
end
if actionhub[effect] then
return ";animation:"..animateName.." "..actionhub[effect]
else
return ";animation:"..animateName.." 2s"
end
end
-- 主函数
function p.main(frame)
local args = getArgs(frame)
local obj_position, imginside, datasrc, imgtitle, changelogo
local imgname = args.url or args[1]
if imgname then
imginside = frame:callParserFunction('filepath', imgname)
imgtitle = mw.title.new('File:'..imgname)
-- 图片数据判定 外部图片 内部图片
datasrc = not imgtitle.file.exists and imgname or imginside
else
datasrc = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkqAcAAIUAgUW0RjgAAAAASUVORK5CYII="
end
-- 生成img标签
if args.position then
obj_position = "object-position:"..args.position
else
obj_position = "object-position:center center"
end
local imgele = html:tag("img")
:attr("data-src", datasrc)
:cssText( 'position:fixed;top:0;width:100%;height:100%;object-fit:cover;'..obj_position)
if imginside then
imgele:attr("srcset", p.width(imgname, imginside, imgtitle, frame)) -- 响应式布局
end
-- 生成动画效果
local animate = args.animate or "show" -- 动画效果-- 动画进行方式
local animation = p.animate(animate, args.position, args.action)
-- 背景颜色生成
local color = args.color or "transparent"
local backcolor = html:tag("div"):cssText( 'position:fixed;top:0;left:0;width:100%;height:100%;background:'..color..animation)
-- make and shade
local opacity = args.shade or 0
local shadeColor = args.shadeColor or "#fff"
local shadeval = "background:"..shadeColor..";opacity:"..opacity..animation
local shade = html:tag("div"):cssText( 'position:fixed; top:0; width:100%; height:100%;'..shadeval)
if args.make then
local make = html:tag("div"):cssText( 'position:fixed; top:0; width:100%; height:100%; '..args.make)
shade = tostring(make)..tostring(shade)
imgele = nil -- make会遮住图片
end
-- display logo
local displaylogo = args.displaylogo ~= "no" and "yes" or "no"
-- 替换logo
if args["logo-url"] then
local logoUrl = frame:callParserFunction('filepath', args["logo-url"])
changelogo = html:tag("span")
:addClass("nomobile")
:attr("id","wglogo")
:attr("data-background-position",args["logo-position"])
:attr("data-background-image", logoUrl and logoUrl or frame:callParserFunction('filepath', "ZhMoegirl15.2.png"))
--对应原来的 false = False = ""
if args["logo-size"] ~= "false" or "False" then
changelogo:attr("data-background-size",args["logo-size"])
end
changelogo = tostring(changelogo)..mw.getCurrentFrame():preprocess("{{#Widget:Wglogo}}")
end
-- 包装
local backpic = html:tag("div")
:addClass("nomobile sidebar-character")
:cssText('display:none;width:100%;height:100%;top:0;left:0;z-index:-3;')
:attr("data-displaylogo", displaylogo)
:wikitext(tostring(backcolor)..tostring(imgele)..tostring(shade))
return tostring(backpic)..tostring(changelogo)
end
return p