When I have a ScrollingFrame on a tablet, moving it in any direction is very smooth. If I try pull it outside the canvassize, it will smoothly return to it’s maximum boundaries.
If I use the same scrollingFrame on PC, I cant even move unless I use the scrollwheel.
This can be seen in my repro file: Repro.rbxl (34.3 KB)
Play as normal
You can’t move unless you use the mouse scroll-wheel
Switch on Device Simulator (pick any phone) and press Play
Now the scrollframe moves smoothly.
How can I get the behavior from 2. to work in PC mode (1)?
Although I am a little confused, my assumption on why this is happening is because of how PC scroll wheels work. A mouse scroll wheel moves in increments. If you try scrolling right now, unless you have one of those mice that unlock rotation, you will see that it snaps into a position, therefore not being smooth.
My best recommendation is to disable scrolling if you are on PC and implement your own scrolling algorithm, but detecting a scroll and then either incrementing by a small amount or tweening to the desired location.
Not sure why you would want it, but here you go (local script in the screen gui):
--!strict
local TweenService = game:GetService("TweenService")
local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")
local TWEEN_INFO = TweenInfo.new(2, Enum.EasingStyle.Quint)
local client = Players.LocalPlayer
local scrollingFrame = script.Parent.ScrollingFrame
local mouse = client:GetMouse()
local mouseMoveConnection: RBXScriptConnection
local lastMouseX: number
local lastMouseY: number
local backTweens: {[GuiObject]: Tween} = {}
local function childAdded(child: Instance)
if child:IsA("GuiObject") then
backTweens[child] = TweenService:Create(child, TWEEN_INFO, {Position = child.Position})
end
end
local function childRemoved(child: Instance)
if child:IsA("GuiObject") then
backTweens[child] = nil
end
end
local function mouseMove()
local dx = mouse.X - lastMouseX
local dy = mouse.Y - lastMouseY
for element, _ in pairs(backTweens) do
local elementX = element.Position.X.Offset
local elementY = element.Position.Y.Offset
local newPos = UDim2.fromOffset(elementX + dx * 5, elementY + dy * 5)
TweenService:Create(element, TWEEN_INFO, {Position = newPos}):Play()
end
lastMouseX = mouse.X
lastMouseY = mouse.Y
end
local function inputBegan(input: InputObject)
if input.UserInputType == Enum.UserInputType.MouseButton1 then
lastMouseX = mouse.X
lastMouseY = mouse.Y
mouseMoveConnection = mouse.Move:Connect(mouseMove)
end
end
local function inputEnded(input: InputObject)
if input.UserInputType == Enum.UserInputType.MouseButton1 then
mouseMoveConnection:Disconnect()
for element, tweenBack in pairs(backTweens) do
tweenBack:Play()
end
end
end
scrollingFrame.ChildAdded:Connect(childAdded)
scrollingFrame.ChildRemoved:Connect(childRemoved)
UserInputService.InputBegan:Connect(inputBegan)
UserInputService.InputEnded:Connect(inputEnded)
for _, child in ipairs(scrollingFrame:GetChildren()) do
childAdded(child)
end
It’s relatively simple to make it register touches and pans alongside the clicks and moves, but when testing it in the emulator, it gets overriden by the default behavior, so no need to do that.