oxygen modules
-- This module displays a radial (circular) progress indicator based on images and config information
-- that is generated at https://eryn.io/RadialSpriteSheetGenerator/
-- @readme https://github.com/evaera/RadialSpriteSheetGenerator/blob/master/README.md
-- @author evaera
local HttpService = game:GetService("HttpService")
local ContentProvider = game:GetService("ContentProvider")
local RadialImage = { _version = 1 }
RadialImage.__index = RadialImage
local ConfigurationProperties = {
version = "number";
size = "number";
count = "number";
columns = "number";
rows = "number";
images = "table";
}
function RadialImage.new(config, label)
if type(config) == "string" then
config = HttpService:JSONDecode(config)
elseif type(config) ~= "table" then
error("Argument #1 (configuration) must be a JSON string or table.", 2)
end
for k, v in pairs(config) do
if ConfigurationProperties[k] == nil then
error(("Invalid property name in Radial Image configuration: %s"):format(k), 2)
end
if type(v) ~= ConfigurationProperties[k] then
error(("Invalid property type %q in Radial Image configuration: must be a %s."):format(k, ConfigurationProperties[k]), 2)
end
end
if config.version ~= RadialImage._version then
error(("Passed configuration version does not match this module's version (which is %d)"):format(RadialImage._version), 2)
end
local self = { config = config; label = label }
setmetatable(self, RadialImage)
return self
end
function RadialImage:Preload()
if self.label == nil then
error("You must provide a label to RadialImage.new to use Preload", 2)
end
self.labels = {}
for _, image in ipairs(self.config.images) do
local label = self.label:Clone()
label.Image = image
label.Visible = true
label.Size = UDim2.new(0, 0, 0, 0)
label.Parent = self.label.Parent
table.insert(self.labels, label)
end
ContentProvider:PreloadAsync(self.labels)
for _, label in ipairs(self.labels) do
label.Visible = false
end
end
function RadialImage:Destroy()
for _, label in ipairs(self.labels) do
label:Destroy()
end
self.labels = nil
end
function RadialImage:GetFromAlpha(alpha)
if type(alpha) ~= "number" then
error("Argument #1 (alpha) to GetFromAlpha must be a number.", 2)
end
local count, size, columns, rows = self.config.count, self.config.size, self.config.columns, self.config.rows
local index = alpha >= 1 and count - 1 or math.floor(alpha * count)
local page = math.floor(index / (columns * rows)) + 1
local pageIndex = index - (columns * rows * (page - 1))
local x = (pageIndex % columns) * size
local y = math.floor(pageIndex / columns) * size
return x, y, page
end
function RadialImage:UpdateLabel(alpha, label)
label = label or self.label
if type(alpha) ~= "number" then
error("Argument #1 (alpha) to UpdateLabel must be a number.", 2)
end
if typeof(label) ~= "Instance" or not (label:IsA("ImageLabel") or label:IsA("ImageButton")) then
error("Attempt to update label but no label has been given. Either pass the label as argument #2 to \"new\", or as argument #2 to \"UpdateLabel\".", 2)
end
local x, y, page = self:GetFromAlpha(alpha)
label.ImageRectSize = Vector2.new(self.config.size, self.config.size)
label.ImageRectOffset = Vector2.new(x, y)
label.Image = alpha <= 0 and "" or self.config.images[page]
end
return RadialImageINFO