Module:ItemBox: Difference between revisionsGive feedback
Jump to navigation
Jump to search
m comments update |
m Use Module:TextFit instead of own implementation |
||
| Line 1: | Line 1: | ||
local p = {} | local p = {} | ||
local ustring = mw.ustring | local ustring = mw.ustring | ||
local textfit = require "Module:TextFit" | |||
-- ============================================================================ | -- ============================================================================ | ||
-- | -- Name box geometry, in em of .itembox's font-size (1em = 10px at size=1). | ||
-- | -- Mirrors Template:ItemBox/styles.css: | ||
-- | -- .itembox width: 8em | ||
-- .itembox-name-area height: 4.5em; padding: 0.5em 0.4em (border-box) | |||
-- .itembox-name line-height: 1.2; font-size: 1.5em (overridden inline) | |||
-- so the name's content box is 8 - 2*0.4 = 7.2em wide and 4.5 - 2*0.5 = 3.5em | |||
-- tall. Keep these in step with that stylesheet. | |||
-- Glyph widths live in [[Module:TextFit]]. | |||
-- ============================================================================ | -- ============================================================================ | ||
local | local NAME_W = 7.2 | ||
local NAME_H = 3.5 | |||
local LINE_H = 1.2 | |||
local MAX_EM = 1.5 | |||
local MIN_EM = 0.8 | |||
local SNAP_EM = 0.05 -- keep emitted sizes on a tidy grid | |||
local LINE_H | |||
local | |||
local | |||
local | |||
-- Returns the name font size as an em string (scales with the card). | -- Returns the name font size as an em string (scales with the card). | ||
function p.getFontSize(frame) | function p.getFontSize(frame) | ||
local name = ustring.gsub(frame.args[1] or "", "^%s*(.-)%s*$", "%1") | local name = ustring.gsub(frame.args[1] or "", "^%s*(.-)%s*$", "%1") | ||
if name == "" then return string.format("%.2f", | if name == "" then return string.format("%.2f", MAX_EM) end | ||
local | local pct = textfit.fit(name, { | ||
aspect = NAME_H / NAME_W, | |||
lineHeight = LINE_H, | |||
max = MAX_EM / NAME_W * 100, | |||
min = MIN_EM / NAME_W * 100, | |||
bold = true, -- .itembox-name is font-weight: bold | |||
}) | |||
return string.format("%.2f", | -- fit() returns a percentage of the usable width. Convert back to em and | ||
-- coarsen downward, so a snapped value still fits. The epsilon guards | |||
-- against binary representation: 1.45 / 0.05 is 28.999999999999996, which | |||
-- would otherwise floor a whole grid step too low. | |||
local em = math.floor(pct / 100 * NAME_W / SNAP_EM + 1e-9) * SNAP_EM | |||
return string.format("%.2f", math.max(em, MIN_EM)) | |||
end | end | ||
Revision as of 18:15, 1 August 2026
Documentation for this module may be created at Module:ItemBox/doc
local p = {}
local ustring = mw.ustring
local textfit = require "Module:TextFit"
-- ============================================================================
-- Name box geometry, in em of .itembox's font-size (1em = 10px at size=1).
-- Mirrors Template:ItemBox/styles.css:
-- .itembox width: 8em
-- .itembox-name-area height: 4.5em; padding: 0.5em 0.4em (border-box)
-- .itembox-name line-height: 1.2; font-size: 1.5em (overridden inline)
-- so the name's content box is 8 - 2*0.4 = 7.2em wide and 4.5 - 2*0.5 = 3.5em
-- tall. Keep these in step with that stylesheet.
-- Glyph widths live in [[Module:TextFit]].
-- ============================================================================
local NAME_W = 7.2
local NAME_H = 3.5
local LINE_H = 1.2
local MAX_EM = 1.5
local MIN_EM = 0.8
local SNAP_EM = 0.05 -- keep emitted sizes on a tidy grid
-- Returns the name font size as an em string (scales with the card).
function p.getFontSize(frame)
local name = ustring.gsub(frame.args[1] or "", "^%s*(.-)%s*$", "%1")
if name == "" then return string.format("%.2f", MAX_EM) end
local pct = textfit.fit(name, {
aspect = NAME_H / NAME_W,
lineHeight = LINE_H,
max = MAX_EM / NAME_W * 100,
min = MIN_EM / NAME_W * 100,
bold = true, -- .itembox-name is font-weight: bold
})
-- fit() returns a percentage of the usable width. Convert back to em and
-- coarsen downward, so a snapped value still fits. The epsilon guards
-- against binary representation: 1.45 / 0.05 is 28.999999999999996, which
-- would otherwise floor a whole grid step too low.
local em = math.floor(pct / 100 * NAME_W / SNAP_EM + 1e-9) * SNAP_EM
return string.format("%.2f", math.max(em, MIN_EM))
end
-- User for stable per-item texture variety
local function hash(s)
local h = 5381
for i = 1, #s do
h = (h * 33 + s:byte(i)) % 2147483647
end
return h
end
function p.variants(frame)
local h = hash(frame.args[1] or "")
local icon = (h % 3) + 1
local wear = (math.floor(h / 3) % 4) + 1
local tex = (math.floor(h / 12) % 3) + 1
return string.format("itembox-icon-v%d itembox-wear-v%d itembox-texture-v%d",
icon, wear, tex)
end
return p