Weird GUI behaviour

I’m working on a coding game, where the player can learn how to code. I’m currently working on the IDE/coding interface but am having trouble with the scrollingGui.

I want the scrollingGUI canvas to be sized according to the amount of lines currently in the textbox inside of the scrollingGUI (with size {1, 0}, {1, 0}). I want it to behave similarly to the roblox script editor, where the size of the canvas is the size of the screen + the number of lines.

Setup in studio
image


(unfortunately the video is cropped, but the idea should be there, otherwise you could try experimenting a bit in studio itself)

I’ve made a custom scrollbar because Roblox lacks the customizations i wanted.

Now the issue is that it just doesn’t work, it’s having a lot of strange behaviors:

Here’s what happens. If the last line is empty, you can keep scrolling until the bottom of the canvas (which is too big in this case). And if the last line has characters, it will correctly scale the canvas, but still gives errors with the scrollbar as you can see.

This is my current code for scaling the canvas:

textBox:GetPropertyChangedSignal("ContentText"):Connect(function()
	local textBox = script.Parent.TextBox
	local scrollingFrame = script.Parent
	local _, numLines = string.gsub(textBox.ContentText, "\n", "\n")
	local lineHeight = textBox.TextSize
	
	local linesPerPage = scrollingFrame.AbsoluteSize.Y / lineHeight
	
	local newCanvasSize = scrollingFrame.Size.Y.Scale + scrollingFrame.Size.Y.Scale * numLines/linesPerPage
	scrollingFrame.CanvasSize = UDim2.new(1, 0, newCanvasSize, 0)
end)

and this is the code for updating the scroll bar:

function updateScrollingFrame()
	local barSize = math.clamp(scrollingFrame.Size.Y.Scale / scrollingFrame.CanvasSize.Y.Scale, 0, 1)
	scrollBar.Size = UDim2.new(1, 0, barSize * barScaleY, 0)
	
	local scrollArea = scrollHeight - (scrollBar.AbsoluteSize.Y / barScaleY)
	local scrollBarPosition = (scrollBar.Position.Y.Scale - barOffsetY) * scrollHeight
	local ratio = scrollBarPosition / scrollArea
	
	local canvasLen = scrollingFrame.AbsoluteCanvasSize.Y
	local canvasPosition = ratio * canvasLen -- scrollPos / scrollArea = canvasPos / canvasLen
	scrollingFrame.CanvasPosition = Vector2.new(0, canvasPosition)
end

scrollingFrame:GetPropertyChangedSignal("CanvasSize"):Connect(updateScrollingFrame)

I’ve already tried a few ways of calculating the canvas size, but nothing seems to work. The scrollbar has more lines of code to deal with the arrow buttons, dragging the scrollbar and using the mouse scroll, but these shouldn’t interfere with the updateScrollingFrame() function.