OK, first, your code is overly convoluted. You’re converting to and from local and global coordinates in multiple places.
Lets refer to your “self.vendor” node as the “parent”, your “map” function as “clamp”, and assume the size of the “parent” node is the limit of your slider range. All you need to do is:
-- get offset/local position of mouse relative to parent node...and divide by parent node scale
local new_x = (action.x - parent_pos.x) * (1/parent_scale.x)
-- then clamp that pos to within the slider range
new_x = clamp(new_x, -parent_size.x/2, parent_size.x/2)
That gives you the local x coordinate you need to use on your slider node, either with gui.animate or gui.set_position.
Your current trouble, when you resize the window, is because of your nodes’ adjust modes. If you set your nodes to “Stretch” mode, it should work fine, but presumably you don’t want your GUI to stretch. With the other adjust modes, you will need to apply both a scale and an offset to your mouse position before you use it.
I added this to Rendercam so I would never have to deal with it again, so I’ll just refer you to my code for that.
Here’s the function I call whenever the window is changed to calculate the scale and offset for each adjust mode:
Click to show code
local function calculate_gui_adjust_data(winX, winY, configX, configY)
-- winX, winY = the new window size
-- configX, configY = the window size settings in your game.project file
-- the X and Y scale of the current window size relative to the original one:
-- these are used to calculate basically everything else
local sx, sy = winX / configX, winY / configY
-- Fit
-- M.guiAdjust is a table that holds the stuff for each adjust mode
local adj = M.guiAdjust[M.GUI_ADJUST_FIT]
local scale = math.min(sx, sy) -- scale for FIT mode is the -smaller- of sx and sy
adj.sx = scale; adj.sy = scale
adj.ox = (winX - configX * adj.sx) * 0.5 / adj.sx -- x offset
adj.oy = (winY - configY * adj.sy) * 0.5 / adj.sy -- y offset
-- Zoom
adj = M.guiAdjust[M.GUI_ADJUST_ZOOM]
scale = math.max(sx, sy) -- scale for ZOOM mode is the -larger- of sx and sy
adj.sx = scale; adj.sy = scale
adj.ox = (winX - configX * adj.sx) * 0.5 / adj.sx -- x offset
adj.oy = (winY - configY * adj.sy) * 0.5 / adj.sy -- y offset
-- Stretch
adj = M.guiAdjust[M.GUI_ADJUST_STRETCH]
adj.sx = sx; adj.sy = sy -- scale for STRETCH mode is...stretched - the scale is non-uniform
-- distorts to fit window, offsets always zero
end
And here’s the function I use to convert from screen coordinates to “gui” coordinates
Click to show code
function M.screen_to_gui(x, y, adjust, isSize)
-- note, this converts from action.screen_x/screen_y, not action.x/y
if not isSize then
x = x / M.guiAdjust[adjust].sx - M.guiAdjust[adjust].ox
y = y / M.guiAdjust[adjust].sy - M.guiAdjust[adjust].oy
else -- if you're converting to a GUI -size- rather than a position, you don't want the offset
x = x / M.guiAdjust[adjust].sx
y = y / M.guiAdjust[adjust].sy
end
return x, y
end
Here’s a little demo project: Slider Test.zip (3.7 KB) (it uses Rendercam, but you only need to add the two functions above to your own setup.)