Module:Map
Jump to navigation
Jump to search
Documentation for this module may be created at Module:Map/doc
local p = {}
local func = require('Module:Func')
local function icon(root, index, x, y, link, caption, item)
-- Assumes that item is either nil, or contains the correct sprite. See the main function
-- Icon span anchor - sets the position of the elements
local anchor = root
:tag('div')
:css('position', 'absolute')
:css('left', tostring(x) .. '%')
:css('top', tostring(y) .. '%')
:css('pointer-events', 'none')
-- Icon span offset - shifts the position of the elements so that they're centered on the top-left corner
-- Image span
local image = anchor
:tag('span')
:css('position', 'absolute')
:css('pointer-events', 'auto')
:addClass('pixelart')
local str
if link then
str = 'link=' .. link .. '|'
else
str = 'link=|'
end
if item then
str = '[[Image:MapChest.png|' .. str
image:css('transform', 'translate(-50%, -50%) scale(1.3,1.3)')
else
str = '[[Image:circle.png|' .. str
image:css('transform', 'translate(-50%, -50%)')
end
image:wikitext(str .. caption .. ']]')
-- Inner content - text or sprite
local content = anchor
:tag('span')
:css('position', 'absolute')
:css('transform', 'translate(-50%, -50%)')
if item then
content
:addClass('pixelart')
:wikitext('[[Image:' ..item.. '|link=|25x25px|' .. caption .. ']]')
else
content
:css('color', 'white')
:css('font-weight', 'bold')
:wikitext(tostring(index))
end
end
local nil_if_empty = func.nil_if_empty
local limit_range = func.limit_range
local is_empty = func.is_empty
function p.main(frame)
local args = frame.args
local image = nil_if_empty(args['image']) or 'Placeholder.png'
local width = tonumber(args['imageWidth']) or 64
local height = tonumber(args['imageHeight']) or 64
local anchor = nil_if_empty(args['anchor'])
local legend = nil_if_empty(args['legend']) or 'Locations'
local groups = limit_range(1, 5, tonumber(args['groups']) or 3)
local offsetX = tonumber(args['imageStartX']) or 0
local offsetY = tonumber(args['imageStartY']) or 0
-- Doesn't really work as I'd like it to, but it will have to do for now
local imageScale = limit_range(0.1, 5, tonumber(args['imageScale']) or 1)
width = width * imageScale
height = height * imageScale
-- Specified in %, refers to max-width
local containerWidth = limit_range(0, 100, tonumber(args['containerWidth']) or 100)
-- Specified in px
local containerHeight = limit_range(0, 1080, tonumber(args['containerHeight']) or 720)
-- Specified in %, refers to width
local elementWidth = limit_range(0, 90, tonumber(args['elementWidth']) or 90)
-- Specified in px
local devContainerHeight = height
if devContainerHeight > containerHeight then
devContainerHeight = containerHeight
end
-- Other Params
local positions = {}
local trueIndex = 1
for i = 1,32 do
-- Get the positions
local arg = 'pos' .. tostring(i)
if not is_empty(args[arg]) then
positions[trueIndex] = {
['index'] = i,
['caption'] = args[arg],
['link'] = nil_if_empty(args[arg .. 'link']),
['x'] = nil_if_empty(args[arg .. 'x']) or 50,
['y'] = nil_if_empty(args[arg .. 'y']) or 50,
['item'] = nil_if_empty(args[arg .. 'item'])
}
trueIndex = trueIndex + 1
end
end
-- Container for the element
local root = mw.html.create('div')
root
:css('border', '1px #ccc solid')
:css('width', elementWidth .. '%')
:css('padding', '8px')
:css('margin-left', 'auto')
:css('margin-right', 'auto')
:css('margin-top', '8px')
:css('margin-bottom', '8px')
-- Create anchor
if anchor ~= nil then
root
:attr('id', anchor)
end
-- Map container:
-- Div tag for hiding overflow
-- Div tag with width and height set to image size (for icon positions)
-- Span tag for JavaScript position changing
local container = root
:tag('div')
:css('width', containerWidth .. '%')
:css('max-height', containerHeight .. 'px') -- To fix placement inside containers
:css('min-height', devContainerHeight .. 'px') -- To fix placement inside containers
:css('max-width', width .. 'px')
:css('margin-left', 'auto')
:css('margin-right', 'auto')
:css('overflow', 'hidden')
:css('border', '1px solid blue')
:css('position', 'relative') -- To fix placement inside containers
:tag('div')
:css('position', 'relative')
:css('left', '0px')
:css('top', '0px')
:css('width', width .. 'px')
:css('height', height .. 'px')
:css('overflow', 'hidden')
:css('position', 'absolute') -- To fix placement inside containers
:addClass('overview-map')
:tag('span')
:css('position', 'absolute')
:css('width', '100%')
:css('height', '100%')
:css('left', offsetX .. 'px')
:css('top', offsetY .. 'px')
:addClass('overview-map-pos')
-- Image wrapper
container
:tag('span')
:css('position', 'absolute')
:css('left', '0px')
:css('top', '0px')
:wikitext('[[Image:' .. image .. '|' .. math.floor(width) .. 'x' .. math.floor(height) .. 'px|link=]]')
-- Create icons
-- Also processes the item fields and turns them to sprites, or nil, for repeated use in cell content
for i=1,#positions do
value = positions[i]
item = value['item']
if item ~= nil then
-- Try to retrieve sprite
local module = require('Module:Item')
if module then
item = module.data({["args"] = {item, "sprite", ["softErrors"] = true}})
if item == "Error" then
item = 'Placeholder.png'
end
else
item = nil
end
end
icon(container, value['index'], value['x'], value['y'], value['link'], value['caption'], item)
value['item'] = item
end
-- Create notice about drag feature
root
:tag('div')
:css('margin-left', 'auto')
:css('margin-right', 'auto')
:css('margin-top', '4px')
:css('margin-bottom', '8px')
:css('text-align', 'center')
:css('font-style', 'italic')
:wikitext('You can move the map around by dragging')
-- Create legend
local legendTable = root
:tag('div')
:css('margin', '0px')
:css('padding', '16px 0px 16px 0px')
:tag('table')
:css('border', '2px solid black')
:css('width', '100%')
:css('line-height', '1.0')
:css('table-layout', 'fixed')
-- Legend title ( wikitext bold styling is escaped)
legendTable
:tag('tr')
:tag('td')
:attr('colspan', tostring(groups))
:css('text-align', 'center')
:wikitext('\'\'\'' .. legend .. '\'\'\'')
-- Contents (balanced across groups)
-- Will not generate more cells than needed
local current = 0
for i=1,#positions do
value = positions[i]
if current == 0 then
legendTable = legendTable
:tag('tr')
end
local cellContent
if value['item'] ~= nil then
-- Use sprite
cellContent = frame:expandTemplate{ title = 'ItemLink', args = { image = value['item'], label = value['caption'], article = value['link'] } }
else
cellContent = '\'\'\'' .. value['index'] .. '\'\'\'. '
if value['link'] ~= nil then
cellContent = cellContent .. '[[' .. value['link'] .. '|' .. value['caption'] .. ']]'
else
cellContent = cellContent .. value['caption']
end
end
legendTable
:tag('td')
:css('vertical-align', 'top')
:wikitext(cellContent)
current = current + 1
if current >= groups then
legendTable = legendTable
:done()
current = 0
end
end
return tostring(root)
end
return p