Advertisement
GUI_Maker_Roblox

Drawing

Sep 28th, 2024
36
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 16.17 KB | Cybersecurity | 0 0
  1. local coreGui = game:GetService("CoreGui")
  2. -- objects
  3. local camera = workspace.CurrentCamera
  4. local drawingUI = Instance.new("ScreenGui")
  5. drawingUI.Name = "Drawing"
  6. drawingUI.IgnoreGuiInset = true
  7. drawingUI.DisplayOrder = 0x7fffffff
  8. drawingUI.Parent = coreGui
  9. -- variables
  10. local drawingIndex = 0
  11. local uiStrokes = table.create(0)
  12. local baseDrawingObj = setmetatable({
  13.     Visible = true,
  14.     ZIndex = 0,
  15.     Transparency = 1,
  16.     Color = Color3.new(),
  17.     Remove = function(self)
  18.         setmetatable(self, nil)
  19.     end,
  20.     Destroy = function(self)
  21.         setmetatable(self, nil)
  22.     end
  23. }, {
  24.     __add = function(t1, t2)
  25.         local result = table.clone(t1)
  26.  
  27.         for index, value in t2 do
  28.             result[index] = value
  29.         end
  30.         return result
  31.     end
  32. })
  33. local drawingFontsEnum = {
  34.     [0] = Font.fromEnum(Enum.Font.Roboto),
  35.     [1] = Font.fromEnum(Enum.Font.Legacy),
  36.     [2] = Font.fromEnum(Enum.Font.SourceSans),
  37.     [3] = Font.fromEnum(Enum.Font.RobotoMono)
  38. }
  39. -- function
  40. local function getFontFromIndex(fontIndex)
  41.     return drawingFontsEnum[fontIndex]
  42. end
  43.  
  44. local function convertTransparency(transparency)
  45.     return math.clamp(1 - transparency, 0, 1)
  46. end
  47. -- main
  48. local DrawingLib = {}
  49. DrawingLib.Fonts = {
  50.     ["UI"] = 0,
  51.     ["System"] = 1,
  52.     ["Plex"] = 2,
  53.     ["Monospace"] = 3
  54. }
  55.  
  56. function DrawingLib.new(drawingType)
  57.     drawingIndex += 1
  58.     if drawingType == "Line" then
  59.         local lineObj = ({
  60.             From = Vector2.zero,
  61.             To = Vector2.zero,
  62.             Thickness = 1
  63.         } + baseDrawingObj)
  64.  
  65.         local lineFrame = Instance.new("Frame")
  66.         lineFrame.Name = drawingIndex
  67.         lineFrame.AnchorPoint = (Vector2.one * 0.5)
  68.         lineFrame.BorderSizePixel = 0
  69.  
  70.         lineFrame.BackgroundColor3 = lineObj.Color
  71.         lineFrame.Visible = lineObj.Visible
  72.         lineFrame.ZIndex = lineObj.ZIndex
  73.         lineFrame.BackgroundTransparency = convertTransparency(lineObj.Transparency)
  74.  
  75.         lineFrame.Size = UDim2.new()
  76.  
  77.         lineFrame.Parent = drawingUI
  78.         return setmetatable(table.create(0), {
  79.             __newindex = function(_, index, value)
  80.                 if typeof(lineObj[index]) == "nil" then return end
  81.  
  82.                 if index == "From" then
  83.                     local direction = (lineObj.To - value)
  84.                     local center = (lineObj.To + value) / 2
  85.                     local distance = direction.Magnitude
  86.                     local theta = math.deg(math.atan2(direction.Y, direction.X))
  87.  
  88.                     lineFrame.Position = UDim2.fromOffset(center.X, center.Y)
  89.                     lineFrame.Rotation = theta
  90.                     lineFrame.Size = UDim2.fromOffset(distance, lineObj.Thickness)
  91.                 elseif index == "To" then
  92.                     local direction = (value - lineObj.From)
  93.                     local center = (value + lineObj.From) / 2
  94.                     local distance = direction.Magnitude
  95.                     local theta = math.deg(math.atan2(direction.Y, direction.X))
  96.  
  97.                     lineFrame.Position = UDim2.fromOffset(center.X, center.Y)
  98.                     lineFrame.Rotation = theta
  99.                     lineFrame.Size = UDim2.fromOffset(distance, lineObj.Thickness)
  100.                 elseif index == "Thickness" then
  101.                     local distance = (lineObj.To - lineObj.From).Magnitude
  102.  
  103.                     lineFrame.Size = UDim2.fromOffset(distance, value)
  104.                 elseif index == "Visible" then
  105.                     lineFrame.Visible = value
  106.                 elseif index == "ZIndex" then
  107.                     lineFrame.ZIndex = value
  108.                 elseif index == "Transparency" then
  109.                     lineFrame.BackgroundTransparency = convertTransparency(value)
  110.                 elseif index == "Color" then
  111.                     lineFrame.BackgroundColor3 = value
  112.                 end
  113.                 lineObj[index] = value
  114.             end,
  115.             __index = function(self, index)
  116.                 if index == "Remove" or index == "Destroy" then
  117.                     return function()
  118.                         lineFrame:Destroy()
  119.                         lineObj.Remove(self)
  120.                         return lineObj:Remove()
  121.                     end
  122.                 end
  123.                 return lineObj[index]
  124.             end,
  125.             __tostring = function() return "Drawing" end
  126.         })
  127.     elseif drawingType == "Text" then
  128.         local textObj = ({
  129.             Text = "",
  130.             Font = DrawingLib.Fonts.UI,
  131.             Size = 0,
  132.             Position = Vector2.zero,
  133.             Center = false,
  134.             Outline = false,
  135.             OutlineColor = Color3.new()
  136.         } + baseDrawingObj)
  137.  
  138.         local textLabel, uiStroke = Instance.new("TextLabel"), Instance.new("UIStroke")
  139.         textLabel.Name = drawingIndex
  140.         textLabel.AnchorPoint = (Vector2.one * .5)
  141.         textLabel.BorderSizePixel = 0
  142.         textLabel.BackgroundTransparency = 1
  143.  
  144.         textLabel.Visible = textObj.Visible
  145.         textLabel.TextColor3 = textObj.Color
  146.         textLabel.TextTransparency = convertTransparency(textObj.Transparency)
  147.         textLabel.ZIndex = textObj.ZIndex
  148.  
  149.         textLabel.FontFace = getFontFromIndex(textObj.Font)
  150.         textLabel.TextSize = textObj.Size
  151.  
  152.         textLabel:GetPropertyChangedSignal("TextBounds"):Connect(function()
  153.             local textBounds = textLabel.TextBounds
  154.             local offset = textBounds / 2
  155.  
  156.             textLabel.Size = UDim2.fromOffset(textBounds.X, textBounds.Y)
  157.             textLabel.Position = UDim2.fromOffset(textObj.Position.X + (if not textObj.Center then offset.X else 0), textObj.Position.Y + offset.Y)
  158.         end)
  159.  
  160.         uiStroke.Thickness = 1
  161.         uiStroke.Enabled = textObj.Outline
  162.         uiStroke.Color = textObj.Color
  163.  
  164.         textLabel.Parent, uiStroke.Parent = drawingUI, textLabel
  165.         return setmetatable(table.create(0), {
  166.             __newindex = function(_, index, value)
  167.                 if typeof(textObj[index]) == "nil" then return end
  168.  
  169.                 if index == "Text" then
  170.                     textLabel.Text = value
  171.                 elseif index == "Font" then
  172.                     value = math.clamp(value, 0, 3)
  173.                     textLabel.FontFace = getFontFromIndex(value)
  174.                 elseif index == "Size" then
  175.                     textLabel.TextSize = value
  176.                 elseif index == "Position" then
  177.                     local offset = textLabel.TextBounds / 2
  178.  
  179.                     textLabel.Position = UDim2.fromOffset(value.X + (if not textObj.Center then offset.X else 0), value.Y + offset.Y)
  180.                 elseif index == "Center" then
  181.                     local position = (
  182.                         if value then
  183.                             camera.ViewportSize / 2
  184.                             else
  185.                             textObj.Position
  186.                     )
  187.  
  188.                     textLabel.Position = UDim2.fromOffset(position.X, position.Y)
  189.                 elseif index == "Outline" then
  190.                     uiStroke.Enabled = value
  191.                 elseif index == "OutlineColor" then
  192.                     uiStroke.Color = value
  193.                 elseif index == "Visible" then
  194.                     textLabel.Visible = value
  195.                 elseif index == "ZIndex" then
  196.                     textLabel.ZIndex = value
  197.                 elseif index == "Transparency" then
  198.                     local transparency = convertTransparency(value)
  199.  
  200.                     textLabel.TextTransparency = transparency
  201.                     uiStroke.Transparency = transparency
  202.                 elseif index == "Color" then
  203.                     textLabel.TextColor3 = value
  204.                 end
  205.                 textObj[index] = value
  206.             end,
  207.             __index = function(self, index)
  208.                 if index == "Remove" or index == "Destroy" then
  209.                     return function()
  210.                         textLabel:Destroy()
  211.                         textObj.Remove(self)
  212.                         return textObj:Remove()
  213.                     end
  214.                 elseif index == "TextBounds" then
  215.                     return textLabel.TextBounds
  216.                 end
  217.                 return textObj[index]
  218.             end,
  219.             __tostring = function() return "Drawing" end
  220.         })
  221.     elseif drawingType == "Circle" then
  222.         local circleObj = ({
  223.             Radius = 150,
  224.             Position = Vector2.zero,
  225.             Thickness = .7,
  226.             Filled = false
  227.         } + baseDrawingObj)
  228.  
  229.         local circleFrame, uiCorner, uiStroke = Instance.new("Frame"), Instance.new("UICorner"), Instance.new("UIStroke")
  230.         circleFrame.Name = drawingIndex
  231.         circleFrame.AnchorPoint = (Vector2.one * .5)
  232.         circleFrame.BorderSizePixel = 0
  233.  
  234.         circleFrame.BackgroundTransparency = (if circleObj.Filled then convertTransparency(circleObj.Transparency) else 1)
  235.         circleFrame.BackgroundColor3 = circleObj.Color
  236.         circleFrame.Visible = circleObj.Visible
  237.         circleFrame.ZIndex = circleObj.ZIndex
  238.  
  239.         uiCorner.CornerRadius = UDim.new(1, 0)
  240.         circleFrame.Size = UDim2.fromOffset(circleObj.Radius, circleObj.Radius)
  241.  
  242.         uiStroke.Thickness = circleObj.Thickness
  243.         uiStroke.Enabled = not circleObj.Filled
  244.         uiStroke.ApplyStrokeMode = Enum.ApplyStrokeMode.Border
  245.  
  246.         circleFrame.Parent, uiCorner.Parent, uiStroke.Parent = drawingUI, circleFrame, circleFrame
  247.         return setmetatable(table.create(0), {
  248.             __newindex = function(_, index, value)
  249.                 if typeof(circleObj[index]) == "nil" then return end
  250.  
  251.                 if index == "Radius" then
  252.                     local radius = value * 2
  253.                     circleFrame.Size = UDim2.fromOffset(radius, radius)
  254.                 elseif index == "Position" then
  255.                     circleFrame.Position = UDim2.fromOffset(value.X, value.Y)
  256.                 elseif index == "Thickness" then
  257.                     value = math.clamp(value, .6, 0x7fffffff)
  258.                     uiStroke.Thickness = value
  259.                 elseif index == "Filled" then
  260.                     circleFrame.BackgroundTransparency = (if value then convertTransparency(circleObj.Transparency) else 1)
  261.                     uiStroke.Enabled = not value
  262.                 elseif index == "Visible" then
  263.                     circleFrame.Visible = value
  264.                 elseif index == "ZIndex" then
  265.                     circleFrame.ZIndex = value
  266.                 elseif index == "Transparency" then
  267.                     local transparency = convertTransparency(value)
  268.  
  269.                     circleFrame.BackgroundTransparency = (if circleObj.Filled then transparency else 1)
  270.                     uiStroke.Transparency = transparency
  271.                 elseif index == "Color" then
  272.                     circleFrame.BackgroundColor3 = value
  273.                     uiStroke.Color = value
  274.                 end
  275.                 circleObj[index] = value
  276.             end,
  277.             __index = function(self, index)
  278.                 if index == "Remove" or index == "Destroy" then
  279.                     return function()
  280.                         circleFrame:Destroy()
  281.                         circleObj.Remove(self)
  282.                         return circleObj:Remove()
  283.                     end
  284.                 end
  285.                 return circleObj[index]
  286.             end,
  287.             __tostring = function() return "Drawing" end
  288.         })
  289.     elseif drawingType == "Square" then
  290.         local squareObj = ({
  291.             Size = Vector2.zero,
  292.             Position = Vector2.zero,
  293.             Thickness = .7,
  294.             Filled = false
  295.         } + baseDrawingObj)
  296.  
  297.         local squareFrame, uiStroke = Instance.new("Frame"), Instance.new("UIStroke")
  298.         squareFrame.Name = drawingIndex
  299.         squareFrame.BorderSizePixel = 0
  300.  
  301.         squareFrame.BackgroundTransparency = (if squareObj.Filled then convertTransparency(squareObj.Transparency) else 1)
  302.         squareFrame.ZIndex = squareObj.ZIndex
  303.         squareFrame.BackgroundColor3 = squareObj.Color
  304.         squareFrame.Visible = squareObj.Visible
  305.  
  306.         uiStroke.Thickness = squareObj.Thickness
  307.         uiStroke.Enabled = not squareObj.Filled
  308.         uiStroke.LineJoinMode = Enum.LineJoinMode.Miter
  309.  
  310.         squareFrame.Parent, uiStroke.Parent = drawingUI, squareFrame
  311.         return setmetatable(table.create(0), {
  312.             __newindex = function(_, index, value)
  313.                 if typeof(squareObj[index]) == "nil" then return end
  314.  
  315.                 if index == "Size" then
  316.                     squareFrame.Size = UDim2.fromOffset(value.X, value.Y)
  317.                 elseif index == "Position" then
  318.                     squareFrame.Position = UDim2.fromOffset(value.X, value.Y)
  319.                 elseif index == "Thickness" then
  320.                     value = math.clamp(value, 0.6, 0x7fffffff)
  321.                     uiStroke.Thickness = value
  322.                 elseif index == "Filled" then
  323.                     squareFrame.BackgroundTransparency = (if value then convertTransparency(squareObj.Transparency) else 1)
  324.                     uiStroke.Enabled = not value
  325.                 elseif index == "Visible" then
  326.                     squareFrame.Visible = value
  327.                 elseif index == "ZIndex" then
  328.                     squareFrame.ZIndex = value
  329.                 elseif index == "Transparency" then
  330.                     local transparency = convertTransparency(value)
  331.  
  332.                     squareFrame.BackgroundTransparency = (if squareObj.Filled then transparency else 1)
  333.                     uiStroke.Transparency = transparency
  334.                 elseif index == "Color" then
  335.                     uiStroke.Color = value
  336.                     squareFrame.BackgroundColor3 = value
  337.                 end
  338.                 squareObj[index] = value
  339.             end,
  340.             __index = function(self, index)
  341.                 if index == "Remove" or index == "Destroy" then
  342.                     return function()
  343.                         squareFrame:Destroy()
  344.                         squareObj.Remove(self)
  345.                         return squareObj:Remove()
  346.                     end
  347.                 end
  348.                 return squareObj[index]
  349.             end,
  350.             __tostring = function() return "Drawing" end
  351.         })
  352.     elseif drawingType == "Image" then
  353.         local imageObj = ({
  354.             Data = "",
  355.             DataURL = "rbxassetid://0",
  356.             Size = Vector2.zero,
  357.             Position = Vector2.zero
  358.         } + baseDrawingObj)
  359.  
  360.         local imageFrame = Instance.new("ImageLabel")
  361.         imageFrame.Name = drawingIndex
  362.         imageFrame.BorderSizePixel = 0
  363.         imageFrame.ScaleType = Enum.ScaleType.Stretch
  364.         imageFrame.BackgroundTransparency = 1
  365.  
  366.         imageFrame.Visible = imageObj.Visible
  367.         imageFrame.ZIndex = imageObj.ZIndex
  368.         imageFrame.ImageTransparency = convertTransparency(imageObj.Transparency)
  369.         imageFrame.ImageColor3 = imageObj.Color
  370.  
  371.         imageFrame.Parent = drawingUI
  372.         return setmetatable(table.create(0), {
  373.             __newindex = function(_, index, value)
  374.                 if typeof(imageObj[index]) == "nil" then return end
  375.  
  376.                 if index == "Data" then
  377.                     -- later
  378.                 elseif index == "DataURL" then -- temporary property
  379.                     imageFrame.Image = value
  380.                 elseif index == "Size" then
  381.                     imageFrame.Size = UDim2.fromOffset(value.X, value.Y)
  382.                 elseif index == "Position" then
  383.                     imageFrame.Position = UDim2.fromOffset(value.X, value.Y)
  384.                 elseif index == "Visible" then
  385.                     imageFrame.Visible = value
  386.                 elseif index == "ZIndex" then
  387.                     imageFrame.ZIndex = value
  388.                 elseif index == "Transparency" then
  389.                     imageFrame.ImageTransparency = convertTransparency(value)
  390.                 elseif index == "Color" then
  391.                     imageFrame.ImageColor3 = value
  392.                 end
  393.                 imageObj[index] = value
  394.             end,
  395.             __index = function(self, index)
  396.                 if index == "Remove" or index == "Destroy" then
  397.                     return function()
  398.                         imageFrame:Destroy()
  399.                         imageObj.Remove(self)
  400.                         return imageObj:Remove()
  401.                     end
  402.                 elseif index == "Data" then
  403.                     return nil -- TODO: add error here
  404.                 end
  405.                 return imageObj[index]
  406.             end,
  407.             __tostring = function() return "Drawing" end
  408.         })
  409.     elseif drawingType == "Quad" then
  410.         local quadObj = ({
  411.             PointA = Vector2.zero,
  412.             PointB = Vector2.zero,
  413.             PointC = Vector2.zero,
  414.             PointD = Vector3.zero,
  415.             Thickness = 1,
  416.             Filled = false
  417.         } + baseDrawingObj)
  418.  
  419.         local _linePoints = table.create(0)
  420.         _linePoints.A = DrawingLib.new("Line")
  421.         _linePoints.B = DrawingLib.new("Line")
  422.         _linePoints.C = DrawingLib.new("Line")
  423.         _linePoints.D = DrawingLib.new("Line")
  424.         return setmetatable(table.create(0), {
  425.             __newindex = function(_, index, value)
  426.                 if typeof(quadObj[index]) == "nil" then return end
  427.  
  428.                 if index == "PointA" then
  429.                     _linePoints.A.From = value
  430.                     _linePoints.B.To = value
  431.                 elseif index == "PointB" then
  432.                     _linePoints.B.From = value
  433.                     _linePoints.C.To = value
  434.                 elseif index == "PointC" then
  435.                     _linePoints.C.From = value
  436.                     _linePoints.D.To = value
  437.                 elseif index == "PointD" then
  438.                     _linePoints.D.From = value
  439.                     _linePoints.A.To = value
  440.                 elseif (index == "Thickness" or index == "Visible" or index == "Color" or index == "ZIndex") then
  441.                     for _, linePoint in _linePoints do
  442.                         linePoint[index] = value
  443.                     end
  444.                 elseif index == "Filled" then
  445.                     -- later
  446.                 end
  447.                 quadObj[index] = value
  448.             end,
  449.             __index = function(self, index)
  450.                 if index == "Remove" or index == "Destroy" then
  451.                     return function()
  452.                         for _, linePoint in _linePoints do
  453.                             linePoint:Remove()
  454.                         end
  455.  
  456.                         quadObj.Remove(self)
  457.                         return quadObj:Remove()
  458.                     end
  459.                 end
  460.                 return quadObj[index]
  461.             end,
  462.             __tostring = function() return "Drawing" end
  463.         })
  464.     elseif drawingType == "Triangle" then
  465.         local triangleObj = ({
  466.             PointA = Vector2.zero,
  467.             PointB = Vector2.zero,
  468.             PointC = Vector2.zero,
  469.             Thickness = 1,
  470.             Filled = false
  471.         } + baseDrawingObj)
  472.  
  473.         local _linePoints = table.create(0)
  474.         _linePoints.A = DrawingLib.new("Line")
  475.         _linePoints.B = DrawingLib.new("Line")
  476.         _linePoints.C = DrawingLib.new("Line")
  477.         return setmetatable(table.create(0), {
  478.             __tostring = function() return "Drawing" end,
  479.             __newindex = function(_, index, value)
  480.                 if typeof(triangleObj[index]) == "nil" then return end
  481.  
  482.                 if index == "PointA" then
  483.                     _linePoints.A.From = value
  484.                     _linePoints.B.To = value
  485.                 elseif index == "PointB" then
  486.                     _linePoints.B.From = value
  487.                     _linePoints.C.To = value
  488.                 elseif index == "PointC" then
  489.                     _linePoints.C.From = value
  490.                     _linePoints.A.To = value
  491.                 elseif (index == "Thickness" or index == "Visible" or index == "Color" or index == "ZIndex") then
  492.                     for _, linePoint in _linePoints do
  493.                         linePoint[index] = value
  494.                     end
  495.                 elseif index == "Filled" then
  496.                     -- later
  497.                 end
  498.                 triangleObj[index] = value
  499.             end,
  500.             __index = function(self, index)
  501.                 if index == "Remove" or index == "Destroy" then
  502.                     return function()
  503.                         for _, linePoint in _linePoints do
  504.                             linePoint:Remove()
  505.                         end
  506.  
  507.                         triangleObj.Remove(self)
  508.                         return triangleObj:Remove()
  509.                     end
  510.                 end
  511.                 return triangleObj[index]
  512.             end,
  513.             __tostring = function() return "Drawing" end
  514.         })
  515.     end
  516. end
  517.  
  518. return DrawingLib
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement