For the past few months I been working on an advanced drawing system (inside of a UI) and I am near finishing, and I just have the undo & redo system, converting the drawn frames to scale, and few bug fixes.
I have been having some issues with these and I really need help I will provide all the code below into sections.
Let me define somethings and explain how my system works.
CircleLine = A circle imagelabel that is used for drawing
DrawLine = the lines to fill in the gaps in between the circles
Old prototype example without the lines in between:
https://gyazo.com/729d2248682710049178d3c660d83f46
Converting to scale issue
I am having trouble converting my currently drawn pieces from offset to scale, they are frames.
Currently, it isn’t converting anything because I had to undo, if you could please explain how I can do this it would be great.
Whenever I do it nothing will work, the “CircleLine” which is an circle works, but not the gap filling lines.
local selectedColor = bg:GetAttribute("Color")
local DrawCircle = CircleBrush:Clone()
DrawCircle.ZIndex = layer
print(OffsetToScale({20,20}))
DrawCircle.Size = UDim2.new(0,20, 0, 20)
DrawCircle.Parent = Canvas
local X = mouse.X - Canvas.AbsolutePosition.X
local Y = mouse.Y - Canvas.AbsolutePosition.Y
--DrawCircle.Position = UDim2.fromOffset(mouse.X, mouse.Y)
DrawCircle.Position = UDim2.fromOffset(X, Y)
--DrawCircle.Position = UDim2.new(0, BrushCricleDecal.AbsolutePosition.X, 0, BrushCricleDecal.AbsolutePosition.Y)
DrawCircle.Transparency = tonumber(DrawingTransparencyTxtBox.Text) or 0
DrawCircle.ZIndex = layer
if isDrawing then
DrawCircle.Name = "DrawCircle"..numberthing
print(numberthing)
print("Renamed")
DrawCircle.BackgroundColor3 = selectedColor
numberthing += 1
if oldDot then
if tonumber(DrawingTransparencyTxtBox.Text) > 0 then
local startX, startY = oldDot.Position.X.Offset, oldDot.Position.Y.Offset
local endX, endY = DrawCircle.Position.X.Offset, DrawCircle.Position.Y.Offset
local line = circleLineBrush:Clone()
line.Name = "line"..numberthing
line.AnchorPoint = Vector2.new(0.5,0.5)
line.Size = UDim2.new(0,(oldDot.AbsolutePosition - DrawCircle.AbsolutePosition).Magnitude,0, 20)
line.Position = UDim2.new(0, (startX + endX) / 2, 0, (startY + endY) / 2)
line.Rotation = math.atan2(endY - startY, endX - startX) * (180 / math.pi)
line.BackgroundColor3 = selectedColor
line.BackgroundTransparency = 0
line.ZIndex = layer
line.Parent = Canvas
local whiteOldDot = oldDot:Clone()
whiteOldDot.Transparency = 0
whiteOldDot.BackgroundColor3 = selectedColor
whiteOldDot.ZIndex = layer
whiteOldDot.Parent = Canvas
local newOldDot = whiteOldDot:Clone()
newOldDot.Transparency = tonumber(DrawingTransparencyTxtBox.Text)
newOldDot.BackGroundColor3 = selectedColor
newOldDot.ZIndex = layer
newOldDot.Parent = Canvas
elseif tonumber(DrawingTransparencyTxtBox.Text) == 0 then
local startX, startY = oldDot.Position.X.Offset, oldDot.Position.Y.Offset
local endX, endY = DrawCircle.Position.X.Offset, DrawCircle.Position.Y.Offset
local line = circleLineBrush:Clone()
line.Name = "line"..numberthing
line.AnchorPoint = Vector2.new(0.5,0.5)
line.Size = UDim2.new(0,(oldDot.AbsolutePosition - DrawCircle.AbsolutePosition).Magnitude,0,20)
line.Position = UDim2.new(0, (startX + endX) / 2, 0, (startY + endY) / 2)
line.Rotation = math.atan2(endY - startY, endX - startX) * (180 / math.pi)
line.BackgroundColor3 = selectedColor
line.BackgroundTransparency = 0
line.ZIndex = layer
line.Parent = Canvas
end
end
oldDot = DrawCircle
There are checks outside of this that are not needed, let me know if you need more information.
Undo & Redo
My undo & redo system issue:
I kind of have it working…? (Not really)
I do have the base of the system but not working properly.
I don’t think I need to explain what the undo and redo is suppose to do, it it clear, undo and redo a drawing fragment.
Here is what happens with my system:
https://gyazo.com/3ebc1f9933302c71a37df575d8b9b397
Issues:
- It completely deletes everything and doesn’t go back to the last cache(as I refer to in my code) / action
- There is a tiny bit left even when it deletes the wrong thing.
Here is my code:
How I cache the drawings:
function cacheDrawing(ui)
if #CacheTable >= 20 then
table.remove(CacheTable, 1)
oldCacheNumber += 1
for i, v in pairs(ui:GetChildren()) do
local clone = v:Clone()
tempCacheTble = {}
table.insert(tempCacheTble, clone)
end
table.insert(CacheTable, tempCacheTble)
totalAmountOfCache += 1
print(#CacheTable)
else
totalAmountOfCache += 1
for i, v in pairs(ui:GetChildren()) do
local clone = v:Clone()
tempCacheTble = {}
table.insert(tempCacheTble, clone)
end
table.insert(CacheTable, tempCacheTble)
print(#CacheTable)
end
end
How I undo:
function UndoAction(index)
local getframe = CacheTable[#CacheTable]
table.insert(redoTable, Canvas:GetChildren())
local orgChild = Canvas:GetChildren()
for z, x in pairs(orgChild) do
if not x:IsA("UIStroke") then
print(typeof(x))
x:Destroy()
end
end
for i, v in pairs(getframe) do
if not v:IsA("UIStroke") then
print(typeof(v))
v.Parent = Canvas
end
end
end
Redo isn’t finished, I wanted undo working first because then I can just reverse it in theory.
The cachetable is called whenever the user was holding down mouse button and lets go, or they leave the drawing canvas.