Module:Stonecutting: Difference between revisions
Jump to navigation
Jump to search
No edit summary |
No edit summary |
||
| Line 58: | Line 58: | ||
local args = getArgs(frame, {removeBlanks = false}) | local args = getArgs(frame, {removeBlanks = false}) | ||
-- | -- ── How many outputs? ────────────────────────────────────────── | ||
local count = 0 | local count = 0 | ||
while true do | while true do | ||
| Line 71: | Line 71: | ||
end | end | ||
-- wrapper | -- ── Outer wrapper ───────────────────────────────────────────── | ||
local outer = mw.html.create('div') | local outer = mw.html.create('div') | ||
:addClass('stonecutting-carousel') | :addClass('stonecutting-carousel') | ||
| Line 80: | Line 80: | ||
end | end | ||
---------------------------------------------------------------- | |||
-- (1) | -- (1) Static stylesheet – simply link the page | ||
---------------------------------------------------------------- | |||
outer:wikitext | outer:wikitext( | ||
'templatestyles | '<templatestyles src="Stonecutting/styles.css" />' | ||
) | |||
---------------------------------------------------------------- | |||
-- (2) | -- (2) Dynamic stylesheet – inline, no attributes | ||
---------------------------------------------------------------- | |||
local dur = count * 4 -- seconds: 4 s per recipe | local dur = count * 4 -- seconds: 4 s per recipe | ||
local pct = 100 / count -- % slice | local pct = 100 / count -- slice in % | ||
local vis = pct - 0.01 -- visible almost the whole slice | |||
local css = {} | local css = {} | ||
css[#css+1] = string.format( | css[#css+1] = string.format( | ||
'.stonecutting-carousel .sc-frame{animation:sc-cycle %ds steps(1) infinite;}', | '.stonecutting-carousel .sc-frame{animation:sc-cycle %ds steps(1) infinite;}', | ||
| Line 106: | Line 105: | ||
) | ) | ||
end | end | ||
css[#css+1] = string.format( | css[#css+1] = string.format( | ||
'@keyframes sc-cycle{0%%{opacity:1;} %.2f%%{opacity:1;} %.2f%%{opacity:0;} 100%%{opacity:0;}}', | '@keyframes sc-cycle{0%%{opacity:1;} %.2f%%{opacity:1;} %.2f%%{opacity:0;} 100%%{opacity:0;}}', | ||
vis, pct | |||
) | ) | ||
outer:wikitext | outer:wikitext( | ||
'templatestyles' | '<templatestyles>' .. table.concat(css) .. '</templatestyles>' | ||
) | |||
return tostring(outer) | return tostring(outer) | ||
Revision as of 02:25, 14 June 2025
Documentation for this module may be created at Module:Stonecutting/doc
------------------------------------------------------------
-- Module:Stonecutting · Stone-cutter recipe carousel
------------------------------------------------------------
local p = {}
local getArgs = require('Module:Arguments').getArgs
local trim = mw.text.trim
------------------------------------------------------------------------
-- slotImage(label, image, link) → wikitext thumbnail
------------------------------------------------------------------------
local function slotImage(label, image, link)
if not label or label == '' then
return ''
end
local file = (image ~= '' and image) or ('Grid_' .. label .. '.png')
local tgt = (link ~= '' and link ) or label
return string.format(
'[[File:%s|32px|class=pixelated|link=%s|alt=%s]]',
file, tgt, label
)
end
------------------------------------------------------------------------
-- buildFrame(args, idx) → html for one output variant
------------------------------------------------------------------------
local function buildFrame(args, idx)
local inL = args.input or args[1] or ''
local inI = args['input-image'] or ''
local inLn = args['input-link'] or ''
local outL = args['output' .. idx] or args[idx + 1] or ''
local outI = args['output' .. idx .. '-image'] or ''
local outLn = args['output' .. idx .. '-link'] or ''
local html = mw.html.create('div'):addClass('sc-frame')
html:wikitext('[[File:StonecutterGUI.png|180px|link=|alt=]]')
html:tag('div'):addClass('sc-slot')
:css{left = '11px', top = '50px'}
:wikitext(slotImage(inL, inI, inLn))
html:tag('div'):addClass('sc-slot')
:css{left = '56.5px', top = '23px'}
:wikitext(slotImage(outL, outI, outLn))
html:tag('div'):addClass('sc-slot')
:css{left = '127px', top = '50px'}
:wikitext(slotImage(outL, outI, outLn))
return tostring(html)
end
------------------------------------------------------------------------
-- main entry
------------------------------------------------------------------------
function p.carousel(frame)
local args = getArgs(frame, {removeBlanks = false})
-- ── How many outputs? ──────────────────────────────────────────
local count = 0
while true do
local raw = args['output' .. (count + 1)] or args[count + 2]
if not raw or trim(tostring(raw)) == '' then
break
end
count = count + 1
end
if count == 0 then
return '<span style="color:red">Stonecutting: no outputs supplied</span>'
end
-- ── Outer wrapper ─────────────────────────────────────────────
local outer = mw.html.create('div')
:addClass('stonecutting-carousel')
:css{width = '180px', height = '131px', position = 'relative'}
for i = 1, count do
outer:wikitext(buildFrame(args, i))
end
----------------------------------------------------------------
-- (1) Static stylesheet – simply link the page
----------------------------------------------------------------
outer:wikitext(
'<templatestyles src="Stonecutting/styles.css" />'
)
----------------------------------------------------------------
-- (2) Dynamic stylesheet – inline, no attributes
----------------------------------------------------------------
local dur = count * 4 -- seconds: 4 s per recipe
local pct = 100 / count -- slice in %
local vis = pct - 0.01 -- visible almost the whole slice
local css = {}
css[#css+1] = string.format(
'.stonecutting-carousel .sc-frame{animation:sc-cycle %ds steps(1) infinite;}',
dur
)
for i = 1, count do
css[#css+1] = string.format(
'.stonecutting-carousel .sc-frame:nth-child(%d){animation-delay:%ds;}',
i, (i - 1) * 4
)
end
css[#css+1] = string.format(
'@keyframes sc-cycle{0%%{opacity:1;} %.2f%%{opacity:1;} %.2f%%{opacity:0;} 100%%{opacity:0;}}',
vis, pct
)
outer:wikitext(
'<templatestyles>' .. table.concat(css) .. '</templatestyles>'
)
return tostring(outer)
end
return p