AutoCanvasSize v2: AutoSize

I am releasing this on the forums as I have previously uploaded a module that achieved something similar, and a lot of people have found that useful. So consider this version 2 of that module.


After struggling with the new AutoSize and AutoCanvasSize properties of GuiObjects for a while (they are a great addition to the engine and work fantastic, most of the time), I decided to create a module to handle this for me with some added utility. It’s nothing impressive but I find it handy.

AutoSize allows automatic resizing of Frame (.Size) and ScrollingFrame (.CanvasSize) objects. The object being resized must have a UIListLayout or UIGridLayout as a direct child to work properly.

Supports tweening on update if you’d like, you can make some smooth effects with this.


Usage:

-- frame is a Frame or ScrollingFrame GuiObject to resize
-- axes is a table which includes "X", "Y", or both. Excluded axes will be ignored during resizing. defaults to {"X", "Y"}.
-- tweenSettings is a dictionary that controls tweening on update. defaults to nil (no tweening)
-- duration = tween duration, direction = Enum.EasingDirection, style = Enum.EasingStyle
AutoSize.Connect(frame, axes, tweenSettings)

-- to stop autosizing, call .Disconnect, passing the frame.
-- the module does not cleanup based on ancestry changed events, so you'll need to do this if you're adding/removing size-able frames at runtime, or you'll have a memory leak.
AutoSize.Disconnect(frame) 
AutoSize Module code
local Tween = require(script:WaitForChild("Tween"))

local DEFAULT_TWEEN_SETTINGS = {
	duration = .5;
	style = Enum.EasingStyle.Quint;
	direction = Enum.EasingDirection.Out;
}
local listening = {}

local AutoSize = {}

function AutoSize.Update(frame)
	local entry = listening[frame]
	if entry then
		local layout = frame:FindFirstChildWhichIsA("UIListLayout") or frame:FindFirstChildWhichIsA("UIGridLayout")
		if layout then
			local property = frame:IsA("ScrollingFrame") and "CanvasSize" or "Size"
			local currentSize = frame[property]
			local contentSize = layout.AbsoluteContentSize

			local sizeX = table.find(entry.axes, "X") and contentSize.X or currentSize.X.Offset
			local sizeY = table.find(entry.axes, "Y") and contentSize.Y or currentSize.Y.Offset
			local size = UDim2.new(currentSize.X.Scale,sizeX,currentSize.Y.Scale, sizeY)
			
			if entry.tweenSettings then
				Tween(frame, {[property] = size;}, entry.tweenSettings.duration or DEFAULT_TWEEN_SETTINGS.duration, entry.tweenSettings.style or DEFAULT_TWEEN_SETTINGS.style, entry.tweenSettings.direction or DEFAULT_TWEEN_SETTINGS.direction)
			else
				frame[property] = size
			end
		end
	end
end

function AutoSize.Connect(frame, axes, tweenSettings)
	if not listening[frame] then
		local layout = frame:FindFirstChildWhichIsA("UIListLayout") or frame:FindFirstChildWhichIsA("UIGridLayout")
		if layout then
			local entry = {
				connections = {
					layout:GetPropertyChangedSignal("AbsoluteContentSize"):Connect(function()
						AutoSize.Update(frame)
					end);
				};
				tweenSettings = tweenSettings;
				axes = axes or {"X";"Y"};
			};
			listening[frame] = entry
			return entry
		end
	end
end

function AutoSize.Disconnect(frame)
	local entry = listening[frame]
	if entry then
		for _,c in pairs(entry.connections) do
			c:Disconnect()
		end
		listening[frame] = nil
	end
end

return AutoSize
Additional Tween utility module code, which is used in AutoSize
local TweenService = game:GetService("TweenService")

local Tween = {}

function Tween.Make(instance, tweenInfo, properties)
	tweenInfo = tweenInfo or TweenInfo.new(1, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut)
	local tween = TweenService:Create(instance, tweenInfo, properties)	
	return tween
end

function Tween.Do(instance, properties, duration, style, direction, yieldUntilFinished)
	local tweenInfo = TweenInfo.new(duration, style, direction)
	local tween = Tween.Make(instance, tweenInfo, properties)
	tween:Play()
	if yieldUntilFinished then
		return tween, tween.Completed:Wait()
	end
	return tween
end

return Tween.Do

or get it on the website: AutoSize Module - Roblox

17 Likes