ease = 0.0, 0.02, 0.08, 0.18, 0.32, 0.5, 0.68, 0.82, 0.92, 0.98, 1.0 def eased(from_, to): interval = to - from_ for e in ease: yield round(from_ + interval * e) def eased_xy(from_x, from_y, to_x, to_y): yield from zip(eased(from_x, to_x), eased(from_y, to_y)) def schedule_animation(callback, from_x, from_y, to_x, to_y, delay=25): t = delay coords = eased_xy(from_x, from_y, to_x, to_y) next(coords) # Discard the starting coords, we're already there! for x, y in coords: callback(t, x, y) # Some after(...) call. t += delay ##def callback(t, x, y): ## canvas.after(t, lambda: canvas.moveto(tag, x, y)) ## # Where tag comes from the surround scope. if __name__ == '__main__': # Show it. schedule_animation(print, 10, 1000, 1000, 10) # Prints: # 25 30 980 # 50 89 921 # 75 188 822 # 100 327 683 # 125 505 505 # 150 683 327 # 175 822 188 # 200 921 89 # 225 980 30 # 250 1000 10