Need help finding absolute canvas position of a textlabel/frame

Hello,

I need help finding the absolute canvas position of a textlabel or frame or anything that has a position.
In a scrolling frame, you have the canvas position where it determines the position you are in the frame. Problem is it is different for mobile and pc or different dimensions.

So now I am trying to figure out how to find the absolute canvas position.

Here’s the current code:

local Shortcuts = {}

local Players = game:GetService("Players")
local TweenService = game:GetService("TweenService")
local Debris = game:GetService("Debris")

local localPlayer = Players.LocalPlayer :: Player

local MenuGui = localPlayer:FindFirstChild("PlayerGui"):FindFirstChild("Menu") :: ScreenGui
local Background = MenuGui:FindFirstChild("Background"):: ScrollingFrame

local SCROLL_TIME = 0.2

Shortcuts._shortcuts = MenuGui.Background.Introduction.Shortcuts:: Frame
Shortcuts._tweenScrollInfo = TweenInfo.new(SCROLL_TIME)

function Shortcuts._scrollDownToSection(Frame: Frame)
	local canvasPosition --= Vector2.new(Background.AbsoluteWindowSize * Frame.Position)
	local canvasTween = TweenService:Create(Background,Shortcuts._tweenScrollInfo,
		{ CanvasPosition = canvasPosition }
	)
	
	local ScrollSound = Instance.new("Sound")
	ScrollSound.SoundId = "rbxassetid://10066914500"
	ScrollSound.Parent = game:GetService("SoundService")
	ScrollSound:Play()
	
	Debris:AddItem(ScrollSound,2)
	
	canvasTween:Play()
end

return Shortcuts

So far, I haven’t found any working solutions.

Here’s a related post:

4 Likes

AbsoluteWindowSize gives the size of the frame, not its position.

Mid snip …

function Shortcuts._scrollDownToSection(Frame)
	local framePosition = Frame.Position
	local canvasPosition = Vector2.new(
		0, -- X-coordinate, assuming you want to scroll horizontally (if vertical, adjust this)
		math.max(0, framePosition.Y - Background.CanvasPosition.Y) -- Y-coordinate
	)
	
	local canvasTween = TweenService:Create(Background, TweenInfo.new(SCROLL_TIME), {
		CanvasPosition = canvasPosition
	})
1 Like

Looks like it would work. I got a error though.

ReplicatedStorage.Source.UserInterface.MenuShortcuts:21: invalid argument #2 (UDim expected, got number)

Full function:


function Shortcuts._scrollDownToSection(Frame: Frame)
	local framePosition = Frame.Position:: UDim2
	local canvasPosition = Vector2.new(
		0, -- X-coordinate, assuming you want to scroll horizontally (if vertical, adjust this)
		math.max(0, framePosition.Y - Background.CanvasPosition.Y) -- Y-coordinate
	)
	
	local canvasTween = TweenService:Create(Background,Shortcuts._tweenScrollInfo,
		{ CanvasPosition = canvasPosition }
	)
	
	local ScrollSound = Instance.new("Sound")
	ScrollSound.SoundId = "rbxassetid://10066914500"
	ScrollSound.Parent = game:GetService("SoundService")
	ScrollSound:Play()
	
	Debris:AddItem(ScrollSound,2)
	
	canvasTween:Play()
end

Just noticed you were using AbsoluteWindowSize for position and guessed on the code …
I don’t have all your menus/gui

1 Like

My bad

All you need is in the shortcuts frame im pretty sure

Sorry misunderstood that … this might be it.

local canvasPosition = Vector2.new(
		UDim.new(0, 0), -- UDim for X-coordinate
		UDim.new(0, math.max(0, framePosition.Y.Offset - Background.CanvasPosition.Y.Offset)) -- UDim for Y-coordinate
	)
1 Like

I got another error:

ReplicatedStorage.Source.UserInterface.MenuShortcuts:22: attempt to index number with 'Offset'

CanvasPosition doesn’t have offset btw. I tried removing it but it didn’t do anything but not error.

local Shortcuts = {}

local Players = game:GetService("Players")
local TweenService = game:GetService("TweenService")
local Debris = game:GetService("Debris")

local localPlayer = Players.LocalPlayer

local MenuGui = localPlayer:FindFirstChild("PlayerGui"):FindFirstChild("Menu")
local Background = MenuGui:FindFirstChild("Background")

local SCROLL_TIME = 0.2

function Shortcuts._scrollDownToSection(Frame)
	local framePosition = Frame.Position
	local canvasPosition = Vector2.new(
		UDim.new(0, 0), -- UDim for X-coordinate
		UDim.new(0, math.max(0, framePosition.Y - Background.CanvasPosition.Y.Offset)) -- UDim for Y-coordinate
	)
	
	local canvasTween = TweenService:Create(Background, TweenInfo.new(SCROLL_TIME), {
		CanvasPosition = canvasPosition
	})

	local ScrollSound = Instance.new("Sound")
	ScrollSound.SoundId = "rbxassetid://10066914500"
	ScrollSound.Parent = game:GetService("SoundService")
	ScrollSound:Play()

	Debris:AddItem(ScrollSound, 2)

	canvasTween:Play()
end

return Shortcuts

Last guess …

1 Like

What did you change exactly? I don’t see a difference.

Edit: I found the difference

He removed offset from framePosition.Y since the error states that you’re attempting to index the ‘offset’ of a ‘number’. However, framePosition.Y does have an offset, the one that does not is CanvasPosition. So in order to resolve the error it should instead be;

local Shortcuts = {}

local Players = game:GetService("Players")
local TweenService = game:GetService("TweenService")
local Debris = game:GetService("Debris")

local localPlayer = Players.LocalPlayer

local MenuGui = localPlayer:FindFirstChild("PlayerGui"):FindFirstChild("Menu")
local Background = MenuGui:FindFirstChild("Background")

local SCROLL_TIME = 0.2

function Shortcuts._scrollDownToSection(Frame)
	local framePosition = Frame.Position
	local canvasPosition = Vector2.new(
		UDim.new(0, 0), -- UDim for X-coordinate
		UDim.new(0, math.max(0, framePosition.Y.Offset - Background.CanvasPosition.Y)) -- UDim for Y-coordinate
	)
	
	local canvasTween = TweenService:Create(Background, TweenInfo.new(SCROLL_TIME), {
		CanvasPosition = canvasPosition
	})

	local ScrollSound = Instance.new("Sound")
	ScrollSound.SoundId = "rbxassetid://10066914500"
	ScrollSound.Parent = game:GetService("SoundService")
	ScrollSound:Play()

	Debris:AddItem(ScrollSound, 2)

	canvasTween:Play()
end

return Shortcuts
1 Like

Yeah that’s what I thought too. I already tried this and all it does is remove the error and doesn’t move anything else.

Maybe the formula I was given doesn’t work.

Assuming you’re scrolling along the Y-axis you can do

local relativeAbsOffset = targetUI.AbsolutePosition.Y - scrollFrame.AbsolutePosition.Y
scrollFrame.CanvasPosition = Vector2.new(scrollFrame.CanvasPosition.X, scrollFrame.CanvasPosition.Y + relativeAbsOffset) 

I use absolute position here for the target position incase you are using a UIListLayout or UIGridLayout, which stop you from reading the UI’s position.

Final Code:

local Shortcuts = {}

local Players = game:GetService("Players")
local TweenService = game:GetService("TweenService")
local Debris = game:GetService("Debris")

local localPlayer = Players.LocalPlayer

local MenuGui = localPlayer:FindFirstChild("PlayerGui"):FindFirstChild("Menu")
local Background = MenuGui:FindFirstChild("Background")

local SCROLL_TIME = 0.2

function Shortcuts._scrollDownToSection(Frame)
	local framePosition = Frame.Position
	local relativeAbsoluteOffset = framePosition.AbsolutePosition.Y - Background.AbsolutePosition.Y
	
	local canvasPosition = Vector2.new(
		Background.CanvasPosition.X,
		Background.CanvasPosition.Y + relativeAbsoluteOffset
	)

	local canvasTween = TweenService:Create(Background, TweenInfo.new(SCROLL_TIME), {
		CanvasPosition = canvasPosition
	})

	local ScrollSound = Instance.new("Sound")
	ScrollSound.SoundId = "rbxassetid://10066914500"
	ScrollSound.Parent = game:GetService("SoundService")
	ScrollSound:Play()

	Debris:AddItem(ScrollSound, 2)

	canvasTween:Play()
end

return Shortcuts
2 Likes

I’ll try that when I get on, it looks promising :ok_hand:

This may just be me … but, I wish with questions like this the GUI setup would also be uploaded.
Guessing is not part of how most programmer’s like to do things …

1 Like

Shouldn’t it just be the AbsolutePosition?

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