How to achieve smooth mouse movement instead of teleportation between points on turns in pyautogui? How to setup paths for your mouse to move instead of it just teleporting unless you try to manually interpolate it for hours?
Pyautogui is a library meant for automation and isn't meant to be used for smooth movement, you can consider other libraries for this if you can find one.
This is a bit of a workaround
To achieve proper smooth motion especially with curves we use mathematical functions to determine our path and loops to increment our x cordinate (in my example the x cordinate is "a" and the y cordinate is "b").
Use Desmos, or a different graphical calcualtor for visualizing the graph of the function before making it in code. Might seem like extra effort but this is vital.
Important: the y cordinate is inversed in pyautogui, account for that.
I used "x" and "y" variables as center's of the screen on respective axis but you can start wherever you want by replacing them.
Then we set pyautogui.pause
to 0 so there's no pause between movements. It's quite frankly broken, duration values above 0.2 yield slow speeds, and <= 0.2 offer very high speed, this is not meant to be used for this but it just works. By setting the duration to 0.2 we can edit our step (the incrementation of the function) to achieve the necessary speed. And it is smooth.
Here's a functional example: it draws an infinity symbol with your mouse. Make sure that you are able to stop it in your IDE, it's ctrl+F2 in Pycharm.
import pyautogui
import time
screenSize = pyautogui.size()
x = screenSize[0]/2
y = screenSize[1]/2
time.sleep(3)
# SETTINGS
pyautogui.PAUSE = 0
# Multiplier
size = 100
# Duration
speed = 0.2
# Incrementation
step = 0.0001
pyautogui.moveTo(x, y, 0)
a = step
loopStart = True
while True:
if loopStart:
while True:
a += step
b = -(a - 2) * 0.5 - 1
pyautogui.moveTo(x + a * size, y + b * size, speed * 0.5, pyautogui.linear)
if a >= 2:
break
while True:
a += step
b = (((a - 2) ** 4) * 0.8) - 1
pyautogui.moveTo(x + a * size, y + b * size, speed * 0.5, pyautogui.linear)
if a >= 3:
a += step
break
while True:
a -= step
b = -(((a - 2) ** 4) * 0.8) + 1
pyautogui.moveTo(x + a * size, y + b * size, speed * 0.5, pyautogui.linear)
if a <= 2:
a -= step * 2
break
while True:
a -= step
b = a * 0.5
pyautogui.moveTo(x + a * size, y + b * size, speed * 0.5, pyautogui.linear)
if a <= -2:
a += step
break
# Side 2
while True:
a -= step
b = (((a + 2) ** 4) * 0.8) - 1
pyautogui.moveTo(x + a * size, y + b * size, speed * 0.5, pyautogui.linear)
if a <= -3:
a -= step
break
while True:
a += step
b = -(((a + 2) ** 4) * 0.8) + 1
pyautogui.moveTo(x + a * size, y + b * size, speed * 0.5, pyautogui.linear)
if a >= -2:
a += step*2
break
while True:
a += step
b = -(a + 2) * 0.5 + 1
pyautogui.moveTo(x + a * size, y + b * size, speed * 0.5, pyautogui.linear)
if a >= 2:
loopStart = False
break
# I think this is also accomplishable by running code in parallel, but this weird method is better anyway.
# Ideally you want to use a proper library like the currently broken (as of August 2023) Autopy for this.
I know this is a highly requested question but I haven't found a single proper answer which weirded me out a lot and resulted in the creation of this QnA-ish post. Hope someone finds this useful <3