绘制类
# 为通用开发提供便利的代码片段会记录在此
**颜色扩展库**
```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)
```
---