Difference between revisions of "Module:Sprite"

From Gamemode 4
Jump to navigation Jump to search
(Removed bug that resulted in using the wrong sprite if the name was unkown and setPosition calculating the right position and changing the css accordingly but storing it wrong internaly (of by 1))
(16 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})
 
 
  
styles = {}
+
setmetatable(self.__settings, {__index=defaultSettings})
--[[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 76: Line 131:
  
 
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 + 1
+
return table.concat( styles, "; " )
return self
 
 
end
 
end
  
Line 91: Line 175:
 
local sprite
 
local sprite
 
if html then
 
if html then
sprite = html:tag("div")
+
if type(html) == "string" then
 +
sprite = mw.html.create(html)
 +
else
 +
sprite = html:tag("div")
 +
end
 
else
 
else
 
sprite = mw.html.create("div")
 
sprite = mw.html.create("div")
Line 97: Line 185:
  
 
sprite:addClass("sprite")
 
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