Module:Stonecutting: Difference between revisions
Jump to navigation
Jump to search
No edit summary |
No edit summary |
||
| Line 89: | Line 89: | ||
end | end | ||
-- attach TemplateStyles (base rules) ---------------------------- | |||
local styleBase = frame:extensionTag( | |||
'templatestyles', '', { src = 'Template:Stonecutting/styles.css' } | |||
) | |||
outer:wikitext(styleBase) | |||
------------------------------------------------------------------ | |||
-- Dynamically adjust animation timing to the number of frames | |||
------------------------------------------------------------------ | |||
local dur = count * 4 -- seconds, 4 s per recipe | |||
local pct = 100 / count -- % slice per recipe | |||
local css = mw.html.create('style'):attr('type', 'text/css') | |||
-- main animation rule with variable duration | |||
css | |||
:wikitext(string.format( | |||
'.stonecutting-carousel .sc-frame{animation:sc-cycle %ds steps(1) infinite;}', | |||
dur | |||
)) | |||
-- per-frame delays | |||
for i = 1, count do | |||
css:wikitext(string.format( | |||
'.stonecutting-carousel .sc-frame:nth-child(%d){animation-delay:%ds;}', | |||
i, (i - 1) * 4 | |||
)) | |||
end | |||
-- keyframes: visible for its whole slice, invisible otherwise | |||
css:wikitext('@keyframes sc-cycle{') | |||
css:wikitext(string.format('0%%{opacity:1;} %.2f%%{opacity:1;}', pct)) | |||
css:wikitext(string.format('%.2f%%{opacity:0;} 100%%{opacity:0;}', pct + 0.01)) | |||
css:wikitext('}') | |||
outer:wikitext(tostring(css)) | |||
return tostring(outer) | |||
end | end | ||
return p | return p | ||
Revision as of 21:56, 13 June 2025
Documentation for this module may be created at Module:Stonecutting/doc
------------------------------------------------------------
-- Stone-cutter recipe carousel
-- Usage example:
-- {{Stonecutting
-- |input=Stone
-- |input-image=Minecraft-stone.png
-- |input-link=https://minecraft.wiki/w/Stone
-- |output1=Slab
-- |output1-image=Minecraft-stoneslab.png
-- |output1-link=https://minecraft.wiki/w/Slab
-- |output2=Chisel
-- |output2-image=Pixelmon-chisel.png
-- |output2-link=Chisel
-- }}
------------------------------------------------------------
local p = {}
local getArgs = require('Module:Arguments').getArgs
------------------------------------------------------------------------
-- tiny helper that turns {label,image,link} → [[File:...]] or text
------------------------------------------------------------------------
local function slotImage(label, image, link)
if not label or label == '' then return '' end
local file = image ~= '' and image or ('Grid_' .. label .. '.png')
local alt = label
local linkTarget = link ~= '' and link or label
return string.format(
'[[File:%s|32px|class=pixelated|link=%s|alt=%s]]',
file, linkTarget, alt
)
end
------------------------------------------------------------------------
-- build a single frame (= one output variant)
------------------------------------------------------------------------
local function buildFrame(args, idx)
local inputL , inputI , inputLink = args.input or args[1] ,
args['input-image'] or '',
args['input-link'] or ''
local outL = args['output'..idx] or args[idx+1] or ''
local outI = args['output'..idx..'-image'] or ''
local outLink= args['output'..idx..'-link'] or ''
local html = mw.html.create('div'):addClass('sc-frame')
html:wikitext('[[File:StonecutterGUI.png|180px|link=|alt=]]')
-- input slot (left, 48 × 48 px area)
local inp = html:tag('div'):addClass('sc-slot'):css{left='11px', top='50px'}
inp:wikitext(slotImage(inputL, inputI, inputLink))
-- Stonecutting Type (middle)
local out = html:tag('div'):addClass('sc-slot'):css{left='56.5px', top='23px'}
out:wikitext(slotImage(outL, outI, outLink))
-- output slot (right)
local out = html:tag('div'):addClass('sc-slot'):css{left='127px', top='50px'}
out:wikitext(slotImage(outL, outI, outLink))
return tostring(html)
end
------------------------------------------------------------------------
-- main entry
------------------------------------------------------------------------
function p.carousel(frame)
local args = getArgs(frame, {removeBlanks = false})
-- count outputs (ignore blanks and whitespace-only params)
local count = 0
while true do
local raw = args['output' .. (count + 1)] or args[count + 2]
if not raw then break end -- truly missing
if mw.text.trim(tostring(raw)) == '' then break end -- empty / spaces
count = count + 1
end
if count == 0 then
return "<span style='color:red'>Stonecutting: no outputs supplied</span>"
end
-- build 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
-- attach TemplateStyles (base rules) ----------------------------
local styleBase = frame:extensionTag(
'templatestyles', '', { src = 'Template:Stonecutting/styles.css' }
)
outer:wikitext(styleBase)
------------------------------------------------------------------
-- Dynamically adjust animation timing to the number of frames
------------------------------------------------------------------
local dur = count * 4 -- seconds, 4 s per recipe
local pct = 100 / count -- % slice per recipe
local css = mw.html.create('style'):attr('type', 'text/css')
-- main animation rule with variable duration
css
:wikitext(string.format(
'.stonecutting-carousel .sc-frame{animation:sc-cycle %ds steps(1) infinite;}',
dur
))
-- per-frame delays
for i = 1, count do
css:wikitext(string.format(
'.stonecutting-carousel .sc-frame:nth-child(%d){animation-delay:%ds;}',
i, (i - 1) * 4
))
end
-- keyframes: visible for its whole slice, invisible otherwise
css:wikitext('@keyframes sc-cycle{')
css:wikitext(string.format('0%%{opacity:1;} %.2f%%{opacity:1;}', pct))
css:wikitext(string.format('%.2f%%{opacity:0;} 100%%{opacity:0;}', pct + 0.01))
css:wikitext('}')
outer:wikitext(tostring(css))
return tostring(outer)
end
return p