Howdy. My goal is to shrink a frame towards the mouse. My idea was if I could position the anchor point to where the mouse first clicked, the frame should resize naturally based off that position.
We don’t HAVE to move the anchor point if someone has a different solution. Either way I’m clueless on how to achieve this.
local textButton = script.Parent
function mouseButton1Down()
warn('button was clicked, move anchor point to position')
end
textButton.MouseButton1Down:Connect(mouseButton1Down)
Those values would be crazy numbers depending on where my mouse is.
local textButton = script.Parent
local mouse = game.Players.LocalPlayer:GetMouse()
function mouseButton1Down()
warn(mouse.x,mouse.y)
end
textButton.MouseButton1Down:Connect(mouseButton1Down)
If you are using scale instead of offset, then yeah these would seem like crazy numbers. However it returns pixels which is what offset uses. But if you would rather use scale, you can convert them to scale values using what @lrd14 said.
You can get the desired anchor point value by that:
local textButton = script.Parent
local player = ...
local function mouseButton1Down()
local mouse = player:GetMouse()
local mouse_position = Vector2.new(mouse.X, mouse.Y)
local anchor_point = (mouse_position - textButton.AbsolutePosition) / textButton.AbsoluteSize
textButton.AnchorPoint = anchor_point
end
textButton.MouseButton1Down:Connect(mouseButton1Down)
Thank you! This is exactly what I was looking for!
This is an unexpected outcome that I wish to resolve… How can I keep the TextButton position locked into what it was before changing the anchor point. I have to offset the position based off the “anchor_point”?
Don’t worry about it boss! I found what I was looking for in another post. Thank you for the help!
--!strict
local Workspace = game:GetService("Workspace")
local Util = {}
-- PS stands for position and size
function Util.GetParentPS(gui: GuiObject): (Vector2, Vector2)
local parent = gui.Parent
if parent then
if parent:IsA("GuiObject") then
return parent.AbsolutePosition, parent.AbsoluteSize
end
end
return Vector2.zero, Workspace.Camera.ViewportSize
end
function Util.SetAnchorPointWithoutMoving(gui: GuiObject, desiredPoint: Vector2)
local parentPosition, parentSize = Util.GetParentPS(gui)
local childSize = gui.AbsoluteSize
local childPosition = gui.AbsolutePosition
-- Calculate the relative position
childPosition = childPosition - parentPosition
local correctionOffsetX = childSize.X * desiredPoint.X
local correctionOffsetY = childSize.Y * desiredPoint.Y
local correctedPosition = UDim2.fromScale(
(childPosition.X + correctionOffsetX) / parentSize.X,
(childPosition.Y + correctionOffsetY) / parentSize.Y
)
gui.AnchorPoint = desiredPoint
gui.Position = correctedPosition
end
return Util
I can’t believe that got dug up again, enjoy the fix.
If you need any more help on other GUI issues feel free to ask me, I should have some knowledge of it.
I’m using a GUI dragging module with your anchor point function. When I click the bottom half AND ONLY the bottom half, it does that weird offset. When I remove the anchor aspect of the script I no longer have the issue when clicking the bottom half.
Sorry this is a lot of code to look at! Just lemme know if anything comes to mind. Thank you.
--[[
@Author: Spynaz
@Description: Enables dragging on GuiObjects. Supports both mouse and touch.
For instructions on how to use this module, go to this link:
https://devforum.roblox.com/t/simple-module-for-creating-draggable-gui-elements/230678
--]]
local UDim2_new = UDim2.new
local UIScaleObject = script.UIScaleObject.Value
local UserInputService = game:GetService("UserInputService")
local DraggableObject = {}
DraggableObject.__index = DraggableObject
-- Sets up a new draggable object
function DraggableObject.new(Object)
local self = {}
self.Object = Object
self.DragStarted = nil
self.DragEnded = nil
self.Dragged = nil
self.Dragging = false
setmetatable(self, DraggableObject)
return self
end
function DraggableObject:ZIndexOverlap(index)
local frame = self.Object
for a,child in frame:GetDescendants() do
if child:IsA('GuiBase') then
child.ZIndex += index
end
end
frame.ZIndex += index
end
function SetAnchorPoint(frame,position)
local mouse_position = Vector2.new(position.X,position.Y)
local anchor_point = (mouse_position - frame.AbsolutePosition) / frame.AbsoluteSize
local Canvas = frame.Parent
local ParentSize = Canvas.AbsoluteSize
local ParentPosition = Canvas.AbsolutePosition
local ChildSize = frame.AbsoluteSize
local ChildPosition = frame.AbsolutePosition
ChildPosition = ChildPosition - ParentPosition
local CorrectionOffsetX = ChildSize.X * anchor_point.X
local CorrectionOffsetY = ChildSize.Y * anchor_point.Y
local CorrectedUDim2 = UDim2.fromScale((ChildPosition.X + CorrectionOffsetX) / ParentSize.X, (ChildPosition.Y + CorrectionOffsetY) / ParentSize.Y)
frame.AnchorPoint = anchor_point
frame.Position = CorrectedUDim2
end
-- Enables dragging
function DraggableObject:Enable()
local object = self.Object
local dragInput = nil
local dragStart = nil
local startPos = nil
local preparingToDrag = false
-- Updates the element
local function update(input)
local delta = (input.Position - dragStart)/UIScaleObject.Scale
local newPosition = UDim2_new(startPos.X.Scale, startPos.X.Offset + delta.X, startPos.Y.Scale, startPos.Y.Offset + delta.Y)
object.Position = newPosition
return newPosition
end
self.InputBegan = object.InputBegan:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
SetAnchorPoint(object,UserInputService:GetMouseLocation()) --SETTING THE ANCHOR POINT HERE
preparingToDrag = true
self:ZIndexOverlap(10)
local connection
connection = input.Changed:Connect(function()
if input.UserInputState == Enum.UserInputState.End and (self.Dragging or preparingToDrag) then
self.Dragging = false
connection:Disconnect()
if self.DragEnded and not preparingToDrag then
self.DragEnded()
end
self:ZIndexOverlap(-10)
preparingToDrag = false
end
end)
end
end)
self.InputChanged = object.InputChanged:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then
dragInput = input
end
end)
self.InputChanged2 = UserInputService.InputChanged:Connect(function(input)
if object.Parent == nil then
self:Disable()
return
end
if preparingToDrag then
preparingToDrag = false
if self.DragStarted then
self.DragStarted()
end
self.Dragging = true
dragStart = input.Position
startPos = object.Position
end
if input == dragInput and self.Dragging then
local newPosition = update(input)
if self.Dragged then
self.Dragged(newPosition)
end
end
end)
end
-- Disables dragging
function DraggableObject:Disable()
self.InputBegan:Disconnect()
self.InputChanged:Disconnect()
self.InputChanged2:Disconnect()
if self.Dragging then
self.Dragging = false
if self.DragEnded then
self.DragEnded()
end
end
end
return DraggableObject
Found this issue. I needed to subtract the “GuiInset” from the mouse Y position.
local guiInset = game:GetService('GuiService'):GetGuiInset()
local function SetAnchorPoint(Gui, mouse)
local mouse_position = Vector2.new(mouse.X, mouse.Y-guiInset.Y)