I have a function that zooms in a frame using UIScale, but it depends on anchor point. I have no idea how to make it zoom properly into mouse location.
function updateMainBoxZoom(v, czv, i)
if typeof(v) == "boolean" then
czv = czv or zoomPercentMin
local zv = (czv + (zoomPercentMax - czv) * (zoom / maxZoom))
if v == false then
zv = -zv
end
v = zoom + zv
end
v = math.clamp(v, minZoom, maxZoom)
zoom = v
zoomFrame.ZoomOutButton.ZoomLabel.Text = "🔎 " .. (math.floor(zoom * 10) / 10)
local lastV = mainBoxUIScale.Scale
if lastV == v then
return
end
if i == true then
mainBoxUIScale.Scale = v
return
end
local mousePosition = UDim2.fromOffset(math.floor(mouse.X - mainFrameBox.Position.X.Offset), math.floor(mouse.Y - mainFrameBox.Position.Y.Offset))
local x1 = mousePosition.X.Offset * (zoom / lastV)
local y1 = mousePosition.Y.Offset * (zoom / lastV)
local x2 = mainFrameBox.Position.X.Offset + (mousePosition.X.Offset - x1)
local y2 = mainFrameBox.Position.Y.Offset + (mousePosition.Y.Offset - y1)
mainFrameBox.Position = UDim2.new(0, x2, 0, y2)
mainBoxUIScale.Scale = v
updatePixelHover()
end
When I first start zooming with this code, it moves the frame incorrectly because anchor point is 0.5, 0.5 but it works fine with 0, 0. I need it to be centered however, that’s why I use anchor point.
To zoom into the mouse location properly, you need to adjust the position of the frame relative to the mouse position before and after the zoom.
Try this new code:
function updateMainBoxZoom(v, czv, i)
if typeof(v) == “boolean” then
czv = czv or zoomPercentMin
local zv = (czv + (zoomPercentMax - czv) * (zoom / maxZoom))
if v == false then
zv = -zv
end
v = zoom + zv
end
v = math.clamp(v, minZoom, maxZoom)
zoom = v
zoomFrame.ZoomOutButton.ZoomLabel.Text = " " … (math.floor(zoom * 10) / 10)
local lastV = mainBoxUIScale.Scale
if lastV == v then
return
end
if i == true then
mainBoxUIScale.Scale = v
return
end
local mousePosition = UDim2.fromOffset(mouse.X - mainFrameBox.AbsolutePosition.X, mouse.Y - mainFrameBox.AbsolutePosition.Y)
local scaleChange = v / lastV
local newOffsetX = mousePosition.X.Offset - (mousePosition.X.Offset * scaleChange)
local newOffsetY = mousePosition.Y.Offset - (mousePosition.Y.Offset * scaleChange)
mainFrameBox.Position = UDim2.new(0, mainFrameBox.Position.X.Offset + newOffsetX, 0, mainFrameBox.Position.Y.Offset + newOffsetY)
mainBoxUIScale.Scale = v
updatePixelHover()
function updateMainBoxZoom(v, czv, i)
if typeof(v) == "boolean" then
czv = czv or zoomPercentMin
local zv = (czv + (zoomPercentMax - czv) * (zoom / maxZoom))
if v == false then
zv = -zv
end
v = zoom + zv
end
v = math.clamp(v, minZoom, maxZoom)
zoom = v
zoomFrame.ZoomOutButton.ZoomLabel.Text = "🔎 " .. (math.floor(zoom * 10) / 10)
local lastV = mainBoxUIScale.Scale
if lastV == v then
return
end
if i == true then
mainBoxUIScale.Scale = v
return
end
local mouseOffsetX = mouse.X - mainFrameBox.Position.X.Offset
local mouseOffsetY = mouse.Y - mainFrameBox.Position.Y.Offset
local mousePosition = UDim2.fromOffset(mouseOffsetX, mouseOffsetY)
local scaleRatio = zoom / lastV
local newPosX = mainFrameBox.Position.X.Offset - (mouseOffsetX * (scaleRatio - 1))
local newPosY = mainFrameBox.Position.Y.Offset - (mouseOffsetY * (scaleRatio - 1))
mainFrameBox.Position = UDim2.new(0, newPosX, 0, newPosY)
mainBoxUIScale.Scale = v
updatePixelHover()
end
If the anchor point is centered at 0.5, 0.5, this means that the magnification must be adjusted so that the frame remains centered relative to the anchor point
function updateMainBoxZoom(v, czv, i)
if typeof(v) == "boolean" then
czv = czv or zoomPercentMin
local zv = (czv + (zoomPercentMax - czv) * (zoom / maxZoom))
if v == false then
zv = -zv
end
v = zoom + zv
end
v = math.clamp(v, minZoom, maxZoom)
zoom = v
zoomFrame.ZoomOutButton.ZoomLabel.Text = "🔎 " .. (math.floor(zoom * 10) / 10)
local lastV = mainBoxUIScale.Scale
if lastV == v then
return
end
if i == true then
mainBoxUIScale.Scale = v
return
end
local scaleRatio = zoom / lastV
local mouseOffsetX = mouse.X - mainFrameBox.AbsolutePosition.X
local mouseOffsetY = mouse.Y - mainFrameBox.AbsolutePosition.Y
local anchorX = mainFrameBox.AnchorPoint.X
local anchorY = mainFrameBox.AnchorPoint.Y
local centerX = mainFrameBox.AbsoluteSize.X * anchorX
local centerY = mainFrameBox.AbsoluteSize.Y * anchorY
local newPosX = mainFrameBox.Position.X.Offset - (mouseOffsetX - centerX) * (scaleRatio - 1)
local newPosY = mainFrameBox.Position.Y.Offset - (mouseOffsetY - centerY) * (scaleRatio - 1)
mainFrameBox.Position = UDim2.new(0, newPosX, 0, newPosY)
mainBoxUIScale.Scale = v
updatePixelHover()
end
To ensure that the mainFrameBox remains correctly centered relative to the anchor point and that it zooms correctly based on that point
function updateMainBoxZoom(v, czv, i)
if typeof(v) == "boolean" then
czv = czv or zoomPercentMin
local zv = (czv + (zoomPercentMax - czv) * (zoom / maxZoom))
if v == false then
zv = -zv
end
v = zoom + zv
end
v = math.clamp(v, minZoom, maxZoom)
zoom = v
zoomFrame.ZoomOutButton.ZoomLabel.Text = "🔎 " .. (math.floor(zoom * 10) / 10)
local lastV = mainBoxUIScale.Scale
if lastV == v then
return
end
if i == true then
mainBoxUIScale.Scale = v
return
end
local scaleRatio = zoom / lastV
local absPosX = mainFrameBox.AbsolutePosition.X
local absPosY = mainFrameBox.AbsolutePosition.Y
local absSizeX = mainFrameBox.AbsoluteSize.X
local absSizeY = mainFrameBox.AbsoluteSize.Y
local anchorX = mainFrameBox.AnchorPoint.X
local anchorY = mainFrameBox.AnchorPoint.Y
local centerX = absPosX + absSizeX * anchorX
local centerY = absPosY + absSizeY * anchorY
local mouseOffsetX = mouse.X - absPosX
local mouseOffsetY = mouse.Y - absPosY
local newPosX = absPosX - (mouseOffsetX - centerX) * (scaleRatio - 1)
local newPosY = absPosY - (mouseOffsetY - centerY) * (scaleRatio - 1)
mainFrameBox.Position = UDim2.new(0, newPosX, 0, newPosY)
mainBoxUIScale.Scale = v
updatePixelHover()
end