mirror of
https://github.com/centau/vide.git
synced 2026-08-20 14:41:37 +00:00
Added smoothing time for vide.draggable utility
This commit is contained in:
parent
babdeed441
commit
cfa61c3b2a
1 changed files with 49 additions and 19 deletions
|
|
@ -1,19 +1,15 @@
|
||||||
-- src/draggable.luau
|
-- src/draggable.luau
|
||||||
local UserInputService = game and game:GetService("UserInputService") or nil
|
local UserInputService = game and game:GetService("UserInputService") or nil
|
||||||
|
|
||||||
-- Factory: injects action from vide
|
|
||||||
return function(action)
|
return function(action)
|
||||||
return function(opts)
|
return function(opts)
|
||||||
opts = opts or {}
|
opts = opts or {}
|
||||||
local axis = opts.axis or "both" -- "x" | "y" | "both"
|
local axis = opts.axis or "both" -- "x" | "y" | "both"
|
||||||
|
local smoothTime = tonumber(opts.smoothTime) or 0 -- seconds; 0 = off
|
||||||
|
|
||||||
return action(function(gui)
|
return action(function(gui)
|
||||||
if not UserInputService then
|
if not UserInputService then return end
|
||||||
return
|
if typeof(gui) ~= "Instance" or not gui:IsA("GuiObject") then return end
|
||||||
end
|
|
||||||
if typeof(gui) ~= "Instance" or not gui:IsA("GuiObject") then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local dragging = false
|
local dragging = false
|
||||||
local dragInput
|
local dragInput
|
||||||
|
|
@ -25,6 +21,11 @@ return function(action)
|
||||||
local uisConn
|
local uisConn
|
||||||
local destroyingConn
|
local destroyingConn
|
||||||
|
|
||||||
|
-- smoothing state (offset-space)
|
||||||
|
local currentX, currentY
|
||||||
|
local targetX, targetY
|
||||||
|
local lastT = os.clock()
|
||||||
|
|
||||||
local function disconnectAll()
|
local function disconnectAll()
|
||||||
if beganConn then beganConn:Disconnect(); beganConn = nil end
|
if beganConn then beganConn:Disconnect(); beganConn = nil end
|
||||||
if inputChangedConn then inputChangedConn:Disconnect(); inputChangedConn = nil end
|
if inputChangedConn then inputChangedConn:Disconnect(); inputChangedConn = nil end
|
||||||
|
|
@ -32,7 +33,11 @@ return function(action)
|
||||||
if destroyingConn then destroyingConn:Disconnect(); destroyingConn = nil end
|
if destroyingConn then destroyingConn:Disconnect(); destroyingConn = nil end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function update(input)
|
local function setPosition(xOff, yOff)
|
||||||
|
gui.Position = UDim2.new(startPos.X.Scale, xOff, startPos.Y.Scale, yOff)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function updateTarget(input)
|
||||||
local delta = input.Position - dragStart
|
local delta = input.Position - dragStart
|
||||||
|
|
||||||
local xOff = startPos.X.Offset
|
local xOff = startPos.X.Offset
|
||||||
|
|
@ -45,7 +50,32 @@ return function(action)
|
||||||
yOff = startPos.Y.Offset + delta.Y
|
yOff = startPos.Y.Offset + delta.Y
|
||||||
end
|
end
|
||||||
|
|
||||||
gui.Position = UDim2.new(startPos.X.Scale, xOff, startPos.Y.Scale, yOff)
|
targetX, targetY = xOff, yOff
|
||||||
|
|
||||||
|
-- init current on first target
|
||||||
|
if currentX == nil then
|
||||||
|
currentX, currentY = targetX, targetY
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function step()
|
||||||
|
if not dragging or not dragInput then return end
|
||||||
|
if smoothTime <= 0 then
|
||||||
|
setPosition(targetX, targetY)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local now = os.clock()
|
||||||
|
local dt = now - lastT
|
||||||
|
lastT = now
|
||||||
|
|
||||||
|
-- alpha in [0..1]
|
||||||
|
local alpha = 1 - math.exp(-dt / smoothTime)
|
||||||
|
|
||||||
|
currentX = currentX + (targetX - currentX) * alpha
|
||||||
|
currentY = currentY + (targetY - currentY) * alpha
|
||||||
|
|
||||||
|
setPosition(currentX, currentY)
|
||||||
end
|
end
|
||||||
|
|
||||||
beganConn = gui.InputBegan:Connect(function(input)
|
beganConn = gui.InputBegan:Connect(function(input)
|
||||||
|
|
@ -54,15 +84,17 @@ return function(action)
|
||||||
dragStart = input.Position
|
dragStart = input.Position
|
||||||
startPos = gui.Position
|
startPos = gui.Position
|
||||||
|
|
||||||
-- stop dragging when the same input ends
|
-- reset smoothing state
|
||||||
|
currentX, currentY, targetX, targetY = nil, nil, nil, nil
|
||||||
|
lastT = os.clock()
|
||||||
|
|
||||||
|
updateTarget(input)
|
||||||
|
|
||||||
local changedConn
|
local changedConn
|
||||||
changedConn = input.Changed:Connect(function()
|
changedConn = input.Changed:Connect(function()
|
||||||
if input.UserInputState == Enum.UserInputState.End then
|
if input.UserInputState == Enum.UserInputState.End then
|
||||||
dragging = false
|
dragging = false
|
||||||
if changedConn then
|
if changedConn then changedConn:Disconnect(); changedConn = nil end
|
||||||
changedConn:Disconnect()
|
|
||||||
changedConn = nil
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
@ -76,18 +108,16 @@ return function(action)
|
||||||
|
|
||||||
uisConn = UserInputService.InputChanged:Connect(function(input)
|
uisConn = UserInputService.InputChanged:Connect(function(input)
|
||||||
if input == dragInput and dragging then
|
if input == dragInput and dragging then
|
||||||
update(input)
|
updateTarget(input)
|
||||||
|
step()
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- Cleanup without vide.cleanup which printed false errors into console
|
|
||||||
if gui.Destroying then
|
if gui.Destroying then
|
||||||
destroyingConn = gui.Destroying:Connect(disconnectAll)
|
destroyingConn = gui.Destroying:Connect(disconnectAll)
|
||||||
else
|
else
|
||||||
destroyingConn = gui.AncestryChanged:Connect(function(_, parent)
|
destroyingConn = gui.AncestryChanged:Connect(function(_, parent)
|
||||||
if parent == nil then
|
if parent == nil then disconnectAll() end
|
||||||
disconnectAll()
|
|
||||||
end
|
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue