How to convert position OFFSET to position SCALE?

Title says it all

I tried searching and it didn’t work so if you know how to fix this, please reply. :slight_smile:

What is the use case of that? Can’t you just use scale only on the UDim2?

1 Like

I am trying a drawing canvas and converting a pixel from offset to scale in position because it’s mainly created from offset. It’s also the reason why I can’t use scale.

What I meant:

Pixel.Position = Udim2.FromOffset(x,y) -- x and y is a vector2 (from mouse position)
-- line of converting an offset to scale which idk how

If I’m advised to just use FromScale, I don’t know how to do that.

Hey! I experimented a little bit and found this approach to be successful:

  1. First of all, get the actual size of the GUI using AbsoluteSize and put it in a Value. (I used 2 Values named `OriginalX` and `OriginalY.
  2. Find the ratio of the GUI to the actual screen.
  3. The Ratios can be used as the Scale values.

Attached Code:

local OriginalAbsoluteSizeX =  Instance.new("NumberValue")
OriginalAbsoluteSizeX.Name = "OriginalX"
OriginalAbsoluteSizeX.Value = script.Parent.AbsoluteSize.X
OriginalAbsoluteSizeX.Parent = script.Parent
local OriginalAbsoluteSizeY =  Instance.new("NumberValue")
OriginalAbsoluteSizeX.Name = "OriginalY"
OriginalAbsoluteSizeY.Value = script.Parent.AbsoluteSize.Y
OriginalAbsoluteSizeY.Parent = script.Parent

local function GetScaledSizeFromOffset(OffsetX,OffsetY) -- The Function that returns the scale from original size.
	local ScreenSize = game.Workspace.CurrentCamera.ViewportSize
	local XRatio = OffsetX / ScreenSize.X
	local YRatio = OffsetY / ScreenSize.Y
	return UDim2.new(XRatio,0,YRatio,0)
end

script.Parent.AncestryChanged:Connect(function() -- Call it everytime it is parented to something else.
	script.Parent.Size = GetScaledSizeFromOffset(OriginalAbsoluteSizeX.Value,OriginalAbsoluteSizeY.Value)
end)

script.Parent.Size = GetScaledSizeFromOffset(OriginalAbsoluteSizeX.Value,OriginalAbsoluteSizeY.Value) -- Call it once to begin with.

Hope this helps.

2 Likes

There’s a plugin called AutoScale Lite that includes a feature that converts offset to scale on the selected ui.

1 Like

@Anurag_UdayS Great start, but I have a couple of suggestions :slight_smile:

  1. I would suggest just using variables instead of NumberValues
    • In fact, no need to store and update anything at all really, you can just access script.Parent.AbsoluteSize inside your function directly
    • So you could delete your Changed listener!
  2. You might want to use the size and position of the thing your clicking on, instead of the ViewportSize.
    • This would mean subtracting the AbsolutePosition of the canvas object from the mouse position before you divide it

If you’re trying to set on the screen GUI without any frame/parent for the pixel(UI object?) then you should use the ViewportSize property from the camera instead of the AbsoluteSize of a possible parent object.

~ sorry for many edits

local cameraSizeY = workspace.CurrentCamera.ViewportSize.Y
local newScalePositionY = mouse.Y / cameraSizeY

You can apply that calculation to fit to your needs, divide the offset position by the absolutesize of the parent object, if there’s no parent you must use the ViewportSize

There’s a Plugin called AutoScale Nightly - Roblox

--Position
function AutoScaleLibrary.SetPos(params)
	--SCALE
	if params == "Scale" then
		for _, v in ipairs(game.Selection:Get()) do
			if v:isA("GuiBase2d") and v.Parent and PropertyExists(v, "Position") then
				if PropertyExists(v.Parent, "AbsoluteSize") then
					local ScaleXPos = v.Position.X.Offset/v.Parent.AbsoluteSize.X + v.Position.X.Scale
					local ScaleYPos = v.Position.Y.Offset/v.Parent.AbsoluteSize.Y  + v.Position.Y.Scale
					v.Position = UDim2.new(ScaleXPos, 0, ScaleYPos, 0)
				end
			end
		end
		
		CustomPrint("Converted to Scale Pos", script.Parent:WaitForChild("CustomPrint"))
		ChangeHistoryService:SetWaypoint("Converted UI element to Scale Position")
	--OFFSET	
	elseif params == "Offset" then
		for _, v in ipairs(game.Selection:Get()) do
			if v:isA("GuiBase2d") and v.Parent and PropertyExists(v, "Position") then
				if  PropertyExists(v.Parent, "AbsoluteSize") then
					local OffsetXPos = v.Position.X.Scale*v.Parent.AbsoluteSize.X + v.Position.X.Offset
					local OffsetYPos = v.Position.Y.Scale*v.Parent.AbsoluteSize.Y + v.Position.Y.Offset
					v.Position = UDim2.new(0, OffsetXPos, 0, OffsetYPos)
				end	
			end
		end
		
		CustomPrint("Converted to Offset Pos", script.Parent:WaitForChild("CustomPrint"))
	    ChangeHistoryService:SetWaypoint("Converted UI element to Offset Position")	
	end
end

--Size
function AutoScaleLibrary.SetSize(params)
	--SCALE
	if params == "Scale" then
		for _, v in ipairs(game.Selection:Get()) do
			if v:isA("GuiBase2d") and PropertyExists(v, "Size") then
				local Viewport_Size
				
				if PropertyExists(v.Parent, "AbsoluteSize") then
					Viewport_Size = v.Parent.AbsoluteSize
				elseif v:FindFirstAncestorWhichIsA("GuiObject") and PropertyExists(v:FindFirstAncestorWhichIsA("GuiObject"), "AbsoluteSize") then
					Viewport_Size = v:FindFirstAncestorWhichIsA("GuiObject").AbsoluteSize
				else
					Viewport_Size = workspace.CurrentCamera.ViewportSize
				end
				
				local LB_Size = v.AbsoluteSize
				v.Size = UDim2.new(LB_Size.X/Viewport_Size.X,0,LB_Size.Y/Viewport_Size.Y, 0)
			end
		end
		
		CustomPrint("Converted to Scale Size", script.Parent:WaitForChild("CustomPrint"))
		ChangeHistoryService:SetWaypoint("Converted UI element to Scale Size")
	--OFFSET
	elseif params == "Offset" then	
		for _, v in ipairs(game.Selection:Get()) do
			if v:isA("GuiBase2d") and PropertyExists(v, "Size")then
				local LB_Size = v.AbsoluteSize
				v.Size = UDim2.new(0, LB_Size.X, 0, LB_Size.Y)
			end
		end
		
		CustomPrint("Converted to Offset Size", script.Parent:WaitForChild("CustomPrint"))
	    ChangeHistoryService:SetWaypoint("Converted UI element to Offset Size")
	end
end
2 Likes