Difference between revisions of "Module:Sprite"

From Gamemode 4
Jump to navigation Jump to search
(removed stringify so that html object can still be used)
(21 intermediate revisions by the same user not shown)
Line 5: Line 5:
 
local types = {
 
local types = {
 
inventory = [[Module:InvSprite]],
 
inventory = [[Module:InvSprite]],
 +
gm4 = [[Module:Gm4Sprite]],
 +
effect = [[Module:EffectSprite]]
 
}
 
}
  
Line 14: Line 16:
 
align = 'text-top'
 
align = 'text-top'
 
}
 
}
 +
 +
function getImage( image )
 +
if not(image) then return nil end
 +
local file = mw.title.new(image,"File").file
 +
if not(file.exists) then return nil end
 +
 +
 +
local f = mw.getCurrentFrame()
 +
local t = {
 +
url = f:expandTemplate{
 +
title = 'FileUrl',
 +
args = {image}
 +
}
 +
}
 +
 +
setmetatable(t, {__index = file})
 +
 +
return t
 +
end
 +
 +
function getSpriteSheet( image )
 +
if not(image) then return nil end
 +
 +
 +
local f = mw.getCurrentFrame()
 +
local t = {
 +
url = f:expandTemplate{
 +
title = 'SpriteSheet',
 +
args = {image}
 +
}
 +
}
 +
if t == "" then return nil end
 +
 +
return t
 +
end
  
 
function Sprite:new (type)
 
function Sprite:new (type)
source = types[type]
+
local source = types[type]
 
if not(source) then
 
if not(source) then
 
error("Unknown type: " .. tostring(type))
 
error("Unknown type: " .. tostring(type))
 
end
 
end
 
o = {
 
o = {
__source = require(source),
+
__source = require(source),
 
}
 
}
 
setmetatable(o, {__index = self})
 
setmetatable(o, {__index = self})
 
o:load()
 
o:load()
 +
return o
 +
end
 +
 +
Sprite.Custom = {}
 +
setmetatable(Sprite.Custom, {__index = Sprite})
 +
local CustomSprite = Sprite.Custom
 +
 +
function CustomSprite:new(name, imagename)
 +
local image = getImage(imagename)
 +
if not(image) then
 +
error("Couldn't find image: " .. tostring(imagename))
 +
end
 +
 +
local size = image.width
 +
 +
 +
o = {
 +
__source = {
 +
settings = {}
 +
},
 +
__settings={
 +
size = size,
 +
sheetsize = 1,
 +
image = image,
 +
sheetWidth = size,
 +
tiles = 1,
 +
name = name
 +
}
 +
}
 +
setmetatable(o, {__index = self})
 +
setmetatable(o.__settings, {__index=defaultSettings})
 
return o
 
return o
 
end
 
end
Line 36: Line 104:
 
scale = settings.scale,
 
scale = settings.scale,
 
autoScale = settings.autoscale,
 
autoScale = settings.autoscale,
 +
image = (settings.image and getImage(settings.image))
 +
or (settings.spriteSheet and getSpriteSheet(settings.spriteSheet))
 
}
 
}
local lSet = self.__settings
 
  
setmetatable(lSet, {__index=defaultSettings})
+
setmetatable(self.__settings, {__index=defaultSettings})
 
 
 
 
styles = {}
 
--[[styles["background-image"] = (settings.url and "url(" .. settings.url .. ")") or mw.getCurrentFrame():expandTemplate{
 
title = 'FileUrl',
 
args = { settings.image}
 
} ]]
 
styles["background-size"] = lSet.sheetWidth * lSet.scale .. 'px auto'
 
 
 
local t = lSet.size * lSet.scale .. 'px'
 
 
 
styles.height = t
 
styles.width = t
 
styles["vertical-align"] = lSet.align
 
self.__styles = styles
 
 
end
 
end
  
 
function Sprite:setItem(item)
 
function Sprite:setItem(item)
 +
self.__settings.name = item;
 
if self.__source.ids[item] then
 
if self.__source.ids[item] then
 
self:setPosition(self.__source.ids[item].pos)
 
self:setPosition(self.__source.ids[item].pos)
Line 69: Line 124:
 
local sprite = {}
 
local sprite = {}
 
setmetatable(sprite, {__index = self})
 
setmetatable(sprite, {__index = self})
 +
local settings = {}
 +
setmetatable(settings, {__index = self.__settings})
 +
sprite.__settings = settings
 
return sprite:setItem(item)
 
return sprite:setItem(item)
 
end
 
end
  
 
function Sprite:setPosition(pos)
 
function Sprite:setPosition(pos)
 +
self.__settings.pos = pos or self.__settings.pos
 +
return self
 +
end
 +
 +
function Sprite:SetScale(scale)
 +
self.__settings.scale = scale
 +
return self
 +
end
 +
 +
function Sprite:SetSize(size)
 +
self.__settings.scale = size / self.__settings.size
 +
return self
 +
end
 +
 +
function Sprite:calculateStyles()
 +
styles = {}
 +
function append(key, value) if value ~= nil then styles[#styles+1]=key .. ": " .. value end end
 
local settings = self.__settings
 
local settings = self.__settings
  
local pos = (pos or settings.pos) - 1
+
-- has to be done first, otherwise the possition is overriden in chrome
 +
if settings.image then
 +
append("background", settings.image.url)
 +
end
  
 +
append ("background-size", settings.sheetWidth * settings.scale .. 'px auto')
 +
 +
local t = settings.size * settings.scale .. 'px'
 +
 +
append ("height", t)
 +
append ("width", t)
 +
append ("vertical-align", settings.align)
 +
 +
local pos = self.__settings.pos - 1
 
local left = pos % settings.tiles * settings.size * settings.scale
 
local left = pos % settings.tiles * settings.size * settings.scale
 
local top = math.floor( pos / settings.tiles ) * settings.size * settings.scale
 
local top = math.floor( pos / settings.tiles ) * settings.size * settings.scale
self.__styles["background-position"] = '-' .. left .. 'px -' .. top .. 'px'
+
append("background-position", '-' .. left .. 'px -' .. top .. 'px')
  
settings.pos = pos
+
 
return self
+
return table.concat( styles, "; " )
 
end
 
end
  
function Sprite:GenerateHTML ()
+
function Sprite:GenerateHTML (html)
local sprite = mw.html.create( 'div' ):addClass( 'sprite' )
+
local sprite
 +
if html then
 +
if type(html) == "string" then
 +
sprite = mw.html.create(html)
 +
else
 +
sprite = html:tag("div")
 +
end
 +
else
 +
sprite = mw.html.create("div")
 +
end
  
 +
sprite:addClass("sprite")
 +
sprite:addClass("masterTooltip")
  
 
local source = self.__source
 
local source = self.__source
 
sprite:addClass(source.settings.classname)
 
sprite:addClass(source.settings.classname)
 +
sprite:attr( "title", self.__settings.name )
  
local styles = {}
+
local styles = self:calculateStyles()
for k,v in pairs(self.__styles) do
+
sprite:cssText( styles )
styles[#styles + 1] = k .. ":" .. v
+
sprite:attr("data-styles", styles)
end
 
 
 
sprite:cssText( table.concat( styles, '; ' ) )
 
  
 
return sprite
 
return sprite

Revision as of 20:48, 30 June 2020

Documentation for this module may be created at Module:Sprite/doc

-- Based on work by the MC wiki: https://minecraft.gamepedia.com/ and https://minecraft.gamepedia.com/Module:Sprite

local Sprite = {}

local types = {
	inventory = [[Module:InvSprite]],
	gm4 = [[Module:Gm4Sprite]],
	effect = [[Module:EffectSprite]]
}

local defaultSettings = {
	scale = 1,
	sheetsize = 256,
	size = 16,
	pos = 1,
	align = 'text-top'
}

function getImage( image )
	if not(image) then return nil end
	local file = mw.title.new(image,"File").file
	if not(file.exists) then return nil end


	local f = mw.getCurrentFrame()
	local t = {
		url = f:expandTemplate{
			title = 'FileUrl',
			args = {image}
		}
	}

	setmetatable(t, {__index = file})

	return t
end

function getSpriteSheet( image )
	if not(image) then return nil end


	local f = mw.getCurrentFrame()
	local t = {
		url = f:expandTemplate{
			title = 'SpriteSheet',
			args = {image}
		}
	}
	if t == "" then return nil end

	return t
end

function Sprite:new (type)
	local source = types[type]
	if not(source) then
		error("Unknown type: " .. tostring(type))
	end
	o = {
			__source = require(source),
		}
	setmetatable(o, {__index = self})
	o:load()
	return o
end

Sprite.Custom = {}
setmetatable(Sprite.Custom, {__index = Sprite})
local CustomSprite = Sprite.Custom

function CustomSprite:new(name, imagename)
	local image = getImage(imagename)
	if not(image) then
		error("Couldn't find image: " .. tostring(imagename))
	end

	local size = image.width


	o = {
			__source = {
				settings = {}
			},
			__settings={
				size = size,
				sheetsize = 1,
				image = image,
				sheetWidth = size,
				tiles = 1,
				name = name
			}
		}
	setmetatable(o, {__index = self})
	setmetatable(o.__settings, {__index=defaultSettings})
	return o
end

function Sprite:load()
	local settings = self.__source.settings
	self.__settings = {
		size = settings.size,
		sheetWidth = settings.sheetsize,
		tiles = settings.sheetsize / settings.size,
		scale = settings.scale,
		autoScale = settings.autoscale,
		image = (settings.image and getImage(settings.image))
			or (settings.spriteSheet and getSpriteSheet(settings.spriteSheet))
	}

	setmetatable(self.__settings, {__index=defaultSettings})
end

function Sprite:setItem(item)
	self.__settings.name = item;
	if self.__source.ids[item] then
		self:setPosition(self.__source.ids[item].pos)
	else
		self:setPosition(nil) --will use default
	end
	return self
end

function Sprite:Item(item)
	local sprite = {}
	setmetatable(sprite, {__index = self})
	local settings = {}
	setmetatable(settings, {__index = self.__settings})
	sprite.__settings = settings
	return sprite:setItem(item)
end

function Sprite:setPosition(pos)
	self.__settings.pos = pos or self.__settings.pos
	return self
end

function Sprite:SetScale(scale)
	self.__settings.scale = scale
	return self
end

function Sprite:SetSize(size)
	self.__settings.scale = size / self.__settings.size
	return self
end

function Sprite:calculateStyles()
	styles = {}
	function append(key, value) if value ~= nil then styles[#styles+1]=key .. ": " .. value end end
	local settings = self.__settings

	-- has to be done first, otherwise the possition is overriden in chrome
	if settings.image then
		append("background", settings.image.url)
	end

	append ("background-size", settings.sheetWidth * settings.scale .. 'px auto')

	local t = settings.size * settings.scale .. 'px'

	append ("height", t)
	append ("width", t)
	append ("vertical-align", settings.align)

	local pos = self.__settings.pos - 1
	local left = pos % settings.tiles * settings.size * settings.scale
	local top = math.floor( pos / settings.tiles ) * settings.size * settings.scale
	append("background-position", '-' .. left .. 'px -' .. top .. 'px')


	return table.concat( styles, "; " )
end

function Sprite:GenerateHTML (html)
	local sprite
	if html then
		if type(html) == "string" then
			sprite = mw.html.create(html)
		else
			sprite = html:tag("div")
		end
	else
		sprite = mw.html.create("div")
	end

	sprite:addClass("sprite")
	sprite:addClass("masterTooltip")

	local source = self.__source
	sprite:addClass(source.settings.classname)
	sprite:attr( "title", self.__settings.name )

	local styles =  self:calculateStyles()
	sprite:cssText( styles )
	sprite:attr("data-styles", styles)

	return sprite
end

return Sprite