Help with auto scrolling in ScrollingFrames

I have a ScrollingFrame containing multiple child frames, and I want to implement functionality where, upon clicking a button inside one of the frames, the ScrollingFrame scrolls to center that frame within the visible area.

For example, if you click on an element that is currently off-screen (e.g., to the right), the ScrollingFrame should scroll so that the clicked element is positioned in the middle. If the clicked element is the last one and cannot be fully centered (because there’s no more content to the right), the ScrollingFrame should scroll as far as possible, which would effectively align the last element to the left. This behavior would still look clean as it’s consistent with the centering logic.

Does this logic make sense, and am I approaching this the right way? I’d appreciate any advice or best practices for implementing this functionality. Thank you!

Current Code:

	local function handleButtonClick(childFrame)
		local imageButton = childFrame:FindFirstChildOfClass("TextButton")
		if imageButton then
			imageButton.MouseButton1Click:Connect(function()
				-- Calculate the target CanvasPosition
				local targetX = childFrame.AbsolutePosition.X - childFrame.Parent.AbsolutePosition.X

				-- Create a tween for smooth scrolling
				local tweenInfo = TweenInfo.new(tweenTime, Enum.EasingStyle.Sine, Enum.EasingDirection.Out)
				local goal = { CanvasPosition = Vector2.new(targetX, childFrame.Parent.CanvasPosition.Y) }
				local tween = tweenService:Create(childFrame.Parent, tweenInfo, goal)

				-- Play the tween
				tween:Play()
			end)
		end
	end

Current Preview:

1 Like

Looks like you should be using a UIPageLayout instead of a scrolling frame

1 Like

I love to have more freedom, therefore using a ScrollingFrame combined with UIListLayout works much better for me.

Hopefully this can help anyone wondering how to create a similar function, as I’ve finally figured it out.

Updated Code:

local TweenService = game:GetService("TweenService")

local function CenterFrame(ScrollingFrame, TargetFrame)
    -- Find the TextButton inside the TargetFrame
    local activateButton = TargetFrame:FindFirstChildWhichIsA("TextButton")
    if activateButton then
        -- Connect the button's Mouse1Click to center the frame
        activateButton.MouseButton1Click:Connect(function()
            -- Centering logic
            local ScrollingFrameAS = ScrollingFrame.AbsoluteSize
            local ScrollingFrameAP = ScrollingFrame.AbsolutePosition

            local TargetFrameAS = TargetFrame.AbsoluteSize
            local TargetFrameAP = TargetFrame.AbsolutePosition

            -- Calculate relative position of the TargetFrame
            local RelativeAP = TargetFrameAP - ScrollingFrameAP

            -- Find the center of the ScrollingFrame
            local Center = ScrollingFrameAS.X / 2

            -- Make the TargetFrame's center relative to the ScrollingFrame's center
            local RelativeCenter = RelativeAP.X - Center

            -- Calculate the goal CanvasPosition
            local Goal = ScrollingFrame.CanvasPosition.X + RelativeCenter
            local AdjustedGoal = Goal + (TargetFrameAS.X / 2)

            -- Tween the CanvasPosition to smoothly transition
            local goalPosition = Vector2.new(AdjustedGoal, 0)
            local tweenInfo = TweenInfo.new(0.5, Enum.EasingStyle.Quad, Enum.EasingDirection.Out) -- 0.5 seconds duration
            local tween = TweenService:Create(ScrollingFrame, tweenInfo, { CanvasPosition = goalPosition })
            tween:Play()
        end)
    else
        warn("No TextButton found inside TargetFrame!")
    end
end

was recommending UIPageLayout because it has a function to jump to the element you want

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.