GUI Object Offset Strangely

Hello - this is my first post, so please tell me if I’m doing anything wrong :slight_smile:

  1. What I want to achieve:
    I want to create a Color Picker that uses HSV to choose a color. The color picker is sort of like a box:
    image
    I created this using gradients in a photo editing software. To determine what color the player’s mouse is hovering over, I planned to get position of the mouse on the image, and then used the Position.X.Scale and the Position.Y.Scale values of that position as the Color3.fromHSV() parameters. (I made sure that the gradient I made in the software was HSV accurate.)

  2. What the issue is:
    Basically, the color picker cursor icon is always offset from the mouse by a certain amount:

Here is the part of the script that determines the position of the Cursor:

ap = hsvImage.AbsolutePosition -- "hsvImage" is the color box
as = hsvImage.AbsoluteSize
local mousePos = uis:GetMouseLocation() -- "uis" is UserInputService
local hueValue = math.clamp((mousePos.X-ap.X)/as.X, 0, 1)
local saturationValue = math.clamp((mousePos.Y-ap.Y)/as.Y, 0, 1)
cursor.Position = UDim2.new(hueValue, 0, saturationValue, 0)
  1. What I’ve tried so far:
    At first I thought it was a problem with the script. But even when I tried doing the same thing, but instead of using X.Scale and Y.Scale, I used X.Offset and Y.Offset. To my surprise, the results were identical. I then thought that it could be something to do with the Cursor Image. The properties of the image were fine, but just to be sure, I made the cursor into a Frame object. Again, the results were the same.

Thank you!

Why don’t you just do something like:

local DistFromBox = (mousePos - ap)
cursor.Position = UDim2.new(0,DistFromBox.X,0,DistFromBox.Y)

You want to line up the cursor with the mouse after all rather than calculating it off of your HSV values.

I wanted to use X.Scale and Y.Scale so that it would be easier to convert the Position values into a Color3.fromHSV() instance. But I’ll try doing what you suggested.

1 Like

Yeah - I tried what you suggested, and, again, the cursor was offset just as before. It didn’t work.

on second thought, i think your calculations are fine, even the ones you were doing in the original piece of code.

Are you 100% sure it’s not the image being miss-sized?
Try printing out ‘DistFromBox’ and the position of the cursor and let me know what that says too

Lastly, make sure the anchor point of the cursor is (0.5,0.5)

I made sure that the anchor point is (0.5,0.5), and I have tried printing those things before. (Well, I printed mousePos, and also the position of the cursor.) What I found was that mousePos was different than the actual position, meaning that for some reason, the cursor isn’t being set to exactly the position I tell it to.

Can i have a look at the entire function? if you don’t mind

Sure. I have this function, and then call it with the correct parameters:

function moveHSVBox(hsvImage, cursor, colorPreview) -- I don't use colorPreview for now
	local mouseDown = false
	local inBounds = false
	local ap = hsvImage.AbsolutePosition
	local as = hsvImage.AbsoluteSize
	local h,s,v = colorPreview.BackgroundColor3:ToHSV() -- I don't use this for now
	hsvImage.MouseEnter:Connect(function() inBounds = true end)
	hsvImage.MouseLeave:Connect(function() inBounds = false end)
	uis.InputBegan:Connect(function(input)
		if input.UserInputType == Enum.UserInputType.MouseButton1 and inBounds then
			mouseDown = true
		end
	end)
	uis.InputEnded:Connect(function(input)
		if input.UserInputType == Enum.UserInputType.MouseButton1 then
			mouseDown = false
		end
	end)
	spawn(function()
		while rs.RenderStepped:Wait() do
			if mouseDown then
				ap = hsvImage.AbsolutePosition
				as = hsvImage.AbsoluteSize
				local mousePos = uis:GetMouseLocation()
				local hueValue = math.clamp((mousePos.X-ap.X)/as.X, 0, 1)
				local saturationValue = math.clamp((mousePos.Y-ap.Y)/as.Y, 0, 1)
				cursor.Position = UDim2.new(hueValue, 0, saturationValue, 0)
			end
		end
	end)
end

I can’t find any error within your code.
Just one thing:

local hueValue = math.clamp((mousePos.X-ap.X)/as.X, 0, 1)
local saturationValue = math.clamp((mousePos.Y-ap.Y)/as.Y, 0, 1)

math.clamp shouldn’t be necessary here (once the cursor works).

Everything seems alligned… I will try re-creating this in a place and i will get back to you in a second.

Thanks! And the reason I do

math.clamp()

is because I don’t want the cursor to go off screen. I limit the X.Scale and Y.Scale values to anything between 0 and 1.

I’m very confused but i think i have found a way to make it work

You need to account for the mouse’s size too. The anchor point on the mouse is weird for some reason.
Doing:

cursor.Position = UDim2.new(0,mousePos.X - ap.X,0,mousePos.Y - ap.Y - 24)

Should work a bit better. just make sure you have the -24 since the roblox’s mouse is 24 pixels.

Sorry i wasn’t able to find out much for you, this is extremely weird

EDIT: Wait, i thought of an idea, give me a second.

Oh, wow. Thanks, I’ll try that. But I always thought that the Robox mouse’s anchor point was at the tip of the arrow, isn’t it?

I thought it was too (and it is, we forgot to account for GUI inset), and i gave my other idea a shot. Make sure ‘IgnoreGUIInset’ is enabled on your screengui then it’s fixed.

Oh, I think I found the reason why it was like this. I googled what the Roblox mouse’s size is, and here’s what I found:

The default mouse image is 64x64 pixels, with the mouse taking up 17x24 pixels of space.

So basically, the cursor is centered, but the actual image is mostly a transparent background, while the mouse icon itself is in the bottom right corner of that image. I’ll try doing something with this and make it work.

Although, if the mouse image’s anchor point is (0.5,0.5), then it should work - so I’m assuming that the anchor point is for some reason (0,0).

1 Like

It’s not the mouse sorry for the mix-up, check my previous post.

Turns out it actually doesn’t work. I enabled IgnoreGuiInset, and it still did the same thing.

Thats strange, it fixed the problem when i re-created it, I’ll send you the exact code I have and the set-up tomorrow when im on my computer again.

Okay, thanks. But I noticed that when I turned on IgnoreGuiInset, the size and position of the frame didn’t change. Maybe I just need to somehow update its position so that it actually follows the IgnoreGuiInset? idk…