绘制类

# 为通用开发提供便利的代码片段会记录在此 **颜色扩展库** ```lua --part of the code comes from github --color color = {} local color_mt = { __index = color, __call = function(tbl, ...) return color.new_rgba(...) end } --update local function update_rgba(color) color.r = math.min(255, math.max(0, color.r)) color.g = math.min(255, math.max(0, color.g)) color.b = math.min(255, math.max(0, color.b)) color.a = math.min(255, math.max(0, color.a)) draw.Color(color.r, color.g, color.b, color.a) end local function update_hex(color) local hex = color.hex local length = hex:len() if (length == 3) then local insert = hex:sub(2) hex = hex .. insert .. insert elseif (length == 4) then hex = hex .. hex:sub(2) end local hex = hex:gsub("#", "") draw.Color(tonumber("0x" .. hex:sub(1, 2)), tonumber("0x" .. hex:sub(3, 4)), tonumber("0x" .. hex:sub(5, 6)), tonumber("0x" .. hex:sub(7, 8))) end local function update_hsv(color) local h, s, v, a = color.h, color.s, color.v, color.a local r, g, b local i = math.floor(h * 6) local f = h * 6 - i local p = v * (1 - s) local q = v * (1 - f * s) local t = v * (1 - (1 - f) * s) i = i % 6 if i == 0 then r, g, b = v, t, p elseif i == 1 then r, g, b = q, v, p elseif i == 2 then r, g, b = p, v, t elseif i == 3 then r, g, b = p, q, v elseif i == 4 then r, g, b = t, p, v elseif i == 5 then r, g, b = v, p, q end draw.Color(r * 255, g * 255, b * 255, a * 255) end --new function color.new_rgba(r, g, b, a) local object = setmetatable({r = r or 255, g = g or 255, b = b or 255, a = a or 255}, color_mt) update_rgba(object) return object end function color.new_hex(hex) local object = setmetatable({hex = hex or "#ffffffff"}, color_mt) update_hex(object) return object end function color.new_hsv(h, s, v, a) local object = setmetatable({h = h or 1, s = s or 1, v = v or 1, a = a or 1}, color_mt) update_hsv(object) return object end function color.new_from_ui_color_picker(ui_reference) local r, g, b, a = ui_reference:GetValue() return color.new_rgba(r, g, b, a) end --set function color.set_rgba(self, r, g, b, a) self.r, self.g, self.b, self.a = r, g, b, a or 255 update_rgba(self) return self end function color.set_r(self, r) self.r = r or 0 update_rgba(self) return self end function color.set_g(self, g) self.g = g or 0 update_rgba(self) return self end function color.set_b(self, b) self.b = b or 0 update_rgba(self) return self end function color.set_a(self, a) self.a = a or 0 update_rgba(self) return self end function color.set_hex(self, hex) self.hex = hex or "#ffffffff" update_hex(self) return self end function color.set_hsv(self, h, s, v, a) self.h, self.s, self.v, self.a = h, s, v, a or 1 update_hsv(self) return self end function color.set_from_ui_color_picker(self, ui_reference) local r, g, b, a = ui_reference:GetValue() self:set_rgba(r, g, b, a) return self end --unpack function color.unpack_rgba(self) return self.r, self.g, self.b, self.a end function color.unpack_hex(self) return self.hex end function color.unpack_hsv(self) return self.h, self.s, self.v, self.a end --examples local ui_color = gui.ColorPicker(gui.Reference(), "color", "color", 255, 255, 255, 255) local function on_draw() --rgba local rgba = color.new_rgba(255, 255, 255, 255):set_rgba(255, 0, 0):set_a(150):unpack_rgba() print("rgba -" .. rgba) draw.Text(100, 100, "rgba") --hex local hex = color.new_hex("#5478ffff"):set_hex("#b43d34ff"):unpack_hex() print("hex -" .. hex) draw.Text(120, 120, "hex") --hsv local hsv = color.new_hsv(globals.RealTime() * 0.1, 1, 1, 0.5):set_hsv(globals.RealTime() * 0.1, 1, 1):unpack_hsv() print("hsv -" .. hsv) draw.Text(140, 140, "hsv") --ui_color local ui_color = color.new_from_ui_color_picker(ui_color):set_from_ui_color_picker(ui_color):unpack_rgba() print("ui_color -" .. ui_color) draw.Text(160, 160, "ui_color") end callbacks.Register("Draw", on_draw) return color ``` --- **鼠标拖动** ```lua --本地api local globals_FrameCount = globals.FrameCount local math_max = math.max local math_min = math.min local table_insert = table.insert local math_modf = math.modf local draw_GetScreenSize = draw.GetScreenSize --鼠标拖动 local reference_menu = gui.Reference("menu") function dragging(parent, varname, base_x, base_y) return (function() local a = {} local b, c, d, e, f, g, h, i, j, k, l, m, n, o local p = { __index = { drag = function(self, ...) local q, r = self:get() local s, t = a.drag(q, r, ...) if q ~= s or r ~= t then self:set(s, t) end return s, t end, set = function(self, q, r) local j, k = draw_GetScreenSize() self.parent_x:SetValue(q / j * self.res) self.parent_y:SetValue(r / k * self.res) end, get = function(self) local j, k = draw_GetScreenSize() return self.parent_x:GetValue() / self.res * j, self.parent_y:GetValue() / self.res * k end } } function a.new(r, u, v, w, x) x = x or 10000 local j, k = draw_GetScreenSize() local y = gui.Slider(r, u .. "x", "position x", v / j * x, 0, x) local z = gui.Slider(r, u .. "y", "position y", w / k * x, 0, x) y:SetInvisible(true) z:SetInvisible(true) return setmetatable({parent = r, varname = u, parent_x = y, parent_y = z, res = x}, p) end function a.drag(q, r, A, B, C, D, E) if globals_FrameCount() ~= b then c = reference_menu:IsActive() f, g = d, e d, e = input.GetMousePos() i = h h = input.IsButtonDown(0x01) == true m = l l = {} o = n n = false j, k = draw_GetScreenSize() end if c and i ~= nil then if (not i or o) and h and f > q and g > r and f < q + A and g < r + B then n = true q, r = q + d - f, r + e - g if not D then q = math_max(0, math_min(j - A, q)) r = math_max(0, math_min(k - B, r)) end end end table_insert(l, {q, r, A, B}) return q, r, A, B end return a end)().new(parent, varname, base_x, base_y) end --演示 local reference = gui.Reference("misc") local dragging_example = dragging(reference, "演示", 200, 200) --参考, 变量名, 屏幕位置 X, 屏幕位置 Y dragging_example:set(0, 0) --设置 x, y callbacks.Register( "Draw", function() local x, y = dragging_example:get() --获取 x, y dragging_example:drag(200, 200) --启用拖动 拖动范围 draw.FilledRect(x, y, x + 200, y + 200) draw.Color(0, 0, 0, 255) draw.Text(x, y, "演示") end ) ``` --- **渐变矩形** ```lua local math_abs = math.abs --assert / 检查 local function assert(expression, message, level, ...) if (not expression) then error(string.format(message, ...), 4) end end local function bad_argument(expression, name, expected) assert(type(expression) == expected, " bad argument #1 to '%s' (%s expected, got %s)", 4, name, expected, tostring(type(expression))) end --[[ rect_filled_fade syntax: draw.rect_filled_fade(x1, y1, x2, y2, r1, g1, b1, a1, r2, g2, b2, a2, ltr) x1 - Screen coordinate of point A / A点屏幕坐标 y1 - Screen coordinate of point A / A点屏幕坐标 x2 - Screen coordinate of point B / B点屏幕坐标 y2 - Screen coordinate of point B / B点屏幕坐标 r1 - Red (0-255) / 红色 (0-255) g1 - Green (0-255) / 绿色 (0-255) b1 - Blue (0-255) / 蓝色 (0-255) a1 - Alpha (0-255) / 透明度 (0-255) r2 - Red (0-255) / 红色 (0-255) g2 - Green (0-255) / 绿色 (0-255) b2 - Blue (0-255) / 蓝色 (0-255) a2 - Alpha (0-255) / 透明度 (0-255) ltr - Left to right. Pass true for horizontal gradient, or false or nil for vertical. / 从左到右. 对于水平渐变, 则传递true, 对于垂直渐变, 则传递false或者nil. ]] function draw.rect_filled_fade(x1, y1, x2, y2, r1, g1, b1, a1, r2, g2, b2, a2, ltr) bad_argument(x1 and y1 and x2 and y2 and r1 and g1 and b1 and a1, "rect_filled_fade", "number") local abs_w = math_abs(x2 - x1) local abs_h = math_abs(y2 - y1) draw.Color(r1, g1, b1, a1) if ltr then if a1 ~= 0 then if a1 and a2 ~= 255 then for i = 1, abs_w do local a1 = i / abs_w * a1 local x1 = x1 < x2 and x1 + i - 1 or x1 - i + 1 local x2 = x1 < x2 and x1 + 1 or x1 - 1 draw.FilledRect(x1, y1, x2, y2, draw.Color(r1, g1, b1, a1)) end else draw.FilledRect(x1, y1, x2, y2) end end if a2 ~= 0 then for i = 1, abs_w do local a2 = i / abs_w * a2 local x1 = x1 < x2 and x2 - i + 1 or x2 + i - 1 local x2 = x1 < x2 and x1 - 1 or x1 + 1 draw.FilledRect(x1, y1, x2, y2, draw.Color(r2, g2, b2, a2)) end end else if a1 ~= 0 then if a1 and a2 ~= 255 then for i = 1, abs_h do local a1 = i / abs_h * a1 local y1 = y1 < y2 and y1 + i - 1 or y1 - i + 1 local y2 = y1 < y2 and y1 + 1 or y1 - 1 draw.FilledRect(x1, y1, x2, y2, draw.Color(r1, g1, b1, a1)) end else draw.FilledRect(x1, y1, x2, y2) end end if a2 ~= 0 then for i = 1, abs_h do local a2 = i / abs_h * a2 local y1 = y1 < y2 and y2 - i + 1 or y2 + i - 1 local y2 = y1 < y2 and y1 - 1 or y1 + 1 draw.FilledRect(x1, y1, x2, y2, draw.Color(r2, g2, b2, a2)) end end end draw.Color(r1, g1, b1, a1) end --examples 示例 local function on_paint() draw.rect_filled_fade(50, 50, 150, 150, 255, 0, 255, 255, 0, 255, 255, 255, true) end callbacks.Register("Draw", on_paint) ``` ---