diff --git a/druid/color.lua b/druid/color.lua index 38a1537..0d0634d 100644 --- a/druid/color.lua +++ b/druid/color.lua @@ -1,18 +1,21 @@ ---@alias color vector4|vector3|string +---Color palette and utility functions for working with colors. +---Supports palette management, hex conversion, RGB/HSB conversion, and color interpolation. +---@class druid.palette +local M = {} + local PALETTE_DATA = {} local COLOR_WHITE = vmath.vector4(1, 1, 1, 1) local COLOR_X = hash("color.x") local COLOR_Y = hash("color.y") local COLOR_Z = hash("color.z") -local ALPHA = hash("color.w") - -local M = {} ----Get color by string (hex or from palette) ----@param color_id string|vector4 Color id from palette or hex color ----@return vector4 +---Get color by ID from palette, hex string, or return vector as-is. +---If color_id is not found in palette and not a hex string, returns white. +---@param color_id string|vector4|vector3 Color id from palette, hex color string, or vector +---@return vector4|vector3 function M.get_color(color_id) if type(color_id) ~= "string" then return color_id @@ -33,8 +36,8 @@ function M.get_color(color_id) end ----Add palette to palette data ----@param palette_data table +---Add colors to palette. Colors can be hex strings or vector4 values. +---@param palette_data table Table with color IDs as keys function M.add_palette(palette_data) for color_id, color in pairs(palette_data) do if type(color) == "string" then @@ -46,14 +49,16 @@ function M.add_palette(palette_data) end +---Get all palette colors. +---@return table function M.get_palette() return PALETTE_DATA end ----Set color of gui node without changing alpha +---Set GUI node color. Does not change alpha. ---@param gui_node node ----@param color vector4|vector3|string Color in vector4, vector3 or color id from palette +---@param color vector4|vector3|string function M.set_color(gui_node, color) if type(color) == "string" then color = M.get_color(color) @@ -65,11 +70,11 @@ function M.set_color(gui_node, color) end ----Lerp colors via color HSB values ----@param t number Lerp value. 0 - color1, 1 - color2 ----@param color1 vector4 Color 1 ----@param color2 vector4 Color 2 ----@return vector4 result Color between color1 and color2 +---Interpolate between two colors using HSB space (better visual results than RGB). +---@param t number Lerp value (0 = color1, 1 = color2) +---@param color1 vector4 +---@param color2 vector4 +---@return vector4 function M.lerp(t, color1, color2) local h1, s1, v1 = M.rgb2hsb(color1.x, color1.y, color1.z) local h2, s2, v2 = M.rgb2hsb(color2.x, color2.y, color2.z) @@ -84,8 +89,8 @@ function M.lerp(t, color1, color2) end ----Convert hex color to rgb values. ----@param hex string Hex color. #00BBAA or 00BBAA or #0BA or 0BA +---Convert hex string to RGB values (0-1 range). Supports #RGB and #RRGGBB formats. +---@param hex string ---@return number, number, number function M.hex2rgb(hex) if not hex or #hex < 3 then @@ -102,9 +107,9 @@ function M.hex2rgb(hex) end ----Convert hex color to vector4. ----@param hex string Hex color. #00BBAA or 00BBAA or #0BA or 0BA ----@param alpha number|nil Alpha value. Default is 1 +---Convert hex string to vector4. +---@param hex string +---@param alpha number|nil Default is 1 ---@return vector4 function M.hex2vector4(hex, alpha) local r, g, b = M.hex2rgb(hex) @@ -112,11 +117,12 @@ function M.hex2vector4(hex, alpha) end ----Convert hsb color to rgb colo ----@param r number Red value ----@param g number Green value ----@param b number Blue value ----@param alpha number|nil Alpha value. Default is 1 +---Convert RGB to HSB. +---@param r number +---@param g number +---@param b number +---@param alpha number|nil +---@return number, number, number, number function M.rgb2hsb(r, g, b, alpha) alpha = alpha or 1 local min, max = math.min(r, g, b), math.max(r, g, b) @@ -136,17 +142,16 @@ function M.rgb2hsb(r, g, b, alpha) h = (h / 6) % 1 end - alpha = alpha > 1 and alpha / 100 or alpha - return h, s, v, alpha end ----Convert hsb color to rgb color ----@param h number Hue ----@param s number Saturation ----@param v number Value ----@param alpha number|nil Alpha value. Default is 1 +---Convert HSB to RGB. +---@param h number +---@param s number +---@param v number +---@param alpha number|nil +---@return number, number, number, number|nil function M.hsb2rgb(h, s, v, alpha) local r, g, b local i = math.floor(h * 6) @@ -169,10 +174,11 @@ function M.hsb2rgb(h, s, v, alpha) end ----Convert rgb color to hex color ----@param red number Red value ----@param green number Green value ----@param blue number Blue value +---Convert RGB to hex string (uppercase, without #). +---@param red number +---@param green number +---@param blue number +---@return string function M.rgb2hex(red, green, blue) local r = string.format("%x", math.floor(red * 255)) local g = string.format("%x", math.floor(green * 255)) @@ -181,15 +187,14 @@ function M.rgb2hex(red, green, blue) end +-- Auto-load palette from config if druid.palette_path is set in game.project local DEFAULT_PALETTE_PATH = sys.get_config_string("druid.palette_path") if DEFAULT_PALETTE_PATH then local loaded_palette = sys.load_resource(DEFAULT_PALETTE_PATH) local data = loaded_palette and json.decode(loaded_palette) - if not data then - return + if data then + M.add_palette(data) end - - M.add_palette(data) end